feat(employee-payroll-register): add per-contribution columns net of exemption
For each social contribution (DSMF, İcbari tibbi sığorta, İşsizlikdən sığorta — işçi and şirkət, everything except Gəlir vergisi) add a column per month that recomputes the amount on gross_pay minus that contribution's "cəlb olunmayan gəlir" amount, using the Salary Component formula. Sits next to the original column. 18 new columns total. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
4e8bb96669
commit
671b2195fe
|
|
@ -35,6 +35,18 @@ DEDUCTION_TYPES = [
|
|||
EH_COMPONENT = "Əsas əmək haqqı"
|
||||
MK_COMPONENT = "Məzuniyyət Kompensasiyası"
|
||||
|
||||
# Social-contribution deductions (everything except Gəlir vergisi) get an extra
|
||||
# column per month: the contribution recomputed on gross_pay net of its own
|
||||
# "cəlb olunmayan gəlir" amount. Maps deduction name → Salary Slip exempt field.
|
||||
CONTRIBUTION_EXEMPT_FIELD = {
|
||||
"DSMF (işçi)": "custom_mdss_amount",
|
||||
"DSMF (şirkət)": "custom_mdss_amount",
|
||||
"İcbari tibbi sığorta (işçi 2%)": "custom_medical_insurance_amount",
|
||||
"İcbari tibbi sığorta (şirkət 2%)": "custom_medical_insurance_amount",
|
||||
"İşsizlikdən sığorta haqqı (işçi 0,5%)": "custom_unemployment_insurance_amount",
|
||||
"İşsizlikdən sığorta haqqı (şirkət 0,5%)": "custom_unemployment_insurance_amount",
|
||||
}
|
||||
|
||||
# Контекст для безопасного eval формул Salary Component. Зеркалит whitelisted_globals из HRMS.
|
||||
FORMULA_GLOBALS = {
|
||||
"int": int,
|
||||
|
|
@ -170,8 +182,10 @@ def execute(filters=None):
|
|||
# формул baseline = 0 (no-op), для Gəlir vergisi baseline = -6 из-за
|
||||
# порога 200 AZN в base-части. Без вычитания MK-колонка для GV давала
|
||||
# бы -3 вместо 3 (см. формулу `(base - 200) * 0.03 + LE * 0.03`).
|
||||
rate = flt(ss.exchange_rate) if currency == company_currency else 1.0
|
||||
eh_amount = flt(ss_earning_map.get(ss.name, {}).get(EH_COMPONENT, 0))
|
||||
mk_amount = flt(ss_earning_map.get(ss.name, {}).get(MK_COMPONENT, 0))
|
||||
gross_rated = flt(ss.gross_pay) * rate
|
||||
for d in DEDUCTION_TYPES:
|
||||
slug = frappe.scrub(d)
|
||||
spec = ded_specs.get(d)
|
||||
|
|
@ -179,15 +193,15 @@ def execute(filters=None):
|
|||
row[prefix + "ded_eh_" + slug] += eval_deduction(spec, eh_amount, 0, ss)
|
||||
row[prefix + "ded_mk_" + slug] += eval_deduction(spec, 0, mk_amount, ss) - baseline
|
||||
|
||||
if currency == company_currency:
|
||||
rate = flt(ss.exchange_rate)
|
||||
row[prefix + "gross_pay"] += flt(ss.gross_pay) * rate
|
||||
row[prefix + "total_deduction"] += flt(ss.total_deduction) * rate
|
||||
row[prefix + "net_pay"] += flt(ss.net_pay) * rate
|
||||
else:
|
||||
row[prefix + "gross_pay"] += flt(ss.gross_pay)
|
||||
row[prefix + "total_deduction"] += flt(ss.total_deduction)
|
||||
row[prefix + "net_pay"] += flt(ss.net_pay)
|
||||
# Contribution recomputed on gross net of its own "cəlb olunmayan" amount.
|
||||
exempt_field = CONTRIBUTION_EXEMPT_FIELD.get(d)
|
||||
if exempt_field:
|
||||
base_net = max(gross_rated - flt(ss.get(exempt_field) or 0) * rate, 0.0)
|
||||
row[prefix + "ded_cg_" + slug] += eval_deduction(spec, base_net, 0, ss) - baseline
|
||||
|
||||
row[prefix + "gross_pay"] += gross_rated
|
||||
row[prefix + "total_deduction"] += flt(ss.total_deduction) * rate
|
||||
row[prefix + "net_pay"] += flt(ss.net_pay) * rate
|
||||
|
||||
for indicator_field, amount_field, _label in TAX_FREE_FIELDS:
|
||||
row[prefix + indicator_field] = ss.get(indicator_field)
|
||||
|
|
@ -228,6 +242,8 @@ def build_empty_row(ss, doj_map, currency, company_currency):
|
|||
row[prefix + slug] = 0.0
|
||||
row[prefix + "ded_eh_" + slug] = 0.0
|
||||
row[prefix + "ded_mk_" + slug] = 0.0
|
||||
if d in CONTRIBUTION_EXEMPT_FIELD:
|
||||
row[prefix + "ded_cg_" + slug] = 0.0
|
||||
for indicator_field, amount_field, _lbl in TAX_FREE_FIELDS:
|
||||
row[prefix + indicator_field] = None
|
||||
row[prefix + amount_field] = 0.0
|
||||
|
|
@ -365,6 +381,16 @@ def get_columns():
|
|||
"width": 140,
|
||||
}
|
||||
)
|
||||
if deduction in CONTRIBUTION_EXEMPT_FIELD:
|
||||
columns.append(
|
||||
{
|
||||
"label": deduction + " (cəlb edilən gəlirdən)" + suffix,
|
||||
"fieldname": prefix + "ded_cg_" + frappe.scrub(deduction),
|
||||
"fieldtype": "Currency",
|
||||
"options": "currency",
|
||||
"width": 200,
|
||||
}
|
||||
)
|
||||
for deduction in DEDUCTION_TYPES:
|
||||
columns.append(
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue