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:
		
							parent
							
								
									16c47c64b2
								
							
						
					
					
						commit
						5849b562d0
					
				
					 2 changed files with 42 additions and 16 deletions
				
			
		| 
						 | 
					@ -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,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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')
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue