Cleanup and fixes on GSTR-2
This commit is contained in:
commit
b02c109e1d
@ -204,7 +204,7 @@ doc_events = {
|
|||||||
'Address': {
|
'Address': {
|
||||||
'validate': 'erpnext.regional.india.utils.validate_gstin_for_india'
|
'validate': 'erpnext.regional.india.utils.validate_gstin_for_india'
|
||||||
},
|
},
|
||||||
'Sales Invoice': {
|
('Sales Invoice', 'Purchase Invoice'): {
|
||||||
'validate': 'erpnext.regional.india.utils.set_place_of_supply'
|
'validate': 'erpnext.regional.india.utils.set_place_of_supply'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -492,3 +492,4 @@ erpnext.patches.v10_0.added_extra_gst_custom_field
|
|||||||
erpnext.patches.v10_0.workflow_leave_application #2018-01-24
|
erpnext.patches.v10_0.workflow_leave_application #2018-01-24
|
||||||
erpnext.patches.v10_0.set_default_payment_terms_based_on_company
|
erpnext.patches.v10_0.set_default_payment_terms_based_on_company
|
||||||
erpnext.patches.v10_0.update_sales_order_link_to_purchase_order
|
erpnext.patches.v10_0.update_sales_order_link_to_purchase_order
|
||||||
|
erpnext.patches.v10_0.added_extra_gst_custom_field_in_gstr2
|
||||||
|
|||||||
@ -0,0 +1,9 @@
|
|||||||
|
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()
|
||||||
@ -87,16 +87,15 @@ def make_custom_fields():
|
|||||||
allow_on_submit=1, print_hide=1)
|
allow_on_submit=1, print_hide=1)
|
||||||
invoice_gst_fields = [
|
invoice_gst_fields = [
|
||||||
dict(fieldname='gst_section', label='GST Details', fieldtype='Section Break',
|
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',
|
dict(fieldname='invoice_copy', label='Invoice Copy',
|
||||||
fieldtype='Select', insert_after='gst_section', print_hide=1, allow_on_submit=1,
|
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'),
|
options='Original for Recipient\nDuplicate for Transporter\nDuplicate for Supplier\nTriplicate for Supplier'),
|
||||||
dict(fieldname='reverse_charge', label='Reverse Charge',
|
dict(fieldname='reverse_charge', label='Reverse Charge',
|
||||||
fieldtype='Select', insert_after='invoice_copy', print_hide=1,
|
fieldtype='Select', insert_after='invoice_copy', print_hide=1,
|
||||||
options='Y\nN', default='N'),
|
options='Y\nN', default='N'),
|
||||||
dict(fieldname='gst_col_break', fieldtype='Column Break', insert_after='reverse_charge'),
|
|
||||||
dict(fieldname='invoice_type', label='Invoice Type',
|
dict(fieldname='invoice_type', label='Invoice Type',
|
||||||
fieldtype='Select', insert_after='reverse_charge', print_hide=1,
|
fieldtype='Select', insert_after='gst_col_break', print_hide=1,
|
||||||
options='Regular\nSEZ\nExport\nDeemed Export', default='Regular'),
|
options='Regular\nSEZ\nExport\nDeemed Export', default='Regular'),
|
||||||
dict(fieldname='export_type', label='Export Type',
|
dict(fieldname='export_type', label='Export Type',
|
||||||
fieldtype='Select', insert_after='invoice_type', print_hide=1,
|
fieldtype='Select', insert_after='invoice_type', print_hide=1,
|
||||||
@ -104,19 +103,11 @@ def make_custom_fields():
|
|||||||
options='\nWith Payment of Tax\nWithout Payment of Tax'),
|
options='\nWith Payment of Tax\nWithout Payment of Tax'),
|
||||||
dict(fieldname='ecommerce_gstin', label='E-commerce GSTIN',
|
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='reason_for_issuing_document'),
|
||||||
dict(fieldname='reason_for_issuing_document', label='Reason For Issuing document',
|
dict(fieldname='reason_for_issuing_document', label='Reason For Issuing document',
|
||||||
fieldtype='Select', insert_after='ecommerce_gstin', print_hide=1,
|
fieldtype='Select', insert_after='gst_col_break', print_hide=1,
|
||||||
depends_on='eval:doc.is_return==1',
|
depends_on='eval:doc.is_return==1', reqd=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'),
|
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', default='01-Sales Return')
|
||||||
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' "),
|
|
||||||
]
|
]
|
||||||
|
|
||||||
purchase_invoice_gst_fields = [
|
purchase_invoice_gst_fields = [
|
||||||
@ -125,7 +116,21 @@ def make_custom_fields():
|
|||||||
options='supplier_address.gstin', print_hide=1),
|
options='supplier_address.gstin', print_hide=1),
|
||||||
dict(fieldname='company_gstin', label='Company GSTIN',
|
dict(fieldname='company_gstin', label='Company GSTIN',
|
||||||
fieldtype='Data', insert_after='shipping_address',
|
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 = [
|
sales_invoice_gst_fields = [
|
||||||
@ -140,7 +145,16 @@ def make_custom_fields():
|
|||||||
print_hide=1, read_only=0),
|
print_hide=1, read_only=0),
|
||||||
dict(fieldname='company_gstin', label='Company GSTIN',
|
dict(fieldname='company_gstin', label='Company GSTIN',
|
||||||
fieldtype='Data', insert_after='company_address',
|
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 = {
|
custom_fields = {
|
||||||
@ -152,8 +166,8 @@ def make_custom_fields():
|
|||||||
dict(fieldname='gst_state_number', label='GST State Number',
|
dict(fieldname='gst_state_number', label='GST State Number',
|
||||||
fieldtype='Int', insert_after='gst_state', read_only=1),
|
fieldtype='Int', insert_after='gst_state', read_only=1),
|
||||||
],
|
],
|
||||||
'Purchase Invoice': purchase_invoice_gst_fields + invoice_gst_fields,
|
'Purchase Invoice': invoice_gst_fields + purchase_invoice_gst_fields,
|
||||||
'Sales Invoice': sales_invoice_gst_fields + invoice_gst_fields,
|
'Sales Invoice': invoice_gst_fields + sales_invoice_gst_fields,
|
||||||
"Delivery Note": sales_invoice_gst_fields,
|
"Delivery Note": sales_invoice_gst_fields,
|
||||||
'Item': [
|
'Item': [
|
||||||
dict(fieldname='gst_hsn_code', label='HSN/SAC',
|
dict(fieldname='gst_hsn_code', label='HSN/SAC',
|
||||||
|
|||||||
@ -64,7 +64,11 @@ def get_itemised_tax_breakup_data(doc):
|
|||||||
def set_place_of_supply(doc, method):
|
def set_place_of_supply(doc, method):
|
||||||
if not frappe.get_meta('Address').has_field('gst_state'): return
|
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
|
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:
|
if address_name:
|
||||||
address = frappe.db.get_value("Address", address_name, ["gst_state", "gst_state_number"], as_dict=1)
|
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)
|
doc.place_of_supply = cstr(address.gst_state_number) + "-" + cstr(address.gst_state)
|
||||||
|
|||||||
@ -12,58 +12,9 @@ def execute(filters=None):
|
|||||||
class Gstr1Report(object):
|
class Gstr1Report(object):
|
||||||
def __init__(self, filters=None):
|
def __init__(self, filters=None):
|
||||||
self.filters = frappe._dict(filters or {})
|
self.filters = frappe._dict(filters or {})
|
||||||
self.customer_type = "Company" if self.filters.get("type_of_business") == "B2B" else "Individual"
|
self.doctype = "Sales Invoice"
|
||||||
|
self.tax_doctype = "Sales Taxes and Charges"
|
||||||
def run(self):
|
self.select_columns = """
|
||||||
self.get_columns()
|
|
||||||
self.get_data()
|
|
||||||
return self.columns, self.data
|
|
||||||
|
|
||||||
def get_data(self):
|
|
||||||
self.data = []
|
|
||||||
self.get_gst_accounts()
|
|
||||||
self.get_invoice_data()
|
|
||||||
|
|
||||||
if not self.invoices: return
|
|
||||||
|
|
||||||
self.get_invoice_items()
|
|
||||||
self.get_items_based_on_tax_rate()
|
|
||||||
invoice_fields = [d["fieldname"] for d in self.invoice_columns]
|
|
||||||
|
|
||||||
|
|
||||||
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 = []
|
|
||||||
for fieldname in 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))
|
|
||||||
|
|
||||||
row += [rate,
|
|
||||||
sum([abs(net_amount) for item_code, net_amount in self.invoice_items.get(inv).items()
|
|
||||||
if item_code in items]),
|
|
||||||
self.invoice_cess.get(inv)
|
|
||||||
]
|
|
||||||
|
|
||||||
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_invoice_data(self):
|
|
||||||
self.invoices = frappe._dict()
|
|
||||||
conditions = self.get_conditions()
|
|
||||||
|
|
||||||
invoice_data = frappe.db.sql("""
|
|
||||||
select
|
|
||||||
name as invoice_number,
|
name as invoice_number,
|
||||||
customer_name,
|
customer_name,
|
||||||
posting_date,
|
posting_date,
|
||||||
@ -82,10 +33,64 @@ class Gstr1Report(object):
|
|||||||
shipping_bill_number,
|
shipping_bill_number,
|
||||||
shipping_bill_date,
|
shipping_bill_date,
|
||||||
reason_for_issuing_document
|
reason_for_issuing_document
|
||||||
from `tabSales Invoice`
|
"""
|
||||||
where docstatus = 1 %s
|
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 not self.invoices: return
|
||||||
|
|
||||||
|
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):
|
||||||
|
self.data = []
|
||||||
|
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
|
order by posting_date desc
|
||||||
""" % (conditions), self.filters, as_dict=1)
|
""".format(select_columns=self.select_columns, doctype=self.doctype,
|
||||||
|
where_conditions=conditions), self.filters, as_dict=1)
|
||||||
|
|
||||||
for d in invoice_data:
|
for d in invoice_data:
|
||||||
self.invoices.setdefault(d.invoice_number, d)
|
self.invoices.setdefault(d.invoice_number, d)
|
||||||
@ -127,30 +132,29 @@ class Gstr1Report(object):
|
|||||||
self.invoice_items = frappe._dict()
|
self.invoice_items = frappe._dict()
|
||||||
items = frappe.db.sql("""
|
items = frappe.db.sql("""
|
||||||
select item_code, parent, base_net_amount
|
select item_code, parent, base_net_amount
|
||||||
from `tabSales Invoice Item`
|
from `tab%s Item`
|
||||||
where parent in (%s)
|
where parent in (%s)
|
||||||
""" % (', '.join(['%s']*len(self.invoices))), tuple(self.invoices), as_dict=1)
|
""" % (self.doctype, ', '.join(['%s']*len(self.invoices))), tuple(self.invoices), as_dict=1)
|
||||||
|
|
||||||
for d in items:
|
for d in items:
|
||||||
self.invoice_items.setdefault(d.parent, {}).setdefault(d.item_code, d.base_net_amount)
|
self.invoice_items.setdefault(d.parent, {}).setdefault(d.item_code, d.base_net_amount)
|
||||||
|
|
||||||
def get_items_based_on_tax_rate(self):
|
def get_items_based_on_tax_rate(self):
|
||||||
tax_details = frappe.db.sql("""
|
self.tax_details = frappe.db.sql("""
|
||||||
select
|
select
|
||||||
parent, account_head, item_wise_tax_detail, base_tax_amount_after_discount_amount
|
parent, account_head, item_wise_tax_detail, base_tax_amount_after_discount_amount
|
||||||
from `tabSales Taxes and Charges`
|
from `tab%s`
|
||||||
where
|
where
|
||||||
parenttype = 'Sales Invoice' and docstatus = 1
|
parenttype = %s and docstatus = 1
|
||||||
and parent in (%s)
|
and parent in (%s)
|
||||||
|
|
||||||
order by account_head
|
order by account_head
|
||||||
""" % (', '.join(['%s']*len(self.invoices.keys()))), tuple(self.invoices.keys()))
|
""" % (self.tax_doctype, '%s', ', '.join(['%s']*len(self.invoices.keys()))),
|
||||||
|
tuple([self.doctype] + self.invoices.keys()))
|
||||||
|
|
||||||
self.items_based_on_tax_rate = {}
|
self.items_based_on_tax_rate = {}
|
||||||
self.invoice_cess = frappe._dict()
|
self.invoice_cess = frappe._dict()
|
||||||
unidentified_gst_accounts = []
|
unidentified_gst_accounts = []
|
||||||
|
for parent, account, item_wise_tax_detail, tax_amount in self.tax_details:
|
||||||
for parent, account, item_wise_tax_detail, tax_amount in tax_details:
|
|
||||||
if account in self.gst_accounts.cess_account:
|
if account in self.gst_accounts.cess_account:
|
||||||
self.invoice_cess.setdefault(parent, tax_amount)
|
self.invoice_cess.setdefault(parent, tax_amount)
|
||||||
else:
|
else:
|
||||||
@ -172,8 +176,8 @@ class Gstr1Report(object):
|
|||||||
if cgst_or_sgst:
|
if cgst_or_sgst:
|
||||||
tax_rate *= 2
|
tax_rate *= 2
|
||||||
|
|
||||||
rate_based_dict = self.items_based_on_tax_rate.setdefault(parent, {})\
|
rate_based_dict = self.items_based_on_tax_rate\
|
||||||
.setdefault(tax_rate, [])
|
.setdefault(parent, {}).setdefault(tax_rate, [])
|
||||||
if item_code not in rate_based_dict:
|
if item_code not in rate_based_dict:
|
||||||
rate_based_dict.append(item_code)
|
rate_based_dict.append(item_code)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
|
|||||||
0
erpnext/regional/report/gstr_2/__init__.py
Normal file
0
erpnext/regional/report/gstr_2/__init__.py
Normal file
39
erpnext/regional/report/gstr_2/gstr_2.js
Normal file
39
erpnext/regional/report/gstr_2/gstr_2.js
Normal file
@ -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"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
29
erpnext/regional/report/gstr_2/gstr_2.json
Normal file
29
erpnext/regional/report/gstr_2/gstr_2.json
Normal file
@ -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"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
276
erpnext/regional/report/gstr_2/gstr_2.py
Normal file
276
erpnext/regional/report/gstr_2/gstr_2.py
Normal file
@ -0,0 +1,276 @@
|
|||||||
|
# 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.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()
|
||||||
|
self.data = []
|
||||||
|
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
|
||||||
Loading…
x
Reference in New Issue
Block a user