meta_payroll_type: Refactor for more code reuse.
This commit is contained in:
parent
9d41f79c52
commit
7c18bc221f
3 changed files with 79 additions and 44 deletions
|
@ -67,7 +67,12 @@ class HookRegistry:
|
|||
'.meta_repo_links': None,
|
||||
'.meta_rt_links': ['MetaRTLinks'],
|
||||
'.meta_tax_implication': None,
|
||||
'.meta_payroll_type': None,
|
||||
'.meta_payroll_type': [
|
||||
'HealthInsuranceHook',
|
||||
'OtherBenefitsHook',
|
||||
'SalaryHook',
|
||||
'TaxHook',
|
||||
],
|
||||
'.txn_date': ['TransactionDate'],
|
||||
}
|
||||
|
||||
|
|
|
@ -14,56 +14,86 @@
|
|||
# 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/>.
|
||||
|
||||
from . import core
|
||||
import datetime
|
||||
|
||||
from . import core
|
||||
from .. import ranges
|
||||
from .. import data
|
||||
from .. import errors as errormod
|
||||
|
||||
from ..beancount_types import (
|
||||
Transaction,
|
||||
)
|
||||
|
||||
class MetaPayrollType(core._PostingHook):
|
||||
"""Verify payroll-type metadata, starting on 2020-03-01 (FY 2020), is provided for the accounts:
|
||||
Expenses:Payroll:Salary, Expenses:Payroll:Taxes, Expenses:Payroll:Benefits:HealthInsurance, and
|
||||
Expenses:Payroll:Benefits:Other.
|
||||
Valid values for payroll-type are listed in the
|
||||
_SALARY_TYPES, _TAX_TYPES, _HEALTH_INSURANCE_TYPES, and _OTHER_BENEFIT_TYPES
|
||||
(respectively) in the class.
|
||||
"""
|
||||
METADATA_KEY = 'payroll-type'
|
||||
HOOK_GROUPS = frozenset(['metadata', METADATA_KEY])
|
||||
_TAX_TYPES = [ "CA:PP", "CA:EI",
|
||||
"US:SocialSecurity", "US:Medicare",
|
||||
"US:IL:Unemployment",
|
||||
"US:MA:Unemployment", "US:MA:WorkTrain", "US:MA:Health",
|
||||
"US:OR:Unemployment" ]
|
||||
_SALARY_TYPES = [ "US:General", "US:PTO", "US:403b:Employee", "US:403b:Match",
|
||||
"CA:General", "CA:PTO",
|
||||
"CA:Taxes:Income", "CA:Taxes:EI", "CA:Taxes:PP",
|
||||
"US:Taxes:Income", "US:Taxes:SocialSecurity", "US:Taxes:Medicare",
|
||||
"US:IL:Taxes:Income",
|
||||
"US:OR:Taxes:Income", "US:OR:Taxes:STT",
|
||||
"US:MA:Taxes:Income", "US:MA:Disability:PML", "US:MA:Disability:PFL",
|
||||
"US:NY:Taxes:Income", "US:NY:Disability:PFL", "US:NY:Disability", "US:NY:Taxes:NYC" ]
|
||||
_HEALTH_INSURANCE_TYPES = [ "US:HRA:Fees", "US:HRA:Usage", "US:Premium:Main", "US:Premium:DentalVision" ]
|
||||
_OTHER_BENEFIT_TYPES = [ "US:403b:Fees" ]
|
||||
TXN_DATE_RANGE = ranges.DateRange(datetime.date(2020, 3, 1), core.DEFAULT_STOP_DATE)
|
||||
METADATA_KEY = 'payroll-type'
|
||||
|
||||
class _PayrollTypeHook(core._NormalizePostingMetadataHook):
|
||||
ACCOUNT: str
|
||||
VALUES_ENUM = core.MetadataEnum(METADATA_KEY, [])
|
||||
TXN_DATE_RANGE = ranges.DateRange(
|
||||
datetime.date(2020, 3, 1),
|
||||
core.DEFAULT_STOP_DATE,
|
||||
)
|
||||
|
||||
def _run_on_post(self, txn: Transaction, post: data.Posting) -> bool:
|
||||
if post.account.is_under('Expenses:Payroll:Salary') or post.account.is_under('Expenses:Payroll:Taxes') or \
|
||||
post.account.is_under('Expenses:Payroll:Benefits:Other') or post.account.is_under('Expenses:Payroll:Benefits:HealthInsurance'):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
return post.account.is_under(self.ACCOUNT) is not None
|
||||
|
||||
def post_run(self, txn: Transaction, post: data.Posting) -> errormod.Iter:
|
||||
value = post.meta.get(self.METADATA_KEY)
|
||||
if value is None or \
|
||||
(post.account.is_under('Expenses:Payroll:Salary') and (not value in self._SALARY_TYPES)) or \
|
||||
(post.account.is_under('Expenses:Payroll:Taxes') and (not value in self._TAX_TYPES)) or \
|
||||
(post.account.is_under('Expenses:Payroll:Benefits:HealthInsurance') and \
|
||||
(not value in self._HEALTH_INSURANCE_TYPES)) or \
|
||||
(post.account.is_under('Expenses:Payroll:Benefits:Other') and \
|
||||
(not value in self._OTHER_BENEFIT_TYPES)):
|
||||
yield errormod.InvalidMetadataError(txn, self.METADATA_KEY, value, post)
|
||||
|
||||
class HealthInsuranceHook(_PayrollTypeHook):
|
||||
ACCOUNT = 'Expenses:Payroll:Benefits:HealthInsurance'
|
||||
VALUES_ENUM = core.MetadataEnum(METADATA_KEY, [
|
||||
'US:HRA:Fees',
|
||||
'US:HRA:Usage',
|
||||
'US:Premium:DentalVision',
|
||||
'US:Premium:Main',
|
||||
])
|
||||
|
||||
|
||||
class OtherBenefitsHook(_PayrollTypeHook):
|
||||
ACCOUNT = 'Expenses:Payroll:Benefits:Other'
|
||||
VALUES_ENUM = core.MetadataEnum(METADATA_KEY, [
|
||||
'US:403b:Fees',
|
||||
])
|
||||
|
||||
|
||||
class SalaryHook(_PayrollTypeHook):
|
||||
ACCOUNT = 'Expenses:Payroll:Salary'
|
||||
VALUES_ENUM = core.MetadataEnum(METADATA_KEY, [
|
||||
'CA:General',
|
||||
'CA:PTO',
|
||||
'CA:Taxes:EI',
|
||||
'CA:Taxes:Income',
|
||||
'CA:Taxes:PP',
|
||||
'US:403b:Employee',
|
||||
'US:403b:Match',
|
||||
'US:General',
|
||||
'US:IL:Taxes:Income',
|
||||
'US:MA:Disability:PFL',
|
||||
'US:MA:Disability:PML',
|
||||
'US:MA:Taxes:Income',
|
||||
'US:NY:Disability',
|
||||
'US:NY:Disability:PFL',
|
||||
'US:NY:Taxes:Income',
|
||||
'US:NY:Taxes:NYC',
|
||||
'US:OR:Taxes:Income',
|
||||
'US:OR:Taxes:STT',
|
||||
'US:PTO',
|
||||
'US:Taxes:Income',
|
||||
'US:Taxes:Medicare',
|
||||
'US:Taxes:SocialSecurity',
|
||||
])
|
||||
|
||||
|
||||
class TaxHook(_PayrollTypeHook):
|
||||
ACCOUNT = 'Expenses:Payroll:Taxes'
|
||||
VALUES_ENUM = core.MetadataEnum(METADATA_KEY, [
|
||||
'CA:EI',
|
||||
'CA:PP',
|
||||
'US:IL:Unemployment',
|
||||
'US:MA:Health',
|
||||
'US:MA:Unemployment',
|
||||
'US:MA:WorkTrain',
|
||||
'US:Medicare',
|
||||
'US:OR:Unemployment',
|
||||
'US:SocialSecurity',
|
||||
])
|
||||
|
|
2
setup.py
2
setup.py
|
@ -5,7 +5,7 @@ from setuptools import setup
|
|||
setup(
|
||||
name='conservancy_beancount',
|
||||
description="Plugin, library, and reports for reading Conservancy's books",
|
||||
version='1.13.1',
|
||||
version='1.14.0',
|
||||
author='Software Freedom Conservancy',
|
||||
author_email='info@sfconservancy.org',
|
||||
license='GNU AGPLv3+',
|
||||
|
|
Loading…
Reference in a new issue