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
This commit is contained in:
parent
3a05b3501c
commit
22b61607c6
@ -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",
|
||||
|
@ -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
|
||||
|
50
erpnext/patches/v12_0/set_gst_category.py
Normal file
50
erpnext/patches/v12_0/set_gst_category.py
Normal file
@ -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
|
||||
|
||||
|
0
erpnext/regional/doctype/gstr_3b_report/__init__.py
Normal file
0
erpnext/regional/doctype/gstr_3b_report/__init__.py
Normal file
297
erpnext/regional/doctype/gstr_3b_report/gstr_3b_report.html
Normal file
297
erpnext/regional/doctype/gstr_3b_report/gstr_3b_report.html
Normal file
@ -0,0 +1,297 @@
|
||||
<style>
|
||||
.print-format {
|
||||
padding: 15mm;
|
||||
font-size: 8.0pt !important;
|
||||
font-family: Tahoma, sans-serif;
|
||||
}
|
||||
.disabled {
|
||||
background-color: #d9d9d9;
|
||||
}
|
||||
|
||||
</style>
|
||||
<div>
|
||||
<h3 class="text-center">{{ __("GSTR3B-Form")}}</h3>
|
||||
<h5>{{__("GSTIN")}}:   {{ data.gstin }}</h5>
|
||||
<h5>{{__("Period")}}:   {{ data.ret_period }}</h5>
|
||||
</div>
|
||||
|
||||
<h5>3.1  {{__("Details of Outward Supplies and inward supplies liable to reverse charge")}}</h5>
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{__("Nature Of Supplies")}}</th>
|
||||
<th>{{__("Total Taxable value")}}</th>
|
||||
<th>{{__("Integrated Tax")}}</th>
|
||||
<th>{{__("Central Tax")}}</th>
|
||||
<th>{{__("State/UT Tax")}}</th>
|
||||
<th>{{__("Cess")}}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>(a) {{__("Outward taxable supplies(other than zero rated, nil rated and exempted")}}</td>
|
||||
<td class="right">{{ flt(data.sup_details.osup_det.txval, 2) }}</td>
|
||||
<td class="right">{{ flt(data.sup_details.osup_det.iamt, 2) }}</td>
|
||||
<td class="right">{{ flt(data.sup_details.osup_det.camt, 2) }}</td>
|
||||
<td class="right">{{ flt(data.sup_details.osup_det.samt, 2) }}</td>
|
||||
<td class="right">{{ flt(data.sup_details.osup_det.csamt, 2) }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>(b) {{__("Outward taxable supplies(zero rated)")}}</td>
|
||||
<td class="right">{{ flt(data.sup_details.osup_zero.txval, 2) }}</td>
|
||||
<td class="right">{{ flt(data.sup_details.osup_zero.iamt, 2) }}</td>
|
||||
<td class="disabled"></td>
|
||||
<td class="disabled"></td>
|
||||
<td class="right">{{ flt(data.sup_details.osup_zero.csamt, 2) }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>(b) {{__("Other outward supplies(Nil rated,Exempted)")}}</td>
|
||||
<td class="right">{{ data.sup_details.osup_nil_exmp.txval }}</td>
|
||||
<td class="disabled"></td>
|
||||
<td class="disabled"></td>
|
||||
<td class="disabled"></td>
|
||||
<td class="disabled"></td>
|
||||
<tr>
|
||||
<td>(d) {{__("Inward Supplies(liable to reverse charge")}}</td>
|
||||
<td class="right">{{ flt(data.sup_details.isup_rev.txval, 2) }}</td>
|
||||
<td class="right">{{ flt(data.sup_details.isup_rev.iamt, 2) }}</td>
|
||||
<td class="right">{{ flt(data.sup_details.isup_rev.camt, 2) }}</td>
|
||||
<td class="right">{{ flt(data.sup_details.isup_rev.samt, 2) }}</td>
|
||||
<td class="right">{{ flt(data.sup_details.isup_rev.csamt,2) }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>(e) {{__("Non-GST outward supplies")}}</td>
|
||||
<td class="right">{{ data.sup_details.osup_nongst.txval }}</td>
|
||||
<td class="disabled"></td>
|
||||
<td class="disabled"></td>
|
||||
<td class="disabled"></td>
|
||||
<td class="disabled"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h5>
|
||||
3.2  {{__("Of the supplies shown in 3.1 (a) above, details of inter-State supplies made to unregisterd
|
||||
persons, composition taxable persons and UIN holders")}}
|
||||
</h5>
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>{{__("Place Of Supply (State/UT)")}}</th>
|
||||
<th>{{__("Total Taxable Value")}}</th>
|
||||
<th>{{__("Amount of Integrated Tax")}}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>{{__("Supplies made to Unregistered Persons")}}</td>
|
||||
<td class="right">
|
||||
{% for row in data.inter_sup.unreg_details %}
|
||||
{% if row %}
|
||||
{{ row.pos }}<br>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</td>
|
||||
<td class="right">
|
||||
{% for row in data.inter_sup.unreg_details %}
|
||||
{% if row %}
|
||||
{{ flt(row.txval, 2) }}<br>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</td>
|
||||
<td class="right">
|
||||
{% for row in data.inter_sup.unreg_details %}
|
||||
{% if row %}
|
||||
{{ flt(row.iamt, 2) }}<br>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{__("Suppliies made to Composition Taxable Persons")}}</td>
|
||||
<td class="right">
|
||||
{% for row in data.inter_sup.unreg_details %}
|
||||
{% if row %}
|
||||
{{ row.pos }}<br>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</td>
|
||||
<td class="right">
|
||||
{% for row in data.inter_sup.unreg_details %}
|
||||
{% if row %}
|
||||
{{ flt(row.txval, 2) }}<br>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</td>
|
||||
<td class="right">
|
||||
{% for row in data.inter_sup.unreg_details %}
|
||||
{% if row %}
|
||||
{{ flt(row.iamt, 2) }}<br>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{__("Supplies made to UIN holders")}}</td>
|
||||
<td class="right">
|
||||
{% for row in data.inter_sup.unreg_details %}
|
||||
{% if row %}
|
||||
{{ row.pos }}<br>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</td>
|
||||
<td class="right">
|
||||
{% for row in data.inter_sup.unreg_details %}
|
||||
{% if row %}
|
||||
{{ flt(row.txval, 2) }}<br>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</td>
|
||||
<td class="right">
|
||||
{% for row in data.inter_sup.unreg_details %}
|
||||
{% if row %}
|
||||
{{ flt(row.iamt, 2) }}<br>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h5>4.   {{__("Eligible ITC")}}</h5>
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Details</th>
|
||||
<th>Integrated Tax</th>
|
||||
<th>Central Tax</th>
|
||||
<th>State/UT tax</th>
|
||||
<th>Cess</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><b>(A) {{__("ITC Available (whether in full op part)")}}</b></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>  (1) {{__("Import of goods")}} </td>
|
||||
<td class="right">{{ flt(data.itc_elg.itc_avl[0].iamt, 2) }}</td>
|
||||
<td class="right">{{ flt(data.itc_elg.itc_avl[0].camt, 2) }}</td>
|
||||
<td class="right">{{ flt(data.itc_elg.itc_avl[0].samt, 2) }}</td>
|
||||
<td class="right">{{ flt(data.itc_elg.itc_avl[0].csamt, 2) }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>  (2) {{__("Import of services")}}</td>
|
||||
<td class="right">{{ flt(data.itc_elg.itc_avl[1].iamt, 2) }}</td>
|
||||
<td class="right">{{ flt(data.itc_elg.itc_avl[1].camt, 2) }}</td>
|
||||
<td class="right">{{ flt(data.itc_elg.itc_avl[1].samt, 2) }}</td>
|
||||
<td class="right">{{ flt(data.itc_elg.itc_avl[1].csamt, 2) }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>  (3) {{__("Inward supplies liable to reverse charge (other than 1 & 2 above)")}}</td>
|
||||
<td class="right">{{ flt(data.itc_elg.itc_avl[2].iamt, 2) }}</td>
|
||||
<td class="right">{{ flt(data.itc_elg.itc_avl[2].camt, 2) }}</td>
|
||||
<td class="right">{{ flt(data.itc_elg.itc_avl[2].samt, 2) }}</td>
|
||||
<td class="right">{{ flt(data.itc_elg.itc_avl[2].csamt, 2) }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>  (4) {{__("Inward supplies from ISD")}}</td>
|
||||
<td class="right">{{ flt(data.itc_elg.itc_avl[3].iamt, 2) }}</td>
|
||||
<td class="right">{{ flt(data.itc_elg.itc_avl[3].camt, 2) }}</td>
|
||||
<td class="right">{{ flt(data.itc_elg.itc_avl[3].samt, 2) }}</td>
|
||||
<td class="right">{{ flt(data.itc_elg.itc_avl[3].csamt, 2) }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>  (5) {{__("All other ITC")}}</td>
|
||||
<td class="right">{{ flt(data.itc_elg.itc_avl[4].iamt, 2) }}</td>
|
||||
<td class="right">{{ flt(data.itc_elg.itc_avl[4].camt, 2) }}</td>
|
||||
<td class="right">{{ flt(data.itc_elg.itc_avl[4].samt, 2) }}</td>
|
||||
<td class="right">{{ flt(data.itc_elg.itc_avl[4].csamt, 2) }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>(B) {{__("ITC Reversed")}}</b></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>  (1) {{__("As per rules 42 & 43 of CGST Rules")}}</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>  (2) {{__("Others")}}</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>(C) {{__("Net ITC Available(A) - (B)")}}</b></td>
|
||||
<td class="right">{{ flt(data.itc_elg.itc_net.iamt, 2) }}</td>
|
||||
<td class="right">{{ flt(data.itc_elg.itc_net.camt, 2) }}</td>
|
||||
<td class="right">{{ flt(data.itc_elg.itc_net.samt, 2) }}</td>
|
||||
<td class="right">{{ flt(data.itc_elg.itc_net.csamt, 2) }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>(D) {{__("Ineligible ITC")}}</b></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>  (1) {{__("As per section 17(5)")}}</td>
|
||||
<td class="right">{{ flt(data.itc_elg.itc_inelg[0].iamt, 2) }}</td>
|
||||
<td class="right">{{ flt(data.itc_elg.itc_inelg[0].camt, 2) }}</td>
|
||||
<td class="right">{{ flt(data.itc_elg.itc_inelg[0].samt, 2) }}</td>
|
||||
<td class="right">{{ flt(data.itc_elg.itc_inelg[0].csamt, 2) }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>  (2) {{__("Others")}}</td>
|
||||
<td class="right">{{ flt(data.itc_elg.itc_inelg[1].iamt, 2) }}</td>
|
||||
<td class="right">{{ flt(data.itc_elg.itc_inelg[1].camt, 2) }}</td>
|
||||
<td class="right">{{ flt(data.itc_elg.itc_inelg[1].samt, 2) }}</td>
|
||||
<td class="right">{{ flt(data.itc_elg.itc_inelg[1].csamt, 2) }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h5>5.    {{__("Values of exempt, nil rated and non-GST inward supplies")}}</h5>
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{__("Nature of Supplies")}}</th>
|
||||
<th>{{__("Inter-State Supplies")}}</th>
|
||||
<th>{{__("Intra-State Supplies")}}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>{{__("From a supplier under composition scheme, Exempt and Nil rated")}}</td>
|
||||
<td class="right">{{ flt(data.inward_sup.isup_details[0].inter, 2) }}</td>
|
||||
<td class="right">{{ flt(data.inward_sup.isup_details[0].intra, 2) }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{__("Non GST Inward Supplies")}}</td>
|
||||
<td class="right">{{ flt(data.inward_sup.isup_details[1].inter, 2) }}</td>
|
||||
<td class="right">{{ flt(data.inward_sup.isup_details[1].intra, 2) }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<style>
|
||||
|
||||
.right{
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
</style>
|
59
erpnext/regional/doctype/gstr_3b_report/gstr_3b_report.js
Normal file
59
erpnext/regional/doctype/gstr_3b_report/gstr_3b_report.js
Normal file
@ -0,0 +1,59 @@
|
||||
// Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('GSTR 3B Report', {
|
||||
refresh : function(frm){
|
||||
if(!frm.is_new()) {
|
||||
frm.set_intro(__("Please save the report again to rebuild or update"));
|
||||
frm.add_custom_button(__('Download JSON'), function() {
|
||||
var w = window.open(
|
||||
frappe.urllib.get_full_url(
|
||||
"/api/method/erpnext.regional.doctype.gstr_3b_report.gstr_3b_report.make_json?"
|
||||
+"name="+encodeURIComponent(frm.doc.name)));
|
||||
|
||||
if(!w) {
|
||||
frappe.msgprint(__("Please enable pop-ups")); return;
|
||||
}
|
||||
});
|
||||
frm.add_custom_button(__('View Form'), function() {
|
||||
frappe.call({
|
||||
"method" : "erpnext.regional.doctype.gstr_3b_report.gstr_3b_report.view_report",
|
||||
"args" : {
|
||||
name : frm.doc.name,
|
||||
},
|
||||
"callback" : function(r){
|
||||
|
||||
let data = r.message;
|
||||
|
||||
frappe.ui.get_print_settings(false, print_settings => {
|
||||
|
||||
frappe.render_grid({
|
||||
template: 'gstr_3b_report',
|
||||
title: __(this.doctype),
|
||||
print_settings: print_settings,
|
||||
data: data,
|
||||
columns:[]
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
setup: function(frm){
|
||||
frm.set_query('company_address', function(doc) {
|
||||
if(!doc.company) {
|
||||
frappe.throw(__('Please set Company'));
|
||||
}
|
||||
|
||||
return {
|
||||
query: 'frappe.contacts.doctype.address.address.address_query',
|
||||
filters: {
|
||||
link_doctype: 'Company',
|
||||
link_name: doc.company
|
||||
}
|
||||
};
|
||||
});
|
||||
},
|
||||
});
|
259
erpnext/regional/doctype/gstr_3b_report/gstr_3b_report.json
Normal file
259
erpnext/regional/doctype/gstr_3b_report/gstr_3b_report.json
Normal file
@ -0,0 +1,259 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_events_in_timeline": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"autoname": "format:GSTR3B-{month}-{year}-{company_address}",
|
||||
"beta": 0,
|
||||
"creation": "2019-02-04 11:35:55.964639",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 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": 0,
|
||||
"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": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "company_address",
|
||||
"fieldtype": "Link",
|
||||
"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": "Company Address",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Address",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "year",
|
||||
"fieldtype": "Data",
|
||||
"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": "Year",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "month",
|
||||
"fieldtype": "Select",
|
||||
"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": "Month",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "January\nFebruary\nMarch\nApril\nMay\nJune\nJuly\nAugust\nSeptember\nOctober\nNovember\nDecember",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "json_output",
|
||||
"fieldtype": "Code",
|
||||
"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": "JSON Output",
|
||||
"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,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "missing_field_invoices",
|
||||
"fieldtype": "Small Text",
|
||||
"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": "Invoices with no Place Of Supply",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 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": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2019-03-04 10:04:44.767655",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Regional",
|
||||
"name": "GSTR 3B Report",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "System Manager",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"quick_entry": 0,
|
||||
"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,
|
||||
"track_views": 0
|
||||
}
|
459
erpnext/regional/doctype/gstr_3b_report/gstr_3b_report.py
Normal file
459
erpnext/regional/doctype/gstr_3b_report/gstr_3b_report.py
Normal file
@ -0,0 +1,459 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2019, 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
|
||||
import json
|
||||
from six import iteritems
|
||||
from frappe.utils import flt, getdate
|
||||
from erpnext.regional.india import state_numbers
|
||||
|
||||
class GSTR3BReport(Document):
|
||||
def before_save(self):
|
||||
|
||||
self.get_data()
|
||||
|
||||
def get_data(self):
|
||||
|
||||
self.report_dict = {
|
||||
"gstin": "",
|
||||
"ret_period": "",
|
||||
"inward_sup": {
|
||||
"isup_details": [
|
||||
{
|
||||
"ty": "GST",
|
||||
"intra": 0,
|
||||
"inter": 0
|
||||
},
|
||||
{
|
||||
"ty": "NONGST",
|
||||
"inter": 0,
|
||||
"intra": 0
|
||||
}
|
||||
]
|
||||
},
|
||||
"sup_details": {
|
||||
"osup_zero": {
|
||||
"csamt": 0,
|
||||
"txval": 0,
|
||||
"iamt": 0
|
||||
},
|
||||
"osup_nil_exmp": {
|
||||
"txval": 0
|
||||
},
|
||||
"osup_det": {
|
||||
"samt": 0,
|
||||
"csamt": 0,
|
||||
"txval": 0,
|
||||
"camt": 0,
|
||||
"iamt": 0
|
||||
},
|
||||
"isup_rev": {
|
||||
"samt": 0,
|
||||
"csamt": 0,
|
||||
"txval": 0,
|
||||
"camt": 0,
|
||||
"iamt": 0
|
||||
},
|
||||
"osup_nongst": {
|
||||
"txval": 0,
|
||||
}
|
||||
},
|
||||
"inter_sup": {
|
||||
"unreg_details": [],
|
||||
"comp_details": [],
|
||||
"uin_details": []
|
||||
},
|
||||
"itc_elg": {
|
||||
"itc_avl": [
|
||||
{
|
||||
"csamt": 0,
|
||||
"samt": 0,
|
||||
"ty": "IMPG",
|
||||
"camt": 0,
|
||||
"iamt": 0
|
||||
},
|
||||
{
|
||||
"csamt": 0,
|
||||
"samt": 0,
|
||||
"ty": "IMPS",
|
||||
"camt": 0,
|
||||
"iamt": 0
|
||||
},
|
||||
{
|
||||
"samt": 0,
|
||||
"csamt": 0,
|
||||
"ty": "ISRC",
|
||||
"camt": 0,
|
||||
"iamt": 0
|
||||
},
|
||||
{
|
||||
"ty": "ISD",
|
||||
"iamt": 1,
|
||||
"camt": 1,
|
||||
"samt": 1,
|
||||
"csamt": 1
|
||||
},
|
||||
{
|
||||
"samt": 0,
|
||||
"csamt": 0,
|
||||
"ty": "OTH",
|
||||
"camt": 0,
|
||||
"iamt": 0
|
||||
}
|
||||
],
|
||||
"itc_net": {
|
||||
"samt": 0,
|
||||
"csamt": 0,
|
||||
"camt": 0,
|
||||
"iamt": 0
|
||||
},
|
||||
"itc_inelg": [
|
||||
{
|
||||
"ty": "RUL",
|
||||
"iamt": 0,
|
||||
"camt": 0,
|
||||
"samt": 0,
|
||||
"csamt": 0
|
||||
},
|
||||
{
|
||||
"ty": "OTH",
|
||||
"iamt": 0,
|
||||
"camt": 0,
|
||||
"samt": 0,
|
||||
"csamt": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
self.gst_details = self.get_company_gst_details()
|
||||
self.report_dict["gstin"] = self.gst_details.get("gstin")
|
||||
self.report_dict["ret_period"] = get_period(self.month, self.year)
|
||||
self.month_no = get_period(self.month)
|
||||
self.account_heads = self.get_account_heads()
|
||||
|
||||
outward_supply_tax_amounts = self.get_tax_amounts("Sales Invoice")
|
||||
inward_supply_tax_amounts = self.get_tax_amounts("Purchase Invoice", reverse_charge="Y")
|
||||
itc_details = self.get_itc_details()
|
||||
inter_state_supplies = self.get_inter_state_supplies(self.gst_details.get("gst_state"))
|
||||
inward_nil_exempt = self.get_inward_nil_exempt(self.gst_details.get("gst_state"))
|
||||
|
||||
self.prepare_data("Sales Invoice", outward_supply_tax_amounts, "sup_details", "osup_det", ["Registered Regular"])
|
||||
self.prepare_data("Sales Invoice", outward_supply_tax_amounts, "sup_details", "osup_zero", ["SEZ", "Deemed Export", "Overseas"])
|
||||
self.prepare_data("Purchase Invoice", inward_supply_tax_amounts, "sup_details", "isup_rev", ["Registered Regular"], reverse_charge="Y")
|
||||
self.report_dict["sup_details"]["osup_nil_exmp"]["txval"] = flt(self.get_nil_rated_supply_value(), 2)
|
||||
self.set_itc_details(itc_details)
|
||||
self.set_inter_state_supply(inter_state_supplies)
|
||||
self.set_inward_nil_exempt(inward_nil_exempt)
|
||||
|
||||
self.missing_field_invoices = self.get_missing_field_invoices()
|
||||
|
||||
self.json_output = frappe.as_json(self.report_dict)
|
||||
|
||||
def set_inward_nil_exempt(self, inward_nil_exempt):
|
||||
|
||||
self.report_dict["inward_sup"]["isup_details"][0]["inter"] = flt(inward_nil_exempt.get("gst").get("inter"), 2)
|
||||
self.report_dict["inward_sup"]["isup_details"][0]["intra"] = flt(inward_nil_exempt.get("gst").get("intra"), 2)
|
||||
self.report_dict["inward_sup"]["isup_details"][1]["inter"] = flt(inward_nil_exempt.get("non_gst").get("inter"), 2)
|
||||
self.report_dict["inward_sup"]["isup_details"][1]["intra"] = flt(inward_nil_exempt.get("non_gst").get("intra"), 2)
|
||||
|
||||
def set_itc_details(self, itc_details):
|
||||
|
||||
itc_type_map = {
|
||||
'IMPG': 'Import Of Capital Goods',
|
||||
'IMPS': 'Import Of Service',
|
||||
'ISD': 'Input Service Distributor',
|
||||
'OTH': 'All Other ITC'
|
||||
}
|
||||
|
||||
net_itc = self.report_dict["itc_elg"]["itc_net"]
|
||||
|
||||
for d in self.report_dict["itc_elg"]["itc_avl"]:
|
||||
if d["ty"] == 'ISRC':
|
||||
reverse_charge = "Y"
|
||||
else:
|
||||
reverse_charge = "N"
|
||||
|
||||
for account_head in self.account_heads:
|
||||
|
||||
d["iamt"] = flt(itc_details.get((itc_type_map.get(d["ty"]), reverse_charge, account_head.get('igst_account')), {}).get("amount"), 2)
|
||||
net_itc["iamt"] += flt(d["iamt"], 2)
|
||||
|
||||
d["camt"] = flt(itc_details.get((itc_type_map.get(d["ty"]), reverse_charge, account_head.get('cgst_account')), {}).get("amount"), 2)
|
||||
net_itc["camt"] += flt(d["camt"], 2)
|
||||
|
||||
d["samt"] = flt(itc_details.get((itc_type_map.get(d["ty"]), reverse_charge, account_head.get('sgst_account')), {}).get("amount"), 2)
|
||||
net_itc["samt"] += flt(d["samt"], 2)
|
||||
|
||||
d["csamt"] = flt(itc_details.get((itc_type_map.get(d["ty"]), reverse_charge, account_head.get('cess_account')), {}).get("amount"), 2)
|
||||
net_itc["csamt"] += flt(d["csamt"], 2)
|
||||
|
||||
for account_head in self.account_heads:
|
||||
|
||||
self.report_dict["itc_elg"]["itc_inelg"][1]["iamt"] = flt(itc_details.get(("Ineligible", "N", account_head.get("igst_account")), {}).get("amount"), 2)
|
||||
self.report_dict["itc_elg"]["itc_inelg"][1]["camt"] = flt(itc_details.get(("Ineligible", "N", account_head.get("cgst_account")), {}).get("amount"), 2)
|
||||
self.report_dict["itc_elg"]["itc_inelg"][1]["samt"] = flt(itc_details.get(("Ineligible", "N", account_head.get("sgst_account")), {}).get("amount"), 2)
|
||||
self.report_dict["itc_elg"]["itc_inelg"][1]["csamt"] = flt(itc_details.get(("Ineligible", "N", account_head.get("cess_account")), {}).get("amount"), 2)
|
||||
|
||||
def prepare_data(self, doctype, tax_details, supply_type, supply_category, gst_category_list, reverse_charge="N"):
|
||||
|
||||
account_map = {
|
||||
'sgst_account': 'samt',
|
||||
'cess_account': 'csamt',
|
||||
'cgst_account': 'camt',
|
||||
'igst_account': 'iamt'
|
||||
}
|
||||
|
||||
txval = 0
|
||||
total_taxable_value = self.get_total_taxable_value(doctype, reverse_charge)
|
||||
|
||||
for gst_category in gst_category_list:
|
||||
txval += total_taxable_value.get(gst_category,0)
|
||||
for account_head in self.account_heads:
|
||||
for account_type, account_name in iteritems(account_head):
|
||||
if account_map.get(account_type) in self.report_dict.get(supply_type).get(supply_category):
|
||||
self.report_dict[supply_type][supply_category][account_map.get(account_type)] += \
|
||||
flt(tax_details.get((account_name, gst_category), {}).get("amount"), 2)
|
||||
|
||||
for k, v in iteritems(account_map):
|
||||
txval -= self.report_dict.get(supply_type, {}).get(supply_category, {}).get(v, 0)
|
||||
|
||||
self.report_dict[supply_type][supply_category]["txval"] = flt(txval, 2)
|
||||
|
||||
def set_inter_state_supply(self, inter_state_supply):
|
||||
|
||||
for d in inter_state_supply.get("Unregistered", []):
|
||||
self.report_dict["inter_sup"]["unreg_details"].append(d)
|
||||
|
||||
for d in inter_state_supply.get("Registered Composition", []):
|
||||
self.report_dict["inter_sup"]["comp_details"].append(d)
|
||||
|
||||
for d in inter_state_supply.get("UIN Holders", []):
|
||||
self.report_dict["inter_sup"]["uin_details"].append(d)
|
||||
|
||||
def get_total_taxable_value(self, doctype, reverse_charge):
|
||||
|
||||
return frappe._dict(frappe.db.sql("""
|
||||
select gst_category, sum(base_grand_total) as total
|
||||
from `tab{doctype}`
|
||||
where docstatus = 1 and month(posting_date) = %s
|
||||
and year(posting_date) = %s and reverse_charge = %s
|
||||
and company = %s and company_gstin = %s
|
||||
group by gst_category
|
||||
""" #nosec
|
||||
.format(doctype = doctype), (self.month_no, self.year, reverse_charge, self.company, self.gst_details.get("gstin"))))
|
||||
|
||||
def get_itc_details(self, reverse_charge='N'):
|
||||
|
||||
itc_amount = frappe.db.sql("""
|
||||
select s.gst_category, sum(t.tax_amount) as tax_amount, t.account_head, s.eligibility_for_itc, s.reverse_charge
|
||||
from `tabPurchase Invoice` s , `tabPurchase Taxes and Charges` t
|
||||
where s.docstatus = 1 and t.parent = s.name and s.reverse_charge = %s
|
||||
and month(s.posting_date) = %s and year(s.posting_date) = %s and s.company = %s
|
||||
and s.company_gstin = %s
|
||||
group by t.account_head, s.gst_category, s.eligibility_for_itc
|
||||
""",
|
||||
(reverse_charge, self.month_no, self.year, self.company, self.gst_details.get("gstin")), as_dict=1)
|
||||
|
||||
itc_details = {}
|
||||
|
||||
for d in itc_amount:
|
||||
itc_details.setdefault((d.eligibility_for_itc, d.reverse_charge, d.account_head),{
|
||||
"amount": d.tax_amount
|
||||
})
|
||||
|
||||
return itc_details
|
||||
|
||||
def get_nil_rated_supply_value(self):
|
||||
|
||||
return frappe.db.sql("""
|
||||
select sum(i.base_amount) as total from
|
||||
`tabSales Invoice Item` i, `tabSales Invoice` s
|
||||
where s.docstatus = 1 and i.parent = s.name and i.is_nil_exempt = 1
|
||||
and month(s.posting_date) = %s and year(s.posting_date) = %s
|
||||
and s.company = %s and s.company_gstin = %s""",
|
||||
(self.month_no, self.year, self.company, self.gst_details.get("gstin")), as_dict=1)[0].total
|
||||
|
||||
def get_inter_state_supplies(self, state):
|
||||
|
||||
inter_state_supply = frappe.db.sql(""" select sum(s.grand_total) as total, t.tax_amount, a.gst_state, s.gst_category
|
||||
from `tabSales Invoice` s, `tabSales Taxes and Charges` t, `tabAddress` a
|
||||
where t.parent = s.name and s.customer_address = a.name and
|
||||
s.docstatus = 1 and month(s.posting_date) = %s and year(s.posting_date) = %s and
|
||||
a.gst_state <> %s and s.company = %s and s.company_gstin = %s and
|
||||
s.gst_category in ('Unregistered', 'Registered Composition', 'UIN Holders')
|
||||
group by s.gst_category, a.state""", (self.month_no, self.year, state, self.company, self.gst_details.get("gstin")), as_dict=1)
|
||||
|
||||
inter_state_supply_details = {}
|
||||
|
||||
for d in inter_state_supply:
|
||||
inter_state_supply_details.setdefault(
|
||||
d.gst_category, []
|
||||
)
|
||||
|
||||
inter_state_supply_details[d.gst_category].append({
|
||||
"pos": get_state_code(d.gst_state),
|
||||
"txval": d.total,
|
||||
"iamt": d.tax_amount
|
||||
})
|
||||
|
||||
return inter_state_supply_details
|
||||
|
||||
def get_inward_nil_exempt(self, state):
|
||||
|
||||
inward_nil_exempt = frappe.db.sql(""" select a.gst_state, sum(i.base_amount) as base_amount,
|
||||
i.is_nil_exempt, i.is_non_gst from `tabPurchase Invoice` p , `tabPurchase Invoice Item` i, `tabAddress` a
|
||||
where p.docstatus = 1 and p.name = i.parent and p.supplier_address = a.name
|
||||
and i.is_nil_exempt = 1 or i.is_non_gst = 1 and
|
||||
month(p.posting_date) = %s and year(p.posting_date) = %s and p.company = %s and p.company_gstin = %s
|
||||
group by a.gst_state """, (self.month_no, self.year, self.company, self.gst_details.get("gstin")), as_dict=1)
|
||||
|
||||
inward_nil_exempt_details = {
|
||||
"gst": {
|
||||
"intra": 0.0,
|
||||
"inter": 0.0
|
||||
},
|
||||
"non_gst": {
|
||||
"intra": 0.0,
|
||||
"inter": 0.0
|
||||
}
|
||||
}
|
||||
|
||||
for d in inward_nil_exempt:
|
||||
if d.is_nil_exempt == 1 and state == d.gst_state:
|
||||
inward_nil_exempt_details["gst"]["intra"] += d.base_amount
|
||||
elif d.is_nil_exempt == 1 and state != d.gst_state:
|
||||
inward_nil_exempt_details["gst"]["inter"] += d.base_amount
|
||||
elif d.is_non_gst == 1 and state == d.gst_state:
|
||||
inward_nil_exempt_details["non_gst"]["inter"] += d.base_amount
|
||||
elif d.is_non_gst == 1 and state != d.gst_state:
|
||||
inward_nil_exempt_details["non_gst"]["intra"] += d.base_amount
|
||||
|
||||
return inward_nil_exempt_details
|
||||
|
||||
def get_tax_amounts(self, doctype, reverse_charge="N"):
|
||||
|
||||
if doctype == "Sales Invoice":
|
||||
tax_template = 'Sales Taxes and Charges'
|
||||
elif doctype == "Purchase Invoice":
|
||||
tax_template = 'Purchase Taxes and Charges'
|
||||
|
||||
tax_amounts = frappe.db.sql("""
|
||||
select s.gst_category, sum(t.tax_amount) as tax_amount, t.account_head
|
||||
from `tab{doctype}` s , `tab{template}` t
|
||||
where s.docstatus = 1 and t.parent = s.name and s.reverse_charge = %s
|
||||
and month(s.posting_date) = %s and year(s.posting_date) = %s and s.company = %s
|
||||
and s.company_gstin = %s
|
||||
group by t.account_head, s.gst_category
|
||||
""" #nosec
|
||||
.format(doctype=doctype, template=tax_template),
|
||||
(reverse_charge, self.month_no, self.year, self.company, self.gst_details.get("gstin")), as_dict=1)
|
||||
|
||||
tax_details = {}
|
||||
|
||||
for d in tax_amounts:
|
||||
tax_details.setdefault(
|
||||
(d.account_head,d.gst_category),{
|
||||
"amount": d.get("tax_amount"),
|
||||
}
|
||||
)
|
||||
|
||||
return tax_details
|
||||
|
||||
def get_company_gst_details(self):
|
||||
|
||||
gst_details = frappe.get_all("Address",
|
||||
fields=["gstin", "gst_state", "gst_state_number"],
|
||||
filters={
|
||||
"name":self.company_address
|
||||
})
|
||||
|
||||
if gst_details:
|
||||
return gst_details[0]
|
||||
else:
|
||||
frappe.throw("Please enter GSTIN and state for the Company Address {0}".format(self.company_address))
|
||||
|
||||
def get_account_heads(self):
|
||||
|
||||
account_heads = frappe.get_all("GST Account",
|
||||
fields=["cgst_account", "sgst_account", "igst_account", "cess_account"],
|
||||
filters={
|
||||
"company":self.company
|
||||
})
|
||||
|
||||
if account_heads:
|
||||
return account_heads
|
||||
else:
|
||||
frappe.throw("Please set account heads in GST Settings for Compnay {0}".format(self.company))
|
||||
|
||||
def get_missing_field_invoices(self):
|
||||
|
||||
missing_field_invoices = []
|
||||
|
||||
for doctype in ["Sales Invoice", "Purchase Invoice"]:
|
||||
|
||||
if doctype == "Sales Invoice":
|
||||
party_type = 'Customer'
|
||||
party = 'customer'
|
||||
else:
|
||||
party_type = 'Supplier'
|
||||
party = 'supplier'
|
||||
|
||||
docnames = frappe.db.sql("""
|
||||
select t1.name from `tab{doctype}` t1, `tab{party_type}` t2
|
||||
where t1.docstatus = 1 and month(t1.posting_date) = %s and year(t1.posting_date) = %s
|
||||
and t1.company = %s and t1.place_of_supply IS NULL and t1.{party} = t2.name and
|
||||
t2.gst_category != 'Overseas'
|
||||
""".format(doctype = doctype, party_type = party_type, party=party), (self.month_no, self.year, self.company), as_dict=1) #nosec
|
||||
|
||||
for d in docnames:
|
||||
missing_field_invoices.append(d.name)
|
||||
|
||||
return ",".join(missing_field_invoices)
|
||||
|
||||
def get_state_code(state):
|
||||
|
||||
state_code = state_numbers.get(state)
|
||||
|
||||
return state_code
|
||||
|
||||
def get_period(month, year=None):
|
||||
|
||||
month_no = {
|
||||
"January": 1,
|
||||
"February": 2,
|
||||
"March": 3,
|
||||
"April": 4,
|
||||
"May": 5,
|
||||
"June": 6,
|
||||
"July": 7,
|
||||
"August": 8,
|
||||
"September": 9,
|
||||
"October": 10,
|
||||
"November": 11,
|
||||
"December": 12
|
||||
}.get(month)
|
||||
|
||||
if year:
|
||||
return str(month_no).zfill(2) + str(year)
|
||||
else:
|
||||
return month_no
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def view_report(name):
|
||||
|
||||
json_data = frappe.get_value("GSTR 3B Report", name, 'json_output')
|
||||
return json.loads(json_data)
|
||||
|
||||
@frappe.whitelist()
|
||||
def make_json(name):
|
||||
|
||||
json_data = frappe.get_value("GSTR 3B Report", name, 'json_output')
|
||||
file_name = "GST3B.json"
|
||||
frappe.local.response.filename = file_name
|
||||
frappe.local.response.filecontent = json_data
|
||||
frappe.local.response.type = "download"
|
380
erpnext/regional/doctype/gstr_3b_report/test_gstr_3b_report.py
Normal file
380
erpnext/regional/doctype/gstr_3b_report/test_gstr_3b_report.py
Normal file
@ -0,0 +1,380 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import frappe
|
||||
import unittest
|
||||
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
|
||||
from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import make_purchase_invoice
|
||||
from erpnext.stock.doctype.item.test_item import make_item
|
||||
import json
|
||||
|
||||
class TestGSTR3BReport(unittest.TestCase):
|
||||
def test_gstr_3b_report(self):
|
||||
frappe.set_user("Administrator")
|
||||
|
||||
frappe.db.sql("delete from `tabSales Invoice` where company='_Test Company GST'")
|
||||
frappe.db.sql("delete from `tabPurchase Invoice` where company='_Test Company GST'")
|
||||
|
||||
make_company()
|
||||
make_item("Milk", properties = {"is_nil_exempt": 1, "standard_rate": 0.000000})
|
||||
set_account_heads()
|
||||
make_customers()
|
||||
make_suppliers()
|
||||
make_sales_invoice()
|
||||
create_purchase_invoices()
|
||||
|
||||
if frappe.db.exists("GSTR 3B Report", "GSTR3B-March-2019-_Test Address-Billing"):
|
||||
report = frappe.get_doc("GSTR 3B Report", "GSTR3B-March-2019-_Test Address-Billing")
|
||||
report.save()
|
||||
else:
|
||||
report = frappe.get_doc({
|
||||
"doctype": "GSTR 3B Report",
|
||||
"company": "_Test Company GST",
|
||||
"company_address": "_Test Address-Billing",
|
||||
"year": "2019",
|
||||
"month": "March"
|
||||
}).insert()
|
||||
|
||||
output = json.loads(report.json_output)
|
||||
|
||||
self.assertEqual(output["sup_details"]["osup_det"]["iamt"], 18),
|
||||
self.assertEqual(output["sup_details"]["osup_zero"]["iamt"], 18),
|
||||
self.assertEqual(output["inter_sup"]["unreg_details"][0]["iamt"], 18),
|
||||
self.assertEqual(output["sup_details"]["osup_nil_exmp"]["txval"], 100),
|
||||
self.assertEqual(output["inward_sup"]["isup_details"][0]["inter"], 250)
|
||||
self.assertEqual(output["itc_elg"]["itc_avl"][4]["iamt"], 45)
|
||||
|
||||
def make_sales_invoice():
|
||||
si = create_sales_invoice(company="_Test Company GST",
|
||||
customer = '_Test GST Customer',
|
||||
currency = 'INR',
|
||||
warehouse = 'Finished Goods - _GST',
|
||||
debit_to = 'Debtors - _GST',
|
||||
income_account = 'Sales - _GST',
|
||||
expense_account = 'Cost of Goods Sold - _GST',
|
||||
cost_center = 'Main - _GST',
|
||||
posting_date = '2019-03-10',
|
||||
do_not_save=1
|
||||
)
|
||||
|
||||
si.append("taxes", {
|
||||
"charge_type": "On Net Total",
|
||||
"account_head": "IGST - _GST",
|
||||
"cost_center": "Main - _GST",
|
||||
"description": "IGST @ 18.0",
|
||||
"rate": 18
|
||||
})
|
||||
|
||||
si.submit()
|
||||
|
||||
si1 = create_sales_invoice(company="_Test Company GST",
|
||||
customer = '_Test GST SEZ Customer',
|
||||
currency = 'INR',
|
||||
warehouse = 'Finished Goods - _GST',
|
||||
debit_to = 'Debtors - _GST',
|
||||
income_account = 'Sales - _GST',
|
||||
expense_account = 'Cost of Goods Sold - _GST',
|
||||
cost_center = 'Main - _GST',
|
||||
posting_date = '2019-03-10',
|
||||
do_not_save=1
|
||||
)
|
||||
|
||||
si1.append("taxes", {
|
||||
"charge_type": "On Net Total",
|
||||
"account_head": "IGST - _GST",
|
||||
"cost_center": "Main - _GST",
|
||||
"description": "IGST @ 18.0",
|
||||
"rate": 18
|
||||
})
|
||||
|
||||
si1.submit()
|
||||
|
||||
si2 = create_sales_invoice(company="_Test Company GST",
|
||||
customer = '_Test Unregistered Customer',
|
||||
currency = 'INR',
|
||||
warehouse = 'Finished Goods - _GST',
|
||||
debit_to = 'Debtors - _GST',
|
||||
income_account = 'Sales - _GST',
|
||||
expense_account = 'Cost of Goods Sold - _GST',
|
||||
cost_center = 'Main - _GST',
|
||||
posting_date = '2019-03-10',
|
||||
do_not_save=1
|
||||
)
|
||||
|
||||
si2.append("taxes", {
|
||||
"charge_type": "On Net Total",
|
||||
"account_head": "IGST - _GST",
|
||||
"cost_center": "Main - _GST",
|
||||
"description": "IGST @ 18.0",
|
||||
"rate": 18
|
||||
})
|
||||
|
||||
si2.submit()
|
||||
|
||||
si3 = create_sales_invoice(company="_Test Company GST",
|
||||
customer = '_Test GST Customer',
|
||||
currency = 'INR',
|
||||
item = 'Milk',
|
||||
warehouse = 'Finished Goods - _GST',
|
||||
debit_to = 'Debtors - _GST',
|
||||
income_account = 'Sales - _GST',
|
||||
expense_account = 'Cost of Goods Sold - _GST',
|
||||
cost_center = 'Main - _GST',
|
||||
posting_date = '2019-03-10',
|
||||
do_not_save=1
|
||||
)
|
||||
si3.submit()
|
||||
|
||||
def create_purchase_invoices():
|
||||
|
||||
pi = make_purchase_invoice(
|
||||
company="_Test Company GST",
|
||||
supplier = '_Test Registered Supplier',
|
||||
currency = 'INR',
|
||||
warehouse = 'Finished Goods - _GST',
|
||||
cost_center = 'Main - _GST',
|
||||
posting_date = '2019-03-10',
|
||||
do_not_save=1,
|
||||
)
|
||||
|
||||
pi.eligibility_for_itc = "All Other ITC"
|
||||
|
||||
pi.append("taxes", {
|
||||
"charge_type": "On Net Total",
|
||||
"account_head": "IGST - _GST",
|
||||
"cost_center": "Main - _GST",
|
||||
"description": "IGST @ 18.0",
|
||||
"rate": 18
|
||||
})
|
||||
|
||||
pi.submit()
|
||||
|
||||
pi1 = make_purchase_invoice(
|
||||
company="_Test Company GST",
|
||||
supplier = '_Test Registered Supplier',
|
||||
currency = 'INR',
|
||||
warehouse = 'Finished Goods - _GST',
|
||||
cost_center = 'Main - _GST',
|
||||
posting_date = '2019-03-10',
|
||||
item = "Milk",
|
||||
do_not_save=1
|
||||
)
|
||||
|
||||
pi1.submit()
|
||||
|
||||
def make_suppliers():
|
||||
|
||||
if not frappe.db.exists("Supplier", "_Test Registered Supplier"):
|
||||
frappe.get_doc({
|
||||
"supplier_group": "_Test Supplier Group",
|
||||
"supplier_name": "_Test Registered Supplier",
|
||||
"gst_category": "Registered Regular",
|
||||
"supplier_type": "Individual",
|
||||
"doctype": "Supplier",
|
||||
}).insert()
|
||||
|
||||
if not frappe.db.exists("Supplier", "_Test Unregistered Supplier"):
|
||||
frappe.get_doc({
|
||||
"supplier_group": "_Test Supplier Group",
|
||||
"supplier_name": "_Test Unregistered Supplier",
|
||||
"gst_category": "Unregistered",
|
||||
"supplier_type": "Individual",
|
||||
"doctype": "Supplier",
|
||||
}).insert()
|
||||
|
||||
if not frappe.db.exists('Address', '_Test Supplier GST-1-Billing'):
|
||||
address = frappe.get_doc({
|
||||
"address_line1": "_Test Address Line 1",
|
||||
"address_title": "_Test Supplier GST-1",
|
||||
"address_type": "Billing",
|
||||
"city": "_Test City",
|
||||
"state": "Test State",
|
||||
"country": "India",
|
||||
"doctype": "Address",
|
||||
"is_primary_address": 1,
|
||||
"phone": "+91 0000000000",
|
||||
"gstin": "29AACCV0498C1Z9",
|
||||
"gst_state": "Karnataka",
|
||||
}).insert()
|
||||
|
||||
address.append("links", {
|
||||
"link_doctype": "Supplier",
|
||||
"link_name": "_Test Registered Supplier"
|
||||
})
|
||||
|
||||
address.save()
|
||||
|
||||
if not frappe.db.exists('Address', '_Test Supplier GST-2-Billing'):
|
||||
address = frappe.get_doc({
|
||||
"address_line1": "_Test Address Line 1",
|
||||
"address_title": "_Test Supplier GST-2",
|
||||
"address_type": "Billing",
|
||||
"city": "_Test City",
|
||||
"state": "Test State",
|
||||
"country": "India",
|
||||
"doctype": "Address",
|
||||
"is_primary_address": 1,
|
||||
"phone": "+91 0000000000",
|
||||
"gst_state": "Karnataka",
|
||||
}).insert()
|
||||
|
||||
address.append("links", {
|
||||
"link_doctype": "Supplier",
|
||||
"link_name": "_Test Unregistered Supplier"
|
||||
})
|
||||
|
||||
address.save()
|
||||
|
||||
def make_customers():
|
||||
|
||||
if not frappe.db.exists("Customer", "_Test GST Customer"):
|
||||
frappe.get_doc({
|
||||
"customer_group": "_Test Customer Group",
|
||||
"customer_name": "_Test GST Customer",
|
||||
"gst_category": "Registered Regular",
|
||||
"customer_type": "Individual",
|
||||
"doctype": "Customer",
|
||||
"territory": "_Test Territory"
|
||||
}).insert()
|
||||
|
||||
if not frappe.db.exists("Customer", "_Test GST SEZ Customer"):
|
||||
frappe.get_doc({
|
||||
"customer_group": "_Test Customer Group",
|
||||
"customer_name": "_Test GST SEZ Customer",
|
||||
"gst_category": "SEZ",
|
||||
"customer_type": "Individual",
|
||||
"doctype": "Customer",
|
||||
"territory": "_Test Territory"
|
||||
}).insert()
|
||||
|
||||
if not frappe.db.exists("Customer", "_Test Unregistered Customer"):
|
||||
frappe.get_doc({
|
||||
"customer_group": "_Test Customer Group",
|
||||
"customer_name": "_Test Unregistered Customer",
|
||||
"gst_category": "Unregistered",
|
||||
"customer_type": "Individual",
|
||||
"doctype": "Customer",
|
||||
"territory": "_Test Territory"
|
||||
}).insert()
|
||||
|
||||
if not frappe.db.exists('Address', '_Test GST-1-Billing'):
|
||||
address = frappe.get_doc({
|
||||
"address_line1": "_Test Address Line 1",
|
||||
"address_title": "_Test GST-1",
|
||||
"address_type": "Billing",
|
||||
"city": "_Test City",
|
||||
"state": "Test State",
|
||||
"country": "India",
|
||||
"doctype": "Address",
|
||||
"is_primary_address": 1,
|
||||
"phone": "+91 0000000000",
|
||||
"gstin": "29AZWPS7135H1ZG",
|
||||
"gst_state": "Karnataka",
|
||||
"gst_state_number": "29"
|
||||
}).insert()
|
||||
|
||||
address.append("links", {
|
||||
"link_doctype": "Customer",
|
||||
"link_name": "_Test GST Customer"
|
||||
})
|
||||
|
||||
address.save()
|
||||
|
||||
if not frappe.db.exists('Address', '_Test GST-2-Billing'):
|
||||
address = frappe.get_doc({
|
||||
"address_line1": "_Test Address Line 1",
|
||||
"address_title": "_Test GST-2",
|
||||
"address_type": "Billing",
|
||||
"city": "_Test City",
|
||||
"state": "Test State",
|
||||
"country": "India",
|
||||
"doctype": "Address",
|
||||
"is_primary_address": 1,
|
||||
"phone": "+91 0000000000",
|
||||
"gst_state": "Haryana",
|
||||
}).insert()
|
||||
|
||||
address.append("links", {
|
||||
"link_doctype": "Customer",
|
||||
"link_name": "_Test Unregistered Customer"
|
||||
})
|
||||
|
||||
address.save()
|
||||
|
||||
if not frappe.db.exists('Address', '_Test GST-3-Billing'):
|
||||
address = frappe.get_doc({
|
||||
"address_line1": "_Test Address Line 1",
|
||||
"address_title": "_Test GST-3",
|
||||
"address_type": "Billing",
|
||||
"city": "_Test City",
|
||||
"state": "Test State",
|
||||
"country": "India",
|
||||
"doctype": "Address",
|
||||
"is_primary_address": 1,
|
||||
"phone": "+91 0000000000",
|
||||
"gst_state": "Gujarat",
|
||||
}).insert()
|
||||
|
||||
address.append("links", {
|
||||
"link_doctype": "Customer",
|
||||
"link_name": "_Test GST SEZ Customer"
|
||||
})
|
||||
|
||||
address.save()
|
||||
|
||||
def make_company():
|
||||
|
||||
if frappe.db.exists("Company", "_Test Company GST"):
|
||||
return
|
||||
company = frappe.new_doc("Company")
|
||||
company.company_name = "_Test Company GST"
|
||||
company.abbr = "_GST"
|
||||
company.default_currency = "INR"
|
||||
company.country = "India"
|
||||
company.insert()
|
||||
|
||||
if not frappe.db.exists('Address', '_Test Address-Billing'):
|
||||
address = frappe.get_doc({
|
||||
"address_line1": "_Test Address Line 1",
|
||||
"address_title": "_Test Address",
|
||||
"address_type": "Billing",
|
||||
"city": "_Test City",
|
||||
"state": "Test State",
|
||||
"country": "India",
|
||||
"doctype": "Address",
|
||||
"is_primary_address": 1,
|
||||
"phone": "+91 0000000000",
|
||||
"gstin": "27AAECE4835E1ZR",
|
||||
"gst_state": "Maharashtra",
|
||||
"gst_state_number": "27"
|
||||
}).insert()
|
||||
|
||||
address.append("links", {
|
||||
"link_doctype": "Company",
|
||||
"link_name": "_Test Company GST"
|
||||
})
|
||||
|
||||
address.save()
|
||||
|
||||
def set_account_heads():
|
||||
|
||||
gst_settings = frappe.get_doc("GST Settings")
|
||||
|
||||
gst_account = frappe.get_all(
|
||||
"GST Account",
|
||||
fields=["cgst_account", "sgst_account", "igst_account"],
|
||||
filters = {"company": "_Test Company GST"})
|
||||
|
||||
if not gst_account:
|
||||
gst_settings.append("gst_accounts", {
|
||||
"company": "_Test Company GST",
|
||||
"cgst_account": "CGST - _GST",
|
||||
"sgst_account": "SGST - _GST",
|
||||
"igst_account": "IGST - _GST",
|
||||
})
|
||||
|
||||
gst_settings.save()
|
||||
|
||||
|
@ -94,21 +94,39 @@ def make_custom_fields(update=True):
|
||||
hsn_sac_field = dict(fieldname='gst_hsn_code', label='HSN/SAC',
|
||||
fieldtype='Data', fetch_from='item_code.gst_hsn_code', insert_after='description',
|
||||
allow_on_submit=1, print_hide=1)
|
||||
invoice_gst_fields = [
|
||||
nil_rated_exempt = dict(fieldname='is_nil_exempt', label='Is nil rated or exempted',
|
||||
fieldtype='Check', fetch_from='item_code.is_nil_exempt', insert_after='gst_hsn_code',
|
||||
print_hide=1)
|
||||
is_non_gst = dict(fieldname='is_non_gst', label='Is Non GST',
|
||||
fieldtype='Check', fetch_from='item_code.is_non_gst', insert_after='is_nil_exempt',
|
||||
print_hide=1)
|
||||
|
||||
purchase_invoice_gst_category = [
|
||||
dict(fieldname='gst_section', label='GST Details', fieldtype='Section Break',
|
||||
insert_after='language', print_hide=1, collapsible=1),
|
||||
dict(fieldname='gst_category', label='GST Category',
|
||||
fieldtype='Data', insert_after='gst_section', print_hide=1,
|
||||
fetch_from='supplier.gst_category')
|
||||
]
|
||||
|
||||
sales_invoice_gst_category = [
|
||||
dict(fieldname='gst_section', label='GST Details', fieldtype='Section Break',
|
||||
insert_after='language', print_hide=1, collapsible=1),
|
||||
dict(fieldname='gst_category', label='GST Category',
|
||||
fieldtype='Data', insert_after='gst_section', print_hide=1,
|
||||
fetch_from='customer.gst_category')
|
||||
]
|
||||
|
||||
invoice_gst_fields = [
|
||||
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_category', 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='invoice_type', label='Invoice Type',
|
||||
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)',
|
||||
fieldtype='Select', insert_after='reverse_charge', print_hide=1,
|
||||
depends_on='eval:in_list(["SEZ", "Overseas", "Deemed Export"], doc.gst_category)',
|
||||
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),
|
||||
@ -134,7 +152,7 @@ def make_custom_fields(update=True):
|
||||
purchase_invoice_itc_fields = [
|
||||
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"),
|
||||
options='Input Service Distributor\nImport Of Service\nImport Of Capital Goods\nIneligible\nAll Other ITC', default="All Other ITC"),
|
||||
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',
|
||||
@ -163,13 +181,13 @@ def make_custom_fields(update=True):
|
||||
sales_invoice_shipping_fields = [
|
||||
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' "),
|
||||
depends_on="eval:doc.gst_category=='Overseas' "),
|
||||
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' "),
|
||||
depends_on="eval:doc.gst_category=='Overseas' "),
|
||||
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' ")
|
||||
depends_on="eval:doc.gst_category=='Overseas' "),
|
||||
]
|
||||
|
||||
inter_state_gst_field = [
|
||||
@ -223,26 +241,30 @@ def make_custom_fields(update=True):
|
||||
dict(fieldname='gst_state_number', label='GST State Number',
|
||||
fieldtype='Data', insert_after='gst_state', read_only=1),
|
||||
],
|
||||
'Purchase Invoice': invoice_gst_fields + purchase_invoice_gst_fields + purchase_invoice_itc_fields,
|
||||
'Purchase Invoice': purchase_invoice_gst_category + invoice_gst_fields + purchase_invoice_itc_fields + purchase_invoice_gst_fields,
|
||||
'Purchase Order': purchase_invoice_gst_fields,
|
||||
'Purchase Receipt': purchase_invoice_gst_fields,
|
||||
'Sales Invoice': invoice_gst_fields + sales_invoice_gst_fields + sales_invoice_shipping_fields,
|
||||
'Delivery Note': sales_invoice_gst_fields + ewaybill_fields + sales_invoice_shipping_fields,
|
||||
'Sales Invoice': sales_invoice_gst_category + invoice_gst_fields + sales_invoice_shipping_fields + sales_invoice_gst_fields,
|
||||
'Delivery Note': sales_invoice_gst_fields + ewaybill_fields,
|
||||
'Sales Order': sales_invoice_gst_fields,
|
||||
'Sales Taxes and Charges Template': inter_state_gst_field,
|
||||
'Purchase Taxes and Charges Template': inter_state_gst_field,
|
||||
'Item': [
|
||||
dict(fieldname='gst_hsn_code', label='HSN/SAC',
|
||||
fieldtype='Link', options='GST HSN Code', insert_after='item_group'),
|
||||
dict(fieldname='is_nil_exempt', label='Is nil rated or exempted',
|
||||
fieldtype='Check', insert_after='gst_hsn_code'),
|
||||
dict(fieldname='is_non_gst', label='Is Non GST ',
|
||||
fieldtype='Check', insert_after='is_nil_exempt')
|
||||
],
|
||||
'Quotation Item': [hsn_sac_field],
|
||||
'Supplier Quotation Item': [hsn_sac_field],
|
||||
'Sales Order Item': [hsn_sac_field],
|
||||
'Delivery Note Item': [hsn_sac_field],
|
||||
'Sales Invoice Item': [hsn_sac_field],
|
||||
'Purchase Order Item': [hsn_sac_field],
|
||||
'Purchase Receipt Item': [hsn_sac_field],
|
||||
'Purchase Invoice Item': [hsn_sac_field],
|
||||
'Quotation Item': [hsn_sac_field, nil_rated_exempt, is_non_gst],
|
||||
'Supplier Quotation Item': [hsn_sac_field, nil_rated_exempt, is_non_gst],
|
||||
'Sales Order Item': [hsn_sac_field, nil_rated_exempt, is_non_gst],
|
||||
'Delivery Note Item': [hsn_sac_field, nil_rated_exempt, is_non_gst],
|
||||
'Sales Invoice Item': [hsn_sac_field, nil_rated_exempt, is_non_gst],
|
||||
'Purchase Order Item': [hsn_sac_field, nil_rated_exempt, is_non_gst],
|
||||
'Purchase Receipt Item': [hsn_sac_field, nil_rated_exempt, is_non_gst],
|
||||
'Purchase Invoice Item': [hsn_sac_field, nil_rated_exempt, is_non_gst],
|
||||
'Employee': [
|
||||
dict(fieldname='ifsc_code', label='IFSC Code',
|
||||
fieldtype='Data', insert_after='bank_ac_no', print_hide=1,
|
||||
@ -301,11 +323,28 @@ def make_custom_fields(update=True):
|
||||
'fieldtype': 'Data',
|
||||
'insert_after': 'supplier_type',
|
||||
'depends_on': 'eval:doc.is_transporter'
|
||||
},
|
||||
{
|
||||
'fieldname': 'gst_category',
|
||||
'label': 'GST Category',
|
||||
'fieldtype': 'Select',
|
||||
'insert_after': 'gst_transporter_id',
|
||||
'options': 'Registered Regular\nRegistered Composition\nUnregistered\nSEZ\nOverseas\nUIN Holders',
|
||||
'default': 'Unregistered'
|
||||
}
|
||||
],
|
||||
'Customer': [
|
||||
{
|
||||
'fieldname': 'gst_category',
|
||||
'label': 'GST Category',
|
||||
'fieldtype': 'Select',
|
||||
'insert_after': 'customer_type',
|
||||
'options': 'Registered Regular\nRegistered Composition\nUnregistered\nSEZ\nOverseas\nConsumer\nDeemed Export\nUIN Holders',
|
||||
'default': 'Unregistered'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
create_custom_fields(custom_fields, ignore_validate = frappe.flags.in_patch, update=update)
|
||||
create_custom_fields(custom_fields, update=update)
|
||||
|
||||
def make_fixtures(company=None):
|
||||
docs = []
|
||||
|
@ -10,7 +10,7 @@ def execute(filters=None):
|
||||
dict(fieldtype='Data', label='Supplier GSTIN', fieldname="supplier_gstin", width=120),
|
||||
dict(fieldtype='Data', label='Company GSTIN', fieldname="company_gstin", width=120),
|
||||
dict(fieldtype='Data', label='Reverse Charge', fieldname="reverse_charge", width=120),
|
||||
dict(fieldtype='Data', label='Invoice Type', fieldname="invoice_type", width=120),
|
||||
dict(fieldtype='Data', label='GST Category', fieldname="gst_category", width=120),
|
||||
dict(fieldtype='Data', label='Export Type', fieldname="export_type", width=120),
|
||||
dict(fieldtype='Data', label='E-Commerce GSTIN', fieldname="ecommerce_gstin", width=130),
|
||||
dict(fieldtype='Data', label='HSN Code', fieldname="hsn_code", width=120),
|
||||
@ -20,7 +20,7 @@ def execute(filters=None):
|
||||
'supplier_gstin',
|
||||
'company_gstin',
|
||||
'reverse_charge',
|
||||
'invoice_type',
|
||||
'gst_category',
|
||||
'export_type',
|
||||
'ecommerce_gstin',
|
||||
'gst_hsn_code',
|
||||
|
@ -12,7 +12,7 @@ def execute(filters=None):
|
||||
dict(fieldtype='Data', label='Company GSTIN', fieldname="company_gstin", width=120),
|
||||
dict(fieldtype='Data', label='Place of Supply', fieldname="place_of_supply", width=120),
|
||||
dict(fieldtype='Data', label='Reverse Charge', fieldname="reverse_charge", width=120),
|
||||
dict(fieldtype='Data', label='Invoice Type', fieldname="invoice_type", width=120),
|
||||
dict(fieldtype='Data', label='GST Category', fieldname="gst_category", width=120),
|
||||
dict(fieldtype='Data', label='Export Type', fieldname="export_type", width=120),
|
||||
dict(fieldtype='Data', label='E-Commerce GSTIN', fieldname="ecommerce_gstin", width=130),
|
||||
dict(fieldtype='Data', label='HSN Code', fieldname="hsn_code", width=120)
|
||||
@ -22,7 +22,7 @@ def execute(filters=None):
|
||||
'company_gstin',
|
||||
'place_of_supply',
|
||||
'reverse_charge',
|
||||
'invoice_type',
|
||||
'gst_category',
|
||||
'export_type',
|
||||
'ecommerce_gstin',
|
||||
'gst_hsn_code'
|
||||
|
@ -10,14 +10,14 @@ def execute(filters=None):
|
||||
dict(fieldtype='Data', label='Supplier GSTIN', fieldname="supplier_gstin", width=120),
|
||||
dict(fieldtype='Data', label='Company GSTIN', fieldname="company_gstin", width=120),
|
||||
dict(fieldtype='Data', label='Reverse Charge', fieldname="reverse_charge", width=120),
|
||||
dict(fieldtype='Data', label='Invoice Type', fieldname="invoice_type", width=120),
|
||||
dict(fieldtype='Data', label='GST Category', fieldname="gst_category", width=120),
|
||||
dict(fieldtype='Data', label='Export Type', fieldname="export_type", width=120),
|
||||
dict(fieldtype='Data', label='E-Commerce GSTIN', fieldname="ecommerce_gstin", width=130)
|
||||
], additional_query_columns=[
|
||||
'supplier_gstin',
|
||||
'company_gstin',
|
||||
'reverse_charge',
|
||||
'invoice_type',
|
||||
'gst_category',
|
||||
'export_type',
|
||||
'ecommerce_gstin'
|
||||
])
|
||||
|
@ -12,7 +12,7 @@ def execute(filters=None):
|
||||
dict(fieldtype='Data', label='Company GSTIN', fieldname="company_gstin", width=120),
|
||||
dict(fieldtype='Data', label='Place of Supply', fieldname="place_of_supply", width=120),
|
||||
dict(fieldtype='Data', label='Reverse Charge', fieldname="reverse_charge", width=120),
|
||||
dict(fieldtype='Data', label='Invoice Type', fieldname="invoice_type", width=120),
|
||||
dict(fieldtype='Data', label='GST Category', fieldname="gst_category", width=120),
|
||||
dict(fieldtype='Data', label='Export Type', fieldname="export_type", width=120),
|
||||
dict(fieldtype='Data', label='E-Commerce GSTIN', fieldname="ecommerce_gstin", width=130)
|
||||
], additional_query_columns=[
|
||||
@ -21,7 +21,7 @@ def execute(filters=None):
|
||||
'company_gstin',
|
||||
'place_of_supply',
|
||||
'reverse_charge',
|
||||
'invoice_type',
|
||||
'gst_category',
|
||||
'export_type',
|
||||
'ecommerce_gstin'
|
||||
])
|
||||
|
@ -28,10 +28,10 @@ class Gstr1Report(object):
|
||||
place_of_supply,
|
||||
ecommerce_gstin,
|
||||
reverse_charge,
|
||||
invoice_type,
|
||||
gst_category,
|
||||
return_against,
|
||||
is_return,
|
||||
invoice_type,
|
||||
gst_category,
|
||||
export_type,
|
||||
port_code,
|
||||
shipping_bill_number,
|
||||
@ -116,7 +116,7 @@ class Gstr1Report(object):
|
||||
customers = frappe.get_all("Customer", filters={"customer_type": self.customer_type})
|
||||
|
||||
if self.filters.get("type_of_business") == "B2B":
|
||||
conditions += """ and ifnull(invoice_type, '') != 'Export' and is_return != 1
|
||||
conditions += """ and ifnull(gst_category, '') != 'Overseas' 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"):
|
||||
@ -138,7 +138,7 @@ class Gstr1Report(object):
|
||||
conditions += """ and is_return = 1 """
|
||||
|
||||
elif self.filters.get("type_of_business") == "EXPORT":
|
||||
conditions += """ and is_return !=1 and invoice_type = 'Export' """
|
||||
conditions += """ and is_return !=1 and gst_category = 'Overseas' """
|
||||
return conditions
|
||||
|
||||
def get_invoice_items(self):
|
||||
@ -283,8 +283,8 @@ class Gstr1Report(object):
|
||||
"fieldtype": "Data"
|
||||
},
|
||||
{
|
||||
"fieldname": "invoice_type",
|
||||
"label": "Invoice Type",
|
||||
"fieldname": "gst_category",
|
||||
"label": "GST Category",
|
||||
"fieldtype": "Data"
|
||||
},
|
||||
{
|
||||
|
@ -26,10 +26,10 @@ class Gstr2Report(Gstr1Report):
|
||||
place_of_supply,
|
||||
ecommerce_gstin,
|
||||
reverse_charge,
|
||||
invoice_type,
|
||||
gst_category,
|
||||
return_against,
|
||||
is_return,
|
||||
invoice_type,
|
||||
gst_category,
|
||||
export_type,
|
||||
reason_for_issuing_document,
|
||||
eligibility_for_itc,
|
||||
@ -82,7 +82,7 @@ class Gstr2Report(Gstr1Report):
|
||||
conditions += opts[1]
|
||||
|
||||
if self.filters.get("type_of_business") == "B2B":
|
||||
conditions += "and ifnull(invoice_type, '') != 'Export' and is_return != 1 "
|
||||
conditions += "and ifnull(gst_category, '') != 'Overseas' and is_return != 1 "
|
||||
|
||||
elif self.filters.get("type_of_business") == "CDNR":
|
||||
conditions += """ and is_return = 1 """
|
||||
@ -200,7 +200,7 @@ class Gstr2Report(Gstr1Report):
|
||||
"width": 80
|
||||
},
|
||||
{
|
||||
"fieldname": "invoice_type",
|
||||
"fieldname": "gst_category",
|
||||
"label": "Invoice Type",
|
||||
"fieldtype": "Data",
|
||||
"width": 80
|
||||
|
Loading…
x
Reference in New Issue
Block a user