Merge branch 'develop' into shopping-cart
This commit is contained in:
commit
45db1c5d74
@ -23,7 +23,7 @@ def validate_einvoice_fields(doc):
|
||||
invalid_doctype = doc.doctype != 'Sales Invoice'
|
||||
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')
|
||||
no_taxes_applied = len(doc.get('taxes', [])) == 0
|
||||
no_taxes_applied = not doc.get('taxes')
|
||||
|
||||
if not einvoicing_enabled or invalid_doctype or invalid_supply_type or company_transaction or no_taxes_applied:
|
||||
return
|
||||
@ -63,7 +63,7 @@ def get_transaction_details(invoice):
|
||||
elif invoice.gst_category == 'Overseas': supply_type = 'EXPWOP'
|
||||
elif invoice.gst_category == 'Deemed Export': supply_type = 'DEXP'
|
||||
|
||||
if not supply_type:
|
||||
if not supply_type:
|
||||
rr, sez, overseas, export = bold('Registered Regular'), bold('SEZ'), bold('Overseas'), bold('Deemed Export')
|
||||
frappe.throw(_('GST category should be one of {}, {}, {}, {}').format(rr, sez, overseas, export),
|
||||
title=_('Invalid Supply Type'))
|
||||
@ -128,7 +128,7 @@ def get_gstin_details(gstin):
|
||||
if details:
|
||||
frappe.local.gstin_cache[key] = details
|
||||
return details
|
||||
|
||||
|
||||
if not details:
|
||||
return GSPConnector.get_gstin_details(gstin)
|
||||
|
||||
@ -174,7 +174,7 @@ def get_item_list(invoice):
|
||||
item.serial_no = ""
|
||||
|
||||
item = update_item_taxes(invoice, item)
|
||||
|
||||
|
||||
item.total_value = abs(
|
||||
item.taxable_value + item.igst_amount + item.sgst_amount +
|
||||
item.cgst_amount + item.cess_amount + item.cess_nadv_amount + item.other_charges
|
||||
@ -232,9 +232,9 @@ def get_invoice_value_details(invoice):
|
||||
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.grand_total = abs(invoice.rounded_total) or abs(invoice.grand_total)
|
||||
|
||||
|
||||
invoice_value_details = update_invoice_taxes(invoice, invoice_value_details)
|
||||
|
||||
|
||||
return invoice_value_details
|
||||
|
||||
def update_invoice_taxes(invoice, invoice_value_details):
|
||||
@ -251,13 +251,13 @@ def update_invoice_taxes(invoice, invoice_value_details):
|
||||
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)
|
||||
|
||||
|
||||
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_after_discount_amount)
|
||||
else:
|
||||
invoice_value_details.total_other_charges += abs(t.base_tax_amount_after_discount_amount)
|
||||
|
||||
|
||||
return invoice_value_details
|
||||
|
||||
def get_payment_details(invoice):
|
||||
@ -329,23 +329,23 @@ def make_einvoice(invoice):
|
||||
place_of_supply = get_place_of_supply(invoice, invoice.doctype) or invoice.billing_address_gstin
|
||||
place_of_supply = place_of_supply[:2]
|
||||
buyer_details.update(dict(place_of_supply=place_of_supply))
|
||||
|
||||
|
||||
shipping_details = payment_details = prev_doc_details = eway_bill_details = frappe._dict({})
|
||||
if invoice.shipping_address_name and invoice.customer_address != invoice.shipping_address_name:
|
||||
if invoice.gst_category == 'Overseas':
|
||||
shipping_details = get_overseas_address_details(invoice.shipping_address_name)
|
||||
else:
|
||||
shipping_details = get_party_details(invoice.shipping_address_name)
|
||||
|
||||
|
||||
if invoice.is_pos and invoice.base_paid_amount:
|
||||
payment_details = get_payment_details(invoice)
|
||||
|
||||
|
||||
if invoice.is_return and invoice.return_against:
|
||||
prev_doc_details = get_return_doc_reference(invoice)
|
||||
|
||||
|
||||
if invoice.transporter:
|
||||
eway_bill_details = get_eway_bill_details(invoice)
|
||||
|
||||
|
||||
# not yet implemented
|
||||
dispatch_details = period_details = export_details = frappe._dict({})
|
||||
|
||||
@ -357,7 +357,7 @@ def make_einvoice(invoice):
|
||||
export_details=export_details, eway_bill_details=eway_bill_details
|
||||
)
|
||||
einvoice = json.loads(einvoice)
|
||||
|
||||
|
||||
validations = json.loads(read_json('einv_validation'))
|
||||
errors = validate_einvoice(validations, einvoice)
|
||||
if errors:
|
||||
@ -419,7 +419,7 @@ def validate_einvoice(validations, einvoice, errors=[]):
|
||||
errors.append(_('{} {} should be between {} and {}').format(label, value, minimum, maximum))
|
||||
if pattern_str and not pattern.match(value):
|
||||
errors.append(field_validation.get('validationMsg'))
|
||||
|
||||
|
||||
return errors
|
||||
|
||||
class RequestFailed(Exception): pass
|
||||
@ -452,19 +452,19 @@ class GSPConnector():
|
||||
else:
|
||||
credentials = self.e_invoice_settings.credentials[0] if self.e_invoice_settings.credentials else None
|
||||
return credentials
|
||||
|
||||
|
||||
def get_seller_gstin(self):
|
||||
gstin = self.invoice.company_gstin or frappe.db.get_value('Address', self.invoice.company_address, 'gstin')
|
||||
if not gstin:
|
||||
frappe.throw(_('Cannot retrieve Company GSTIN. Please select company address with valid GSTIN.'))
|
||||
return gstin
|
||||
|
||||
|
||||
def get_auth_token(self):
|
||||
if time_diff_in_seconds(self.e_invoice_settings.token_expiry, now_datetime()) < 150.0:
|
||||
self.fetch_auth_token()
|
||||
|
||||
|
||||
return self.e_invoice_settings.auth_token
|
||||
|
||||
|
||||
def make_request(self, request_type, url, headers=None, data=None):
|
||||
if request_type == 'post':
|
||||
res = make_post_request(url, headers=headers, data=data)
|
||||
@ -473,7 +473,7 @@ class GSPConnector():
|
||||
|
||||
self.log_request(url, headers, data, res)
|
||||
return res
|
||||
|
||||
|
||||
def log_request(self, url, headers, data, res):
|
||||
headers.update({ 'password': self.credentials.password })
|
||||
request_log = frappe.get_doc({
|
||||
@ -504,7 +504,7 @@ class GSPConnector():
|
||||
except Exception:
|
||||
self.log_error(res)
|
||||
self.raise_error(True)
|
||||
|
||||
|
||||
def get_headers(self):
|
||||
return {
|
||||
'content-type': 'application/json',
|
||||
@ -526,7 +526,7 @@ class GSPConnector():
|
||||
else:
|
||||
self.log_error(res)
|
||||
raise RequestFailed
|
||||
|
||||
|
||||
except RequestFailed:
|
||||
self.raise_error()
|
||||
|
||||
@ -571,7 +571,7 @@ class GSPConnector():
|
||||
|
||||
else:
|
||||
raise RequestFailed
|
||||
|
||||
|
||||
except RequestFailed:
|
||||
errors = self.sanitize_error_message(res.get('message'))
|
||||
self.raise_error(errors=errors)
|
||||
@ -579,7 +579,7 @@ class GSPConnector():
|
||||
except Exception:
|
||||
self.log_error(data)
|
||||
self.raise_error(True)
|
||||
|
||||
|
||||
def get_irn_details(self, irn):
|
||||
headers = self.get_headers()
|
||||
|
||||
@ -590,7 +590,7 @@ class GSPConnector():
|
||||
return res.get('result')
|
||||
else:
|
||||
raise RequestFailed
|
||||
|
||||
|
||||
except RequestFailed:
|
||||
errors = self.sanitize_error_message(res.get('message'))
|
||||
self.raise_error(errors=errors)
|
||||
@ -598,7 +598,7 @@ class GSPConnector():
|
||||
except Exception:
|
||||
self.log_error()
|
||||
self.raise_error(True)
|
||||
|
||||
|
||||
def cancel_irn(self, irn, reason, remark):
|
||||
headers = self.get_headers()
|
||||
data = json.dumps({
|
||||
@ -620,7 +620,7 @@ class GSPConnector():
|
||||
|
||||
else:
|
||||
raise RequestFailed
|
||||
|
||||
|
||||
except RequestFailed:
|
||||
errors = self.sanitize_error_message(res.get('message'))
|
||||
self.raise_error(errors=errors)
|
||||
@ -669,7 +669,7 @@ class GSPConnector():
|
||||
except Exception:
|
||||
self.log_error(data)
|
||||
self.raise_error(True)
|
||||
|
||||
|
||||
def cancel_eway_bill(self, eway_bill, reason, remark):
|
||||
headers = self.get_headers()
|
||||
data = json.dumps({
|
||||
@ -701,7 +701,7 @@ class GSPConnector():
|
||||
except Exception:
|
||||
self.log_error(data)
|
||||
self.raise_error(True)
|
||||
|
||||
|
||||
def sanitize_error_message(self, message):
|
||||
'''
|
||||
On validation errors, response message looks something like this:
|
||||
@ -740,7 +740,7 @@ class GSPConnector():
|
||||
"Exception:", err_tb
|
||||
])
|
||||
frappe.log_error(title=_('E Invoice Request Failed'), message=message)
|
||||
|
||||
|
||||
def raise_error(self, raise_exception=False, errors=[]):
|
||||
title = _('E Invoice Request Failed')
|
||||
if errors:
|
||||
@ -753,7 +753,7 @@ class GSPConnector():
|
||||
raise_exception=raise_exception,
|
||||
indicator='red'
|
||||
)
|
||||
|
||||
|
||||
def set_einvoice_data(self, res):
|
||||
enc_signed_invoice = res.get('SignedInvoice')
|
||||
dec_signed_invoice = jwt.decode(enc_signed_invoice, verify=False)['data']
|
||||
@ -792,7 +792,7 @@ class GSPConnector():
|
||||
_file.save()
|
||||
frappe.db.commit()
|
||||
self.invoice.qrcode_image = _file.file_url
|
||||
|
||||
|
||||
def update_invoice(self):
|
||||
self.invoice.flags.ignore_validate_update_after_submit = True
|
||||
self.invoice.flags.ignore_validate = True
|
||||
|
Loading…
Reference in New Issue
Block a user