meta_payroll_type: Basic validation support for payroll-type
This commit is contained in:
parent
51eee8ec8f
commit
9d41f79c52
2 changed files with 70 additions and 0 deletions
|
@ -67,6 +67,7 @@ class HookRegistry:
|
|||
'.meta_repo_links': None,
|
||||
'.meta_rt_links': ['MetaRTLinks'],
|
||||
'.meta_tax_implication': None,
|
||||
'.meta_payroll_type': None,
|
||||
'.txn_date': ['TransactionDate'],
|
||||
}
|
||||
|
||||
|
|
69
conservancy_beancount/plugin/meta_payroll_type.py
Normal file
69
conservancy_beancount/plugin/meta_payroll_type.py
Normal file
|
@ -0,0 +1,69 @@
|
|||
"""meta_payroll_type - Validate payroll-type metadata"""
|
||||
# Copyright © 2020 Bradley M. Kuhn, Brett Smith
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# 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 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)
|
||||
|
||||
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
|
||||
|
||||
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)
|
Loading…
Reference in a new issue