From 22b61607c6fe16f9a76fad03dc854603e27f3afe Mon Sep 17 00:00:00 2001 From: Deepesh Garg <42651287+deepeshgarg007@users.noreply.github.com> Date: Thu, 21 Mar 2019 20:47:47 +0530 Subject: [PATCH] feat: GSTR3B Report JSON creation and Print Format (#16595) * feat: Created doctype for GSTR3B report and added boilerplate code * feat: Updated gst_fields and patches for gst_category * feat: Functions for calculating itc amount * fix: Patched eligibility_for_itc_field * fix: Updated set_category for gst * fix: Function for setting iter_state supplies * fix: Changed route to regional module, minor fix in inster_state_supply grouping and fixes in print format * fix(style): Added missing semicolon and removed unused imports * fix: Patch field only if column is available * fix: Make custom fields only for india sepecific company * fix: Add intro to gstr3b report * fix: Updated patch in patches.txt * fix: Update patches.txt * fix: Update patch to set GST Category * fix: Add fields for nil rated and non gst in item master * fix: Added logic for nil rated and non gst inward flow * fix: Initial test case for GSTR3B Report * fix: Codacy fixes * fix: Test Case fixes * fix: Add link for gstr_3b_report in accounting module * fix: Updated report template * fix: Changes in GSTR3B Report doctype * fix: Added function to get missing field invoices * fix: Added more test cases * fix: Item not found error in test case * fix: Key error in state numbers * fix: Changes in GSTR3b Doctype * fix: Changed functions to method * fix: Minor fix in patch * fix: Add gst_ctegory in GST Reports * fix: Minor fixes in patch and itc_mapping * fix: Query to patch itc field * fix: Patch registered customers and fix for multiple gst accounts * fix: Test case * fix: Total taxable calculation logic fix and template enhancement * fix: Calculate txval seperately * fix: itc amount calculation fix and patch improvement * fix: Updated test_cases for itc calculation * fix: Missing field query * fix: Multiple minor fixes inreport * fix: Added transalations in GSTR3B-Form * fix: Use double underscore for translation * fix: GST fields ordering fix * fix: Print form precision fix and get_period function fix --- erpnext/config/accounting.py | 4 + erpnext/patches.txt | 1 + erpnext/patches/v12_0/set_gst_category.py | 50 ++ .../doctype/gstr_3b_report/__init__.py | 0 .../gstr_3b_report/gstr_3b_report.html | 297 ++++++++++++ .../doctype/gstr_3b_report/gstr_3b_report.js | 59 +++ .../gstr_3b_report/gstr_3b_report.json | 259 ++++++++++ .../doctype/gstr_3b_report/gstr_3b_report.py | 459 ++++++++++++++++++ .../gstr_3b_report/test_gstr_3b_report.py | 380 +++++++++++++++ erpnext/regional/india/setup.py | 87 +++- .../gst_itemised_purchase_register.py | 4 +- .../gst_itemised_sales_register.py | 4 +- .../gst_purchase_register.py | 4 +- .../gst_sales_register/gst_sales_register.py | 4 +- erpnext/regional/report/gstr_1/gstr_1.py | 12 +- erpnext/regional/report/gstr_2/gstr_2.py | 8 +- 16 files changed, 1590 insertions(+), 42 deletions(-) create mode 100644 erpnext/patches/v12_0/set_gst_category.py create mode 100644 erpnext/regional/doctype/gstr_3b_report/__init__.py create mode 100644 erpnext/regional/doctype/gstr_3b_report/gstr_3b_report.html create mode 100644 erpnext/regional/doctype/gstr_3b_report/gstr_3b_report.js create mode 100644 erpnext/regional/doctype/gstr_3b_report/gstr_3b_report.json create mode 100644 erpnext/regional/doctype/gstr_3b_report/gstr_3b_report.py create mode 100644 erpnext/regional/doctype/gstr_3b_report/test_gstr_3b_report.py diff --git a/erpnext/config/accounting.py b/erpnext/config/accounting.py index 9de5b368db..afe35f8078 100644 --- a/erpnext/config/accounting.py +++ b/erpnext/config/accounting.py @@ -563,6 +563,10 @@ def get_data(): "name": "GSTR-2", "is_query_report": True }, + { + "type": "doctype", + "name": "GSTR 3B Report", + }, { "type": "report", "name": "GST Sales Register", diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 79efe1be42..6643982eb1 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -583,6 +583,7 @@ erpnext.patches.v11_0.renamed_from_to_fields_in_project erpnext.patches.v11_0.add_permissions_in_gst_settings erpnext.patches.v11_1.setup_guardian_role execute:frappe.delete_doc('DocType', 'Notification Control') +erpnext.patches.v12_0.set_gst_category erpnext.patches.v11_0.remove_barcodes_field_from_copy_fields_to_variants erpnext.patches.v12_0.set_task_status erpnext.patches.v11_0.make_italian_localization_fields # 01-03-2019 diff --git a/erpnext/patches/v12_0/set_gst_category.py b/erpnext/patches/v12_0/set_gst_category.py new file mode 100644 index 0000000000..54bc5b3c74 --- /dev/null +++ b/erpnext/patches/v12_0/set_gst_category.py @@ -0,0 +1,50 @@ +import frappe +from erpnext.regional.india.setup import make_custom_fields + +def execute(): + + company = frappe.get_all('Company', filters = {'country': 'India'}) + if not company: + return + + make_custom_fields() + + for doctype in ['Sales Invoice', 'Purchase Invoice']: + has_column = frappe.db.has_column(doctype,'invoice_type') + + if has_column: + update_map = { + 'Regular': 'Registered Regular', + 'Export': 'Overseas', + 'SEZ': 'SEZ', + 'Deemed Export': 'Deemed Export', + } + + for old, new in update_map.items(): + frappe.db.sql("UPDATE `tab{doctype}` SET gst_category = %s where invoice_type = %s".format(doctype=doctype), (new, old)) #nosec + + frappe.delete_doc('Custom Field', 'Sales Invoice-invoice_type') + frappe.delete_doc('Custom Field', 'Purchase Invoice-invoice_type') + + itc_update_map = { + "ineligible": "Ineligible", + "input service": "Input Service Distributor", + "capital goods": "Import Of Capital Goods", + "input": "All Other ITC" + } + + has_gst_fields = frappe.db.has_column('Purchase Invoice','eligibility_for_itc') + + if has_gst_fields: + for old, new in itc_update_map.items(): + frappe.db.sql("UPDATE `tabPurchase Invoice` SET eligibility_for_itc = %s where eligibility_for_itc = %s ", (new, old)) + + for doctype in ["Customer", "Supplier"]: + + frappe.db.sql(""" UPDATE `tab{doctype}` t1, `tabAddress` t2, `tabDynamic Link` t3 SET t1.gst_category = "Registered Regular" + where t3.link_name = t1.name and t3.parent = t2.name and t2.gstin IS NOT NULL and t2.gstin != '' """.format(doctype=doctype)) #nosec + + frappe.db.sql(""" UPDATE `tab{doctype}` t1, `tabAddress` t2, `tabDynamic Link` t3 SET t1.gst_category = "Overseas" + where t3.link_name = t1.name and t3.parent = t2.name and t2.country != 'India' """.format(doctype=doctype)) #nosec + + diff --git a/erpnext/regional/doctype/gstr_3b_report/__init__.py b/erpnext/regional/doctype/gstr_3b_report/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/regional/doctype/gstr_3b_report/gstr_3b_report.html b/erpnext/regional/doctype/gstr_3b_report/gstr_3b_report.html new file mode 100644 index 0000000000..4bf0de1ad2 --- /dev/null +++ b/erpnext/regional/doctype/gstr_3b_report/gstr_3b_report.html @@ -0,0 +1,297 @@ + +
{{__("Nature Of Supplies")}} | +{{__("Total Taxable value")}} | +{{__("Integrated Tax")}} | +{{__("Central Tax")}} | +{{__("State/UT Tax")}} | +{{__("Cess")}} | +
---|---|---|---|---|---|
(a) {{__("Outward taxable supplies(other than zero rated, nil rated and exempted")}} | +{{ flt(data.sup_details.osup_det.txval, 2) }} | +{{ flt(data.sup_details.osup_det.iamt, 2) }} | +{{ flt(data.sup_details.osup_det.camt, 2) }} | +{{ flt(data.sup_details.osup_det.samt, 2) }} | +{{ flt(data.sup_details.osup_det.csamt, 2) }} | +
(b) {{__("Outward taxable supplies(zero rated)")}} | +{{ flt(data.sup_details.osup_zero.txval, 2) }} | +{{ flt(data.sup_details.osup_zero.iamt, 2) }} | ++ | + | {{ flt(data.sup_details.osup_zero.csamt, 2) }} | +
(b) {{__("Other outward supplies(Nil rated,Exempted)")}} | +{{ data.sup_details.osup_nil_exmp.txval }} | ++ | + | + | + |
(d) {{__("Inward Supplies(liable to reverse charge")}} | +{{ flt(data.sup_details.isup_rev.txval, 2) }} | +{{ flt(data.sup_details.isup_rev.iamt, 2) }} | +{{ flt(data.sup_details.isup_rev.camt, 2) }} | +{{ flt(data.sup_details.isup_rev.samt, 2) }} | +{{ flt(data.sup_details.isup_rev.csamt,2) }} | +
(e) {{__("Non-GST outward supplies")}} | +{{ data.sup_details.osup_nongst.txval }} | ++ | + | + | + |
+ | {{__("Place Of Supply (State/UT)")}} | +{{__("Total Taxable Value")}} | +{{__("Amount of Integrated Tax")}} | +
---|---|---|---|
{{__("Supplies made to Unregistered Persons")}} | +
+ {% for row in data.inter_sup.unreg_details %}
+ {% if row %}
+ {{ row.pos }} + {% endif %} + {% endfor %} + |
+
+ {% for row in data.inter_sup.unreg_details %}
+ {% if row %}
+ {{ flt(row.txval, 2) }} + {% endif %} + {% endfor %} + |
+
+ {% for row in data.inter_sup.unreg_details %}
+ {% if row %}
+ {{ flt(row.iamt, 2) }} + {% endif %} + {% endfor %} + |
+
{{__("Suppliies made to Composition Taxable Persons")}} | +
+ {% for row in data.inter_sup.unreg_details %}
+ {% if row %}
+ {{ row.pos }} + {% endif %} + {% endfor %} + |
+
+ {% for row in data.inter_sup.unreg_details %}
+ {% if row %}
+ {{ flt(row.txval, 2) }} + {% endif %} + {% endfor %} + |
+
+ {% for row in data.inter_sup.unreg_details %}
+ {% if row %}
+ {{ flt(row.iamt, 2) }} + {% endif %} + {% endfor %} + |
+
{{__("Supplies made to UIN holders")}} | +
+ {% for row in data.inter_sup.unreg_details %}
+ {% if row %}
+ {{ row.pos }} + {% endif %} + {% endfor %} + |
+
+ {% for row in data.inter_sup.unreg_details %}
+ {% if row %}
+ {{ flt(row.txval, 2) }} + {% endif %} + {% endfor %} + |
+
+ {% for row in data.inter_sup.unreg_details %}
+ {% if row %}
+ {{ flt(row.iamt, 2) }} + {% endif %} + {% endfor %} + |
+
Details | +Integrated Tax | +Central Tax | +State/UT tax | +Cess | +
---|---|---|---|---|
(A) {{__("ITC Available (whether in full op part)")}} | ++ | + | + | + |
  (1) {{__("Import of goods")}} | +{{ flt(data.itc_elg.itc_avl[0].iamt, 2) }} | +{{ flt(data.itc_elg.itc_avl[0].camt, 2) }} | +{{ flt(data.itc_elg.itc_avl[0].samt, 2) }} | +{{ flt(data.itc_elg.itc_avl[0].csamt, 2) }} | +
  (2) {{__("Import of services")}} | +{{ flt(data.itc_elg.itc_avl[1].iamt, 2) }} | +{{ flt(data.itc_elg.itc_avl[1].camt, 2) }} | +{{ flt(data.itc_elg.itc_avl[1].samt, 2) }} | +{{ flt(data.itc_elg.itc_avl[1].csamt, 2) }} | +
  (3) {{__("Inward supplies liable to reverse charge (other than 1 & 2 above)")}} | +{{ flt(data.itc_elg.itc_avl[2].iamt, 2) }} | +{{ flt(data.itc_elg.itc_avl[2].camt, 2) }} | +{{ flt(data.itc_elg.itc_avl[2].samt, 2) }} | +{{ flt(data.itc_elg.itc_avl[2].csamt, 2) }} | +
  (4) {{__("Inward supplies from ISD")}} | +{{ flt(data.itc_elg.itc_avl[3].iamt, 2) }} | +{{ flt(data.itc_elg.itc_avl[3].camt, 2) }} | +{{ flt(data.itc_elg.itc_avl[3].samt, 2) }} | +{{ flt(data.itc_elg.itc_avl[3].csamt, 2) }} | +
  (5) {{__("All other ITC")}} | +{{ flt(data.itc_elg.itc_avl[4].iamt, 2) }} | +{{ flt(data.itc_elg.itc_avl[4].camt, 2) }} | +{{ flt(data.itc_elg.itc_avl[4].samt, 2) }} | +{{ flt(data.itc_elg.itc_avl[4].csamt, 2) }} | +
(B) {{__("ITC Reversed")}} | ++ | + | + | + |
  (1) {{__("As per rules 42 & 43 of CGST Rules")}} | ++ | + | + | + |
  (2) {{__("Others")}} | ++ | + | + | + |
(C) {{__("Net ITC Available(A) - (B)")}} | +{{ flt(data.itc_elg.itc_net.iamt, 2) }} | +{{ flt(data.itc_elg.itc_net.camt, 2) }} | +{{ flt(data.itc_elg.itc_net.samt, 2) }} | +{{ flt(data.itc_elg.itc_net.csamt, 2) }} | +
(D) {{__("Ineligible ITC")}} | ++ | + | + | + |
  (1) {{__("As per section 17(5)")}} | +{{ flt(data.itc_elg.itc_inelg[0].iamt, 2) }} | +{{ flt(data.itc_elg.itc_inelg[0].camt, 2) }} | +{{ flt(data.itc_elg.itc_inelg[0].samt, 2) }} | +{{ flt(data.itc_elg.itc_inelg[0].csamt, 2) }} | +
  (2) {{__("Others")}} | +{{ flt(data.itc_elg.itc_inelg[1].iamt, 2) }} | +{{ flt(data.itc_elg.itc_inelg[1].camt, 2) }} | +{{ flt(data.itc_elg.itc_inelg[1].samt, 2) }} | +{{ flt(data.itc_elg.itc_inelg[1].csamt, 2) }} | +
{{__("Nature of Supplies")}} | +{{__("Inter-State Supplies")}} | +{{__("Intra-State Supplies")}} | +
---|---|---|
{{__("From a supplier under composition scheme, Exempt and Nil rated")}} | +{{ flt(data.inward_sup.isup_details[0].inter, 2) }} | +{{ flt(data.inward_sup.isup_details[0].intra, 2) }} | +
{{__("Non GST Inward Supplies")}} | +{{ flt(data.inward_sup.isup_details[1].inter, 2) }} | +{{ flt(data.inward_sup.isup_details[1].intra, 2) }} | +