blob: b878a1ea5d030222353e0ecb78d68ae7ccb97c64 [file] [log] [blame]
Rushabh Mehtab3c8f442017-06-21 17:22:38 +05301import frappe, re
2from frappe import _
Nabin Haitb95ecd72018-02-16 13:19:04 +05303from frappe.utils import cstr
Rushabh Mehtab3c8f442017-06-21 17:22:38 +05304from erpnext.regional.india import states, state_numbers
Nabin Haitb962fc12017-07-17 18:02:31 +05305from erpnext.controllers.taxes_and_totals import get_itemised_tax, get_itemised_taxable_amount
Rushabh Mehtab3c8f442017-06-21 17:22:38 +05306
7def validate_gstin_for_india(doc, method):
8 if not hasattr(doc, 'gstin'):
9 return
10
11 if doc.gstin:
Nabin Haitf3f0dfe2017-07-06 14:49:34 +053012 doc.gstin = doc.gstin.upper()
rohitwaghchaure2c111b72018-04-11 15:50:06 +053013 if doc.gstin not in ["NA", "na"]:
Aditya Duggalf1bd39c2017-06-29 14:25:19 +053014 p = re.compile("[0-9]{2}[a-zA-Z]{5}[0-9]{4}[a-zA-Z]{1}[1-9A-Za-z]{1}[Z]{1}[0-9a-zA-Z]{1}")
15 if not p.match(doc.gstin):
16 frappe.throw(_("Invalid GSTIN or Enter NA for Unregistered"))
Rushabh Mehtab3c8f442017-06-21 17:22:38 +053017
Nabin Hait35cd1d32017-11-28 13:01:01 +053018 if not doc.gst_state:
19 if doc.state in states:
20 doc.gst_state = doc.state
Rushabh Mehtab3c8f442017-06-21 17:22:38 +053021
Nabin Hait35cd1d32017-11-28 13:01:01 +053022 if doc.gst_state:
23 doc.gst_state_number = state_numbers[doc.gst_state]
24 if doc.gstin and doc.gstin != "NA" and doc.gst_state_number != doc.gstin[:2]:
25 frappe.throw(_("First 2 digits of GSTIN should match with State number {0}")
26 .format(doc.gst_state_number))
Rushabh Mehta7231f292017-07-13 15:00:56 +053027
Nabin Haitb962fc12017-07-17 18:02:31 +053028def get_itemised_tax_breakup_header(item_doctype, tax_accounts):
29 if frappe.get_meta(item_doctype).has_field('gst_hsn_code'):
30 return [_("HSN/SAC"), _("Taxable Amount")] + tax_accounts
31 else:
32 return [_("Item"), _("Taxable Amount")] + tax_accounts
Nabin Haitb95ecd72018-02-16 13:19:04 +053033
Nabin Haitb962fc12017-07-17 18:02:31 +053034def get_itemised_tax_breakup_data(doc):
35 itemised_tax = get_itemised_tax(doc.taxes)
36
37 itemised_taxable_amount = get_itemised_taxable_amount(doc.items)
Nabin Haitb95ecd72018-02-16 13:19:04 +053038
Nabin Haitb962fc12017-07-17 18:02:31 +053039 if not frappe.get_meta(doc.doctype + " Item").has_field('gst_hsn_code'):
40 return itemised_tax, itemised_taxable_amount
41
42 item_hsn_map = frappe._dict()
43 for d in doc.items:
44 item_hsn_map.setdefault(d.item_code or d.item_name, d.get("gst_hsn_code"))
45
46 hsn_tax = {}
47 for item, taxes in itemised_tax.items():
48 hsn_code = item_hsn_map.get(item)
49 hsn_tax.setdefault(hsn_code, frappe._dict())
50 for tax_account, tax_detail in taxes.items():
51 hsn_tax[hsn_code].setdefault(tax_account, {"tax_rate": 0, "tax_amount": 0})
52 hsn_tax[hsn_code][tax_account]["tax_rate"] = tax_detail.get("tax_rate")
53 hsn_tax[hsn_code][tax_account]["tax_amount"] += tax_detail.get("tax_amount")
54
55 # set taxable amount
56 hsn_taxable_amount = frappe._dict()
57 for item, taxable_amount in itemised_taxable_amount.items():
58 hsn_code = item_hsn_map.get(item)
59 hsn_taxable_amount.setdefault(hsn_code, 0)
60 hsn_taxable_amount[hsn_code] += itemised_taxable_amount.get(item)
61
62 return hsn_tax, hsn_taxable_amount
63
Nabin Haitb95ecd72018-02-16 13:19:04 +053064def set_place_of_supply(doc, method):
65 if not frappe.get_meta('Address').has_field('gst_state'): return
66
Vishal Dhayagude2505c742018-04-04 11:05:21 +053067 if doc.doctype in ("Sales Invoice", "Delivery Note"):
Nabin Haitb95ecd72018-02-16 13:19:04 +053068 address_name = doc.shipping_address_name or doc.customer_address
69 elif doc.doctype == "Purchase Invoice":
70 address_name = doc.shipping_address or doc.supplier_address
71
72 if address_name:
73 address = frappe.db.get_value("Address", address_name, ["gst_state", "gst_state_number"], as_dict=1)
74 doc.place_of_supply = cstr(address.gst_state_number) + "-" + cstr(address.gst_state)
75
Rushabh Mehta7231f292017-07-13 15:00:56 +053076# don't remove this function it is used in tests
77def test_method():
78 '''test function'''
Nabin Haitb95ecd72018-02-16 13:19:04 +053079 return 'overridden'