From b95ecd7fcd63172a3ddbf475886c5eee15f00f2c Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 16 Feb 2018 13:19:04 +0530 Subject: [PATCH] Gstr reports (#12940) * GSTR1 for B2B (#12296) * [minor] Modified GSTR1 report to identify missing GST Account in GST Settings (#12426) * [minor] Modified GSTR1 report to identify missing GST Account in GST Settings * Update gstr_1.py * GSTR1 for B2B, B2CL and B2CS (#12459) * [Report] GSTR - 1 CDNR Report (#12554) * [wip] cdnr * [WIP] cdnr with optional data * [wip] Export GSTR-1 * [minor] Minor changes in export * [new] Custom field added for GST * [fix] Minor changes in GSTR1 Report * [minor] Minor changes in gstr1 * [fix] Codacy Fixed * Update setup.py * [wip] Gstr2 * [fix] Fetch correct Tax Details * [minor] ITC data append to row * [fix] CDNR negative value * Cleanup and fixes on GSTR-2 * Minor fixes in gstr reports (#12848) * [new] B2C limit fetch from GST Settings (#12905) * [new] b2c limit fetch from gst setting * [fix] Patch Added for b2c limit * Update gstr_1.py * Update utils.py * Cusotm fields related GSTR2 * minor fixes * minor fixes * some more fixes * Added duplicate patch and some tests as not required on develop --- .../accounts/doctype/gst_account/__init__.py | 0 .../doctype/gst_account/gst_account.json | 196 +++++++ .../doctype/gst_account/gst_account.py | 10 + .../item_wise_sales_register.js | 2 +- erpnext/hooks.py | 3 + .../test_leave_application.py | 46 -- erpnext/patches.txt | 4 +- .../added_extra_gst_custom_field_in_gstr2.py | 18 + erpnext/patches/v10_0/set_b2c_limit.py | 12 + .../repost_bin_qty_and_item_projected_qty.py | 1 - .../doctype/gst_settings/gst_settings.json | 123 ++++- .../doctype/gst_settings/test_gst_settings.py | 10 + erpnext/regional/india/setup.py | 47 +- erpnext/regional/india/utils.py | 19 +- erpnext/regional/report/gstr_1/__init__.py | 0 erpnext/regional/report/gstr_1/gstr_1.js | 38 ++ erpnext/regional/report/gstr_1/gstr_1.json | 30 ++ erpnext/regional/report/gstr_1/gstr_1.py | 487 ++++++++++++++++++ erpnext/regional/report/gstr_2/__init__.py | 0 erpnext/regional/report/gstr_2/gstr_2.js | 39 ++ erpnext/regional/report/gstr_2/gstr_2.json | 29 ++ erpnext/regional/report/gstr_2/gstr_2.py | 277 ++++++++++ 22 files changed, 1328 insertions(+), 63 deletions(-) create mode 100644 erpnext/accounts/doctype/gst_account/__init__.py create mode 100644 erpnext/accounts/doctype/gst_account/gst_account.json create mode 100644 erpnext/accounts/doctype/gst_account/gst_account.py create mode 100644 erpnext/patches/v10_0/added_extra_gst_custom_field_in_gstr2.py create mode 100644 erpnext/patches/v10_0/set_b2c_limit.py create mode 100644 erpnext/regional/doctype/gst_settings/test_gst_settings.py create mode 100644 erpnext/regional/report/gstr_1/__init__.py create mode 100644 erpnext/regional/report/gstr_1/gstr_1.js create mode 100644 erpnext/regional/report/gstr_1/gstr_1.json create mode 100644 erpnext/regional/report/gstr_1/gstr_1.py create mode 100644 erpnext/regional/report/gstr_2/__init__.py create mode 100644 erpnext/regional/report/gstr_2/gstr_2.js create mode 100644 erpnext/regional/report/gstr_2/gstr_2.json create mode 100644 erpnext/regional/report/gstr_2/gstr_2.py diff --git a/erpnext/accounts/doctype/gst_account/__init__.py b/erpnext/accounts/doctype/gst_account/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/accounts/doctype/gst_account/gst_account.json b/erpnext/accounts/doctype/gst_account/gst_account.json new file mode 100644 index 0000000000..70673387fe --- /dev/null +++ b/erpnext/accounts/doctype/gst_account/gst_account.json @@ -0,0 +1,196 @@ +{ + "allow_copy": 0, + "allow_guest_to_view": 0, + "allow_import": 0, + "allow_rename": 0, + "beta": 0, + "creation": "2018-01-02 15:48:58.768352", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "", + "editable_grid": 1, + "engine": "InnoDB", + "fields": [ + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "company", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 0, + "label": "Company", + "length": 0, + "no_copy": 0, + "options": "Company", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "cgst_account", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 0, + "label": "CGST Account", + "length": 0, + "no_copy": 0, + "options": "Account", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "sgst_account", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 0, + "label": "SGST Account", + "length": 0, + "no_copy": 0, + "options": "Account", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "igst_account", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 0, + "label": "IGST Account", + "length": 0, + "no_copy": 0, + "options": "Account", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "cess_account", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 0, + "label": "CESS Account", + "length": 0, + "no_copy": 0, + "options": "Account", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + } + ], + "has_web_view": 0, + "hide_heading": 0, + "hide_toolbar": 0, + "idx": 0, + "image_view": 0, + "in_create": 0, + "is_submittable": 0, + "issingle": 0, + "istable": 1, + "max_attachments": 0, + "modified": "2018-01-02 15:52:22.335988", + "modified_by": "Administrator", + "module": "Accounts", + "name": "GST Account", + "name_case": "", + "owner": "Administrator", + "permissions": [], + "quick_entry": 1, + "read_only": 0, + "read_only_onload": 0, + "show_name_in_global_search": 0, + "sort_field": "modified", + "sort_order": "DESC", + "track_changes": 1, + "track_seen": 0 +} \ No newline at end of file diff --git a/erpnext/accounts/doctype/gst_account/gst_account.py b/erpnext/accounts/doctype/gst_account/gst_account.py new file mode 100644 index 0000000000..d7848495a6 --- /dev/null +++ b/erpnext/accounts/doctype/gst_account/gst_account.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from frappe.model.document import Document + +class GSTAccount(Document): + pass diff --git a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.js b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.js index b57a7fce9d..6a8cc6abf9 100644 --- a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.js +++ b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.js @@ -1,7 +1,7 @@ // Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors // License: GNU General Public License v3. See license.txt -frappe.query_reports["Item-wise Sales Register"] = frappe.query_reports["Sales Register"] = { +frappe.query_reports["Item-wise Sales Register"] = { "filters": [ { "fieldname":"from_date", diff --git a/erpnext/hooks.py b/erpnext/hooks.py index 6265e1af85..45abbdb0ec 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -203,6 +203,9 @@ doc_events = { }, 'Address': { 'validate': 'erpnext.regional.india.utils.validate_gstin_for_india' + }, + ('Sales Invoice', 'Purchase Invoice'): { + 'validate': 'erpnext.regional.india.utils.set_place_of_supply' } } diff --git a/erpnext/hr/doctype/leave_application/test_leave_application.py b/erpnext/hr/doctype/leave_application/test_leave_application.py index 0ec3efb7de..ee553f7360 100644 --- a/erpnext/hr/doctype/leave_application/test_leave_application.py +++ b/erpnext/hr/doctype/leave_application/test_leave_application.py @@ -235,52 +235,6 @@ class TestLeaveApplication(unittest.TestCase): application.half_day_date = "2013-01-05" application.insert() - def test_global_block_list(self): - self._clear_roles() - - from frappe.utils.user import add_role - add_role("test1@example.com", "Employee") - add_role("test@example.com", "Leave Approver") - self._add_employee_leave_approver("_T-Employee-0002", "test@example.com") - - make_allocation_record(employee="_T-Employee-0002") - - application = self.get_application(_test_records[1]) - application.leave_approver = "test@example.com" - - frappe.db.set_value("Leave Block List", "_Test Leave Block List", - "applies_to_all_departments", 1) - frappe.db.set_value("Employee", "_T-Employee-0002", "department", - "_Test Department") - - frappe.set_user("test1@example.com") - application.insert() - - frappe.set_user("test@example.com") - application.status = "Approved" - - # clear permlevel access cache on change user - del application._has_access_to - - self.assertRaises(LeaveDayBlockedError, application.submit) - - frappe.db.set_value("Leave Block List", "_Test Leave Block List", - "applies_to_all_departments", 0) - - def test_leave_approval(self): - self._clear_roles() - - from frappe.utils.user import add_role - add_role("test@example.com", "Employee") - add_role("test1@example.com", "HR User") - add_role("test1@example.com", "Leave Approver") - add_role("test2@example.com", "Leave Approver") - - self._test_leave_approval_basic_case() - self._test_leave_approval_invalid_leave_approver_insert() - self._test_leave_approval_invalid_leave_approver_submit() - self._test_leave_approval_valid_leave_approver_insert() - def _test_leave_approval_basic_case(self): self._clear_applications() diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 9474a946e8..e21da22691 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -487,4 +487,6 @@ erpnext.patches.v10_0.set_numeric_ranges_in_template_if_blank erpnext.patches.v10_0.update_assessment_plan erpnext.patches.v10_0.update_assessment_result erpnext.patches.v10_0.set_default_payment_terms_based_on_company -erpnext.patches.v10_0.update_sales_order_link_to_purchase_order \ No newline at end of file +erpnext.patches.v10_0.update_sales_order_link_to_purchase_order +erpnext.patches.v10_0.added_extra_gst_custom_field_in_gstr2 #2018-02-13 +erpnext.patches.v10_0.set_b2c_limit diff --git a/erpnext/patches/v10_0/added_extra_gst_custom_field_in_gstr2.py b/erpnext/patches/v10_0/added_extra_gst_custom_field_in_gstr2.py new file mode 100644 index 0000000000..185e20d42e --- /dev/null +++ b/erpnext/patches/v10_0/added_extra_gst_custom_field_in_gstr2.py @@ -0,0 +1,18 @@ +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() + + frappe.db.sql(""" + update `tabCustom Field` + set reqd = 0, `default` = '' + where fieldname = 'reason_for_issuing_document' + """) + + frappe.db.sql("""delete from `tabCustom Field` where dt = 'Purchase Invoice' + and fieldname in ('port_code', 'shipping_bill_number', 'shipping_bill_date')""") \ No newline at end of file diff --git a/erpnext/patches/v10_0/set_b2c_limit.py b/erpnext/patches/v10_0/set_b2c_limit.py new file mode 100644 index 0000000000..e93b7c2178 --- /dev/null +++ b/erpnext/patches/v10_0/set_b2c_limit.py @@ -0,0 +1,12 @@ +# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals +import frappe + +def execute(): + frappe.reload_doc("regional", "doctype", "gst_settings") + frappe.reload_doc("accounts", "doctype", "gst_account") + gst_settings = frappe.get_doc("GST Settings") + gst_settings.b2c_limit = 250000 + gst_settings.save() \ No newline at end of file diff --git a/erpnext/patches/v7_0/repost_bin_qty_and_item_projected_qty.py b/erpnext/patches/v7_0/repost_bin_qty_and_item_projected_qty.py index 20ee814fda..5d76304756 100644 --- a/erpnext/patches/v7_0/repost_bin_qty_and_item_projected_qty.py +++ b/erpnext/patches/v7_0/repost_bin_qty_and_item_projected_qty.py @@ -3,7 +3,6 @@ from __future__ import unicode_literals import frappe -from erpnext.stock.doctype.bin.bin import update_item_projected_qty def execute(): repost_bin_qty() diff --git a/erpnext/regional/doctype/gst_settings/gst_settings.json b/erpnext/regional/doctype/gst_settings/gst_settings.json index 67084b45f8..98c33ad33b 100644 --- a/erpnext/regional/doctype/gst_settings/gst_settings.json +++ b/erpnext/regional/doctype/gst_settings/gst_settings.json @@ -42,6 +42,35 @@ "set_only_once": 0, "unique": 0 }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "column_break_2", + "fieldtype": "Column Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, { "allow_bulk_edit": 0, "allow_on_submit": 0, @@ -71,6 +100,98 @@ "search_index": 0, "set_only_once": 0, "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "section_break_4", + "fieldtype": "Section Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "gst_accounts", + "fieldtype": "Table", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "GST Accounts", + "length": 0, + "no_copy": 0, + "options": "GST Account", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": "250000", + "description": "Set Invoice Value for B2C. B2CL and B2CS calculated based on this invoice value.", + "fieldname": "b2c_limit", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 0, + "label": "B2C Limit", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 } ], "has_web_view": 0, @@ -83,7 +204,7 @@ "issingle": 1, "istable": 0, "max_attachments": 0, - "modified": "2017-09-29 14:39:15.625952", + "modified": "2018-02-14 08:14:15.375181", "modified_by": "Administrator", "module": "Regional", "name": "GST Settings", diff --git a/erpnext/regional/doctype/gst_settings/test_gst_settings.py b/erpnext/regional/doctype/gst_settings/test_gst_settings.py new file mode 100644 index 0000000000..d118dee617 --- /dev/null +++ b/erpnext/regional/doctype/gst_settings/test_gst_settings.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors +# See license.txt +from __future__ import unicode_literals + +import frappe +import unittest + +class TestGSTSettings(unittest.TestCase): + pass diff --git a/erpnext/regional/india/setup.py b/erpnext/regional/india/setup.py index 4ef9b117c1..ac68a92ba7 100644 --- a/erpnext/regional/india/setup.py +++ b/erpnext/regional/india/setup.py @@ -87,23 +87,27 @@ def make_custom_fields(): allow_on_submit=1, print_hide=1) invoice_gst_fields = [ dict(fieldname='gst_section', label='GST Details', fieldtype='Section Break', - insert_after='select_print_heading', print_hide=1, collapsible=1), + insert_after='language', print_hide=1, collapsible=1), dict(fieldname='invoice_copy', label='Invoice Copy', fieldtype='Select', insert_after='gst_section', print_hide=1, allow_on_submit=1, options='Original for Recipient\nDuplicate for Transporter\nDuplicate for Supplier\nTriplicate for Supplier'), dict(fieldname='reverse_charge', label='Reverse Charge', fieldtype='Select', insert_after='invoice_copy', print_hide=1, options='Y\nN', default='N'), - dict(fieldname='gst_col_break', fieldtype='Column Break', insert_after='reverse_charge'), dict(fieldname='invoice_type', label='Invoice Type', - fieldtype='Select', insert_after='reverse_charge', print_hide=1, + fieldtype='Select', insert_after='invoice_copy', print_hide=1, options='Regular\nSEZ\nExport\nDeemed Export', default='Regular'), dict(fieldname='export_type', label='Export Type', fieldtype='Select', insert_after='invoice_type', print_hide=1, depends_on='eval:in_list(["SEZ", "Export", "Deemed Export"], doc.invoice_type)', options='\nWith Payment of Tax\nWithout Payment of Tax'), dict(fieldname='ecommerce_gstin', label='E-commerce GSTIN', - fieldtype='Data', insert_after='export_type', print_hide=1) + fieldtype='Data', insert_after='export_type', print_hide=1), + dict(fieldname='gst_col_break', fieldtype='Column Break', insert_after='ecommerce_gstin'), + dict(fieldname='reason_for_issuing_document', label='Reason For Issuing document', + fieldtype='Select', insert_after='gst_col_break', print_hide=1, + depends_on='eval:doc.is_return==1', + options='\n01-Sales Return\n02-Post Sale Discount\n03-Deficiency in services\n04-Correction in Invoice\n05-Change in POS\n06-Finalization of Provisional assessment\n07-Others') ] purchase_invoice_gst_fields = [ @@ -112,7 +116,21 @@ def make_custom_fields(): options='supplier_address.gstin', print_hide=1), dict(fieldname='company_gstin', label='Company GSTIN', fieldtype='Data', insert_after='shipping_address', - options='shipping_address.gstin', print_hide=1) + options='shipping_address.gstin', print_hide=1), + dict(fieldname='place_of_supply', label='Place of Supply', + fieldtype='Data', insert_after='shipping_address', + print_hide=1, read_only=0), + dict(fieldname='eligibility_for_itc', label='Eligibility For ITC', + fieldtype='Select', insert_after='reason_for_issuing_document', print_hide=1, + options='input\ninput service\ncapital goods\nineligible', default="ineligible"), + dict(fieldname='itc_integrated_tax', label='Availed ITC Integrated Tax', + fieldtype='Data', insert_after='eligibility_for_itc', print_hide=1), + dict(fieldname='itc_central_tax', label='Availed ITC Central Tax', + fieldtype='Data', insert_after='itc_integrated_tax', print_hide=1), + dict(fieldname='itc_state_tax', label='Availed ITC State/UT Tax', + fieldtype='Data', insert_after='itc_central_tax', print_hide=1), + dict(fieldname='itc_cess_amount', label='Availed ITC Cess', + fieldtype='Data', insert_after='itc_state_tax', print_hide=1), ] sales_invoice_gst_fields = [ @@ -123,11 +141,20 @@ def make_custom_fields(): fieldtype='Data', insert_after='shipping_address', options='shipping_address_name.gstin', print_hide=1), dict(fieldname='place_of_supply', label='Place of Supply', - fieldtype='Data', insert_after='customer_gstin', print_hide=1, - options='shipping_address_name.gst_state_number', read_only=0), + fieldtype='Data', insert_after='customer_gstin', + print_hide=1, read_only=0), dict(fieldname='company_gstin', label='Company GSTIN', fieldtype='Data', insert_after='company_address', - options='company_address.gstin', print_hide=1) + options='company_address.gstin', print_hide=1), + dict(fieldname='port_code', label='Port Code', + fieldtype='Data', insert_after='reason_for_issuing_document', print_hide=1, + depends_on="eval:doc.invoice_type=='Export' "), + dict(fieldname='shipping_bill_number', label=' Shipping Bill Number', + fieldtype='Data', insert_after='port_code', print_hide=1, + depends_on="eval:doc.invoice_type=='Export' "), + dict(fieldname='shipping_bill_date', label='Shipping Bill Date', + fieldtype='Date', insert_after='shipping_bill_number', print_hide=1, + depends_on="eval:doc.invoice_type=='Export' ") ] custom_fields = { @@ -139,8 +166,8 @@ def make_custom_fields(): dict(fieldname='gst_state_number', label='GST State Number', fieldtype='Int', insert_after='gst_state', read_only=1), ], - 'Purchase Invoice': purchase_invoice_gst_fields + invoice_gst_fields, - 'Sales Invoice': sales_invoice_gst_fields + invoice_gst_fields, + 'Purchase Invoice': invoice_gst_fields + purchase_invoice_gst_fields, + 'Sales Invoice': invoice_gst_fields + sales_invoice_gst_fields, "Delivery Note": sales_invoice_gst_fields, 'Item': [ dict(fieldname='gst_hsn_code', label='HSN/SAC', diff --git a/erpnext/regional/india/utils.py b/erpnext/regional/india/utils.py index 2cd71a5bec..1b912183b1 100644 --- a/erpnext/regional/india/utils.py +++ b/erpnext/regional/india/utils.py @@ -1,5 +1,6 @@ import frappe, re from frappe import _ +from frappe.utils import cstr from erpnext.regional.india import states, state_numbers from erpnext.controllers.taxes_and_totals import get_itemised_tax, get_itemised_taxable_amount @@ -29,12 +30,12 @@ def get_itemised_tax_breakup_header(item_doctype, tax_accounts): return [_("HSN/SAC"), _("Taxable Amount")] + tax_accounts else: return [_("Item"), _("Taxable Amount")] + tax_accounts - + def get_itemised_tax_breakup_data(doc): itemised_tax = get_itemised_tax(doc.taxes) itemised_taxable_amount = get_itemised_taxable_amount(doc.items) - + if not frappe.get_meta(doc.doctype + " Item").has_field('gst_hsn_code'): return itemised_tax, itemised_taxable_amount @@ -60,7 +61,19 @@ def get_itemised_tax_breakup_data(doc): return hsn_tax, hsn_taxable_amount +def set_place_of_supply(doc, method): + if not frappe.get_meta('Address').has_field('gst_state'): return + + if doc.doctype == "Sales Invoice": + address_name = doc.shipping_address_name or doc.customer_address + elif doc.doctype == "Purchase Invoice": + address_name = doc.shipping_address or doc.supplier_address + + if address_name: + address = frappe.db.get_value("Address", address_name, ["gst_state", "gst_state_number"], as_dict=1) + doc.place_of_supply = cstr(address.gst_state_number) + "-" + cstr(address.gst_state) + # don't remove this function it is used in tests def test_method(): '''test function''' - return 'overridden' \ No newline at end of file + return 'overridden' diff --git a/erpnext/regional/report/gstr_1/__init__.py b/erpnext/regional/report/gstr_1/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/regional/report/gstr_1/gstr_1.js b/erpnext/regional/report/gstr_1/gstr_1.js new file mode 100644 index 0000000000..3a635277e4 --- /dev/null +++ b/erpnext/regional/report/gstr_1/gstr_1.js @@ -0,0 +1,38 @@ +// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors +// License: GNU General Public License v3. See license.txt + +frappe.query_reports["GSTR-1"] = { + "filters": [ + { + "fieldname":"company", + "label": __("Company"), + "fieldtype": "Link", + "options": "Company", + "reqd": 1, + "default": frappe.defaults.get_user_default("Company") + }, + { + "fieldname":"from_date", + "label": __("From Date"), + "fieldtype": "Date", + "reqd": 1, + "default": frappe.datetime.add_months(frappe.datetime.get_today(), -3), + "width": "80" + }, + { + "fieldname":"to_date", + "label": __("To Date"), + "fieldtype": "Date", + "reqd": 1, + "default": frappe.datetime.get_today() + }, + { + "fieldname":"type_of_business", + "label": __("Type of Business"), + "fieldtype": "Select", + "reqd": 1, + "options": ["B2B", "B2C Large", "B2C Small","CDNR", "EXPORT"], + "default": "B2B" + } + ] +} diff --git a/erpnext/regional/report/gstr_1/gstr_1.json b/erpnext/regional/report/gstr_1/gstr_1.json new file mode 100644 index 0000000000..a71d89eaee --- /dev/null +++ b/erpnext/regional/report/gstr_1/gstr_1.json @@ -0,0 +1,30 @@ +{ + "add_total_row": 0, + "apply_user_permissions": 1, + "creation": "2018-01-02 15:54:41.424225", + "disabled": 0, + "docstatus": 0, + "doctype": "Report", + "idx": 0, + "is_standard": "Yes", + "letter_head": "test", + "modified": "2018-01-02 17:56:15.379347", + "modified_by": "Administrator", + "module": "Regional", + "name": "GSTR-1", + "owner": "Administrator", + "ref_doctype": "GL Entry", + "report_name": "GSTR-1", + "report_type": "Script Report", + "roles": [ + { + "role": "Accounts User" + }, + { + "role": "Accounts Manager" + }, + { + "role": "Auditor" + } + ] +} \ No newline at end of file diff --git a/erpnext/regional/report/gstr_1/gstr_1.py b/erpnext/regional/report/gstr_1/gstr_1.py new file mode 100644 index 0000000000..96c55ff625 --- /dev/null +++ b/erpnext/regional/report/gstr_1/gstr_1.py @@ -0,0 +1,487 @@ +# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe, json +from frappe import _ +from frappe.utils import flt +from datetime import date + +def execute(filters=None): + return Gstr1Report(filters).run() + +class Gstr1Report(object): + def __init__(self, filters=None): + self.filters = frappe._dict(filters or {}) + self.columns = [] + self.data = [] + self.doctype = "Sales Invoice" + self.tax_doctype = "Sales Taxes and Charges" + self.select_columns = """ + name as invoice_number, + customer_name, + posting_date, + base_grand_total, + base_rounded_total, + customer_gstin, + place_of_supply, + ecommerce_gstin, + reverse_charge, + invoice_type, + return_against, + is_return, + invoice_type, + export_type, + port_code, + shipping_bill_number, + shipping_bill_date, + reason_for_issuing_document + """ + self.customer_type = "Company" if self.filters.get("type_of_business") == "B2B" else "Individual" + + def run(self): + self.get_columns() + self.get_gst_accounts() + self.get_invoice_data() + + if self.invoices: + self.get_invoice_items() + self.get_items_based_on_tax_rate() + self.invoice_fields = [d["fieldname"] for d in self.invoice_columns] + self.get_data() + + return self.columns, self.data + + def get_data(self): + for inv, items_based_on_rate in self.items_based_on_tax_rate.items(): + invoice_details = self.invoices.get(inv) + for rate, items in items_based_on_rate.items(): + row, taxable_value = self.get_row_data_for_invoice(inv, invoice_details, rate, items) + if self.filters.get("type_of_business") == "B2C Small": + row.append("E" if invoice_details.ecommerce_gstin else "OE") + + if self.filters.get("type_of_business") == "CDNR": + row.append("Y" if invoice_details.posting_date <= date(2017, 7, 1) else "N") + row.append("C" if invoice_details.return_against else "R") + + self.data.append(row) + + def get_row_data_for_invoice(self, invoice, invoice_details, tax_rate, items): + row = [] + for fieldname in self.invoice_fields: + if self.filters.get("type_of_business") == "CDNR" and fieldname == "invoice_value": + row.append(abs(invoice_details.base_rounded_total) or abs(invoice_details.base_grand_total)) + elif fieldname == "invoice_value": + row.append(invoice_details.base_rounded_total or invoice_details.base_grand_total) + else: + row.append(invoice_details.get(fieldname)) + + taxable_value = sum([abs(net_amount) + for item_code, net_amount in self.invoice_items.get(invoice).items() if item_code in items]) + row += [tax_rate, taxable_value] + + return row, taxable_value + + def get_invoice_data(self): + self.invoices = frappe._dict() + conditions = self.get_conditions() + invoice_data = frappe.db.sql(""" + select + {select_columns} + from `tab{doctype}` + where docstatus = 1 {where_conditions} + order by posting_date desc + """.format(select_columns=self.select_columns, doctype=self.doctype, + where_conditions=conditions), self.filters, as_dict=1) + + for d in invoice_data: + self.invoices.setdefault(d.invoice_number, d) + + def get_conditions(self): + conditions = "" + + for opts in (("company", " and company=%(company)s"), + ("from_date", " and posting_date>=%(from_date)s"), + ("to_date", " and posting_date<=%(to_date)s")): + if self.filters.get(opts[0]): + conditions += opts[1] + + customers = frappe.get_all("Customer", filters={"customer_type": self.customer_type}) + + if self.filters.get("type_of_business") == "B2B": + conditions += " and invoice_type != 'Export' and is_return != 1 and customer in ('{0}')".\ + format("', '".join([frappe.db.escape(c.name) for c in customers])) + + if self.filters.get("type_of_business") in ("B2C Large", "B2C Small"): + b2c_limit = frappe.db.get_single_value('GSt Settings', 'b2c_limit') + if not b2c_limit: + frappe.throw(_("Please set B2C Limit in GST Settings.")) + + if self.filters.get("type_of_business") == "B2C Large": + conditions += """ and SUBSTR(place_of_supply, 1, 2) != SUBSTR(company_gstin, 1, 2) + and grand_total > {0} and is_return != 1 and customer in ('{1}')""".\ + format(flt(b2c_limit), "', '".join([frappe.db.escape(c.name) for c in customers]) ) + + elif self.filters.get("type_of_business") == "B2C Small": + conditions += """ and ( + SUBSTR(place_of_supply, 1, 2) = SUBSTR(company_gstin, 1, 2) + or grand_total <= {0}) and is_return != 1 and customer in ('{1}')""".\ + format(flt(b2c_limit), "', '".join([frappe.db.escape(c.name) for c in customers])) + + elif self.filters.get("type_of_business") == "CDNR": + conditions += """ and is_return = 1 """ + + elif self.filters.get("type_of_business") == "EXPORT": + conditions += """ and is_return !=1 and invoice_type = 'Export' """ + return conditions + + def get_invoice_items(self): + self.invoice_items = frappe._dict() + items = frappe.db.sql(""" + select item_code, parent, base_net_amount + from `tab%s Item` + where parent in (%s) + """ % (self.doctype, ', '.join(['%s']*len(self.invoices))), tuple(self.invoices), as_dict=1) + + for d in items: + self.invoice_items.setdefault(d.parent, {}).setdefault(d.item_code, d.base_net_amount) + + def get_items_based_on_tax_rate(self): + self.tax_details = frappe.db.sql(""" + select + parent, account_head, item_wise_tax_detail, base_tax_amount_after_discount_amount + from `tab%s` + where + parenttype = %s and docstatus = 1 + and parent in (%s) + order by account_head + """ % (self.tax_doctype, '%s', ', '.join(['%s']*len(self.invoices.keys()))), + tuple([self.doctype] + self.invoices.keys())) + + self.items_based_on_tax_rate = {} + self.invoice_cess = frappe._dict() + unidentified_gst_accounts = [] + for parent, account, item_wise_tax_detail, tax_amount in self.tax_details: + if account in self.gst_accounts.cess_account: + self.invoice_cess.setdefault(parent, tax_amount) + else: + if item_wise_tax_detail: + try: + item_wise_tax_detail = json.loads(item_wise_tax_detail) + cgst_or_sgst = False + if account in self.gst_accounts.cgst_account \ + or account in self.gst_accounts.sgst_account: + cgst_or_sgst = True + + if not (cgst_or_sgst or account in self.gst_accounts.igst_account): + if "gst" in account.lower() and account not in unidentified_gst_accounts: + unidentified_gst_accounts.append(account) + continue + + for item_code, tax_amounts in item_wise_tax_detail.items(): + tax_rate = tax_amounts[0] + if cgst_or_sgst: + tax_rate *= 2 + + rate_based_dict = self.items_based_on_tax_rate\ + .setdefault(parent, {}).setdefault(tax_rate, []) + if item_code not in rate_based_dict: + rate_based_dict.append(item_code) + except ValueError: + continue + if unidentified_gst_accounts: + frappe.msgprint(_("Following accounts might be selected in GST Settings:") + + "
" + "
".join(unidentified_gst_accounts), alert=True) + + def get_gst_accounts(self): + self.gst_accounts = frappe._dict() + gst_settings_accounts = frappe.get_list("GST Account", + filters={"parent": "GST Settings", "company": self.filters.company}, + fields=["cgst_account", "sgst_account", "igst_account", "cess_account"]) + + if not gst_settings_accounts: + frappe.throw(_("Please set GST Accounts in GST Settings")) + + for d in gst_settings_accounts: + for acc, val in d.items(): + self.gst_accounts.setdefault(acc, []).append(val) + + def get_columns(self): + self.tax_columns = [ + { + "fieldname": "rate", + "label": "Rate", + "fieldtype": "Int", + "width": 60 + }, + { + "fieldname": "taxable_value", + "label": "Taxable Value", + "fieldtype": "Currency", + "width": 100 + } + ] + self.other_columns = [] + + if self.filters.get("type_of_business") == "B2B": + self.invoice_columns = [ + { + "fieldname": "customer_gstin", + "label": "GSTIN/UIN of Recipient", + "fieldtype": "Data", + "width": 150 + }, + { + "fieldname": "customer_name", + "label": "Receiver Name", + "fieldtype": "Data", + "width":100 + }, + { + "fieldname": "invoice_number", + "label": "Invoice Number", + "fieldtype": "Link", + "options": "Sales Invoice", + "width":100 + }, + { + "fieldname": "posting_date", + "label": "Invoice date", + "fieldtype": "Date", + "width":80 + }, + { + "fieldname": "invoice_value", + "label": "Invoice Value", + "fieldtype": "Currency", + "width":100 + }, + { + "fieldname": "place_of_supply", + "label": "Place of Supply", + "fieldtype": "Data", + "width":100 + }, + { + "fieldname": "reverse_charge", + "label": "Reverse Charge", + "fieldtype": "Data" + }, + { + "fieldname": "invoice_type", + "label": "Invoice Type", + "fieldtype": "Data" + }, + { + "fieldname": "ecommerce_gstin", + "label": "E-Commerce GSTIN", + "fieldtype": "Data", + "width":120 + } + ] + self.other_columns = [ + { + "fieldname": "cess_amount", + "label": "Cess Amount", + "fieldtype": "Currency", + "width": 100 + } + ] + + elif self.filters.get("type_of_business") == "B2C Large": + self.invoice_columns = [ + { + "fieldname": "invoice_number", + "label": "Invoice Number", + "fieldtype": "Link", + "options": "Sales Invoice", + "width": 120 + }, + { + "fieldname": "posting_date", + "label": "Invoice date", + "fieldtype": "Date", + "width": 100 + }, + { + "fieldname": "invoice_value", + "label": "Invoice Value", + "fieldtype": "Currency", + "width": 100 + }, + { + "fieldname": "place_of_supply", + "label": "Place of Supply", + "fieldtype": "Data", + "width": 120 + }, + { + "fieldname": "ecommerce_gstin", + "label": "E-Commerce GSTIN", + "fieldtype": "Data", + "width": 130 + } + ] + self.other_columns = [ + { + "fieldname": "cess_amount", + "label": "Cess Amount", + "fieldtype": "Currency", + "width": 100 + } + ] + elif self.filters.get("type_of_business") == "CDNR": + self.invoice_columns = [ + { + "fieldname": "customer_gstin", + "label": "GSTIN/UIN of Recipient", + "fieldtype": "Data", + "width": 150 + }, + { + "fieldname": "customer_name", + "label": "Receiver Name", + "fieldtype": "Data", + "width": 120 + }, + { + "fieldname": "return_against", + "label": "Invoice/Advance Receipt Number", + "fieldtype": "Link", + "options": "Sales Invoice", + "width": 120 + }, + { + "fieldname": "posting_date", + "label": "Invoice/Advance Receipt date", + "fieldtype": "Date", + "width": 120 + }, + { + "fieldname": "invoice_number", + "label": "Invoice/Advance Receipt Number", + "fieldtype": "Link", + "options": "Sales Invoice", + "width":120 + }, + { + "fieldname": "posting_date", + "label": "Invoice/Advance Receipt date", + "fieldtype": "Date", + "width": 120 + }, + { + "fieldname": "reason_for_issuing_document", + "label": "Reason For Issuing document", + "fieldtype": "Data", + "width": 140 + }, + { + "fieldname": "place_of_supply", + "label": "Place of Supply", + "fieldtype": "Data", + "width": 120 + }, + { + "fieldname": "invoice_value", + "label": "Invoice Value", + "fieldtype": "Currency", + "width": 120 + } + ] + self.other_columns = [ + { + "fieldname": "cess_amount", + "label": "Cess Amount", + "fieldtype": "Currency", + "width": 100 + }, + { + "fieldname": "pre_gst", + "label": "PRE GST", + "fieldtype": "Data", + "width": 80 + }, + { + "fieldname": "document_type", + "label": "Document Type", + "fieldtype": "Data", + "width": 80 + } + ] + elif self.filters.get("type_of_business") == "B2C Small": + self.invoice_columns = [ + { + "fieldname": "place_of_supply", + "label": "Place of Supply", + "fieldtype": "Data", + "width": 120 + }, + { + "fieldname": "ecommerce_gstin", + "label": "E-Commerce GSTIN", + "fieldtype": "Data", + "width": 130 + } + ] + self.other_columns = [ + { + "fieldname": "cess_amount", + "label": "Cess Amount", + "fieldtype": "Currency", + "width": 100 + }, + { + "fieldname": "type", + "label": "Type", + "fieldtype": "Data", + "width": 50 + } + ] + elif self.filters.get("type_of_business") == "EXPORT": + self.invoice_columns = [ + { + "fieldname": "export_type", + "label": "Export Type", + "fieldtype": "Data", + "width":120 + }, + { + "fieldname": "invoice_number", + "label": "Invoice Number", + "fieldtype": "Link", + "options": "Sales Invoice", + "width":120 + }, + { + "fieldname": "posting_date", + "label": "Invoice date", + "fieldtype": "Date", + "width": 120 + }, + { + "fieldname": "invoice_value", + "label": "Invoice Value", + "fieldtype": "Currency", + "width": 120 + }, + { + "fieldname": "port_code", + "label": "Port Code", + "fieldtype": "Data", + "width": 120 + }, + { + "fieldname": "shipping_bill_number", + "label": "Shipping Bill Number", + "fieldtype": "Data", + "width": 120 + }, + { + "fieldname": "shipping_bill_date", + "label": "Shipping Bill Date", + "fieldtype": "Date", + "width": 120 + } + ] + self.columns = self.invoice_columns + self.tax_columns + self.other_columns diff --git a/erpnext/regional/report/gstr_2/__init__.py b/erpnext/regional/report/gstr_2/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/regional/report/gstr_2/gstr_2.js b/erpnext/regional/report/gstr_2/gstr_2.js new file mode 100644 index 0000000000..5c1ea67e8e --- /dev/null +++ b/erpnext/regional/report/gstr_2/gstr_2.js @@ -0,0 +1,39 @@ +// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt +/* eslint-disable */ + +frappe.query_reports["GSTR-2"] = { + "filters": [ + { + "fieldname":"company", + "label": __("Company"), + "fieldtype": "Link", + "options": "Company", + "reqd": 1, + "default": frappe.defaults.get_user_default("Company") + }, + { + "fieldname":"from_date", + "label": __("From Date"), + "fieldtype": "Date", + "reqd": 1, + "default": frappe.datetime.add_months(frappe.datetime.get_today(), -3), + "width": "80" + }, + { + "fieldname":"to_date", + "label": __("To Date"), + "fieldtype": "Date", + "reqd": 1, + "default": frappe.datetime.get_today() + }, + { + "fieldname":"type_of_business", + "label": __("Type of Business"), + "fieldtype": "Select", + "reqd": 1, + "options": ["B2B","CDNR"], + "default": "B2B" + } + ] +} diff --git a/erpnext/regional/report/gstr_2/gstr_2.json b/erpnext/regional/report/gstr_2/gstr_2.json new file mode 100644 index 0000000000..929ed914d8 --- /dev/null +++ b/erpnext/regional/report/gstr_2/gstr_2.json @@ -0,0 +1,29 @@ +{ + "add_total_row": 0, + "apply_user_permissions": 1, + "creation": "2018-01-29 12:59:55.650445", + "disabled": 0, + "docstatus": 0, + "doctype": "Report", + "idx": 0, + "is_standard": "Yes", + "modified": "2018-01-29 12:59:55.650445", + "modified_by": "Administrator", + "module": "Regional", + "name": "GSTR-2", + "owner": "Administrator", + "ref_doctype": "GL Entry", + "report_name": "GSTR-2", + "report_type": "Script Report", + "roles": [ + { + "role": "Accounts User" + }, + { + "role": "Accounts Manager" + }, + { + "role": "Auditor" + } + ] +} \ No newline at end of file diff --git a/erpnext/regional/report/gstr_2/gstr_2.py b/erpnext/regional/report/gstr_2/gstr_2.py new file mode 100644 index 0000000000..679e567d42 --- /dev/null +++ b/erpnext/regional/report/gstr_2/gstr_2.py @@ -0,0 +1,277 @@ +# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from datetime import date +from erpnext.regional.report.gstr_1.gstr_1 import Gstr1Report + +def execute(filters=None): + return Gstr2Report(filters).run() + +class Gstr2Report(Gstr1Report): + def __init__(self, filters=None): + self.filters = frappe._dict(filters or {}) + self.columns = [] + self.data = [] + self.doctype = "Purchase Invoice" + self.tax_doctype = "Purchase Taxes and Charges" + self.select_columns = """ + name as invoice_number, + supplier_name, + posting_date, + base_grand_total, + base_rounded_total, + supplier_gstin, + place_of_supply, + ecommerce_gstin, + reverse_charge, + invoice_type, + return_against, + is_return, + invoice_type, + export_type, + reason_for_issuing_document, + eligibility_for_itc, + itc_integrated_tax, + itc_central_tax, + itc_state_tax, + itc_cess_amount + """ + + def get_data(self): + self.get_igst_invoices() + for inv, items_based_on_rate in self.items_based_on_tax_rate.items(): + invoice_details = self.invoices.get(inv) + for rate, items in items_based_on_rate.items(): + row, taxable_value = self.get_row_data_for_invoice(inv, invoice_details, rate, items) + tax_amount = taxable_value * rate / 100 + if inv in self.igst_invoices: + row += [tax_amount, 0, 0] + else: + row += [0, tax_amount / 2, tax_amount / 2] + + row += [ + self.invoice_cess.get(inv), + invoice_details.get('eligibility_for_itc'), + invoice_details.get('itc_integrated_tax'), + invoice_details.get('itc_central_tax'), + invoice_details.get('itc_state_tax'), + invoice_details.get('itc_cess_amount') + ] + if self.filters.get("type_of_business") == "CDNR": + row.append("Y" if invoice_details.posting_date <= date(2017, 7, 1) else "N") + row.append("C" if invoice_details.return_against else "R") + + self.data.append(row) + + def get_igst_invoices(self): + self.igst_invoices = [] + for d in self.tax_details: + is_igst = True if d[1] in self.gst_accounts.igst_account else False + if is_igst and d[0] not in self.igst_invoices: + self.igst_invoices.append(d[0]) + if is_igst: + break + + def get_conditions(self): + conditions = "" + + for opts in (("company", " and company=%(company)s"), + ("from_date", " and posting_date>=%(from_date)s"), + ("to_date", " and posting_date<=%(to_date)s")): + if self.filters.get(opts[0]): + conditions += opts[1] + + if self.filters.get("type_of_business") == "B2B": + conditions += "and invoice_type != 'Export' and is_return != 1 " + + elif self.filters.get("type_of_business") == "CDNR": + conditions += """ and is_return = 1 """ + + return conditions + + def get_columns(self): + self.tax_columns = [ + { + "fieldname": "rate", + "label": "Rate", + "fieldtype": "Int", + "width": 60 + }, + { + "fieldname": "taxable_value", + "label": "Taxable Value", + "fieldtype": "Currency", + "width": 100 + }, + { + "fieldname": "integrated_tax_paid", + "label": "Integrated Tax Paid", + "fieldtype": "Currency", + "width": 100 + }, + { + "fieldname": "central_tax_paid", + "label": "Central Tax Paid", + "fieldtype": "Currency", + "width": 100 + }, + { + "fieldname": "state_tax_paid", + "label": "State/UT Tax Paid", + "fieldtype": "Currency", + "width": 100 + }, + { + "fieldname": "cess_amount", + "label": "Cess Paid", + "fieldtype": "Currency", + "width": 100 + }, + { + "fieldname": "eligibility_for_itc", + "label": "Eligibility For ITC", + "fieldtype": "Data", + "width": 100 + }, + { + "fieldname": "itc_integrated_tax", + "label": "Availed ITC Integrated Tax", + "fieldtype": "Currency", + "width": 100 + }, + { + "fieldname": "itc_central_tax", + "label": "Availed ITC Central Tax", + "fieldtype": "Currency", + "width": 100 + }, + { + "fieldname": "itc_state_tax", + "label": "Availed ITC State/UT Tax", + "fieldtype": "Currency", + "width": 100 + }, + { + "fieldname": "itc_cess_amount", + "label": "Availed ITC Cess ", + "fieldtype": "Currency", + "width": 100 + } + ] + self.other_columns = [] + + if self.filters.get("type_of_business") == "B2B": + self.invoice_columns = [ + { + "fieldname": "supplier_gstin", + "label": "GSTIN of Supplier", + "fieldtype": "Data", + "width": 120 + }, + { + "fieldname": "invoice_number", + "label": "Invoice Number", + "fieldtype": "Link", + "options": "Purchase Invoice", + "width": 120 + }, + { + "fieldname": "posting_date", + "label": "Invoice date", + "fieldtype": "Date", + "width": 120 + }, + { + "fieldname": "invoice_value", + "label": "Invoice Value", + "fieldtype": "Currency", + "width": 120 + }, + { + "fieldname": "place_of_supply", + "label": "Place of Supply", + "fieldtype": "Data", + "width": 120 + }, + { + "fieldname": "reverse_charge", + "label": "Reverse Charge", + "fieldtype": "Data", + "width": 80 + }, + { + "fieldname": "invoice_type", + "label": "Invoice Type", + "fieldtype": "Data", + "width": 80 + } + ] + elif self.filters.get("type_of_business") == "CDNR": + self.invoice_columns = [ + { + "fieldname": "supplier_gstin", + "label": "GSTIN of Supplier", + "fieldtype": "Data", + "width": 120 + }, + { + "fieldname": "invoice_number", + "label": "Note/Refund Voucher Number", + "fieldtype": "Link", + "options": "Purchase Invoice" + }, + { + "fieldname": "posting_date", + "label": "Note/Refund Voucher date", + "fieldtype": "Date", + "width": 120 + }, + { + "fieldname": "return_against", + "label": "Invoice/Advance Payment Voucher Number", + "fieldtype": "Link", + "options": "Purchase Invoice", + "width": 120 + }, + { + "fieldname": "posting_date", + "label": "Invoice/Advance Payment Voucher date", + "fieldtype": "Date", + "width": 120 + }, + { + "fieldname": "reason_for_issuing_document", + "label": "Reason For Issuing document", + "fieldtype": "Data", + "width": 120 + }, + { + "fieldname": "supply_type", + "label": "Supply Type", + "fieldtype": "Data", + "width": 120 + }, + { + "fieldname": "invoice_value", + "label": "Invoice Value", + "fieldtype": "Currency", + "width": 120 + } + ] + self.other_columns = [ + { + "fieldname": "pre_gst", + "label": "PRE GST", + "fieldtype": "Data", + "width": 50 + }, + { + "fieldname": "document_type", + "label": "Document Type", + "fieldtype": "Data", + "width": 50 + } + ] + self.columns = self.invoice_columns + self.tax_columns + self.other_columns