expenseAllocation: Switch to own MetadataEnum class.

Python's own enum works fine for the simple values that expenseAllocation
uses, but it won't work as well for metadata like taxImplication where
many of the values aren't legal Python identifiers. Introduce our own
MetadataEnum class with the necessary functionality, and switch to that.
This commit is contained in:
Brett Smith 2020-03-05 15:13:17 -05:00
parent 16c47c64b2
commit 5849b562d0
2 changed files with 42 additions and 16 deletions

View file

@ -36,6 +36,36 @@ class _GenericRange:
return self.start <= item < self.stop return self.start <= item < self.stop
class MetadataEnum:
def __init__(self, key, standard_values, aliases_map):
self.key = key
self._stdvalues = frozenset(standard_values)
self._aliases = dict(aliases_map)
self._aliases.update((v, v) for v in standard_values)
assert self._stdvalues == set(self._aliases.values())
def __repr__(self):
return "{}<{}>".format(type(self).__name__, self.key)
def __contains__(self, key):
return key in self._aliases
def __getitem__(self, key):
return self._aliases[key]
def __iter__(self):
return iter(self._stdvalues)
def get(self, key, default_key=None):
try:
return self[key]
except KeyError:
if default_key is None:
return None
else:
return self[default_key]
class PostingChecker: class PostingChecker:
ACCOUNTS = ('',) ACCOUNTS = ('',)
TXN_DATE_RANGE = _GenericRange(DEFAULT_START_DATE, DEFAULT_STOP_DATE) TXN_DATE_RANGE = _GenericRange(DEFAULT_START_DATE, DEFAULT_STOP_DATE)
@ -76,7 +106,7 @@ class PostingChecker:
errors.append(error) errors.append(error)
else: else:
try: try:
set_value = self.VALUES_ENUM[source_value].value set_value = self.VALUES_ENUM[source_value]
except KeyError: except KeyError:
errors.append(errormod.InvalidMetadataError( errors.append(errormod.InvalidMetadataError(
txn, post, self.METADATA_KEY, source_value, txn, post, self.METADATA_KEY, source_value,

View file

@ -14,27 +14,23 @@
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # along with this program. If not, see <https://www.gnu.org/licenses/>.
import enum
from . import core from . import core
class ExpenseAllocations(enum.Enum):
administration = 'administration'
fundraising = 'fundraising'
program = 'program'
admin = administration
class MetaExpenseAllocation(core.PostingChecker): class MetaExpenseAllocation(core.PostingChecker):
ACCOUNTS = ('Expenses:',) ACCOUNTS = ('Expenses:',)
METADATA_KEY = 'expenseAllocation' METADATA_KEY = 'expenseAllocation'
VALUES_ENUM = ExpenseAllocations VALUES_ENUM = core.MetadataEnum(METADATA_KEY, {
'administration',
'fundraising',
'program',
}, {
'admin': 'administration',
})
DEFAULT_VALUES = { DEFAULT_VALUES = {
'Expenses:Services:Accounting': VALUES_ENUM.administration, 'Expenses:Services:Accounting': VALUES_ENUM['administration'],
'Expenses:Services:Administration': VALUES_ENUM.administration, 'Expenses:Services:Administration': VALUES_ENUM['administration'],
'Expenses:Services:Fundraising': VALUES_ENUM.fundraising, 'Expenses:Services:Fundraising': VALUES_ENUM['fundraising'],
} }
def _default_value(self, txn, post): def _default_value(self, txn, post):
return self.DEFAULT_VALUES.get(post.account, self.VALUES_ENUM.program).value return self.DEFAULT_VALUES.get(post.account, 'program')