fix: Report and JSON generation for Advances received
This commit is contained in:
parent
5e22405c45
commit
8b644d8889
29
erpnext/accounts/doctype/payment_entry/regional/india.js
Normal file
29
erpnext/accounts/doctype/payment_entry/regional/india.js
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
frappe.ui.form.on("Payment Entry", {
|
||||||
|
company: function(frm) {
|
||||||
|
frappe.call({
|
||||||
|
'method': 'frappe.contacts.doctype.address.address.get_default_address',
|
||||||
|
'args': {
|
||||||
|
'doctype': 'Company',
|
||||||
|
'name': frm.doc.company
|
||||||
|
},
|
||||||
|
'callback': function(r) {
|
||||||
|
me.frm.set_value('company_address', r.message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
party: function(frm) {
|
||||||
|
if (frm.doc.party_type == "Customer" && frm.doc.party) {
|
||||||
|
frappe.call({
|
||||||
|
'method': 'frappe.contacts.doctype.address.address.get_default_address',
|
||||||
|
'args': {
|
||||||
|
'doctype': 'Customer',
|
||||||
|
'name': frm.doc.party
|
||||||
|
},
|
||||||
|
'callback': function(r) {
|
||||||
|
me.frm.set_value('customer_address', r.message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
@ -286,6 +286,7 @@ doc_events = {
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"Payment Entry": {
|
"Payment Entry": {
|
||||||
|
"validate": "erpnext.regional.india.utils.update_place_of_supply",
|
||||||
"on_submit": ["erpnext.regional.create_transaction_log", "erpnext.accounts.doctype.payment_request.payment_request.update_payment_req_status", "erpnext.accounts.doctype.dunning.dunning.resolve_dunning"],
|
"on_submit": ["erpnext.regional.create_transaction_log", "erpnext.accounts.doctype.payment_request.payment_request.update_payment_req_status", "erpnext.accounts.doctype.dunning.dunning.resolve_dunning"],
|
||||||
"on_trash": "erpnext.regional.check_deletion_permission"
|
"on_trash": "erpnext.regional.check_deletion_permission"
|
||||||
},
|
},
|
||||||
|
@ -300,4 +300,5 @@ erpnext.patches.v13_0.reset_clearance_date_for_intracompany_payment_entries
|
|||||||
erpnext.patches.v13_0.einvoicing_deprecation_warning
|
erpnext.patches.v13_0.einvoicing_deprecation_warning
|
||||||
erpnext.patches.v14_0.delete_einvoicing_doctypes
|
erpnext.patches.v14_0.delete_einvoicing_doctypes
|
||||||
erpnext.patches.v13_0.set_operation_time_based_on_operating_cost
|
erpnext.patches.v13_0.set_operation_time_based_on_operating_cost
|
||||||
erpnext.patches.v13_0.validate_options_for_data_field
|
erpnext.patches.v13_0.validate_options_for_data_field
|
||||||
|
erpnext.patches.v13_0.create_gst_payment_entry_fields
|
||||||
|
31
erpnext/patches/v13_0/create_gst_payment_entry_fields.py
Normal file
31
erpnext/patches/v13_0/create_gst_payment_entry_fields.py
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
# Copyright (c) 2021, Frappe and Contributors
|
||||||
|
# License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
import frappe
|
||||||
|
from frappe.custom.doctype.custom_field.custom_field import create_custom_fields
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
custom_fields = {
|
||||||
|
'Payment Entry': [
|
||||||
|
dict(fieldname='gst_section', label='GST Details', fieldtype='Section Break', insert_after='deductions',
|
||||||
|
print_hide=1, collapsible=1),
|
||||||
|
dict(fieldname='company_address', label='Company Address', fieldtype='Link', insert_after='gst_section',
|
||||||
|
print_hide=1, options='Address'),
|
||||||
|
dict(fieldname='company_gstin', label='Company GSTIN',
|
||||||
|
fieldtype='Data', insert_after='company_address',
|
||||||
|
fetch_from='company_address.gstin', print_hide=1, read_only=1),
|
||||||
|
dict(fieldname='place_of_supply', label='Place of Supply',
|
||||||
|
fieldtype='Data', insert_after='company_gstin',
|
||||||
|
print_hide=1, read_only=1),
|
||||||
|
dict(fieldname='gst_column_break', fieldtype='Column Break',
|
||||||
|
insert_after='place_of_supply'),
|
||||||
|
dict(fieldname='customer_address', label='Customer Address', fieldtype='Link', insert_after='gst_column_break',
|
||||||
|
print_hide=1, options='Address', depends_on = 'eval:doc.party_type == "Customer"'),
|
||||||
|
dict(fieldname='customer_gstin', label='Customer GSTIN',
|
||||||
|
fieldtype='Data', insert_after='customer_address',
|
||||||
|
fetch_from='customer_address.gstin', print_hide=1, read_only=1)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
create_custom_fields(custom_fields, update=True)
|
@ -123,8 +123,8 @@ def add_print_formats():
|
|||||||
def make_property_setters(patch=False):
|
def make_property_setters(patch=False):
|
||||||
# GST rules do not allow for an invoice no. bigger than 16 characters
|
# GST rules do not allow for an invoice no. bigger than 16 characters
|
||||||
journal_entry_types = frappe.get_meta("Journal Entry").get_options("voucher_type").split("\n") + ['Reversal Of ITC']
|
journal_entry_types = frappe.get_meta("Journal Entry").get_options("voucher_type").split("\n") + ['Reversal Of ITC']
|
||||||
sales_invoice_series = ['SINV-.YY.-', 'SRET-.YY.-', ''] + frappe.get_meta("Sales Invoice").get_options("naming_series").split("\n")
|
sales_invoice_series = frappe.get_meta("Sales Invoice").get_options("naming_series").split("\n") + ['SINV-.YY.-', 'SRET-.YY.-', '']
|
||||||
purchase_invoice_series = ['PINV-.YY.-', 'PRET-.YY.-', ''] + frappe.get_meta("Purchase Invoice").get_options("naming_series").split("\n")
|
purchase_invoice_series = frappe.get_meta("Purchase Invoice").get_options("naming_series").split("\n") + ['PINV-.YY.-', 'PRET-.YY.-', '']
|
||||||
|
|
||||||
if not patch:
|
if not patch:
|
||||||
make_property_setter('Sales Invoice', 'naming_series', 'options', '\n'.join(sales_invoice_series), '')
|
make_property_setter('Sales Invoice', 'naming_series', 'options', '\n'.join(sales_invoice_series), '')
|
||||||
@ -464,6 +464,7 @@ def make_custom_fields(update=True):
|
|||||||
'Purchase Receipt': purchase_invoice_gst_fields,
|
'Purchase Receipt': purchase_invoice_gst_fields,
|
||||||
'Sales Invoice': sales_invoice_gst_category + invoice_gst_fields + sales_invoice_shipping_fields + sales_invoice_gst_fields + si_ewaybill_fields,
|
'Sales Invoice': sales_invoice_gst_category + invoice_gst_fields + sales_invoice_shipping_fields + sales_invoice_gst_fields + si_ewaybill_fields,
|
||||||
'Delivery Note': sales_invoice_gst_fields + ewaybill_fields + sales_invoice_shipping_fields + delivery_note_gst_category,
|
'Delivery Note': sales_invoice_gst_fields + ewaybill_fields + sales_invoice_shipping_fields + delivery_note_gst_category,
|
||||||
|
'Payment Entry': payment_entry_fields,
|
||||||
'Journal Entry': journal_entry_fields,
|
'Journal Entry': journal_entry_fields,
|
||||||
'Sales Order': sales_invoice_gst_fields,
|
'Sales Order': sales_invoice_gst_fields,
|
||||||
'Tax Category': inter_state_gst_field,
|
'Tax Category': inter_state_gst_field,
|
||||||
|
@ -767,6 +767,15 @@ def update_itc_availed_fields(doc, method):
|
|||||||
if tax.account_head in gst_accounts.get('cess_account', []):
|
if tax.account_head in gst_accounts.get('cess_account', []):
|
||||||
doc.itc_cess_amount += flt(tax.base_tax_amount_after_discount_amount)
|
doc.itc_cess_amount += flt(tax.base_tax_amount_after_discount_amount)
|
||||||
|
|
||||||
|
def update_place_of_supply(doc, method):
|
||||||
|
country = frappe.get_cached_value('Company', doc.company, 'country')
|
||||||
|
if country != 'India':
|
||||||
|
return
|
||||||
|
|
||||||
|
address = frappe.db.get_value("Address", doc.customer_address, ["gst_state", "gst_state_number"], as_dict=1)
|
||||||
|
if address and address.gst_state and address.gst_state_number:
|
||||||
|
doc.place_of_supply = cstr(address.gst_state_number) + "-" + cstr(address.gst_state)
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_regional_round_off_accounts(company, account_list):
|
def get_regional_round_off_accounts(company, account_list):
|
||||||
country = frappe.get_cached_value('Company', company, 'country')
|
country = frappe.get_cached_value('Company', company, 'country')
|
||||||
|
@ -52,7 +52,8 @@ frappe.query_reports["GSTR-1"] = {
|
|||||||
{ "value": "B2C Small", "label": __("B2C(Small) Invoices - 7") },
|
{ "value": "B2C Small", "label": __("B2C(Small) Invoices - 7") },
|
||||||
{ "value": "CDNR-REG", "label": __("Credit/Debit Notes (Registered) - 9B") },
|
{ "value": "CDNR-REG", "label": __("Credit/Debit Notes (Registered) - 9B") },
|
||||||
{ "value": "CDNR-UNREG", "label": __("Credit/Debit Notes (Unregistered) - 9B") },
|
{ "value": "CDNR-UNREG", "label": __("Credit/Debit Notes (Unregistered) - 9B") },
|
||||||
{ "value": "EXPORT", "label": __("Export Invoice - 6A") }
|
{ "value": "EXPORT", "label": __("Export Invoice - 6A") },
|
||||||
|
{ "value": "Advances", "label": __("Tax Liability (Advances Received) - 11A(1), 11A(2)") }
|
||||||
],
|
],
|
||||||
"default": "B2B"
|
"default": "B2B"
|
||||||
}
|
}
|
||||||
|
@ -50,14 +50,17 @@ class Gstr1Report(object):
|
|||||||
self.get_invoice_items()
|
self.get_invoice_items()
|
||||||
self.get_items_based_on_tax_rate()
|
self.get_items_based_on_tax_rate()
|
||||||
self.invoice_fields = [d["fieldname"] for d in self.invoice_columns]
|
self.invoice_fields = [d["fieldname"] for d in self.invoice_columns]
|
||||||
self.get_data()
|
|
||||||
|
self.get_data()
|
||||||
|
|
||||||
return self.columns, self.data
|
return self.columns, self.data
|
||||||
|
|
||||||
def get_data(self):
|
def get_data(self):
|
||||||
if self.filters.get("type_of_business") in ("B2C Small", "B2C Large"):
|
if self.filters.get("type_of_business") in ("B2C Small", "B2C Large"):
|
||||||
self.get_b2c_data()
|
self.get_b2c_data()
|
||||||
else:
|
elif self.filters.get("type_of_business") in ("Advances"):
|
||||||
|
self.get_advance_data()
|
||||||
|
elif self.invoices:
|
||||||
for inv, items_based_on_rate in self.items_based_on_tax_rate.items():
|
for inv, items_based_on_rate in self.items_based_on_tax_rate.items():
|
||||||
invoice_details = self.invoices.get(inv)
|
invoice_details = self.invoices.get(inv)
|
||||||
for rate, items in items_based_on_rate.items():
|
for rate, items in items_based_on_rate.items():
|
||||||
@ -70,6 +73,22 @@ class Gstr1Report(object):
|
|||||||
if taxable_value:
|
if taxable_value:
|
||||||
self.data.append(row)
|
self.data.append(row)
|
||||||
|
|
||||||
|
def get_advance_data(self):
|
||||||
|
advances_data = {}
|
||||||
|
advances = self.get_advance_entries()
|
||||||
|
for entry in advances:
|
||||||
|
# only consider IGST and SGST so as to avoid duplication of taxable amount
|
||||||
|
if entry.account_head in self.gst_accounts.igst_account or \
|
||||||
|
entry.account_head in self.gst_accounts.sgst_account:
|
||||||
|
advances_data.setdefault((entry.place_of_supply, entry.rate), [0.0, 0.0])
|
||||||
|
advances_data[(entry.place_of_supply, entry.rate)][0] += (entry.amount * 100 / entry.rate)
|
||||||
|
elif entry.account_head in self.gst_accounts.cess_account:
|
||||||
|
advances_data[(entry.place_of_supply, entry.rate)][1] += entry.amount
|
||||||
|
|
||||||
|
for key, value in advances_data.items():
|
||||||
|
row= [key[0], key[1], value[0], value[1]]
|
||||||
|
self.data.append(row)
|
||||||
|
|
||||||
def get_b2c_data(self):
|
def get_b2c_data(self):
|
||||||
b2cs_output = {}
|
b2cs_output = {}
|
||||||
|
|
||||||
@ -167,6 +186,16 @@ class Gstr1Report(object):
|
|||||||
for d in invoice_data:
|
for d in invoice_data:
|
||||||
self.invoices.setdefault(d.invoice_number, d)
|
self.invoices.setdefault(d.invoice_number, d)
|
||||||
|
|
||||||
|
def get_advance_entries(self):
|
||||||
|
return frappe.db.sql("""
|
||||||
|
SELECT SUM(a.base_tax_amount) as amount, a.account_head, a.rate, p.place_of_supply
|
||||||
|
FROM `tabPayment Entry` p, `tabAdvance Taxes and Charges` a
|
||||||
|
WHERE p.docstatus = 1
|
||||||
|
AND p.name = a.parent
|
||||||
|
AND posting_date between %s and %s
|
||||||
|
GROUP BY a.account_head, p.place_of_supply, a.rate
|
||||||
|
""", (self.filters.get('from_date'), self.filters.get('to_date')), as_dict=1)
|
||||||
|
|
||||||
def get_conditions(self):
|
def get_conditions(self):
|
||||||
conditions = ""
|
conditions = ""
|
||||||
|
|
||||||
@ -662,6 +691,25 @@ class Gstr1Report(object):
|
|||||||
"width": 120
|
"width": 120
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
elif self.filters.get("type_of_business") == "Advances":
|
||||||
|
self.invoice_columns = [
|
||||||
|
{
|
||||||
|
"fieldname": "place_of_supply",
|
||||||
|
"label": "Place Of Supply",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"width": 120
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
self.other_columns = [
|
||||||
|
{
|
||||||
|
"fieldname": "cess_amount",
|
||||||
|
"label": "Cess Amount",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"width": 100
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
self.columns = self.invoice_columns + self.tax_columns + self.other_columns
|
self.columns = self.invoice_columns + self.tax_columns + self.other_columns
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
@ -700,19 +748,29 @@ def get_json(filters, report_name, data):
|
|||||||
|
|
||||||
out = get_export_json(res)
|
out = get_export_json(res)
|
||||||
gst_json["exp"] = out
|
gst_json["exp"] = out
|
||||||
elif filters["type_of_business"] == 'CDNR-REG':
|
elif filters["type_of_business"] == "CDNR-REG":
|
||||||
for item in report_data[:-1]:
|
for item in report_data[:-1]:
|
||||||
res.setdefault(item["customer_gstin"], {}).setdefault(item["invoice_number"],[]).append(item)
|
res.setdefault(item["customer_gstin"], {}).setdefault(item["invoice_number"],[]).append(item)
|
||||||
|
|
||||||
out = get_cdnr_reg_json(res, gstin)
|
out = get_cdnr_reg_json(res, gstin)
|
||||||
gst_json["cdnr"] = out
|
gst_json["cdnr"] = out
|
||||||
elif filters["type_of_business"] == 'CDNR-UNREG':
|
elif filters["type_of_business"] == "CDNR-UNREG":
|
||||||
for item in report_data[:-1]:
|
for item in report_data[:-1]:
|
||||||
res.setdefault(item["invoice_number"],[]).append(item)
|
res.setdefault(item["invoice_number"],[]).append(item)
|
||||||
|
|
||||||
out = get_cdnr_unreg_json(res, gstin)
|
out = get_cdnr_unreg_json(res, gstin)
|
||||||
gst_json["cdnur"] = out
|
gst_json["cdnur"] = out
|
||||||
|
|
||||||
|
elif filters["type_of_business"] == "Advances":
|
||||||
|
for item in report_data[:-1]:
|
||||||
|
if not item.get("place_of_supply"):
|
||||||
|
frappe.throw(_("""{0} not entered in some entries.
|
||||||
|
Please update and try again""").format(frappe.bold("Place Of Supply")))
|
||||||
|
|
||||||
|
res.setdefault(item["place_of_supply"],[]).append(item)
|
||||||
|
|
||||||
|
out = get_advances_json(res, gstin)
|
||||||
|
gst_json["at"] = out
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'report_name': report_name,
|
'report_name': report_name,
|
||||||
@ -792,6 +850,40 @@ def get_b2cs_json(data, gstin):
|
|||||||
|
|
||||||
return out
|
return out
|
||||||
|
|
||||||
|
def get_advances_json(data, gstin):
|
||||||
|
company_state_number = gstin[0:2]
|
||||||
|
out = []
|
||||||
|
for place_of_supply, items in iteritems(data):
|
||||||
|
supply_type = "INTRA" if company_state_number == place_of_supply.split('-')[0] else "INTER"
|
||||||
|
row = {
|
||||||
|
"pos": place_of_supply.split('-')[0],
|
||||||
|
"itms": [],
|
||||||
|
"sply_ty": supply_type
|
||||||
|
}
|
||||||
|
|
||||||
|
for item in items:
|
||||||
|
itms = {
|
||||||
|
'rt': item['rate'],
|
||||||
|
'ad_amount': flt(item.get('taxable_value')),
|
||||||
|
'csamt': flt(item.get('cess_amount'))
|
||||||
|
}
|
||||||
|
|
||||||
|
if supply_type == "INTRA":
|
||||||
|
itms.update({
|
||||||
|
"samt": flt((itms["ad_amount"] * itms["rt"]) / 100),
|
||||||
|
"camt": flt((itms["ad_amount"] * itms["rt"]) / 100),
|
||||||
|
"rt": itms["rt"] * 2
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
itms.update({
|
||||||
|
"iamt": flt((itms["ad_amount"] * itms["rt"]) / 100)
|
||||||
|
})
|
||||||
|
|
||||||
|
row['itms'].append(itms)
|
||||||
|
out.append(row)
|
||||||
|
|
||||||
|
return out
|
||||||
|
|
||||||
def get_b2cl_json(res, gstin):
|
def get_b2cl_json(res, gstin):
|
||||||
out = []
|
out = []
|
||||||
for pos in res:
|
for pos in res:
|
||||||
@ -955,7 +1047,7 @@ def get_company_gstin_number(company, address=None, all_gstins=False):
|
|||||||
["Dynamic Link", "link_name", "=", company],
|
["Dynamic Link", "link_name", "=", company],
|
||||||
["Dynamic Link", "parenttype", "=", "Address"],
|
["Dynamic Link", "parenttype", "=", "Address"],
|
||||||
]
|
]
|
||||||
gstin = frappe.get_all("Address", filters=filters, pluck="gstin")
|
gstin = frappe.get_all("Address", filters=filters, pluck="gstin", order_by="is_primary_address desc")
|
||||||
if gstin and not all_gstins:
|
if gstin and not all_gstins:
|
||||||
gstin = gstin[0]
|
gstin = gstin[0]
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user