Merge pull request #26056 from deepeshgarg007/gst_taxtable_value_with_discount_v13
fix(India): Taxable value for invoices with additional discount
This commit is contained in:
commit
95bc141531
@ -1937,69 +1937,53 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
frappe.flags.country = country
|
frappe.flags.country = country
|
||||||
|
|
||||||
def test_einvoice_json(self):
|
def test_einvoice_json(self):
|
||||||
from erpnext.regional.india.e_invoice.utils import make_einvoice
|
from erpnext.regional.india.e_invoice.utils import make_einvoice, validate_totals
|
||||||
|
|
||||||
si = make_sales_invoice_for_ewaybill()
|
si = get_sales_invoice_for_e_invoice()
|
||||||
si.naming_series = 'INV-2020-.#####'
|
|
||||||
si.items = []
|
|
||||||
si.append("items", {
|
|
||||||
"item_code": "_Test Item",
|
|
||||||
"uom": "Nos",
|
|
||||||
"warehouse": "_Test Warehouse - _TC",
|
|
||||||
"qty": 2000,
|
|
||||||
"rate": 12,
|
|
||||||
"income_account": "Sales - _TC",
|
|
||||||
"expense_account": "Cost of Goods Sold - _TC",
|
|
||||||
"cost_center": "_Test Cost Center - _TC",
|
|
||||||
})
|
|
||||||
si.append("items", {
|
|
||||||
"item_code": "_Test Item 2",
|
|
||||||
"uom": "Nos",
|
|
||||||
"warehouse": "_Test Warehouse - _TC",
|
|
||||||
"qty": 420,
|
|
||||||
"rate": 15,
|
|
||||||
"income_account": "Sales - _TC",
|
|
||||||
"expense_account": "Cost of Goods Sold - _TC",
|
|
||||||
"cost_center": "_Test Cost Center - _TC",
|
|
||||||
})
|
|
||||||
si.discount_amount = 100
|
si.discount_amount = 100
|
||||||
si.save()
|
si.save()
|
||||||
|
|
||||||
einvoice = make_einvoice(si)
|
einvoice = make_einvoice(si)
|
||||||
|
|
||||||
total_item_ass_value = 0
|
|
||||||
total_item_cgst_value = 0
|
|
||||||
total_item_sgst_value = 0
|
|
||||||
total_item_igst_value = 0
|
|
||||||
total_item_value = 0
|
|
||||||
|
|
||||||
for item in einvoice['ItemList']:
|
|
||||||
total_item_ass_value += item['AssAmt']
|
|
||||||
total_item_cgst_value += item['CgstAmt']
|
|
||||||
total_item_sgst_value += item['SgstAmt']
|
|
||||||
total_item_igst_value += item['IgstAmt']
|
|
||||||
total_item_value += item['TotItemVal']
|
|
||||||
|
|
||||||
self.assertTrue(item['AssAmt'], item['TotAmt'] - item['Discount'])
|
|
||||||
self.assertTrue(item['TotItemVal'], item['AssAmt'] + item['CgstAmt'] + item['SgstAmt'] + item['IgstAmt'])
|
|
||||||
|
|
||||||
value_details = einvoice['ValDtls']
|
|
||||||
|
|
||||||
self.assertEqual(einvoice['Version'], '1.1')
|
|
||||||
self.assertEqual(value_details['AssVal'], total_item_ass_value)
|
|
||||||
self.assertEqual(value_details['CgstVal'], total_item_cgst_value)
|
|
||||||
self.assertEqual(value_details['SgstVal'], total_item_sgst_value)
|
|
||||||
self.assertEqual(value_details['IgstVal'], total_item_igst_value)
|
|
||||||
|
|
||||||
calculated_invoice_value = \
|
|
||||||
value_details['AssVal'] + value_details['CgstVal'] \
|
|
||||||
+ value_details['SgstVal'] + value_details['IgstVal'] \
|
|
||||||
+ value_details['OthChrg'] - value_details['Discount']
|
|
||||||
|
|
||||||
self.assertTrue(value_details['TotInvVal'] - calculated_invoice_value < 0.1)
|
|
||||||
|
|
||||||
self.assertEqual(value_details['TotInvVal'], si.base_grand_total)
|
|
||||||
self.assertTrue(einvoice['EwbDtls'])
|
self.assertTrue(einvoice['EwbDtls'])
|
||||||
|
validate_totals(einvoice)
|
||||||
|
|
||||||
|
si.apply_discount_on = 'Net Total'
|
||||||
|
si.save()
|
||||||
|
einvoice = make_einvoice(si)
|
||||||
|
validate_totals(einvoice)
|
||||||
|
|
||||||
|
[d.set('included_in_print_rate', 1) for d in si.taxes]
|
||||||
|
si.save()
|
||||||
|
einvoice = make_einvoice(si)
|
||||||
|
validate_totals(einvoice)
|
||||||
|
|
||||||
|
def get_sales_invoice_for_e_invoice():
|
||||||
|
si = make_sales_invoice_for_ewaybill()
|
||||||
|
si.naming_series = 'INV-2020-.#####'
|
||||||
|
si.items = []
|
||||||
|
si.append("items", {
|
||||||
|
"item_code": "_Test Item",
|
||||||
|
"uom": "Nos",
|
||||||
|
"warehouse": "_Test Warehouse - _TC",
|
||||||
|
"qty": 2000,
|
||||||
|
"rate": 12,
|
||||||
|
"income_account": "Sales - _TC",
|
||||||
|
"expense_account": "Cost of Goods Sold - _TC",
|
||||||
|
"cost_center": "_Test Cost Center - _TC",
|
||||||
|
})
|
||||||
|
|
||||||
|
si.append("items", {
|
||||||
|
"item_code": "_Test Item 2",
|
||||||
|
"uom": "Nos",
|
||||||
|
"warehouse": "_Test Warehouse - _TC",
|
||||||
|
"qty": 420,
|
||||||
|
"rate": 15,
|
||||||
|
"income_account": "Sales - _TC",
|
||||||
|
"expense_account": "Cost of Goods Sold - _TC",
|
||||||
|
"cost_center": "_Test Cost Center - _TC",
|
||||||
|
})
|
||||||
|
|
||||||
|
return si
|
||||||
|
|
||||||
def test_item_tax_net_range(self):
|
def test_item_tax_net_range(self):
|
||||||
item = create_item("T Shirt")
|
item = create_item("T Shirt")
|
||||||
|
|||||||
@ -38,7 +38,7 @@ def validate_eligibility(doc):
|
|||||||
einvoicing_eligible_from = frappe.db.get_single_value('E Invoice Settings', 'applicable_from') or '2021-04-01'
|
einvoicing_eligible_from = frappe.db.get_single_value('E Invoice Settings', 'applicable_from') or '2021-04-01'
|
||||||
if getdate(doc.get('posting_date')) < getdate(einvoicing_eligible_from):
|
if getdate(doc.get('posting_date')) < getdate(einvoicing_eligible_from):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
invalid_company = not frappe.db.get_value('E Invoice User', { 'company': doc.get('company') })
|
invalid_company = not frappe.db.get_value('E Invoice User', { 'company': doc.get('company') })
|
||||||
invalid_supply_type = doc.get('gst_category') not in ['Registered Regular', 'SEZ', 'Overseas', 'Deemed Export']
|
invalid_supply_type = doc.get('gst_category') not in ['Registered Regular', 'SEZ', 'Overseas', 'Deemed Export']
|
||||||
company_transaction = doc.get('billing_address_gstin') == doc.get('company_gstin')
|
company_transaction = doc.get('billing_address_gstin') == doc.get('company_gstin')
|
||||||
@ -135,7 +135,7 @@ def validate_address_fields(address, is_shipping_address):
|
|||||||
|
|
||||||
def get_party_details(address_name, is_shipping_address=False):
|
def get_party_details(address_name, is_shipping_address=False):
|
||||||
addr = frappe.get_doc('Address', address_name)
|
addr = frappe.get_doc('Address', address_name)
|
||||||
|
|
||||||
validate_address_fields(addr, is_shipping_address)
|
validate_address_fields(addr, is_shipping_address)
|
||||||
|
|
||||||
if addr.gst_state_number == 97:
|
if addr.gst_state_number == 97:
|
||||||
@ -188,11 +188,6 @@ def get_item_list(invoice):
|
|||||||
|
|
||||||
item.qty = abs(item.qty)
|
item.qty = abs(item.qty)
|
||||||
|
|
||||||
if invoice.apply_discount_on == 'Net Total' and invoice.discount_amount:
|
|
||||||
item.discount_amount = abs(item.base_amount - item.base_net_amount)
|
|
||||||
else:
|
|
||||||
item.discount_amount = 0
|
|
||||||
|
|
||||||
item.unit_rate = abs((abs(item.taxable_value) - item.discount_amount)/ item.qty)
|
item.unit_rate = abs((abs(item.taxable_value) - item.discount_amount)/ item.qty)
|
||||||
item.gross_amount = abs(item.taxable_value) + item.discount_amount
|
item.gross_amount = abs(item.taxable_value) + item.discount_amount
|
||||||
item.taxable_value = abs(item.taxable_value)
|
item.taxable_value = abs(item.taxable_value)
|
||||||
@ -254,18 +249,8 @@ def update_item_taxes(invoice, item):
|
|||||||
|
|
||||||
def get_invoice_value_details(invoice):
|
def get_invoice_value_details(invoice):
|
||||||
invoice_value_details = frappe._dict(dict())
|
invoice_value_details = frappe._dict(dict())
|
||||||
|
invoice_value_details.base_total = abs(sum([i.taxable_value for i in invoice.get('items')]))
|
||||||
if invoice.apply_discount_on == 'Net Total' and invoice.discount_amount:
|
invoice_value_details.invoice_discount_amt = 0
|
||||||
# Discount already applied on net total which means on items
|
|
||||||
invoice_value_details.base_total = abs(sum([i.taxable_value for i in invoice.get('items')]))
|
|
||||||
invoice_value_details.invoice_discount_amt = 0
|
|
||||||
elif invoice.apply_discount_on == 'Grand Total' and invoice.discount_amount:
|
|
||||||
invoice_value_details.invoice_discount_amt = invoice.base_discount_amount
|
|
||||||
invoice_value_details.base_total = abs(sum([i.taxable_value for i in invoice.get('items')]))
|
|
||||||
else:
|
|
||||||
invoice_value_details.base_total = abs(sum([i.taxable_value for i in invoice.get('items')]))
|
|
||||||
# since tax already considers discount amount
|
|
||||||
invoice_value_details.invoice_discount_amt = 0
|
|
||||||
|
|
||||||
invoice_value_details.round_off = invoice.base_rounding_adjustment
|
invoice_value_details.round_off = invoice.base_rounding_adjustment
|
||||||
invoice_value_details.base_grand_total = abs(invoice.base_rounded_total) or abs(invoice.base_grand_total)
|
invoice_value_details.base_grand_total = abs(invoice.base_rounded_total) or abs(invoice.base_grand_total)
|
||||||
@ -287,8 +272,7 @@ def update_invoice_taxes(invoice, invoice_value_details):
|
|||||||
considered_rows = []
|
considered_rows = []
|
||||||
|
|
||||||
for t in invoice.taxes:
|
for t in invoice.taxes:
|
||||||
tax_amount = t.base_tax_amount if (invoice.apply_discount_on == 'Grand Total' and invoice.discount_amount) \
|
tax_amount = t.base_tax_amount_after_discount_amount
|
||||||
else t.base_tax_amount_after_discount_amount
|
|
||||||
if t.account_head in gst_accounts_list:
|
if t.account_head in gst_accounts_list:
|
||||||
if t.account_head in gst_accounts.cess_account:
|
if t.account_head in gst_accounts.cess_account:
|
||||||
# using after discount amt since item also uses after discount amt for cess calc
|
# using after discount amt since item also uses after discount amt for cess calc
|
||||||
@ -995,7 +979,7 @@ class GSPConnector():
|
|||||||
self.invoice.failure_description = self.get_failure_message(errors) if errors else ""
|
self.invoice.failure_description = self.get_failure_message(errors) if errors else ""
|
||||||
self.update_invoice()
|
self.update_invoice()
|
||||||
frappe.db.commit()
|
frappe.db.commit()
|
||||||
|
|
||||||
def get_failure_message(self, errors):
|
def get_failure_message(self, errors):
|
||||||
if isinstance(errors, list):
|
if isinstance(errors, list):
|
||||||
errors = ', '.join(errors)
|
errors = ', '.join(errors)
|
||||||
@ -1052,7 +1036,7 @@ def generate_einvoices(docnames):
|
|||||||
_('{} e-invoices generated successfully').format(success),
|
_('{} e-invoices generated successfully').format(success),
|
||||||
title=_('Bulk E-Invoice Generation Complete')
|
title=_('Bulk E-Invoice Generation Complete')
|
||||||
)
|
)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
enqueue_bulk_action(schedule_bulk_generate_irn, docnames=docnames)
|
enqueue_bulk_action(schedule_bulk_generate_irn, docnames=docnames)
|
||||||
|
|
||||||
|
|||||||
@ -817,12 +817,8 @@ def update_taxable_values(doc, method):
|
|||||||
considered_rows.append(prev_row_id)
|
considered_rows.append(prev_row_id)
|
||||||
|
|
||||||
for item in doc.get('items'):
|
for item in doc.get('items'):
|
||||||
if doc.apply_discount_on == 'Grand Total' and doc.discount_amount:
|
proportionate_value = item.base_net_amount if doc.base_net_total else item.qty
|
||||||
proportionate_value = item.base_amount if doc.base_total else item.qty
|
total_value = doc.base_net_total if doc.base_net_total else doc.total_qty
|
||||||
total_value = doc.base_total if doc.base_total else doc.total_qty
|
|
||||||
else:
|
|
||||||
proportionate_value = item.base_net_amount if doc.base_net_total else item.qty
|
|
||||||
total_value = doc.base_net_total if doc.base_net_total else doc.total_qty
|
|
||||||
|
|
||||||
applicable_charges = flt(flt(proportionate_value * (flt(additional_taxes) / flt(total_value)),
|
applicable_charges = flt(flt(proportionate_value * (flt(additional_taxes) / flt(total_value)),
|
||||||
item.precision('taxable_value')))
|
item.precision('taxable_value')))
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user