Merge branch 'version-13-beta-pre-release' into version-13-beta
This commit is contained in:
commit
5049d83a0c
@ -5,7 +5,7 @@ import frappe
|
||||
from erpnext.hooks import regional_overrides
|
||||
from frappe.utils import getdate
|
||||
|
||||
__version__ = '13.0.0-beta.7'
|
||||
__version__ = '13.0.0-beta.8'
|
||||
|
||||
def get_default_company(user=None):
|
||||
'''Get default company for user'''
|
||||
|
@ -1885,8 +1885,8 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
"item_code": "_Test Item",
|
||||
"uom": "Nos",
|
||||
"warehouse": "_Test Warehouse - _TC",
|
||||
"qty": 2,
|
||||
"rate": 100,
|
||||
"qty": 2000,
|
||||
"rate": 12,
|
||||
"income_account": "Sales - _TC",
|
||||
"expense_account": "Cost of Goods Sold - _TC",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
@ -1895,31 +1895,52 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
"item_code": "_Test Item 2",
|
||||
"uom": "Nos",
|
||||
"warehouse": "_Test Warehouse - _TC",
|
||||
"qty": 4,
|
||||
"rate": 150,
|
||||
"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.save()
|
||||
|
||||
einvoice = make_einvoice(si)
|
||||
|
||||
total_item_ass_value = sum([d['AssAmt'] for d in einvoice['ItemList']])
|
||||
total_item_cgst_value = sum([d['CgstAmt'] for d in einvoice['ItemList']])
|
||||
total_item_sgst_value = sum([d['SgstAmt'] for d in einvoice['ItemList']])
|
||||
total_item_igst_value = sum([d['IgstAmt'] for d in einvoice['ItemList']])
|
||||
total_item_value = sum([d['TotItemVal'] for d in einvoice['ItemList']])
|
||||
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(einvoice['ValDtls']['AssVal'], total_item_ass_value)
|
||||
self.assertEqual(einvoice['ValDtls']['CgstVal'], total_item_cgst_value)
|
||||
self.assertEqual(einvoice['ValDtls']['SgstVal'], total_item_sgst_value)
|
||||
self.assertEqual(einvoice['ValDtls']['IgstVal'], total_item_igst_value)
|
||||
self.assertEqual(einvoice['ValDtls']['TotInvVal'], total_item_value)
|
||||
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)
|
||||
|
||||
self.assertEqual(
|
||||
value_details['TotInvVal'],
|
||||
value_details['AssVal'] + value_details['CgstVal']
|
||||
+ value_details['SgstVal'] + value_details['IgstVal']
|
||||
+ value_details['OthChrg'] - value_details['Discount']
|
||||
)
|
||||
|
||||
self.assertEqual(value_details['TotInvVal'], si.base_grand_total)
|
||||
self.assertTrue(einvoice['EwbDtls'])
|
||||
|
||||
def make_sales_invoice_for_ewaybill():
|
||||
def make_test_address_for_ewaybill():
|
||||
if not frappe.db.exists('Address', '_Test Address for Eway bill-Billing'):
|
||||
address = frappe.get_doc({
|
||||
"address_line1": "_Test Address Line 1",
|
||||
@ -1967,7 +1988,8 @@ def make_sales_invoice_for_ewaybill():
|
||||
})
|
||||
|
||||
address.save()
|
||||
|
||||
|
||||
def make_test_transporter_for_ewaybill():
|
||||
if not frappe.db.exists('Supplier', '_Test Transporter'):
|
||||
frappe.get_doc({
|
||||
"doctype": "Supplier",
|
||||
@ -1978,12 +2000,17 @@ def make_sales_invoice_for_ewaybill():
|
||||
"is_transporter": 1
|
||||
}).insert()
|
||||
|
||||
def make_sales_invoice_for_ewaybill():
|
||||
make_test_address_for_ewaybill()
|
||||
make_test_transporter_for_ewaybill()
|
||||
|
||||
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"})
|
||||
filters = {"company": "_Test Company"}
|
||||
)
|
||||
|
||||
if not gst_account:
|
||||
gst_settings.append("gst_accounts", {
|
||||
@ -1995,7 +2022,7 @@ def make_sales_invoice_for_ewaybill():
|
||||
|
||||
gst_settings.save()
|
||||
|
||||
si = create_sales_invoice(do_not_save =1, rate = '60000')
|
||||
si = create_sales_invoice(do_not_save=1, rate='60000')
|
||||
|
||||
si.distance = 2000
|
||||
si.company_address = "_Test Address for Eway bill-Billing"
|
||||
|
@ -712,6 +712,7 @@ erpnext.patches.v13_0.delete_old_sales_reports
|
||||
execute:frappe.delete_doc_if_exists("DocType", "Bank Reconciliation")
|
||||
erpnext.patches.v13_0.move_doctype_reports_and_notification_from_hr_to_payroll #22-06-2020
|
||||
erpnext.patches.v13_0.move_payroll_setting_separately_from_hr_settings #22-06-2020
|
||||
execute:frappe.reload_doc("regional", "doctype", "e_invoice_settings")
|
||||
erpnext.patches.v13_0.check_is_income_tax_component #22-06-2020
|
||||
erpnext.patches.v13_0.loyalty_points_entry_for_pos_invoice #22-07-2020
|
||||
erpnext.patches.v12_0.add_taxjar_integration_field
|
||||
|
@ -8,6 +8,7 @@ def execute():
|
||||
if not company:
|
||||
return
|
||||
|
||||
frappe.reload_doc("custom", "doctype", "custom_field")
|
||||
frappe.reload_doc("regional", "doctype", "e_invoice_settings")
|
||||
custom_fields = {
|
||||
'Sales Invoice': [
|
||||
|
@ -59,7 +59,7 @@
|
||||
{item_list}
|
||||
],
|
||||
"ValDtls": {{
|
||||
"AssVal": "{invoice_value_details.base_net_total}",
|
||||
"AssVal": "{invoice_value_details.base_total}",
|
||||
"CgstVal": "{invoice_value_details.total_cgst_amt}",
|
||||
"SgstVal": "{invoice_value_details.total_sgst_amt}",
|
||||
"IgstVal": "{invoice_value_details.total_igst_amt}",
|
||||
|
@ -146,12 +146,12 @@ def get_item_list(invoice):
|
||||
item.update(d.as_dict())
|
||||
|
||||
item.sr_no = d.idx
|
||||
item.qty = abs(item.qty)
|
||||
item.description = d.item_name
|
||||
item.taxable_value = abs(item.base_net_amount)
|
||||
item.discount_amount = abs(item.discount_amount * item.qty)
|
||||
item.unit_rate = abs(item.base_price_list_rate) if item.discount_amount else abs(item.base_net_rate)
|
||||
item.gross_amount = abs(item.unit_rate * item.qty)
|
||||
item.description = d.item_name
|
||||
item.qty = abs(item.qty)
|
||||
item.unit_rate = abs(item.base_amount / item.qty)
|
||||
item.gross_amount = abs(item.base_amount)
|
||||
item.taxable_value = abs(item.base_amount)
|
||||
|
||||
item.batch_expiry_date = frappe.db.get_value('Batch', d.batch_no, 'expiry_date') if d.batch_no else None
|
||||
item.batch_expiry_date = format_date(item.batch_expiry_date, 'dd/mm/yyyy') if item.batch_expiry_date else None
|
||||
@ -180,35 +180,35 @@ def update_item_taxes(invoice, item):
|
||||
item[attr] = 0
|
||||
|
||||
for t in invoice.taxes:
|
||||
# this contains item wise tax rate & tax amount (incl. discount)
|
||||
item_tax_detail = json.loads(t.item_wise_tax_detail).get(item.item_code)
|
||||
if t.account_head in gst_accounts_list:
|
||||
item_tax_rate = item_tax_detail[0]
|
||||
# item tax amount excluding discount amount
|
||||
item_tax_amount = (item_tax_rate / 100) * item.base_amount
|
||||
|
||||
if t.account_head in gst_accounts.cess_account:
|
||||
item_tax_amount_after_discount = item_tax_detail[1]
|
||||
if t.charge_type == 'On Item Quantity':
|
||||
item.cess_nadv_amount += abs(item_tax_detail[1])
|
||||
item.cess_nadv_amount += abs(item_tax_amount_after_discount)
|
||||
else:
|
||||
item.cess_rate += item_tax_detail[0]
|
||||
item.cess_amount += abs(item_tax_detail[1])
|
||||
elif t.account_head in gst_accounts.igst_account:
|
||||
item.tax_rate += item_tax_detail[0]
|
||||
item.igst_amount += abs(item_tax_detail[1])
|
||||
elif t.account_head in gst_accounts.sgst_account:
|
||||
item.tax_rate += item_tax_detail[0]
|
||||
item.sgst_amount += abs(item_tax_detail[1])
|
||||
elif t.account_head in gst_accounts.cgst_account:
|
||||
item.tax_rate += item_tax_detail[0]
|
||||
item.cgst_amount += abs(item_tax_detail[1])
|
||||
|
||||
item.cess_rate += item_tax_rate
|
||||
item.cess_amount += abs(item_tax_amount_after_discount)
|
||||
|
||||
for tax_type in ['igst', 'cgst', 'sgst']:
|
||||
if t.account_head in gst_accounts[f'{tax_type}_account']:
|
||||
item.tax_rate += item_tax_rate
|
||||
item[f'{tax_type}_amount'] += abs(item_tax_amount)
|
||||
|
||||
return item
|
||||
|
||||
def get_invoice_value_details(invoice):
|
||||
invoice_value_details = frappe._dict(dict())
|
||||
invoice_value_details.base_net_total = abs(invoice.base_net_total)
|
||||
invoice_value_details.invoice_discount_amt = invoice.discount_amount if invoice.discount_amount and invoice.discount_amount > 0 else 0
|
||||
# discount amount cannnot be -ve in an e-invoice, so if -ve include discount in round_off
|
||||
invoice_value_details.round_off = invoice.rounding_adjustment - (invoice.discount_amount if invoice.discount_amount and invoice.discount_amount < 0 else 0)
|
||||
disable_rounded = frappe.db.get_single_value('Global Defaults', 'disable_rounded_total')
|
||||
invoice_value_details.base_grand_total = abs(invoice.base_grand_total) if disable_rounded else abs(invoice.base_rounded_total)
|
||||
invoice_value_details.grand_total = abs(invoice.grand_total) if disable_rounded else abs(invoice.rounded_total)
|
||||
invoice_value_details.base_total = abs(invoice.base_total)
|
||||
invoice_value_details.invoice_discount_amt = invoice.discount_amount
|
||||
invoice_value_details.round_off = invoice.rounding_adjustment
|
||||
invoice_value_details.base_grand_total = abs(invoice.base_rounded_total) or abs(invoice.base_grand_total)
|
||||
invoice_value_details.grand_total = abs(invoice.rounded_total) or abs(invoice.grand_total)
|
||||
|
||||
invoice_value_details = update_invoice_taxes(invoice, invoice_value_details)
|
||||
|
||||
@ -226,15 +226,14 @@ def update_invoice_taxes(invoice, invoice_value_details):
|
||||
for t in invoice.taxes:
|
||||
if t.account_head in gst_accounts_list:
|
||||
if t.account_head in gst_accounts.cess_account:
|
||||
# using after discount amt since item also uses after discount amt for cess calc
|
||||
invoice_value_details.total_cess_amt += abs(t.base_tax_amount_after_discount_amount)
|
||||
elif t.account_head in gst_accounts.igst_account:
|
||||
invoice_value_details.total_igst_amt += abs(t.base_tax_amount_after_discount_amount)
|
||||
elif t.account_head in gst_accounts.sgst_account:
|
||||
invoice_value_details.total_sgst_amt += abs(t.base_tax_amount_after_discount_amount)
|
||||
elif t.account_head in gst_accounts.cgst_account:
|
||||
invoice_value_details.total_cgst_amt += abs(t.base_tax_amount_after_discount_amount)
|
||||
|
||||
for tax_type in ['igst', 'cgst', 'sgst']:
|
||||
if t.account_head in gst_accounts[f'{tax_type}_account']:
|
||||
invoice_value_details[f'total_{tax_type}_amt'] += abs(t.base_tax_amount)
|
||||
else:
|
||||
invoice_value_details.total_other_charges += abs(t.base_tax_amount_after_discount_amount)
|
||||
invoice_value_details.total_other_charges += abs(t.base_tax_amount)
|
||||
|
||||
return invoice_value_details
|
||||
|
||||
@ -358,7 +357,8 @@ def validate_einvoice(validations, einvoice, errors=[]):
|
||||
einvoice[fieldname] = str(value)
|
||||
elif value_type == 'number':
|
||||
is_integer = '.' not in str(field_validation.get('maximum'))
|
||||
einvoice[fieldname] = flt(value, 2) if not is_integer else cint(value)
|
||||
precision = 3 if '.999' in str(field_validation.get('maximum')) else 2
|
||||
einvoice[fieldname] = flt(value, precision) if not is_integer else cint(value)
|
||||
value = einvoice[fieldname]
|
||||
|
||||
max_length = field_validation.get('maxLength')
|
||||
@ -386,15 +386,15 @@ class GSPConnector():
|
||||
self.invoice = frappe.get_cached_doc(doctype, docname) if doctype and docname else None
|
||||
self.credentials = self.get_credentials()
|
||||
|
||||
self.base_url = 'https://gsp.adaequare.com/'
|
||||
self.authenticate_url = self.base_url + 'gsp/authenticate?grant_type=token'
|
||||
self.gstin_details_url = self.base_url + 'test/enriched/ei/api/master/gstin'
|
||||
self.generate_irn_url = self.base_url + 'test/enriched/ei/api/invoice'
|
||||
self.irn_details_url = self.base_url + 'test/enriched/ei/api/invoice/irn'
|
||||
self.cancel_irn_url = self.base_url + 'test/enriched/ei/api/invoice/cancel'
|
||||
self.cancel_ewaybill_url = self.base_url + '/test/enriched/ei/api/ewayapi'
|
||||
self.generate_ewaybill_url = self.base_url + 'test/enriched/ei/api/ewaybill'
|
||||
|
||||
self.base_url = 'https://gsp.adaequare.com'
|
||||
self.authenticate_url = self.base_url + '/gsp/authenticate?grant_type=token'
|
||||
self.gstin_details_url = self.base_url + '/enriched/ei/api/master/gstin'
|
||||
self.generate_irn_url = self.base_url + '/enriched/ei/api/invoice'
|
||||
self.irn_details_url = self.base_url + '/enriched/ei/api/invoice/irn'
|
||||
self.cancel_irn_url = self.base_url + '/enriched/ei/api/invoice/cancel'
|
||||
self.cancel_ewaybill_url = self.base_url + '/enriched/ei/api/ewayapi'
|
||||
self.generate_ewaybill_url = self.base_url + '/enriched/ei/api/ewaybill'
|
||||
|
||||
def get_credentials(self):
|
||||
if self.invoice:
|
||||
gstin = self.get_seller_gstin()
|
||||
|
Loading…
Reference in New Issue
Block a user