Refactor for Journal Entries (payroll)

This commit is contained in:
casesolved-co-uk 2021-03-27 03:02:30 +00:00
parent 3027cc7da6
commit ece00287ea

View File

@ -7,15 +7,18 @@ import frappe, json
from frappe import _ from frappe import _
# NOTE: Not compatible with the frappe custom report feature of adding arbitrary doctype columns to the report # NOTE: Not compatible with the frappe custom report feature of adding arbitrary doctype columns to the report
# NOTE: Payroll is implemented using Journal Entries
# field lists in multiple doctypes will be coalesced # field lists in multiple doctypes will be coalesced
required_sql_fields = { required_sql_fields = {
"GL Entry": ["posting_date", "voucher_type", "voucher_no", "account", "account_currency", "debit", "credit"], "GL Entry": ["posting_date", "voucher_type", "voucher_no", "account as tax_account", "account_currency", "debit", "credit"],
"Account": ["account_type"], # "Account": ["account_type"],
"Journal Entry Account": ["account_type", "account", "debit_in_account_currency", "credit_in_account_currency"],
("Purchase Invoice Item", "Sales Invoice Item"): ["base_net_amount", "item_tax_rate", "item_tax_template", "item_name"],
("Purchase Invoice", "Sales Invoice"): ["taxes_and_charges", "tax_category"], ("Purchase Invoice", "Sales Invoice"): ["taxes_and_charges", "tax_category"],
("Purchase Invoice Item", "Sales Invoice Item"): ["item_tax_template", "item_name", "base_net_amount", "item_tax_rate"],
# "Journal Entry": ["total_amount_currency"], # "Journal Entry": ["total_amount_currency"],
# "Journal Entry Account": ["debit_in_account_currency", "credit_in_account_currency"] "Purchase Invoice Item": ["expense_account"],
"Sales Invoice Item": ["income_account"]
} }
@ -40,9 +43,9 @@ def execute(filters=None):
left join `tabPurchase Invoice Item` pii on left join `tabPurchase Invoice Item` pii on
pi.name=pii.parent pi.name=pii.parent
/* left outer join `tabJournal Entry` je on /* left outer join `tabJournal Entry` je on
ge.voucher_no=je.name and ge.company=je.company ge.voucher_no=je.name and ge.company=je.company */
left outer join `tabJournal Entry Account` jea on left outer join `tabJournal Entry Account` jea on
je.name=jea.parent and a.account_type='Tax' */ ge.voucher_type=jea.parenttype and ge.voucher_no=jea.parent
where (ge.voucher_type, ge.voucher_no) in ( where (ge.voucher_type, ge.voucher_no) in (
select ge.voucher_type, ge.voucher_no select ge.voucher_type, ge.voucher_no
from `tabGL Entry` ge from `tabGL Entry` ge
@ -142,7 +145,18 @@ def subtotal(data, field):
abbrev = lambda dt: ''.join(l[0].lower() for l in dt.split(' ')) + '.' abbrev = lambda dt: ''.join(l[0].lower() for l in dt.split(' ')) + '.'
doclist = lambda dt, dfs: [abbrev(dt) + f for f in dfs] doclist = lambda dt, dfs: [abbrev(dt) + f for f in dfs]
coalesce = lambda dts, dfs: ['coalesce(' + ', '.join(abbrev(dt) + f for dt in dts) + ') ' + f for f in dfs]
def as_split(fields):
for field in fields:
split = field.split(' as ')
yield (split[0], split[1] if len(split) > 1 else split[0])
def coalesce(doctypes, fields):
coalesce = []
for name, new_name in as_split(fields):
sharedfields = ', '.join(abbrev(dt) + name for dt in doctypes)
coalesce += [f'coalesce({sharedfields}) as {new_name}']
return coalesce
def get_fieldstr(fieldlist): def get_fieldstr(fieldlist):
fields = [] fields = []
@ -158,20 +172,22 @@ def get_columns(fieldlist):
for doctypes, docfields in fieldlist.items(): for doctypes, docfields in fieldlist.items():
if isinstance(doctypes, str): if isinstance(doctypes, str):
doctypes = [doctypes] doctypes = [doctypes]
fieldmap = {name: new_name for name, new_name in as_split(docfields)}
for doctype in doctypes: for doctype in doctypes:
meta = frappe.get_meta(doctype) meta = frappe.get_meta(doctype)
# get column field metadata from the db # get column field metadata from the db
fieldmeta = {} fieldmeta = {}
for field in meta.get('fields'): for field in meta.get('fields'):
if field.fieldname in docfields: if field.fieldname in fieldmap.keys():
fieldmeta[field.fieldname] = { new_name = fieldmap[field.fieldname]
fieldmeta[new_name] = {
"label": _(field.label), "label": _(field.label),
"fieldname": field.fieldname, "fieldname": new_name,
"fieldtype": field.fieldtype, "fieldtype": field.fieldtype,
"options": field.options "options": field.options
} }
# edit the columns to match the modified data # edit the columns to match the modified data
for field in docfields: for field in fieldmap.values():
col = modify_report_columns(doctype, field, fieldmeta[field]) col = modify_report_columns(doctype, field, fieldmeta[field])
if col: if col:
columns[col["fieldname"]] = col columns[col["fieldname"]] = col
@ -182,10 +198,28 @@ def modify_report_columns(doctype, field, column):
"Because data is rearranged into other columns" "Because data is rearranged into other columns"
if doctype in ["Sales Invoice Item", "Purchase Invoice Item"] and field == "item_tax_rate": if doctype in ["Sales Invoice Item", "Purchase Invoice Item"] and field == "item_tax_rate":
return None return None
if doctype == "GL Entry" and field == "tax_account":
column.update({"label": _("Tax Account")})
if doctype == "GL Entry" and field == "debit":
column.update({"label": _("Tax Debit")})
if doctype == "GL Entry" and field == "credit":
column.update({"label": _("Tax Credit")})
if doctype == "Journal Entry Account" and field == "debit_in_account_currency":
column.update({"label": _("Debit Net Amount"), "fieldname": "debit_net_amount"})
if doctype == "Journal Entry Account" and field == "credit_in_account_currency":
column.update({"label": _("Credit Net Amount"), "fieldname": "credit_net_amount"})
if doctype == "Sales Invoice Item" and field == "base_net_amount": if doctype == "Sales Invoice Item" and field == "base_net_amount":
column.update({"label": _("Credit Net Amount"), "fieldname": "credit_net_amount"}) column.update({"label": _("Credit Net Amount"), "fieldname": "credit_net_amount"})
if doctype == "Sales Invoice Item" and field == "income_account":
column.update({"label": _("Account"), "fieldname": "account"})
if doctype == "Purchase Invoice Item" and field == "base_net_amount": if doctype == "Purchase Invoice Item" and field == "base_net_amount":
column.update({"label": _("Debit Net Amount"), "fieldname": "debit_net_amount"}) column.update({"label": _("Debit Net Amount"), "fieldname": "debit_net_amount"})
if doctype == "Purchase Invoice Item" and field == "expense_account":
column.update({"label": _("Account"), "fieldname": "account"})
if field == "taxes_and_charges": if field == "taxes_and_charges":
column.update({"label": _("Taxes and Charges Template")}) column.update({"label": _("Taxes and Charges Template")})
return column return column
@ -193,7 +227,15 @@ def modify_report_columns(doctype, field, column):
def modify_report_data(data): def modify_report_data(data):
import json import json
for line in data: for line in data:
if line.account_type == "Tax" and line.item_tax_rate: # Transform Invoice lines
if "Invoice" in line.voucher_type:
if line.income_account:
line.account = line.income_account
line.account_type = "Income Account"
if line.expense_account:
line.account = line.expense_account
line.account_type = "Expense Account"
if line.item_tax_rate:
tax_rates = json.loads(line.item_tax_rate) tax_rates = json.loads(line.item_tax_rate)
for account, rate in tax_rates.items(): for account, rate in tax_rates.items():
if account == line.account: if account == line.account:
@ -203,6 +245,12 @@ def modify_report_data(data):
if line.voucher_type == "Purchase Invoice": if line.voucher_type == "Purchase Invoice":
line.debit = line.base_net_amount * (rate / 100) line.debit = line.base_net_amount * (rate / 100)
line.debit_net_amount = line.base_net_amount line.debit_net_amount = line.base_net_amount
# Transform Journal Entry lines
if "Journal" in line.voucher_type:
if line.debit_in_account_currency:
line.debit_net_amount = line.debit_in_account_currency
if line.credit_in_account_currency:
line.credit_net_amount = line.credit_in_account_currency
return data return data
####### JS client utilities ####### JS client utilities