revert: "refactor!: drop e-invoicing integration from erpnext (#26940)"
This reverts commit c335962827e4927f7ada084e9ba4ab2db15e3eb6.
This commit is contained in:
parent
b75b00fefc
commit
c5782b0e71
@ -1,6 +1,8 @@
|
|||||||
{% include "erpnext/regional/india/taxes.js" %}
|
{% include "erpnext/regional/india/taxes.js" %}
|
||||||
|
{% include "erpnext/regional/india/e_invoice/einvoice.js" %}
|
||||||
|
|
||||||
erpnext.setup_auto_gst_taxation('Sales Invoice');
|
erpnext.setup_auto_gst_taxation('Sales Invoice');
|
||||||
|
erpnext.setup_einvoice_actions('Sales Invoice')
|
||||||
|
|
||||||
frappe.ui.form.on("Sales Invoice", {
|
frappe.ui.form.on("Sales Invoice", {
|
||||||
setup: function(frm) {
|
setup: function(frm) {
|
||||||
|
@ -36,4 +36,139 @@ frappe.listview_settings['Sales Invoice'].onload = function (list_view) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
list_view.page.add_actions_menu_item(__('Generate E-Way Bill JSON'), action, false);
|
list_view.page.add_actions_menu_item(__('Generate E-Way Bill JSON'), action, false);
|
||||||
|
|
||||||
|
const generate_irns = () => {
|
||||||
|
const docnames = list_view.get_checked_items(true);
|
||||||
|
if (docnames && docnames.length) {
|
||||||
|
frappe.call({
|
||||||
|
method: 'erpnext.regional.india.e_invoice.utils.generate_einvoices',
|
||||||
|
args: { docnames },
|
||||||
|
freeze: true,
|
||||||
|
freeze_message: __('Generating E-Invoices...')
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
frappe.msgprint({
|
||||||
|
message: __('Please select at least one sales invoice to generate IRN'),
|
||||||
|
title: __('No Invoice Selected'),
|
||||||
|
indicator: 'red'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const cancel_irns = () => {
|
||||||
|
const docnames = list_view.get_checked_items(true);
|
||||||
|
|
||||||
|
const fields = [
|
||||||
|
{
|
||||||
|
"label": "Reason",
|
||||||
|
"fieldname": "reason",
|
||||||
|
"fieldtype": "Select",
|
||||||
|
"reqd": 1,
|
||||||
|
"default": "1-Duplicate",
|
||||||
|
"options": ["1-Duplicate", "2-Data Entry Error", "3-Order Cancelled", "4-Other"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Remark",
|
||||||
|
"fieldname": "remark",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"reqd": 1
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const d = new frappe.ui.Dialog({
|
||||||
|
title: __("Cancel IRN"),
|
||||||
|
fields: fields,
|
||||||
|
primary_action: function() {
|
||||||
|
const data = d.get_values();
|
||||||
|
frappe.call({
|
||||||
|
method: 'erpnext.regional.india.e_invoice.utils.cancel_irns',
|
||||||
|
args: {
|
||||||
|
doctype: list_view.doctype,
|
||||||
|
docnames,
|
||||||
|
reason: data.reason.split('-')[0],
|
||||||
|
remark: data.remark
|
||||||
|
},
|
||||||
|
freeze: true,
|
||||||
|
freeze_message: __('Cancelling E-Invoices...'),
|
||||||
|
});
|
||||||
|
d.hide();
|
||||||
|
},
|
||||||
|
primary_action_label: __('Submit')
|
||||||
|
});
|
||||||
|
d.show();
|
||||||
|
};
|
||||||
|
|
||||||
|
let einvoicing_enabled = false;
|
||||||
|
frappe.db.get_single_value("E Invoice Settings", "enable").then(enabled => {
|
||||||
|
einvoicing_enabled = enabled;
|
||||||
|
});
|
||||||
|
|
||||||
|
list_view.$result.on("change", "input[type=checkbox]", () => {
|
||||||
|
if (einvoicing_enabled) {
|
||||||
|
const docnames = list_view.get_checked_items(true);
|
||||||
|
// show/hide e-invoicing actions when no sales invoices are checked
|
||||||
|
if (docnames && docnames.length) {
|
||||||
|
// prevent adding actions twice if e-invoicing action group already exists
|
||||||
|
if (list_view.page.get_inner_group_button(__('E-Invoicing')).length == 0) {
|
||||||
|
list_view.page.add_inner_button(__('Generate IRNs'), generate_irns, __('E-Invoicing'));
|
||||||
|
list_view.page.add_inner_button(__('Cancel IRNs'), cancel_irns, __('E-Invoicing'));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
list_view.page.remove_inner_button(__('Generate IRNs'), __('E-Invoicing'));
|
||||||
|
list_view.page.remove_inner_button(__('Cancel IRNs'), __('E-Invoicing'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
frappe.realtime.on("bulk_einvoice_generation_complete", (data) => {
|
||||||
|
const { failures, user, invoices } = data;
|
||||||
|
|
||||||
|
if (invoices.length != failures.length) {
|
||||||
|
frappe.msgprint({
|
||||||
|
message: __('{0} e-invoices generated successfully', [invoices.length]),
|
||||||
|
title: __('Bulk E-Invoice Generation Complete'),
|
||||||
|
indicator: 'orange'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (failures && failures.length && user == frappe.session.user) {
|
||||||
|
let message = `
|
||||||
|
Failed to generate IRNs for following ${failures.length} sales invoices:
|
||||||
|
<ul style="padding-left: 20px; padding-top: 5px;">
|
||||||
|
${failures.map(d => `<li>${d.docname}</li>`).join('')}
|
||||||
|
</ul>
|
||||||
|
`;
|
||||||
|
frappe.msgprint({
|
||||||
|
message: message,
|
||||||
|
title: __('Bulk E-Invoice Generation Complete'),
|
||||||
|
indicator: 'orange'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
frappe.realtime.on("bulk_einvoice_cancellation_complete", (data) => {
|
||||||
|
const { failures, user, invoices } = data;
|
||||||
|
|
||||||
|
if (invoices.length != failures.length) {
|
||||||
|
frappe.msgprint({
|
||||||
|
message: __('{0} e-invoices cancelled successfully', [invoices.length]),
|
||||||
|
title: __('Bulk E-Invoice Cancellation Complete'),
|
||||||
|
indicator: 'orange'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (failures && failures.length && user == frappe.session.user) {
|
||||||
|
let message = `
|
||||||
|
Failed to cancel IRNs for following ${failures.length} sales invoices:
|
||||||
|
<ul style="padding-left: 20px; padding-top: 5px;">
|
||||||
|
${failures.map(d => `<li>${d.docname}</li>`).join('')}
|
||||||
|
</ul>
|
||||||
|
`;
|
||||||
|
frappe.msgprint({
|
||||||
|
message: message,
|
||||||
|
title: __('Bulk E-Invoice Cancellation Complete'),
|
||||||
|
indicator: 'orange'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
@ -294,6 +294,8 @@ class SalesInvoice(SellingController):
|
|||||||
|
|
||||||
def before_cancel(self):
|
def before_cancel(self):
|
||||||
self.check_if_consolidated_invoice()
|
self.check_if_consolidated_invoice()
|
||||||
|
|
||||||
|
super(SalesInvoice, self).before_cancel()
|
||||||
self.update_time_sheet(None)
|
self.update_time_sheet(None)
|
||||||
|
|
||||||
def on_cancel(self):
|
def on_cancel(self):
|
||||||
|
@ -2100,6 +2100,54 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
self.assertEqual(data['billLists'][0]['actualFromStateCode'],7)
|
self.assertEqual(data['billLists'][0]['actualFromStateCode'],7)
|
||||||
self.assertEqual(data['billLists'][0]['fromStateCode'],27)
|
self.assertEqual(data['billLists'][0]['fromStateCode'],27)
|
||||||
|
|
||||||
|
def test_einvoice_submission_without_irn(self):
|
||||||
|
# init
|
||||||
|
einvoice_settings = frappe.get_doc('E Invoice Settings')
|
||||||
|
einvoice_settings.enable = 1
|
||||||
|
einvoice_settings.applicable_from = nowdate()
|
||||||
|
einvoice_settings.append('credentials', {
|
||||||
|
'company': '_Test Company',
|
||||||
|
'gstin': '27AAECE4835E1ZR',
|
||||||
|
'username': 'test',
|
||||||
|
'password': 'test'
|
||||||
|
})
|
||||||
|
einvoice_settings.save()
|
||||||
|
|
||||||
|
country = frappe.flags.country
|
||||||
|
frappe.flags.country = 'India'
|
||||||
|
|
||||||
|
si = make_sales_invoice_for_ewaybill()
|
||||||
|
self.assertRaises(frappe.ValidationError, si.submit)
|
||||||
|
|
||||||
|
si.irn = 'test_irn'
|
||||||
|
si.submit()
|
||||||
|
|
||||||
|
# reset
|
||||||
|
einvoice_settings = frappe.get_doc('E Invoice Settings')
|
||||||
|
einvoice_settings.enable = 0
|
||||||
|
frappe.flags.country = country
|
||||||
|
|
||||||
|
def test_einvoice_json(self):
|
||||||
|
from erpnext.regional.india.e_invoice.utils import make_einvoice, validate_totals
|
||||||
|
|
||||||
|
si = get_sales_invoice_for_e_invoice()
|
||||||
|
si.discount_amount = 100
|
||||||
|
si.save()
|
||||||
|
|
||||||
|
einvoice = make_einvoice(si)
|
||||||
|
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 test_item_tax_net_range(self):
|
def test_item_tax_net_range(self):
|
||||||
item = create_item("T Shirt")
|
item = create_item("T Shirt")
|
||||||
|
|
||||||
|
162
erpnext/accounts/print_format/gst_e_invoice/gst_e_invoice.html
Normal file
162
erpnext/accounts/print_format/gst_e_invoice/gst_e_invoice.html
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
{%- from "templates/print_formats/standard_macros.html" import add_header, render_field, print_value -%}
|
||||||
|
{%- set einvoice = json.loads(doc.signed_einvoice) -%}
|
||||||
|
|
||||||
|
<div class="page-break">
|
||||||
|
<div {% if print_settings.repeat_header_footer %} id="header-html" class="hidden-pdf" {% endif %}>
|
||||||
|
{% if letter_head and not no_letterhead %}
|
||||||
|
<div class="letter-head">{{ letter_head }}</div>
|
||||||
|
{% endif %}
|
||||||
|
<div class="print-heading">
|
||||||
|
<h2>E Invoice<br><small>{{ doc.name }}</small></h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% if print_settings.repeat_header_footer %}
|
||||||
|
<div id="footer-html" class="visible-pdf">
|
||||||
|
{% if not no_letterhead and footer %}
|
||||||
|
<div class="letter-head-footer">
|
||||||
|
{{ footer }}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
<p class="text-center small page-number visible-pdf">
|
||||||
|
{{ _("Page {0} of {1}").format('<span class="page"></span>', '<span class="topage"></span>') }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
<h5 class="font-bold" style="margin-top: 0px;">1. Transaction Details</h5>
|
||||||
|
<div class="row section-break" style="border-bottom: 1px solid #d1d8dd; padding-bottom: 10px;">
|
||||||
|
<div class="col-xs-8 column-break">
|
||||||
|
<div class="row data-field">
|
||||||
|
<div class="col-xs-4"><label>IRN</label></div>
|
||||||
|
<div class="col-xs-8 value">{{ einvoice.Irn }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="row data-field">
|
||||||
|
<div class="col-xs-4"><label>Ack. No</label></div>
|
||||||
|
<div class="col-xs-8 value">{{ einvoice.AckNo }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="row data-field">
|
||||||
|
<div class="col-xs-4"><label>Ack. Date</label></div>
|
||||||
|
<div class="col-xs-8 value">{{ frappe.utils.format_datetime(einvoice.AckDt, "dd/MM/yyyy hh:mm:ss") }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="row data-field">
|
||||||
|
<div class="col-xs-4"><label>Category</label></div>
|
||||||
|
<div class="col-xs-8 value">{{ einvoice.TranDtls.SupTyp }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="row data-field">
|
||||||
|
<div class="col-xs-4"><label>Document Type</label></div>
|
||||||
|
<div class="col-xs-8 value">{{ einvoice.DocDtls.Typ }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="row data-field">
|
||||||
|
<div class="col-xs-4"><label>Document No</label></div>
|
||||||
|
<div class="col-xs-8 value">{{ einvoice.DocDtls.No }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-4 column-break">
|
||||||
|
<img src="{{ doc.qrcode_image }}" width="175px" style="float: right;">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<h5 class="font-bold" style="margin-top: 15px; margin-bottom: 10px;">2. Party Details</h5>
|
||||||
|
<div class="row section-break" style="border-bottom: 1px solid #d1d8dd; padding-bottom: 10px;">
|
||||||
|
{%- set seller = einvoice.SellerDtls -%}
|
||||||
|
<div class="col-xs-6 column-break">
|
||||||
|
<h5 style="margin-bottom: 5px;">Seller</h5>
|
||||||
|
<p>{{ seller.Gstin }}</p>
|
||||||
|
<p>{{ seller.LglNm }}</p>
|
||||||
|
<p>{{ seller.Addr1 }}</p>
|
||||||
|
{%- if seller.Addr2 -%} <p>{{ seller.Addr2 }}</p> {% endif %}
|
||||||
|
<p>{{ seller.Loc }}</p>
|
||||||
|
<p>{{ frappe.db.get_value("Address", doc.company_address, "gst_state") }} - {{ seller.Pin }}</p>
|
||||||
|
|
||||||
|
{%- if einvoice.ShipDtls -%}
|
||||||
|
{%- set shipping = einvoice.ShipDtls -%}
|
||||||
|
<h5 style="margin-bottom: 5px;">Shipping</h5>
|
||||||
|
<p>{{ shipping.Gstin }}</p>
|
||||||
|
<p>{{ shipping.LglNm }}</p>
|
||||||
|
<p>{{ shipping.Addr1 }}</p>
|
||||||
|
{%- if shipping.Addr2 -%} <p>{{ shipping.Addr2 }}</p> {% endif %}
|
||||||
|
<p>{{ shipping.Loc }}</p>
|
||||||
|
<p>{{ frappe.db.get_value("Address", doc.shipping_address_name, "gst_state") }} - {{ shipping.Pin }}</p>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{%- set buyer = einvoice.BuyerDtls -%}
|
||||||
|
<div class="col-xs-6 column-break">
|
||||||
|
<h5 style="margin-bottom: 5px;">Buyer</h5>
|
||||||
|
<p>{{ buyer.Gstin }}</p>
|
||||||
|
<p>{{ buyer.LglNm }}</p>
|
||||||
|
<p>{{ buyer.Addr1 }}</p>
|
||||||
|
{%- if buyer.Addr2 -%} <p>{{ buyer.Addr2 }}</p> {% endif %}
|
||||||
|
<p>{{ buyer.Loc }}</p>
|
||||||
|
<p>{{ frappe.db.get_value("Address", doc.customer_address, "gst_state") }} - {{ buyer.Pin }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div style="overflow-x: auto;">
|
||||||
|
<h5 class="font-bold" style="margin-top: 15px; margin-bottom: 10px;">3. Item Details</h5>
|
||||||
|
<table class="table table-bordered">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="text-left" style="width: 3%;">Sr. No.</th>
|
||||||
|
<th class="text-left">Item</th>
|
||||||
|
<th class="text-left" style="width: 10%;">HSN Code</th>
|
||||||
|
<th class="text-left" style="width: 5%;">Qty</th>
|
||||||
|
<th class="text-left" style="width: 5%;">UOM</th>
|
||||||
|
<th class="text-left">Rate</th>
|
||||||
|
<th class="text-left" style="width: 5%;">Discount</th>
|
||||||
|
<th class="text-left">Taxable Amount</th>
|
||||||
|
<th class="text-left" style="width: 7%;">Tax Rate</th>
|
||||||
|
<th class="text-left" style="width: 5%;">Other Charges</th>
|
||||||
|
<th class="text-left">Total</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for item in einvoice.ItemList %}
|
||||||
|
<tr>
|
||||||
|
<td class="text-left" style="width: 3%;">{{ item.SlNo }}</td>
|
||||||
|
<td class="text-left">{{ item.PrdDesc }}</td>
|
||||||
|
<td class="text-left" style="width: 10%;">{{ item.HsnCd }}</td>
|
||||||
|
<td class="text-right" style="width: 5%;">{{ item.Qty }}</td>
|
||||||
|
<td class="text-left" style="width: 5%;">{{ item.Unit }}</td>
|
||||||
|
<td class="text-right">{{ frappe.utils.fmt_money(item.UnitPrice, None, "INR") }}</td>
|
||||||
|
<td class="text-right" style="width: 5%;">{{ frappe.utils.fmt_money(item.Discount, None, "INR") }}</td>
|
||||||
|
<td class="text-right">{{ frappe.utils.fmt_money(item.AssAmt, None, "INR") }}</td>
|
||||||
|
<td class="text-right" style="width: 7%;">{{ item.GstRt + item.CesRt }} %</td>
|
||||||
|
<td class="text-right" style="width: 5%;">{{ frappe.utils.fmt_money(0, None, "INR") }}</td>
|
||||||
|
<td class="text-right">{{ frappe.utils.fmt_money(item.TotItemVal, None, "INR") }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div style="overflow-x: auto;">
|
||||||
|
<h5 class="font-bold" style="margin-bottom: 0px;">4. Value Details</h5>
|
||||||
|
<table class="table table-bordered">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="text-left">Taxable Amount</th>
|
||||||
|
<th class="text-left">CGST</th>
|
||||||
|
<th class="text-left"">SGST</th>
|
||||||
|
<th class="text-left">IGST</th>
|
||||||
|
<th class="text-left">CESS</th>
|
||||||
|
<th class="text-left" style="width: 10%;">State CESS</th>
|
||||||
|
<th class="text-left">Discount</th>
|
||||||
|
<th class="text-left" style="width: 10%;">Other Charges</th>
|
||||||
|
<th class="text-left" style="width: 10%;">Round Off</th>
|
||||||
|
<th class="text-left">Total Value</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{%- set value_details = einvoice.ValDtls -%}
|
||||||
|
<tr>
|
||||||
|
<td class="text-right">{{ frappe.utils.fmt_money(value_details.AssVal, None, "INR") }}</td>
|
||||||
|
<td class="text-right">{{ frappe.utils.fmt_money(value_details.CgstVal, None, "INR") }}</td>
|
||||||
|
<td class="text-right">{{ frappe.utils.fmt_money(value_details.SgstVal, None, "INR") }}</td>
|
||||||
|
<td class="text-right">{{ frappe.utils.fmt_money(value_details.IgstVal, None, "INR") }}</td>
|
||||||
|
<td class="text-right">{{ frappe.utils.fmt_money(value_details.CesVal, None, "INR") }}</td>
|
||||||
|
<td class="text-right">{{ frappe.utils.fmt_money(0, None, "INR") }}</td>
|
||||||
|
<td class="text-right">{{ frappe.utils.fmt_money(value_details.Discount, None, "INR") }}</td>
|
||||||
|
<td class="text-right">{{ frappe.utils.fmt_money(value_details.OthChrg, None, "INR") }}</td>
|
||||||
|
<td class="text-right">{{ frappe.utils.fmt_money(value_details.RndOffAmt, None, "INR") }}</td>
|
||||||
|
<td class="text-right">{{ frappe.utils.fmt_money(value_details.TotInvVal, None, "INR") }}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"align_labels_right": 1,
|
||||||
|
"creation": "2020-10-10 18:01:21.032914",
|
||||||
|
"custom_format": 0,
|
||||||
|
"default_print_language": "en-US",
|
||||||
|
"disabled": 1,
|
||||||
|
"doc_type": "Sales Invoice",
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "Print Format",
|
||||||
|
"font": "Default",
|
||||||
|
"html": "",
|
||||||
|
"idx": 0,
|
||||||
|
"line_breaks": 1,
|
||||||
|
"modified": "2020-10-23 19:54:40.634936",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "Accounts",
|
||||||
|
"name": "GST E-Invoice",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"print_format_builder": 0,
|
||||||
|
"print_format_type": "Jinja",
|
||||||
|
"raw_printing": 0,
|
||||||
|
"show_section_headings": 1,
|
||||||
|
"standard": "Yes"
|
||||||
|
}
|
@ -167,9 +167,14 @@ class AccountsController(TransactionBase):
|
|||||||
|
|
||||||
validate_regional(self)
|
validate_regional(self)
|
||||||
|
|
||||||
|
validate_einvoice_fields(self)
|
||||||
|
|
||||||
if self.doctype != 'Material Request':
|
if self.doctype != 'Material Request':
|
||||||
apply_pricing_rule_on_transaction(self)
|
apply_pricing_rule_on_transaction(self)
|
||||||
|
|
||||||
|
def before_cancel(self):
|
||||||
|
validate_einvoice_fields(self)
|
||||||
|
|
||||||
def on_trash(self):
|
def on_trash(self):
|
||||||
# delete sl and gl entries on deletion of transaction
|
# delete sl and gl entries on deletion of transaction
|
||||||
if frappe.db.get_single_value('Accounts Settings', 'delete_linked_ledger_entries'):
|
if frappe.db.get_single_value('Accounts Settings', 'delete_linked_ledger_entries'):
|
||||||
@ -2151,3 +2156,7 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil
|
|||||||
@erpnext.allow_regional
|
@erpnext.allow_regional
|
||||||
def validate_regional(doc):
|
def validate_regional(doc):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@erpnext.allow_regional
|
||||||
|
def validate_einvoice_fields(doc):
|
||||||
|
pass
|
||||||
|
@ -443,6 +443,7 @@ regional_overrides = {
|
|||||||
'erpnext.controllers.taxes_and_totals.get_regional_round_off_accounts': 'erpnext.regional.india.utils.get_regional_round_off_accounts',
|
'erpnext.controllers.taxes_and_totals.get_regional_round_off_accounts': 'erpnext.regional.india.utils.get_regional_round_off_accounts',
|
||||||
'erpnext.hr.utils.calculate_annual_eligible_hra_exemption': 'erpnext.regional.india.utils.calculate_annual_eligible_hra_exemption',
|
'erpnext.hr.utils.calculate_annual_eligible_hra_exemption': 'erpnext.regional.india.utils.calculate_annual_eligible_hra_exemption',
|
||||||
'erpnext.hr.utils.calculate_hra_exemption_for_period': 'erpnext.regional.india.utils.calculate_hra_exemption_for_period',
|
'erpnext.hr.utils.calculate_hra_exemption_for_period': 'erpnext.regional.india.utils.calculate_hra_exemption_for_period',
|
||||||
|
'erpnext.controllers.accounts_controller.validate_einvoice_fields': 'erpnext.regional.india.e_invoice.utils.validate_einvoice_fields',
|
||||||
'erpnext.assets.doctype.asset.asset.get_depreciation_amount': 'erpnext.regional.india.utils.get_depreciation_amount',
|
'erpnext.assets.doctype.asset.asset.get_depreciation_amount': 'erpnext.regional.india.utils.get_depreciation_amount',
|
||||||
'erpnext.stock.doctype.item.item.set_item_tax_from_hsn_code': 'erpnext.regional.india.utils.set_item_tax_from_hsn_code'
|
'erpnext.stock.doctype.item.item.set_item_tax_from_hsn_code': 'erpnext.regional.india.utils.set_item_tax_from_hsn_code'
|
||||||
},
|
},
|
||||||
|
@ -203,6 +203,7 @@ 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_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
|
erpnext.patches.v13_0.move_payroll_setting_separately_from_hr_settings #22-06-2020
|
||||||
erpnext.patches.v12_0.create_itc_reversal_custom_fields
|
erpnext.patches.v12_0.create_itc_reversal_custom_fields
|
||||||
|
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.check_is_income_tax_component #22-06-2020
|
||||||
erpnext.patches.v13_0.loyalty_points_entry_for_pos_invoice #22-07-2020
|
erpnext.patches.v13_0.loyalty_points_entry_for_pos_invoice #22-07-2020
|
||||||
erpnext.patches.v12_0.add_taxjar_integration_field
|
erpnext.patches.v12_0.add_taxjar_integration_field
|
||||||
@ -223,6 +224,7 @@ erpnext.patches.v13_0.set_youtube_video_id
|
|||||||
erpnext.patches.v13_0.set_app_name
|
erpnext.patches.v13_0.set_app_name
|
||||||
erpnext.patches.v13_0.print_uom_after_quantity_patch
|
erpnext.patches.v13_0.print_uom_after_quantity_patch
|
||||||
erpnext.patches.v13_0.set_payment_channel_in_payment_gateway_account
|
erpnext.patches.v13_0.set_payment_channel_in_payment_gateway_account
|
||||||
|
erpnext.patches.v12_0.setup_einvoice_fields #2020-12-02
|
||||||
erpnext.patches.v13_0.updates_for_multi_currency_payroll
|
erpnext.patches.v13_0.updates_for_multi_currency_payroll
|
||||||
erpnext.patches.v13_0.update_reason_for_resignation_in_employee
|
erpnext.patches.v13_0.update_reason_for_resignation_in_employee
|
||||||
execute:frappe.delete_doc("Report", "Quoted Item Comparison")
|
execute:frappe.delete_doc("Report", "Quoted Item Comparison")
|
||||||
@ -241,12 +243,15 @@ erpnext.patches.v13_0.update_payment_terms_outstanding
|
|||||||
erpnext.patches.v12_0.add_state_code_for_ladakh
|
erpnext.patches.v12_0.add_state_code_for_ladakh
|
||||||
erpnext.patches.v13_0.item_reposting_for_incorrect_sl_and_gl
|
erpnext.patches.v13_0.item_reposting_for_incorrect_sl_and_gl
|
||||||
erpnext.patches.v13_0.delete_old_bank_reconciliation_doctypes
|
erpnext.patches.v13_0.delete_old_bank_reconciliation_doctypes
|
||||||
erpnext.patches.v13_0.update_vehicle_no_reqd_condition
|
erpnext.patches.v12_0.update_vehicle_no_reqd_condition
|
||||||
|
erpnext.patches.v12_0.add_einvoice_status_field #2021-03-17
|
||||||
|
erpnext.patches.v12_0.add_einvoice_summary_report_permissions
|
||||||
erpnext.patches.v13_0.setup_fields_for_80g_certificate_and_donation
|
erpnext.patches.v13_0.setup_fields_for_80g_certificate_and_donation
|
||||||
erpnext.patches.v13_0.rename_membership_settings_to_non_profit_settings
|
erpnext.patches.v13_0.rename_membership_settings_to_non_profit_settings
|
||||||
erpnext.patches.v13_0.setup_gratuity_rule_for_india_and_uae
|
erpnext.patches.v13_0.setup_gratuity_rule_for_india_and_uae
|
||||||
erpnext.patches.v13_0.setup_uae_vat_fields
|
erpnext.patches.v13_0.setup_uae_vat_fields
|
||||||
execute:frappe.db.set_value('System Settings', None, 'app_name', 'ERPNext')
|
execute:frappe.db.set_value('System Settings', None, 'app_name', 'ERPNext')
|
||||||
|
erpnext.patches.v12_0.add_company_link_to_einvoice_settings
|
||||||
erpnext.patches.v12_0.create_taxable_value_field
|
erpnext.patches.v12_0.create_taxable_value_field
|
||||||
erpnext.patches.v12_0.add_gst_category_in_delivery_note
|
erpnext.patches.v12_0.add_gst_category_in_delivery_note
|
||||||
erpnext.patches.v12_0.purchase_receipt_status
|
erpnext.patches.v12_0.purchase_receipt_status
|
||||||
@ -255,6 +260,7 @@ erpnext.patches.v12_0.add_document_type_field_for_italy_einvoicing
|
|||||||
erpnext.patches.v13_0.make_non_standard_user_type #13-04-2021 #17-01-2022
|
erpnext.patches.v13_0.make_non_standard_user_type #13-04-2021 #17-01-2022
|
||||||
erpnext.patches.v13_0.update_shipment_status
|
erpnext.patches.v13_0.update_shipment_status
|
||||||
erpnext.patches.v13_0.remove_attribute_field_from_item_variant_setting
|
erpnext.patches.v13_0.remove_attribute_field_from_item_variant_setting
|
||||||
|
erpnext.patches.v12_0.add_ewaybill_validity_field
|
||||||
erpnext.patches.v13_0.germany_make_custom_fields
|
erpnext.patches.v13_0.germany_make_custom_fields
|
||||||
erpnext.patches.v13_0.germany_fill_debtor_creditor_number
|
erpnext.patches.v13_0.germany_fill_debtor_creditor_number
|
||||||
erpnext.patches.v13_0.set_pos_closing_as_failed
|
erpnext.patches.v13_0.set_pos_closing_as_failed
|
||||||
@ -271,6 +277,7 @@ erpnext.patches.v13_0.update_level_in_bom #1234sswef
|
|||||||
erpnext.patches.v13_0.add_missing_fg_item_for_stock_entry
|
erpnext.patches.v13_0.add_missing_fg_item_for_stock_entry
|
||||||
erpnext.patches.v13_0.update_subscription_status_in_memberships
|
erpnext.patches.v13_0.update_subscription_status_in_memberships
|
||||||
erpnext.patches.v13_0.update_amt_in_work_order_required_items
|
erpnext.patches.v13_0.update_amt_in_work_order_required_items
|
||||||
|
erpnext.patches.v12_0.show_einvoice_irn_cancelled_field
|
||||||
erpnext.patches.v13_0.delete_orphaned_tables
|
erpnext.patches.v13_0.delete_orphaned_tables
|
||||||
erpnext.patches.v13_0.update_export_type_for_gst #2021-08-16
|
erpnext.patches.v13_0.update_export_type_for_gst #2021-08-16
|
||||||
erpnext.patches.v13_0.update_tds_check_field #3
|
erpnext.patches.v13_0.update_tds_check_field #3
|
||||||
@ -327,10 +334,10 @@ erpnext.patches.v13_0.delete_bank_reconciliation_detail
|
|||||||
[post_model_sync]
|
[post_model_sync]
|
||||||
erpnext.patches.v14_0.rename_ongoing_status_in_sla_documents
|
erpnext.patches.v14_0.rename_ongoing_status_in_sla_documents
|
||||||
erpnext.patches.v14_0.add_default_exit_questionnaire_notification_template
|
erpnext.patches.v14_0.add_default_exit_questionnaire_notification_template
|
||||||
erpnext.patches.v14_0.delete_einvoicing_doctypes
|
|
||||||
erpnext.patches.v14_0.delete_shopify_doctypes
|
erpnext.patches.v14_0.delete_shopify_doctypes
|
||||||
erpnext.patches.v14_0.delete_hub_doctypes
|
erpnext.patches.v14_0.delete_hub_doctypes
|
||||||
erpnext.patches.v14_0.delete_hospitality_doctypes # 20-01-2022
|
erpnext.patches.v14_0.delete_hospitality_doctypes # 20-01-2022
|
||||||
erpnext.patches.v14_0.delete_agriculture_doctypes
|
erpnext.patches.v14_0.delete_agriculture_doctypes
|
||||||
erpnext.patches.v14_0.rearrange_company_fields
|
erpnext.patches.v14_0.rearrange_company_fields
|
||||||
erpnext.patches.v14_0.update_leave_notification_template
|
erpnext.patches.v14_0.update_leave_notification_template
|
||||||
|
erpnext.patches.v14_0.restore_einvoice_fields
|
@ -0,0 +1,18 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import frappe
|
||||||
|
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
company = frappe.get_all('Company', filters = {'country': 'India'})
|
||||||
|
if not company or not frappe.db.count('E Invoice User'):
|
||||||
|
return
|
||||||
|
|
||||||
|
frappe.reload_doc("regional", "doctype", "e_invoice_user")
|
||||||
|
for creds in frappe.db.get_all('E Invoice User', fields=['name', 'gstin']):
|
||||||
|
company_name = frappe.db.sql("""
|
||||||
|
select dl.link_name from `tabAddress` a, `tabDynamic Link` dl
|
||||||
|
where a.gstin = %s and dl.parent = a.name and dl.link_doctype = 'Company'
|
||||||
|
""", (creds.get('gstin')))
|
||||||
|
if company_name and len(company_name) > 0:
|
||||||
|
frappe.db.set_value('E Invoice User', creds.get('name'), 'company', company_name[0][0])
|
72
erpnext/patches/v12_0/add_einvoice_status_field.py
Normal file
72
erpnext/patches/v12_0/add_einvoice_status_field.py
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import json
|
||||||
|
|
||||||
|
import frappe
|
||||||
|
from frappe.custom.doctype.custom_field.custom_field import create_custom_fields
|
||||||
|
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
company = frappe.get_all('Company', filters = {'country': 'India'})
|
||||||
|
if not company:
|
||||||
|
return
|
||||||
|
|
||||||
|
# move hidden einvoice fields to a different section
|
||||||
|
custom_fields = {
|
||||||
|
'Sales Invoice': [
|
||||||
|
dict(fieldname='einvoice_section', label='E-Invoice Fields', fieldtype='Section Break', insert_after='gst_vehicle_type',
|
||||||
|
print_hide=1, hidden=1),
|
||||||
|
|
||||||
|
dict(fieldname='ack_no', label='Ack. No.', fieldtype='Data', read_only=1, hidden=1, insert_after='einvoice_section',
|
||||||
|
no_copy=1, print_hide=1),
|
||||||
|
|
||||||
|
dict(fieldname='ack_date', label='Ack. Date', fieldtype='Data', read_only=1, hidden=1, insert_after='ack_no', no_copy=1, print_hide=1),
|
||||||
|
|
||||||
|
dict(fieldname='irn_cancel_date', label='Cancel Date', fieldtype='Data', read_only=1, hidden=1, insert_after='ack_date',
|
||||||
|
no_copy=1, print_hide=1),
|
||||||
|
|
||||||
|
dict(fieldname='signed_einvoice', label='Signed E-Invoice', fieldtype='Code', options='JSON', hidden=1, insert_after='irn_cancel_date',
|
||||||
|
no_copy=1, print_hide=1, read_only=1),
|
||||||
|
|
||||||
|
dict(fieldname='signed_qr_code', label='Signed QRCode', fieldtype='Code', options='JSON', hidden=1, insert_after='signed_einvoice',
|
||||||
|
no_copy=1, print_hide=1, read_only=1),
|
||||||
|
|
||||||
|
dict(fieldname='qrcode_image', label='QRCode', fieldtype='Attach Image', hidden=1, insert_after='signed_qr_code',
|
||||||
|
no_copy=1, print_hide=1, read_only=1),
|
||||||
|
|
||||||
|
dict(fieldname='einvoice_status', label='E-Invoice Status', fieldtype='Select', insert_after='qrcode_image',
|
||||||
|
options='\nPending\nGenerated\nCancelled\nFailed', default=None, hidden=1, no_copy=1, print_hide=1, read_only=1),
|
||||||
|
|
||||||
|
dict(fieldname='failure_description', label='E-Invoice Failure Description', fieldtype='Code', options='JSON',
|
||||||
|
hidden=1, insert_after='einvoice_status', no_copy=1, print_hide=1, read_only=1)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
create_custom_fields(custom_fields, update=True)
|
||||||
|
|
||||||
|
if frappe.db.exists('E Invoice Settings') and frappe.db.get_single_value('E Invoice Settings', 'enable'):
|
||||||
|
frappe.db.sql('''
|
||||||
|
UPDATE `tabSales Invoice` SET einvoice_status = 'Pending'
|
||||||
|
WHERE
|
||||||
|
posting_date >= '2021-04-01'
|
||||||
|
AND ifnull(irn, '') = ''
|
||||||
|
AND ifnull(`billing_address_gstin`, '') != ifnull(`company_gstin`, '')
|
||||||
|
AND ifnull(gst_category, '') in ('Registered Regular', 'SEZ', 'Overseas', 'Deemed Export')
|
||||||
|
''')
|
||||||
|
|
||||||
|
# set appropriate statuses
|
||||||
|
frappe.db.sql('''UPDATE `tabSales Invoice` SET einvoice_status = 'Generated'
|
||||||
|
WHERE ifnull(irn, '') != '' AND ifnull(irn_cancelled, 0) = 0''')
|
||||||
|
|
||||||
|
frappe.db.sql('''UPDATE `tabSales Invoice` SET einvoice_status = 'Cancelled'
|
||||||
|
WHERE ifnull(irn_cancelled, 0) = 1''')
|
||||||
|
|
||||||
|
# set correct acknowledgement in e-invoices
|
||||||
|
einvoices = frappe.get_all('Sales Invoice', {'irn': ['is', 'set']}, ['name', 'signed_einvoice'])
|
||||||
|
|
||||||
|
if einvoices:
|
||||||
|
for inv in einvoices:
|
||||||
|
signed_einvoice = inv.get('signed_einvoice')
|
||||||
|
if signed_einvoice:
|
||||||
|
signed_einvoice = json.loads(signed_einvoice)
|
||||||
|
frappe.db.set_value('Sales Invoice', inv.get('name'), 'ack_no', signed_einvoice.get('AckNo'), update_modified=False)
|
||||||
|
frappe.db.set_value('Sales Invoice', inv.get('name'), 'ack_date', signed_einvoice.get('AckDt'), update_modified=False)
|
@ -0,0 +1,20 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import frappe
|
||||||
|
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
company = frappe.get_all('Company', filters = {'country': 'India'})
|
||||||
|
if not company:
|
||||||
|
return
|
||||||
|
|
||||||
|
if frappe.db.exists('Report', 'E-Invoice Summary') and \
|
||||||
|
not frappe.db.get_value('Custom Role', dict(report='E-Invoice Summary')):
|
||||||
|
frappe.get_doc(dict(
|
||||||
|
doctype='Custom Role',
|
||||||
|
report='E-Invoice Summary',
|
||||||
|
roles= [
|
||||||
|
dict(role='Accounts User'),
|
||||||
|
dict(role='Accounts Manager')
|
||||||
|
]
|
||||||
|
)).insert()
|
18
erpnext/patches/v12_0/add_ewaybill_validity_field.py
Normal file
18
erpnext/patches/v12_0/add_ewaybill_validity_field.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import frappe
|
||||||
|
from frappe.custom.doctype.custom_field.custom_field import create_custom_fields
|
||||||
|
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
company = frappe.get_all('Company', filters = {'country': 'India'})
|
||||||
|
if not company:
|
||||||
|
return
|
||||||
|
|
||||||
|
custom_fields = {
|
||||||
|
'Sales Invoice': [
|
||||||
|
dict(fieldname='eway_bill_validity', label='E-Way Bill Validity', fieldtype='Data', no_copy=1, print_hide=1,
|
||||||
|
depends_on='ewaybill', read_only=1, allow_on_submit=1, insert_after='ewaybill')
|
||||||
|
]
|
||||||
|
}
|
||||||
|
create_custom_fields(custom_fields, update=True)
|
59
erpnext/patches/v12_0/setup_einvoice_fields.py
Normal file
59
erpnext/patches/v12_0/setup_einvoice_fields.py
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import frappe
|
||||||
|
from frappe.custom.doctype.custom_field.custom_field import create_custom_fields
|
||||||
|
|
||||||
|
from erpnext.regional.india.setup import add_permissions, add_print_formats
|
||||||
|
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
company = frappe.get_all('Company', filters = {'country': 'India'})
|
||||||
|
if not company:
|
||||||
|
return
|
||||||
|
|
||||||
|
frappe.reload_doc("custom", "doctype", "custom_field")
|
||||||
|
frappe.reload_doc("regional", "doctype", "e_invoice_settings")
|
||||||
|
custom_fields = {
|
||||||
|
'Sales Invoice': [
|
||||||
|
dict(fieldname='irn', label='IRN', fieldtype='Data', read_only=1, insert_after='customer', no_copy=1, print_hide=1,
|
||||||
|
depends_on='eval:in_list(["Registered Regular", "SEZ", "Overseas", "Deemed Export"], doc.gst_category) && doc.irn_cancelled === 0'),
|
||||||
|
|
||||||
|
dict(fieldname='ack_no', label='Ack. No.', fieldtype='Data', read_only=1, hidden=1, insert_after='irn', no_copy=1, print_hide=1),
|
||||||
|
|
||||||
|
dict(fieldname='ack_date', label='Ack. Date', fieldtype='Data', read_only=1, hidden=1, insert_after='ack_no', no_copy=1, print_hide=1),
|
||||||
|
|
||||||
|
dict(fieldname='irn_cancelled', label='IRN Cancelled', fieldtype='Check', no_copy=1, print_hide=1,
|
||||||
|
depends_on='eval:(doc.irn_cancelled === 1)', read_only=1, allow_on_submit=1, insert_after='customer'),
|
||||||
|
|
||||||
|
dict(fieldname='eway_bill_cancelled', label='E-Way Bill Cancelled', fieldtype='Check', no_copy=1, print_hide=1,
|
||||||
|
depends_on='eval:(doc.eway_bill_cancelled === 1)', read_only=1, allow_on_submit=1, insert_after='customer'),
|
||||||
|
|
||||||
|
dict(fieldname='signed_einvoice', fieldtype='Code', options='JSON', hidden=1, no_copy=1, print_hide=1, read_only=1),
|
||||||
|
|
||||||
|
dict(fieldname='signed_qr_code', fieldtype='Code', options='JSON', hidden=1, no_copy=1, print_hide=1, read_only=1),
|
||||||
|
|
||||||
|
dict(fieldname='qrcode_image', label='QRCode', fieldtype='Attach Image', hidden=1, no_copy=1, print_hide=1, read_only=1)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
create_custom_fields(custom_fields, update=True)
|
||||||
|
add_permissions()
|
||||||
|
add_print_formats()
|
||||||
|
|
||||||
|
einvoice_cond = 'in_list(["Registered Regular", "SEZ", "Overseas", "Deemed Export"], doc.gst_category)'
|
||||||
|
t = {
|
||||||
|
'mode_of_transport': [{'default': None}],
|
||||||
|
'distance': [{'mandatory_depends_on': f'eval:{einvoice_cond} && doc.transporter'}],
|
||||||
|
'gst_vehicle_type': [{'mandatory_depends_on': f'eval:{einvoice_cond} && doc.mode_of_transport == "Road"'}],
|
||||||
|
'lr_date': [{'mandatory_depends_on': f'eval:{einvoice_cond} && in_list(["Air", "Ship", "Rail"], doc.mode_of_transport)'}],
|
||||||
|
'lr_no': [{'mandatory_depends_on': f'eval:{einvoice_cond} && in_list(["Air", "Ship", "Rail"], doc.mode_of_transport)'}],
|
||||||
|
'vehicle_no': [{'mandatory_depends_on': f'eval:{einvoice_cond} && doc.mode_of_transport == "Road"'}],
|
||||||
|
'ewaybill': [
|
||||||
|
{'read_only_depends_on': 'eval:doc.irn && doc.ewaybill'},
|
||||||
|
{'depends_on': 'eval:((doc.docstatus === 1 || doc.ewaybill) && doc.eway_bill_cancelled === 0)'}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
for field, conditions in t.items():
|
||||||
|
for c in conditions:
|
||||||
|
[(prop, value)] = c.items()
|
||||||
|
frappe.db.set_value('Custom Field', { 'fieldname': field }, prop, value)
|
14
erpnext/patches/v12_0/show_einvoice_irn_cancelled_field.py
Normal file
14
erpnext/patches/v12_0/show_einvoice_irn_cancelled_field.py
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import frappe
|
||||||
|
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
company = frappe.get_all('Company', filters = {'country': 'India'})
|
||||||
|
if not company:
|
||||||
|
return
|
||||||
|
|
||||||
|
irn_cancelled_field = frappe.db.exists('Custom Field', {'dt': 'Sales Invoice', 'fieldname': 'irn_cancelled'})
|
||||||
|
if irn_cancelled_field:
|
||||||
|
frappe.db.set_value('Custom Field', irn_cancelled_field, 'depends_on', 'eval: doc.irn')
|
||||||
|
frappe.db.set_value('Custom Field', irn_cancelled_field, 'read_only', 0)
|
@ -1,9 +0,0 @@
|
|||||||
import click
|
|
||||||
|
|
||||||
|
|
||||||
def execute():
|
|
||||||
click.secho(
|
|
||||||
"Indian E-Invoicing integration is moved to a separate app and will be removed from ERPNext in version-14.\n"
|
|
||||||
"Please install the app to continue using the integration: https://github.com/frappe/erpnext_gst_compliance",
|
|
||||||
fg="yellow",
|
|
||||||
)
|
|
@ -1,10 +0,0 @@
|
|||||||
import frappe
|
|
||||||
|
|
||||||
|
|
||||||
def execute():
|
|
||||||
frappe.delete_doc('DocType', 'E Invoice Settings', ignore_missing=True)
|
|
||||||
frappe.delete_doc('DocType', 'E Invoice User', ignore_missing=True)
|
|
||||||
frappe.delete_doc('Report', 'E-Invoice Summary', ignore_missing=True)
|
|
||||||
frappe.delete_doc('Print Format', 'GST E-Invoice', ignore_missing=True)
|
|
||||||
frappe.delete_doc('Custom Field', 'Sales Invoice-eway_bill_cancelled', ignore_missing=True)
|
|
||||||
frappe.delete_doc('Custom Field', 'Sales Invoice-irn_cancelled', ignore_missing=True)
|
|
24
erpnext/patches/v14_0/restore_einvoice_fields.py
Normal file
24
erpnext/patches/v14_0/restore_einvoice_fields.py
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import frappe
|
||||||
|
from frappe.custom.doctype.custom_field.custom_field import create_custom_fields
|
||||||
|
|
||||||
|
from erpnext.regional.india.setup import add_permissions, add_print_formats
|
||||||
|
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
# restores back the 2 custom fields that was deleted while removing e-invoicing from v14
|
||||||
|
company = frappe.get_all('Company', filters = {'country': 'India'})
|
||||||
|
if not company:
|
||||||
|
return
|
||||||
|
|
||||||
|
custom_fields = {
|
||||||
|
'Sales Invoice': [
|
||||||
|
dict(fieldname='irn_cancelled', label='IRN Cancelled', fieldtype='Check', no_copy=1, print_hide=1,
|
||||||
|
depends_on='eval:(doc.irn_cancelled === 1)', read_only=1, allow_on_submit=1, insert_after='customer'),
|
||||||
|
|
||||||
|
dict(fieldname='eway_bill_cancelled', label='E-Way Bill Cancelled', fieldtype='Check', no_copy=1, print_hide=1,
|
||||||
|
depends_on='eval:(doc.eway_bill_cancelled === 1)', read_only=1, allow_on_submit=1, insert_after='customer'),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
create_custom_fields(custom_fields, update=True)
|
||||||
|
add_permissions()
|
||||||
|
add_print_formats()
|
@ -0,0 +1,8 @@
|
|||||||
|
// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
// For license information, please see license.txt
|
||||||
|
|
||||||
|
frappe.ui.form.on('E Invoice Request Log', {
|
||||||
|
// refresh: function(frm) {
|
||||||
|
|
||||||
|
// }
|
||||||
|
});
|
@ -0,0 +1,102 @@
|
|||||||
|
{
|
||||||
|
"actions": [],
|
||||||
|
"autoname": "EINV-REQ-.#####",
|
||||||
|
"creation": "2020-12-08 12:54:08.175992",
|
||||||
|
"doctype": "DocType",
|
||||||
|
"editable_grid": 1,
|
||||||
|
"engine": "InnoDB",
|
||||||
|
"field_order": [
|
||||||
|
"user",
|
||||||
|
"url",
|
||||||
|
"headers",
|
||||||
|
"response",
|
||||||
|
"column_break_7",
|
||||||
|
"timestamp",
|
||||||
|
"reference_invoice",
|
||||||
|
"data"
|
||||||
|
],
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldname": "user",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "User",
|
||||||
|
"options": "User"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "reference_invoice",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"label": "Reference Invoice"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "headers",
|
||||||
|
"fieldtype": "Code",
|
||||||
|
"label": "Headers",
|
||||||
|
"options": "JSON"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "data",
|
||||||
|
"fieldtype": "Code",
|
||||||
|
"label": "Data",
|
||||||
|
"options": "JSON"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "Now",
|
||||||
|
"fieldname": "timestamp",
|
||||||
|
"fieldtype": "Datetime",
|
||||||
|
"label": "Timestamp"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "response",
|
||||||
|
"fieldtype": "Code",
|
||||||
|
"label": "Response",
|
||||||
|
"options": "JSON"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "url",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"label": "URL"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "column_break_7",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"index_web_pages_for_search": 1,
|
||||||
|
"links": [],
|
||||||
|
"modified": "2021-01-13 12:06:57.253111",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "Regional",
|
||||||
|
"name": "E Invoice Request Log",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"permissions": [
|
||||||
|
{
|
||||||
|
"email": 1,
|
||||||
|
"export": 1,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"report": 1,
|
||||||
|
"role": "System Manager",
|
||||||
|
"share": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"email": 1,
|
||||||
|
"export": 1,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"report": 1,
|
||||||
|
"role": "Accounts User",
|
||||||
|
"share": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"email": 1,
|
||||||
|
"export": 1,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"report": 1,
|
||||||
|
"role": "Accounts Manager",
|
||||||
|
"share": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"sort_field": "modified",
|
||||||
|
"sort_order": "DESC"
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (c) 2020, 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
|
||||||
|
|
||||||
|
|
||||||
|
class EInvoiceRequestLog(Document):
|
||||||
|
pass
|
@ -0,0 +1,11 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
|
# See license.txt
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
# import frappe
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
|
||||||
|
class TestEInvoiceRequestLog(unittest.TestCase):
|
||||||
|
pass
|
@ -0,0 +1,11 @@
|
|||||||
|
// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
// For license information, please see license.txt
|
||||||
|
|
||||||
|
frappe.ui.form.on('E Invoice Settings', {
|
||||||
|
refresh(frm) {
|
||||||
|
const docs_link = 'https://docs.erpnext.com/docs/v13/user/manual/en/regional/india/setup-e-invoicing';
|
||||||
|
frm.dashboard.set_headline(
|
||||||
|
__("Read {0} for more information on E Invoicing features.", [`<a href='${docs_link}'>documentation</a>`])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +1,73 @@
|
|||||||
|
{
|
||||||
|
"actions": [],
|
||||||
|
"creation": "2020-09-24 16:23:16.235722",
|
||||||
|
"doctype": "DocType",
|
||||||
|
"editable_grid": 1,
|
||||||
|
"engine": "InnoDB",
|
||||||
|
"field_order": [
|
||||||
|
"enable",
|
||||||
|
"section_break_2",
|
||||||
|
"sandbox_mode",
|
||||||
|
"applicable_from",
|
||||||
|
"credentials",
|
||||||
|
"auth_token",
|
||||||
|
"token_expiry"
|
||||||
|
],
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"fieldname": "enable",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Enable"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "enable",
|
||||||
|
"fieldname": "section_break_2",
|
||||||
|
"fieldtype": "Section Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "auth_token",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"hidden": 1,
|
||||||
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "token_expiry",
|
||||||
|
"fieldtype": "Datetime",
|
||||||
|
"hidden": 1,
|
||||||
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "credentials",
|
||||||
|
"fieldtype": "Table",
|
||||||
|
"label": "Credentials",
|
||||||
|
"mandatory_depends_on": "enable",
|
||||||
|
"options": "E Invoice User"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"fieldname": "sandbox_mode",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Sandbox Mode"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "applicable_from",
|
||||||
|
"fieldtype": "Date",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "Applicable From",
|
||||||
|
"reqd": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"index_web_pages_for_search": 1,
|
||||||
|
"issingle": 1,
|
||||||
|
"links": [],
|
||||||
|
"modified": "2021-03-30 12:26:25.538294",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "Regional",
|
||||||
|
"name": "E Invoice Settings",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"permissions": [],
|
||||||
|
"sort_field": "modified",
|
||||||
|
"sort_order": "DESC",
|
||||||
|
"track_changes": 1
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import frappe
|
||||||
|
from frappe import _
|
||||||
|
from frappe.model.document import Document
|
||||||
|
|
||||||
|
|
||||||
|
class EInvoiceSettings(Document):
|
||||||
|
def validate(self):
|
||||||
|
if self.enable and not self.credentials:
|
||||||
|
frappe.throw(_('You must add atleast one credentials to be able to use E Invoicing.'))
|
@ -0,0 +1,11 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
|
# See license.txt
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
# import frappe
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
|
||||||
|
class TestEInvoiceSettings(unittest.TestCase):
|
||||||
|
pass
|
0
erpnext/regional/doctype/e_invoice_user/__init__.py
Normal file
0
erpnext/regional/doctype/e_invoice_user/__init__.py
Normal file
57
erpnext/regional/doctype/e_invoice_user/e_invoice_user.json
Normal file
57
erpnext/regional/doctype/e_invoice_user/e_invoice_user.json
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
{
|
||||||
|
"actions": [],
|
||||||
|
"creation": "2020-12-22 15:02:46.229474",
|
||||||
|
"doctype": "DocType",
|
||||||
|
"editable_grid": 1,
|
||||||
|
"engine": "InnoDB",
|
||||||
|
"field_order": [
|
||||||
|
"company",
|
||||||
|
"gstin",
|
||||||
|
"username",
|
||||||
|
"password"
|
||||||
|
],
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldname": "gstin",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "GSTIN",
|
||||||
|
"reqd": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "username",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "Username",
|
||||||
|
"reqd": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "password",
|
||||||
|
"fieldtype": "Password",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "Password",
|
||||||
|
"reqd": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "company",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "Company",
|
||||||
|
"options": "Company",
|
||||||
|
"reqd": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"index_web_pages_for_search": 1,
|
||||||
|
"istable": 1,
|
||||||
|
"links": [],
|
||||||
|
"modified": "2021-03-22 12:16:56.365616",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "Regional",
|
||||||
|
"name": "E Invoice User",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"permissions": [],
|
||||||
|
"quick_entry": 1,
|
||||||
|
"sort_field": "modified",
|
||||||
|
"sort_order": "DESC",
|
||||||
|
"track_changes": 1
|
||||||
|
}
|
12
erpnext/regional/doctype/e_invoice_user/e_invoice_user.py
Normal file
12
erpnext/regional/doctype/e_invoice_user/e_invoice_user.py
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (c) 2020, 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
|
||||||
|
|
||||||
|
|
||||||
|
class EInvoiceUser(Document):
|
||||||
|
pass
|
0
erpnext/regional/india/e_invoice/__init__.py
Normal file
0
erpnext/regional/india/e_invoice/__init__.py
Normal file
31
erpnext/regional/india/e_invoice/einv_item_template.json
Normal file
31
erpnext/regional/india/e_invoice/einv_item_template.json
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
{{
|
||||||
|
"SlNo": "{item.sr_no}",
|
||||||
|
"PrdDesc": "{item.description}",
|
||||||
|
"IsServc": "{item.is_service_item}",
|
||||||
|
"HsnCd": "{item.gst_hsn_code}",
|
||||||
|
"Barcde": "{item.barcode}",
|
||||||
|
"Unit": "{item.uom}",
|
||||||
|
"Qty": "{item.qty}",
|
||||||
|
"FreeQty": "{item.free_qty}",
|
||||||
|
"UnitPrice": "{item.unit_rate}",
|
||||||
|
"TotAmt": "{item.gross_amount}",
|
||||||
|
"Discount": "{item.discount_amount}",
|
||||||
|
"AssAmt": "{item.taxable_value}",
|
||||||
|
"PrdSlNo": "{item.serial_no}",
|
||||||
|
"GstRt": "{item.tax_rate}",
|
||||||
|
"IgstAmt": "{item.igst_amount}",
|
||||||
|
"CgstAmt": "{item.cgst_amount}",
|
||||||
|
"SgstAmt": "{item.sgst_amount}",
|
||||||
|
"CesRt": "{item.cess_rate}",
|
||||||
|
"CesAmt": "{item.cess_amount}",
|
||||||
|
"CesNonAdvlAmt": "{item.cess_nadv_amount}",
|
||||||
|
"StateCesRt": "{item.state_cess_rate}",
|
||||||
|
"StateCesAmt": "{item.state_cess_amount}",
|
||||||
|
"StateCesNonAdvlAmt": "{item.state_cess_nadv_amount}",
|
||||||
|
"OthChrg": "{item.other_charges}",
|
||||||
|
"TotItemVal": "{item.total_value}",
|
||||||
|
"BchDtls": {{
|
||||||
|
"Nm": "{item.batch_no}",
|
||||||
|
"ExpDt": "{item.batch_expiry_date}"
|
||||||
|
}}
|
||||||
|
}}
|
110
erpnext/regional/india/e_invoice/einv_template.json
Normal file
110
erpnext/regional/india/e_invoice/einv_template.json
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
{{
|
||||||
|
"Version": "1.1",
|
||||||
|
"TranDtls": {{
|
||||||
|
"TaxSch": "{transaction_details.tax_scheme}",
|
||||||
|
"SupTyp": "{transaction_details.supply_type}",
|
||||||
|
"RegRev": "{transaction_details.reverse_charge}",
|
||||||
|
"EcmGstin": "{transaction_details.ecom_gstin}",
|
||||||
|
"IgstOnIntra": "{transaction_details.igst_on_intra}"
|
||||||
|
}},
|
||||||
|
"DocDtls": {{
|
||||||
|
"Typ": "{doc_details.invoice_type}",
|
||||||
|
"No": "{doc_details.invoice_name}",
|
||||||
|
"Dt": "{doc_details.invoice_date}"
|
||||||
|
}},
|
||||||
|
"SellerDtls": {{
|
||||||
|
"Gstin": "{seller_details.gstin}",
|
||||||
|
"LglNm": "{seller_details.legal_name}",
|
||||||
|
"TrdNm": "{seller_details.trade_name}",
|
||||||
|
"Loc": "{seller_details.location}",
|
||||||
|
"Pin": "{seller_details.pincode}",
|
||||||
|
"Stcd": "{seller_details.state_code}",
|
||||||
|
"Addr1": "{seller_details.address_line1}",
|
||||||
|
"Addr2": "{seller_details.address_line2}",
|
||||||
|
"Ph": "{seller_details.phone}",
|
||||||
|
"Em": "{seller_details.email}"
|
||||||
|
}},
|
||||||
|
"BuyerDtls": {{
|
||||||
|
"Gstin": "{buyer_details.gstin}",
|
||||||
|
"LglNm": "{buyer_details.legal_name}",
|
||||||
|
"TrdNm": "{buyer_details.trade_name}",
|
||||||
|
"Addr1": "{buyer_details.address_line1}",
|
||||||
|
"Addr2": "{buyer_details.address_line2}",
|
||||||
|
"Loc": "{buyer_details.location}",
|
||||||
|
"Pin": "{buyer_details.pincode}",
|
||||||
|
"Stcd": "{buyer_details.state_code}",
|
||||||
|
"Ph": "{buyer_details.phone}",
|
||||||
|
"Em": "{buyer_details.email}",
|
||||||
|
"Pos": "{buyer_details.place_of_supply}"
|
||||||
|
}},
|
||||||
|
"DispDtls": {{
|
||||||
|
"Nm": "{dispatch_details.company_name}",
|
||||||
|
"Addr1": "{dispatch_details.address_line1}",
|
||||||
|
"Addr2": "{dispatch_details.address_line2}",
|
||||||
|
"Loc": "{dispatch_details.location}",
|
||||||
|
"Pin": "{dispatch_details.pincode}",
|
||||||
|
"Stcd": "{dispatch_details.state_code}"
|
||||||
|
}},
|
||||||
|
"ShipDtls": {{
|
||||||
|
"Gstin": "{shipping_details.gstin}",
|
||||||
|
"LglNm": "{shipping_details.legal_name}",
|
||||||
|
"TrdNm": "{shipping_details.trader_name}",
|
||||||
|
"Addr1": "{shipping_details.address_line1}",
|
||||||
|
"Addr2": "{shipping_details.address_line2}",
|
||||||
|
"Loc": "{shipping_details.location}",
|
||||||
|
"Pin": "{shipping_details.pincode}",
|
||||||
|
"Stcd": "{shipping_details.state_code}"
|
||||||
|
}},
|
||||||
|
"ItemList": [
|
||||||
|
{item_list}
|
||||||
|
],
|
||||||
|
"ValDtls": {{
|
||||||
|
"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}",
|
||||||
|
"CesVal": "{invoice_value_details.total_cess_amt}",
|
||||||
|
"Discount": "{invoice_value_details.invoice_discount_amt}",
|
||||||
|
"RndOffAmt": "{invoice_value_details.round_off}",
|
||||||
|
"OthChrg": "{invoice_value_details.total_other_charges}",
|
||||||
|
"TotInvVal": "{invoice_value_details.base_grand_total}",
|
||||||
|
"TotInvValFc": "{invoice_value_details.grand_total}"
|
||||||
|
}},
|
||||||
|
"PayDtls": {{
|
||||||
|
"Nm": "{payment_details.payee_name}",
|
||||||
|
"AccDet": "{payment_details.account_no}",
|
||||||
|
"Mode": "{payment_details.mode_of_payment}",
|
||||||
|
"FinInsBr": "{payment_details.ifsc_code}",
|
||||||
|
"PayTerm": "{payment_details.terms}",
|
||||||
|
"PaidAmt": "{payment_details.paid_amount}",
|
||||||
|
"PaymtDue": "{payment_details.outstanding_amount}"
|
||||||
|
}},
|
||||||
|
"RefDtls": {{
|
||||||
|
"DocPerdDtls": {{
|
||||||
|
"InvStDt": "{period_details.start_date}",
|
||||||
|
"InvEndDt": "{period_details.end_date}"
|
||||||
|
}},
|
||||||
|
"PrecDocDtls": [{{
|
||||||
|
"InvNo": "{prev_doc_details.invoice_name}",
|
||||||
|
"InvDt": "{prev_doc_details.invoice_date}"
|
||||||
|
}}]
|
||||||
|
}},
|
||||||
|
"ExpDtls": {{
|
||||||
|
"ShipBNo": "{export_details.bill_no}",
|
||||||
|
"ShipBDt": "{export_details.bill_date}",
|
||||||
|
"Port": "{export_details.port}",
|
||||||
|
"ForCur": "{export_details.foreign_curr_code}",
|
||||||
|
"CntCode": "{export_details.country_code}",
|
||||||
|
"ExpDuty": "{export_details.export_duty}"
|
||||||
|
}},
|
||||||
|
"EwbDtls": {{
|
||||||
|
"TransId": "{eway_bill_details.gstin}",
|
||||||
|
"TransName": "{eway_bill_details.name}",
|
||||||
|
"TransMode": "{eway_bill_details.mode_of_transport}",
|
||||||
|
"Distance": "{eway_bill_details.distance}",
|
||||||
|
"TransDocNo": "{eway_bill_details.document_name}",
|
||||||
|
"TransDocDt": "{eway_bill_details.document_date}",
|
||||||
|
"VehNo": "{eway_bill_details.vehicle_no}",
|
||||||
|
"VehType": "{eway_bill_details.vehicle_type}"
|
||||||
|
}}
|
||||||
|
}}
|
957
erpnext/regional/india/e_invoice/einv_validation.json
Normal file
957
erpnext/regional/india/e_invoice/einv_validation.json
Normal file
@ -0,0 +1,957 @@
|
|||||||
|
{
|
||||||
|
"Version": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 6,
|
||||||
|
"description": "Version of the schema"
|
||||||
|
},
|
||||||
|
"Irn": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 64,
|
||||||
|
"maxLength": 64,
|
||||||
|
"description": "Invoice Reference Number"
|
||||||
|
},
|
||||||
|
"TranDtls": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"TaxSch": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 3,
|
||||||
|
"maxLength": 10,
|
||||||
|
"enum": ["GST"],
|
||||||
|
"description": "GST- Goods and Services Tax Scheme"
|
||||||
|
},
|
||||||
|
"SupTyp": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 3,
|
||||||
|
"maxLength": 10,
|
||||||
|
"enum": ["B2B", "SEZWP", "SEZWOP", "EXPWP", "EXPWOP", "DEXP"],
|
||||||
|
"description": "Type of Supply: B2B-Business to Business, SEZWP - SEZ with payment, SEZWOP - SEZ without payment, EXPWP - Export with Payment, EXPWOP - Export without payment,DEXP - Deemed Export"
|
||||||
|
},
|
||||||
|
"RegRev": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 1,
|
||||||
|
"enum": ["Y", "N"],
|
||||||
|
"description": "Y- whether the tax liability is payable under reverse charge"
|
||||||
|
},
|
||||||
|
"EcmGstin": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 15,
|
||||||
|
"maxLength": 15,
|
||||||
|
"pattern": "([0-9]{2}[0-9A-Z]{13})",
|
||||||
|
"description": "E-Commerce GSTIN",
|
||||||
|
"validationMsg": "E-Commerce GSTIN is invalid"
|
||||||
|
},
|
||||||
|
"IgstOnIntra": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 1,
|
||||||
|
"enum": ["Y", "N"],
|
||||||
|
"description": "Y- indicates the supply is intra state but chargeable to IGST"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["TaxSch", "SupTyp"]
|
||||||
|
},
|
||||||
|
"DocDtls": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"Typ": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 3,
|
||||||
|
"maxLength": 3,
|
||||||
|
"enum": ["INV", "CRN", "DBN"],
|
||||||
|
"description": "Document Type"
|
||||||
|
},
|
||||||
|
"No": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 16,
|
||||||
|
"pattern": "^([A-Z1-9]{1}[A-Z0-9/-]{0,15})$",
|
||||||
|
"description": "Document Number",
|
||||||
|
"validationMsg": "Document Number should not be starting with 0, / and -"
|
||||||
|
},
|
||||||
|
"Dt": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 10,
|
||||||
|
"maxLength": 10,
|
||||||
|
"pattern": "[0-3][0-9]/[0-1][0-9]/[2][0][1-2][0-9]",
|
||||||
|
"description": "Document Date"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["Typ", "No", "Dt"]
|
||||||
|
},
|
||||||
|
"SellerDtls": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"Gstin": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 15,
|
||||||
|
"maxLength": 15,
|
||||||
|
"pattern": "([0-9]{2}[0-9A-Z]{13})",
|
||||||
|
"description": "Supplier GSTIN",
|
||||||
|
"validationMsg": "Company GSTIN is invalid"
|
||||||
|
},
|
||||||
|
"LglNm": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 3,
|
||||||
|
"maxLength": 100,
|
||||||
|
"description": "Legal Name"
|
||||||
|
},
|
||||||
|
"TrdNm": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 3,
|
||||||
|
"maxLength": 100,
|
||||||
|
"description": "Tradename"
|
||||||
|
},
|
||||||
|
"Addr1": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 100,
|
||||||
|
"description": "Address Line 1"
|
||||||
|
},
|
||||||
|
"Addr2": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 3,
|
||||||
|
"maxLength": 100,
|
||||||
|
"description": "Address Line 2"
|
||||||
|
},
|
||||||
|
"Loc": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 3,
|
||||||
|
"maxLength": 50,
|
||||||
|
"description": "Location"
|
||||||
|
},
|
||||||
|
"Pin": {
|
||||||
|
"type": "number",
|
||||||
|
"minimum": 100000,
|
||||||
|
"maximum": 999999,
|
||||||
|
"description": "Pincode"
|
||||||
|
},
|
||||||
|
"Stcd": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 2,
|
||||||
|
"description": "Supplier State Code"
|
||||||
|
},
|
||||||
|
"Ph": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 6,
|
||||||
|
"maxLength": 12,
|
||||||
|
"description": "Phone"
|
||||||
|
},
|
||||||
|
"Em": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 6,
|
||||||
|
"maxLength": 100,
|
||||||
|
"description": "Email-Id"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["Gstin", "LglNm", "Addr1", "Loc", "Pin", "Stcd"]
|
||||||
|
},
|
||||||
|
"BuyerDtls": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"Gstin": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 3,
|
||||||
|
"maxLength": 15,
|
||||||
|
"pattern": "^(([0-9]{2}[0-9A-Z]{13})|URP)$",
|
||||||
|
"description": "Buyer GSTIN",
|
||||||
|
"validationMsg": "Customer GSTIN is invalid"
|
||||||
|
},
|
||||||
|
"LglNm": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 3,
|
||||||
|
"maxLength": 100,
|
||||||
|
"description": "Legal Name"
|
||||||
|
},
|
||||||
|
"TrdNm": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 3,
|
||||||
|
"maxLength": 100,
|
||||||
|
"description": "Trade Name"
|
||||||
|
},
|
||||||
|
"Pos": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 2,
|
||||||
|
"description": "Place of Supply State code"
|
||||||
|
},
|
||||||
|
"Addr1": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 100,
|
||||||
|
"description": "Address Line 1"
|
||||||
|
},
|
||||||
|
"Addr2": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 3,
|
||||||
|
"maxLength": 100,
|
||||||
|
"description": "Address Line 2"
|
||||||
|
},
|
||||||
|
"Loc": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 3,
|
||||||
|
"maxLength": 100,
|
||||||
|
"description": "Location"
|
||||||
|
},
|
||||||
|
"Pin": {
|
||||||
|
"type": "number",
|
||||||
|
"minimum": 100000,
|
||||||
|
"maximum": 999999,
|
||||||
|
"description": "Pincode"
|
||||||
|
},
|
||||||
|
"Stcd": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 2,
|
||||||
|
"description": "Buyer State Code"
|
||||||
|
},
|
||||||
|
"Ph": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 6,
|
||||||
|
"maxLength": 12,
|
||||||
|
"description": "Phone"
|
||||||
|
},
|
||||||
|
"Em": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 6,
|
||||||
|
"maxLength": 100,
|
||||||
|
"description": "Email-Id"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["Gstin", "LglNm", "Pos", "Addr1", "Loc", "Stcd"]
|
||||||
|
},
|
||||||
|
"DispDtls": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"Nm": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 3,
|
||||||
|
"maxLength": 100,
|
||||||
|
"description": "Dispatch Address Name"
|
||||||
|
},
|
||||||
|
"Addr1": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 100,
|
||||||
|
"description": "Address Line 1"
|
||||||
|
},
|
||||||
|
"Addr2": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 3,
|
||||||
|
"maxLength": 100,
|
||||||
|
"description": "Address Line 2"
|
||||||
|
},
|
||||||
|
"Loc": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 3,
|
||||||
|
"maxLength": 100,
|
||||||
|
"description": "Location"
|
||||||
|
},
|
||||||
|
"Pin": {
|
||||||
|
"type": "number",
|
||||||
|
"minimum": 100000,
|
||||||
|
"maximum": 999999,
|
||||||
|
"description": "Pincode"
|
||||||
|
},
|
||||||
|
"Stcd": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 2,
|
||||||
|
"description": "State Code"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["Nm", "Addr1", "Loc", "Pin", "Stcd"]
|
||||||
|
},
|
||||||
|
"ShipDtls": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"Gstin": {
|
||||||
|
"type": "string",
|
||||||
|
"maxLength": 15,
|
||||||
|
"minLength": 3,
|
||||||
|
"pattern": "^(([0-9]{2}[0-9A-Z]{13})|URP)$",
|
||||||
|
"description": "Shipping Address GSTIN",
|
||||||
|
"validationMsg": "Shipping Address GSTIN is invalid"
|
||||||
|
},
|
||||||
|
"LglNm": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 3,
|
||||||
|
"maxLength": 100,
|
||||||
|
"description": "Legal Name"
|
||||||
|
},
|
||||||
|
"TrdNm": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 3,
|
||||||
|
"maxLength": 100,
|
||||||
|
"description": "Trade Name"
|
||||||
|
},
|
||||||
|
"Addr1": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 100,
|
||||||
|
"description": "Address Line 1"
|
||||||
|
},
|
||||||
|
"Addr2": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 3,
|
||||||
|
"maxLength": 100,
|
||||||
|
"description": "Address Line 2"
|
||||||
|
},
|
||||||
|
"Loc": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 3,
|
||||||
|
"maxLength": 100,
|
||||||
|
"description": "Location"
|
||||||
|
},
|
||||||
|
"Pin": {
|
||||||
|
"type": "number",
|
||||||
|
"minimum": 100000,
|
||||||
|
"maximum": 999999,
|
||||||
|
"description": "Pincode"
|
||||||
|
},
|
||||||
|
"Stcd": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 2,
|
||||||
|
"description": "State Code"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["LglNm", "Addr1", "Loc", "Pin", "Stcd"]
|
||||||
|
},
|
||||||
|
"ItemList": {
|
||||||
|
"type": "Array",
|
||||||
|
"properties": {
|
||||||
|
"SlNo": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 6,
|
||||||
|
"description": "Serial No. of Item"
|
||||||
|
},
|
||||||
|
"PrdDesc": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 3,
|
||||||
|
"maxLength": 300,
|
||||||
|
"description": "Item Name"
|
||||||
|
},
|
||||||
|
"IsServc": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 1,
|
||||||
|
"enum": ["Y", "N"],
|
||||||
|
"description": "Is Service Item"
|
||||||
|
},
|
||||||
|
"HsnCd": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 4,
|
||||||
|
"maxLength": 8,
|
||||||
|
"description": "HSN Code"
|
||||||
|
},
|
||||||
|
"Barcde": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 3,
|
||||||
|
"maxLength": 30,
|
||||||
|
"description": "Barcode"
|
||||||
|
},
|
||||||
|
"Qty": {
|
||||||
|
"type": "number",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 9999999999.999,
|
||||||
|
"description": "Quantity"
|
||||||
|
},
|
||||||
|
"FreeQty": {
|
||||||
|
"type": "number",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 9999999999.999,
|
||||||
|
"description": "Free Quantity"
|
||||||
|
},
|
||||||
|
"Unit": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 3,
|
||||||
|
"maxLength": 8,
|
||||||
|
"description": "UOM"
|
||||||
|
},
|
||||||
|
"UnitPrice": {
|
||||||
|
"type": "number",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 999999999999.999,
|
||||||
|
"description": "Rate"
|
||||||
|
},
|
||||||
|
"TotAmt": {
|
||||||
|
"type": "number",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 999999999999.99,
|
||||||
|
"description": "Gross Amount"
|
||||||
|
},
|
||||||
|
"Discount": {
|
||||||
|
"type": "number",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 999999999999.99,
|
||||||
|
"description": "Discount"
|
||||||
|
},
|
||||||
|
"PreTaxVal": {
|
||||||
|
"type": "number",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 999999999999.99,
|
||||||
|
"description": "Pre tax value"
|
||||||
|
},
|
||||||
|
"AssAmt": {
|
||||||
|
"type": "number",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 999999999999.99,
|
||||||
|
"description": "Taxable Value"
|
||||||
|
},
|
||||||
|
"GstRt": {
|
||||||
|
"type": "number",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 999.999,
|
||||||
|
"description": "GST Rate"
|
||||||
|
},
|
||||||
|
"IgstAmt": {
|
||||||
|
"type": "number",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 999999999999.99,
|
||||||
|
"description": "IGST Amount"
|
||||||
|
},
|
||||||
|
"CgstAmt": {
|
||||||
|
"type": "number",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 999999999999.99,
|
||||||
|
"description": "CGST Amount"
|
||||||
|
},
|
||||||
|
"SgstAmt": {
|
||||||
|
"type": "number",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 999999999999.99,
|
||||||
|
"description": "SGST Amount"
|
||||||
|
},
|
||||||
|
"CesRt": {
|
||||||
|
"type": "number",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 999.999,
|
||||||
|
"description": "Cess Rate"
|
||||||
|
},
|
||||||
|
"CesAmt": {
|
||||||
|
"type": "number",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 999999999999.99,
|
||||||
|
"description": "Cess Amount (Advalorem)"
|
||||||
|
},
|
||||||
|
"CesNonAdvlAmt": {
|
||||||
|
"type": "number",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 999999999999.99,
|
||||||
|
"description": "Cess Amount (Non-Advalorem)"
|
||||||
|
},
|
||||||
|
"StateCesRt": {
|
||||||
|
"type": "number",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 999.999,
|
||||||
|
"description": "State CESS Rate"
|
||||||
|
},
|
||||||
|
"StateCesAmt": {
|
||||||
|
"type": "number",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 999999999999.99,
|
||||||
|
"description": "State CESS Amount"
|
||||||
|
},
|
||||||
|
"StateCesNonAdvlAmt": {
|
||||||
|
"type": "number",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 999999999999.99,
|
||||||
|
"description": "State CESS Amount (Non Advalorem)"
|
||||||
|
},
|
||||||
|
"OthChrg": {
|
||||||
|
"type": "number",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 999999999999.99,
|
||||||
|
"description": "Other Charges"
|
||||||
|
},
|
||||||
|
"TotItemVal": {
|
||||||
|
"type": "number",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 999999999999.99,
|
||||||
|
"description": "Total Item Value"
|
||||||
|
},
|
||||||
|
"OrdLineRef": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 50,
|
||||||
|
"description": "Order line reference"
|
||||||
|
},
|
||||||
|
"OrgCntry": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 2,
|
||||||
|
"maxLength": 2,
|
||||||
|
"description": "Origin Country"
|
||||||
|
},
|
||||||
|
"PrdSlNo": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 20,
|
||||||
|
"description": "Serial number"
|
||||||
|
},
|
||||||
|
"BchDtls": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"Nm": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 3,
|
||||||
|
"maxLength": 20,
|
||||||
|
"description": "Batch number"
|
||||||
|
},
|
||||||
|
"ExpDt": {
|
||||||
|
"type": "string",
|
||||||
|
"maxLength": 10,
|
||||||
|
"minLength": 10,
|
||||||
|
"pattern": "[0-3][0-9]/[0-1][0-9]/[2][0][1-2][0-9]",
|
||||||
|
"description": "Batch Expiry Date"
|
||||||
|
},
|
||||||
|
"WrDt": {
|
||||||
|
"type": "string",
|
||||||
|
"maxLength": 10,
|
||||||
|
"minLength": 10,
|
||||||
|
"pattern": "[0-3][0-9]/[0-1][0-9]/[2][0][1-2][0-9]",
|
||||||
|
"description": "Warranty Date"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["Nm"]
|
||||||
|
},
|
||||||
|
"AttribDtls": {
|
||||||
|
"type": "Array",
|
||||||
|
"Attribute": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"Nm": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 100,
|
||||||
|
"description": "Attribute name of the item"
|
||||||
|
},
|
||||||
|
"Val": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 100,
|
||||||
|
"description": "Attribute value of the item"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"SlNo",
|
||||||
|
"IsServc",
|
||||||
|
"HsnCd",
|
||||||
|
"UnitPrice",
|
||||||
|
"TotAmt",
|
||||||
|
"AssAmt",
|
||||||
|
"GstRt",
|
||||||
|
"TotItemVal"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"ValDtls": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"AssVal": {
|
||||||
|
"type": "number",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 99999999999999.99,
|
||||||
|
"description": "Total Assessable value of all items"
|
||||||
|
},
|
||||||
|
"CgstVal": {
|
||||||
|
"type": "number",
|
||||||
|
"maximum": 99999999999999.99,
|
||||||
|
"minimum": 0,
|
||||||
|
"description": "Total CGST value of all items"
|
||||||
|
},
|
||||||
|
"SgstVal": {
|
||||||
|
"type": "number",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 99999999999999.99,
|
||||||
|
"description": "Total SGST value of all items"
|
||||||
|
},
|
||||||
|
"IgstVal": {
|
||||||
|
"type": "number",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 99999999999999.99,
|
||||||
|
"description": "Total IGST value of all items"
|
||||||
|
},
|
||||||
|
"CesVal": {
|
||||||
|
"type": "number",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 99999999999999.99,
|
||||||
|
"description": "Total CESS value of all items"
|
||||||
|
},
|
||||||
|
"StCesVal": {
|
||||||
|
"type": "number",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 99999999999999.99,
|
||||||
|
"description": "Total State CESS value of all items"
|
||||||
|
},
|
||||||
|
"Discount": {
|
||||||
|
"type": "number",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 99999999999999.99,
|
||||||
|
"description": "Invoice Discount"
|
||||||
|
},
|
||||||
|
"OthChrg": {
|
||||||
|
"type": "number",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 99999999999999.99,
|
||||||
|
"description": "Other Charges"
|
||||||
|
},
|
||||||
|
"RndOffAmt": {
|
||||||
|
"type": "number",
|
||||||
|
"minimum": -99.99,
|
||||||
|
"maximum": 99.99,
|
||||||
|
"description": "Rounded off Amount"
|
||||||
|
},
|
||||||
|
"TotInvVal": {
|
||||||
|
"type": "number",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 99999999999999.99,
|
||||||
|
"description": "Final Invoice Value "
|
||||||
|
},
|
||||||
|
"TotInvValFc": {
|
||||||
|
"type": "number",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 99999999999999.99,
|
||||||
|
"description": "Final Invoice value in Foreign Currency"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["AssVal", "TotInvVal"]
|
||||||
|
},
|
||||||
|
"PayDtls": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"Nm": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 100,
|
||||||
|
"description": "Payee Name"
|
||||||
|
},
|
||||||
|
"AccDet": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 18,
|
||||||
|
"description": "Bank Account Number of Payee"
|
||||||
|
},
|
||||||
|
"Mode": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 18,
|
||||||
|
"description": "Mode of Payment"
|
||||||
|
},
|
||||||
|
"FinInsBr": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 11,
|
||||||
|
"description": "Branch or IFSC code"
|
||||||
|
},
|
||||||
|
"PayTerm": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 100,
|
||||||
|
"description": "Terms of Payment"
|
||||||
|
},
|
||||||
|
"PayInstr": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 100,
|
||||||
|
"description": "Payment Instruction"
|
||||||
|
},
|
||||||
|
"CrTrn": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 100,
|
||||||
|
"description": "Credit Transfer"
|
||||||
|
},
|
||||||
|
"DirDr": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 100,
|
||||||
|
"description": "Direct Debit"
|
||||||
|
},
|
||||||
|
"CrDay": {
|
||||||
|
"type": "number",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 9999,
|
||||||
|
"description": "Credit Days"
|
||||||
|
},
|
||||||
|
"PaidAmt": {
|
||||||
|
"type": "number",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 99999999999999.99,
|
||||||
|
"description": "Advance Amount"
|
||||||
|
},
|
||||||
|
"PaymtDue": {
|
||||||
|
"type": "number",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 99999999999999.99,
|
||||||
|
"description": "Outstanding Amount"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"RefDtls": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"InvRm": {
|
||||||
|
"type": "string",
|
||||||
|
"maxLength": 100,
|
||||||
|
"minLength": 3,
|
||||||
|
"pattern": "^[0-9A-Za-z/-]{3,100}$",
|
||||||
|
"description": "Remarks/Note"
|
||||||
|
},
|
||||||
|
"DocPerdDtls": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"InvStDt": {
|
||||||
|
"type": "string",
|
||||||
|
"maxLength": 10,
|
||||||
|
"minLength": 10,
|
||||||
|
"pattern": "[0-3][0-9]/[0-1][0-9]/[2][0][1-2][0-9]",
|
||||||
|
"description": "Invoice Period Start Date"
|
||||||
|
},
|
||||||
|
"InvEndDt": {
|
||||||
|
"type": "string",
|
||||||
|
"maxLength": 10,
|
||||||
|
"minLength": 10,
|
||||||
|
"pattern": "[0-3][0-9]/[0-1][0-9]/[2][0][1-2][0-9]",
|
||||||
|
"description": "Invoice Period End Date"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["InvStDt ", "InvEndDt "]
|
||||||
|
},
|
||||||
|
"PrecDocDtls": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"InvNo": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 16,
|
||||||
|
"pattern": "^[1-9A-Z]{1}[0-9A-Z/-]{1,15}$",
|
||||||
|
"description": "Reference of Original Invoice"
|
||||||
|
},
|
||||||
|
"InvDt": {
|
||||||
|
"type": "string",
|
||||||
|
"maxLength": 10,
|
||||||
|
"minLength": 10,
|
||||||
|
"pattern": "[0-3][0-9]/[0-1][0-9]/[2][0][1-2][0-9]",
|
||||||
|
"description": "Date of Orginal Invoice"
|
||||||
|
},
|
||||||
|
"OthRefNo": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 20,
|
||||||
|
"description": "Other Reference"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["InvNo", "InvDt"],
|
||||||
|
"ContrDtls": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"RecAdvRefr": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 20,
|
||||||
|
"pattern": "^([0-9A-Za-z/-]){1,20}$",
|
||||||
|
"description": "Receipt Advice No."
|
||||||
|
},
|
||||||
|
"RecAdvDt": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 10,
|
||||||
|
"maxLength": 10,
|
||||||
|
"pattern": "[0-3][0-9]/[0-1][0-9]/[2][0][1-2][0-9]",
|
||||||
|
"description": "Date of receipt advice"
|
||||||
|
},
|
||||||
|
"TendRefr": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 20,
|
||||||
|
"pattern": "^([0-9A-Za-z/-]){1,20}$",
|
||||||
|
"description": "Lot/Batch Reference No."
|
||||||
|
},
|
||||||
|
"ContrRefr": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 20,
|
||||||
|
"pattern": "^([0-9A-Za-z/-]){1,20}$",
|
||||||
|
"description": "Contract Reference Number"
|
||||||
|
},
|
||||||
|
"ExtRefr": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 20,
|
||||||
|
"pattern": "^([0-9A-Za-z/-]){1,20}$",
|
||||||
|
"description": "Any other reference"
|
||||||
|
},
|
||||||
|
"ProjRefr": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 20,
|
||||||
|
"pattern": "^([0-9A-Za-z/-]){1,20}$",
|
||||||
|
"description": "Project Reference Number"
|
||||||
|
},
|
||||||
|
"PORefr": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 16,
|
||||||
|
"pattern": "^([0-9A-Za-z/-]){1,16}$",
|
||||||
|
"description": "PO Reference Number"
|
||||||
|
},
|
||||||
|
"PORefDt": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 10,
|
||||||
|
"maxLength": 10,
|
||||||
|
"pattern": "[0-3][0-9]/[0-1][0-9]/[2][0][1-2][0-9]",
|
||||||
|
"description": "PO Reference date"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"AddlDocDtls": {
|
||||||
|
"type": "Array",
|
||||||
|
"properties": {
|
||||||
|
"Url": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 3,
|
||||||
|
"maxLength": 100,
|
||||||
|
"description": "Supporting document URL"
|
||||||
|
},
|
||||||
|
"Docs": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 3,
|
||||||
|
"maxLength": 1000,
|
||||||
|
"description": "Supporting document in Base64 Format"
|
||||||
|
},
|
||||||
|
"Info": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 3,
|
||||||
|
"maxLength": 1000,
|
||||||
|
"description": "Any additional information"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"ExpDtls": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"ShipBNo": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 20,
|
||||||
|
"description": "Shipping Bill No."
|
||||||
|
},
|
||||||
|
"ShipBDt": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 10,
|
||||||
|
"maxLength": 10,
|
||||||
|
"pattern": "[0-3][0-9]/[0-1][0-9]/[2][0][1-2][0-9]",
|
||||||
|
"description": "Shipping Bill Date"
|
||||||
|
},
|
||||||
|
"Port": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 2,
|
||||||
|
"maxLength": 10,
|
||||||
|
"pattern": "^[0-9A-Za-z]{2,10}$",
|
||||||
|
"description": "Port Code. Refer the master"
|
||||||
|
},
|
||||||
|
"RefClm": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 1,
|
||||||
|
"description": "Claiming Refund. Y/N"
|
||||||
|
},
|
||||||
|
"ForCur": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 3,
|
||||||
|
"maxLength": 16,
|
||||||
|
"description": "Additional Currency Code. Refer the master"
|
||||||
|
},
|
||||||
|
"CntCode": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 2,
|
||||||
|
"maxLength": 2,
|
||||||
|
"description": "Country Code. Refer the master"
|
||||||
|
},
|
||||||
|
"ExpDuty": {
|
||||||
|
"type": "number",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 999999999999.99,
|
||||||
|
"description": "Export Duty"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"EwbDtls": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"TransId": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 15,
|
||||||
|
"maxLength": 15,
|
||||||
|
"description": "Transporter GSTIN"
|
||||||
|
},
|
||||||
|
"TransName": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 3,
|
||||||
|
"maxLength": 100,
|
||||||
|
"description": "Transporter Name"
|
||||||
|
},
|
||||||
|
"TransMode": {
|
||||||
|
"type": "string",
|
||||||
|
"maxLength": 1,
|
||||||
|
"minLength": 1,
|
||||||
|
"enum": ["1", "2", "3", "4"],
|
||||||
|
"description": "Mode of Transport"
|
||||||
|
},
|
||||||
|
"Distance": {
|
||||||
|
"type": "number",
|
||||||
|
"minimum": 1,
|
||||||
|
"maximum": 9999,
|
||||||
|
"description": "Distance"
|
||||||
|
},
|
||||||
|
"TransDocNo": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 15,
|
||||||
|
"pattern": "^([0-9A-Z/-]){1,15}$",
|
||||||
|
"description": "Tranport Document Number",
|
||||||
|
"validationMsg": "Transport Receipt No is invalid"
|
||||||
|
},
|
||||||
|
"TransDocDt": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 10,
|
||||||
|
"maxLength": 10,
|
||||||
|
"pattern": "[0-3][0-9]/[0-1][0-9]/[2][0][1-2][0-9]",
|
||||||
|
"description": "Transport Document Date"
|
||||||
|
},
|
||||||
|
"VehNo": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 4,
|
||||||
|
"maxLength": 20,
|
||||||
|
"description": "Vehicle Number"
|
||||||
|
},
|
||||||
|
"VehType": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 1,
|
||||||
|
"enum": ["O", "R"],
|
||||||
|
"description": "Vehicle Type"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["Distance"]
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"Version",
|
||||||
|
"TranDtls",
|
||||||
|
"DocDtls",
|
||||||
|
"SellerDtls",
|
||||||
|
"BuyerDtls",
|
||||||
|
"ItemList",
|
||||||
|
"ValDtls"
|
||||||
|
]
|
||||||
|
}
|
292
erpnext/regional/india/e_invoice/einvoice.js
Normal file
292
erpnext/regional/india/e_invoice/einvoice.js
Normal file
@ -0,0 +1,292 @@
|
|||||||
|
erpnext.setup_einvoice_actions = (doctype) => {
|
||||||
|
frappe.ui.form.on(doctype, {
|
||||||
|
async refresh(frm) {
|
||||||
|
if (frm.doc.docstatus == 2) return;
|
||||||
|
|
||||||
|
const res = await frappe.call({
|
||||||
|
method: 'erpnext.regional.india.e_invoice.utils.validate_eligibility',
|
||||||
|
args: { doc: frm.doc }
|
||||||
|
});
|
||||||
|
const invoice_eligible = res.message;
|
||||||
|
|
||||||
|
if (!invoice_eligible) return;
|
||||||
|
|
||||||
|
const { doctype, irn, irn_cancelled, ewaybill, eway_bill_cancelled, name, __unsaved } = frm.doc;
|
||||||
|
|
||||||
|
const add_custom_button = (label, action) => {
|
||||||
|
if (!frm.custom_buttons[label]) {
|
||||||
|
frm.add_custom_button(label, action, __('E Invoicing'));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!irn && !__unsaved) {
|
||||||
|
const action = () => {
|
||||||
|
if (frm.doc.__unsaved) {
|
||||||
|
frappe.throw(__('Please save the document to generate IRN.'));
|
||||||
|
}
|
||||||
|
frappe.call({
|
||||||
|
method: 'erpnext.regional.india.e_invoice.utils.get_einvoice',
|
||||||
|
args: { doctype, docname: name },
|
||||||
|
freeze: true,
|
||||||
|
callback: (res) => {
|
||||||
|
const einvoice = res.message;
|
||||||
|
show_einvoice_preview(frm, einvoice);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
add_custom_button(__("Generate IRN"), action);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (irn && !irn_cancelled && !ewaybill) {
|
||||||
|
const fields = [
|
||||||
|
{
|
||||||
|
"label": "Reason",
|
||||||
|
"fieldname": "reason",
|
||||||
|
"fieldtype": "Select",
|
||||||
|
"reqd": 1,
|
||||||
|
"default": "1-Duplicate",
|
||||||
|
"options": ["1-Duplicate", "2-Data Entry Error", "3-Order Cancelled", "4-Other"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Remark",
|
||||||
|
"fieldname": "remark",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"reqd": 1
|
||||||
|
}
|
||||||
|
];
|
||||||
|
const action = () => {
|
||||||
|
const d = new frappe.ui.Dialog({
|
||||||
|
title: __("Cancel IRN"),
|
||||||
|
fields: fields,
|
||||||
|
primary_action: function() {
|
||||||
|
const data = d.get_values();
|
||||||
|
frappe.call({
|
||||||
|
method: 'erpnext.regional.india.e_invoice.utils.cancel_irn',
|
||||||
|
args: {
|
||||||
|
doctype,
|
||||||
|
docname: name,
|
||||||
|
irn: irn,
|
||||||
|
reason: data.reason.split('-')[0],
|
||||||
|
remark: data.remark
|
||||||
|
},
|
||||||
|
freeze: true,
|
||||||
|
callback: () => frm.reload_doc() || d.hide(),
|
||||||
|
error: () => d.hide()
|
||||||
|
});
|
||||||
|
},
|
||||||
|
primary_action_label: __('Submit')
|
||||||
|
});
|
||||||
|
d.show();
|
||||||
|
};
|
||||||
|
add_custom_button(__("Cancel IRN"), action);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (irn && !irn_cancelled && !ewaybill) {
|
||||||
|
const action = () => {
|
||||||
|
const d = new frappe.ui.Dialog({
|
||||||
|
title: __('Generate E-Way Bill'),
|
||||||
|
size: "large",
|
||||||
|
fields: get_ewaybill_fields(frm),
|
||||||
|
primary_action: function() {
|
||||||
|
const data = d.get_values();
|
||||||
|
frappe.call({
|
||||||
|
method: 'erpnext.regional.india.e_invoice.utils.generate_eway_bill',
|
||||||
|
args: {
|
||||||
|
doctype,
|
||||||
|
docname: name,
|
||||||
|
irn,
|
||||||
|
...data
|
||||||
|
},
|
||||||
|
freeze: true,
|
||||||
|
callback: () => frm.reload_doc() || d.hide(),
|
||||||
|
error: () => d.hide()
|
||||||
|
});
|
||||||
|
},
|
||||||
|
primary_action_label: __('Submit')
|
||||||
|
});
|
||||||
|
d.show();
|
||||||
|
};
|
||||||
|
|
||||||
|
add_custom_button(__("Generate E-Way Bill"), action);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (irn && ewaybill && !irn_cancelled && !eway_bill_cancelled) {
|
||||||
|
const action = () => {
|
||||||
|
let message = __('Cancellation of e-way bill is currently not supported.') + ' ';
|
||||||
|
message += '<br><br>';
|
||||||
|
message += __('You must first use the portal to cancel the e-way bill and then update the cancelled status in the ERPNext system.');
|
||||||
|
|
||||||
|
const dialog = frappe.msgprint({
|
||||||
|
title: __('Update E-Way Bill Cancelled Status?'),
|
||||||
|
message: message,
|
||||||
|
indicator: 'orange',
|
||||||
|
primary_action: {
|
||||||
|
action: function() {
|
||||||
|
frappe.call({
|
||||||
|
method: 'erpnext.regional.india.e_invoice.utils.cancel_eway_bill',
|
||||||
|
args: { doctype, docname: name },
|
||||||
|
freeze: true,
|
||||||
|
callback: () => frm.reload_doc() || dialog.hide()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
primary_action_label: __('Yes')
|
||||||
|
});
|
||||||
|
};
|
||||||
|
add_custom_button(__("Cancel E-Way Bill"), action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const get_ewaybill_fields = (frm) => {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
'fieldname': 'transporter',
|
||||||
|
'label': 'Transporter',
|
||||||
|
'fieldtype': 'Link',
|
||||||
|
'options': 'Supplier',
|
||||||
|
'default': frm.doc.transporter
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'fieldname': 'gst_transporter_id',
|
||||||
|
'label': 'GST Transporter ID',
|
||||||
|
'fieldtype': 'Data',
|
||||||
|
'fetch_from': 'transporter.gst_transporter_id',
|
||||||
|
'default': frm.doc.gst_transporter_id
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'fieldname': 'driver',
|
||||||
|
'label': 'Driver',
|
||||||
|
'fieldtype': 'Link',
|
||||||
|
'options': 'Driver',
|
||||||
|
'default': frm.doc.driver
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'fieldname': 'lr_no',
|
||||||
|
'label': 'Transport Receipt No',
|
||||||
|
'fieldtype': 'Data',
|
||||||
|
'default': frm.doc.lr_no
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'fieldname': 'vehicle_no',
|
||||||
|
'label': 'Vehicle No',
|
||||||
|
'fieldtype': 'Data',
|
||||||
|
'default': frm.doc.vehicle_no
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'fieldname': 'distance',
|
||||||
|
'label': 'Distance (in km)',
|
||||||
|
'fieldtype': 'Float',
|
||||||
|
'default': frm.doc.distance
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'fieldname': 'transporter_col_break',
|
||||||
|
'fieldtype': 'Column Break',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'fieldname': 'transporter_name',
|
||||||
|
'label': 'Transporter Name',
|
||||||
|
'fieldtype': 'Data',
|
||||||
|
'fetch_from': 'transporter.name',
|
||||||
|
'read_only': 1,
|
||||||
|
'default': frm.doc.transporter_name
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'fieldname': 'mode_of_transport',
|
||||||
|
'label': 'Mode of Transport',
|
||||||
|
'fieldtype': 'Select',
|
||||||
|
'options': `\nRoad\nAir\nRail\nShip`,
|
||||||
|
'default': frm.doc.mode_of_transport
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'fieldname': 'driver_name',
|
||||||
|
'label': 'Driver Name',
|
||||||
|
'fieldtype': 'Data',
|
||||||
|
'fetch_from': 'driver.full_name',
|
||||||
|
'read_only': 1,
|
||||||
|
'default': frm.doc.driver_name
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'fieldname': 'lr_date',
|
||||||
|
'label': 'Transport Receipt Date',
|
||||||
|
'fieldtype': 'Date',
|
||||||
|
'default': frm.doc.lr_date
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'fieldname': 'gst_vehicle_type',
|
||||||
|
'label': 'GST Vehicle Type',
|
||||||
|
'fieldtype': 'Select',
|
||||||
|
'options': `Regular\nOver Dimensional Cargo (ODC)`,
|
||||||
|
'depends_on': 'eval:(doc.mode_of_transport === "Road")',
|
||||||
|
'default': frm.doc.gst_vehicle_type
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
const request_irn_generation = (frm) => {
|
||||||
|
frappe.call({
|
||||||
|
method: 'erpnext.regional.india.e_invoice.utils.generate_irn',
|
||||||
|
args: { doctype: frm.doc.doctype, docname: frm.doc.name },
|
||||||
|
freeze: true,
|
||||||
|
callback: () => frm.reload_doc()
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const get_preview_dialog = (frm, action) => {
|
||||||
|
const dialog = new frappe.ui.Dialog({
|
||||||
|
title: __("Preview"),
|
||||||
|
size: "large",
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
"label": "Preview",
|
||||||
|
"fieldname": "preview_html",
|
||||||
|
"fieldtype": "HTML"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
primary_action: () => action(frm) || dialog.hide(),
|
||||||
|
primary_action_label: __('Generate IRN')
|
||||||
|
});
|
||||||
|
return dialog;
|
||||||
|
};
|
||||||
|
|
||||||
|
const show_einvoice_preview = (frm, einvoice) => {
|
||||||
|
const preview_dialog = get_preview_dialog(frm, request_irn_generation);
|
||||||
|
|
||||||
|
// initialize e-invoice fields
|
||||||
|
einvoice["Irn"] = einvoice["AckNo"] = ''; einvoice["AckDt"] = frappe.datetime.nowdate();
|
||||||
|
frm.doc.signed_einvoice = JSON.stringify(einvoice);
|
||||||
|
|
||||||
|
// initialize preview wrapper
|
||||||
|
const $preview_wrapper = preview_dialog.get_field("preview_html").$wrapper;
|
||||||
|
$preview_wrapper.html(
|
||||||
|
`<div>
|
||||||
|
<div class="print-preview">
|
||||||
|
<div class="print-format"></div>
|
||||||
|
</div>
|
||||||
|
<div class="page-break-message text-muted text-center text-medium margin-top"></div>
|
||||||
|
</div>`
|
||||||
|
);
|
||||||
|
|
||||||
|
frappe.call({
|
||||||
|
method: "frappe.www.printview.get_html_and_style",
|
||||||
|
args: {
|
||||||
|
doc: frm.doc,
|
||||||
|
print_format: "GST E-Invoice",
|
||||||
|
no_letterhead: 1
|
||||||
|
},
|
||||||
|
callback: function (r) {
|
||||||
|
if (!r.exc) {
|
||||||
|
$preview_wrapper.find(".print-format").html(r.message.html);
|
||||||
|
const style = `
|
||||||
|
.print-format { box-shadow: 0px 0px 5px rgba(0,0,0,0.2); padding: 0.30in; min-height: 80vh; }
|
||||||
|
.print-preview { min-height: 0px; }
|
||||||
|
.modal-dialog { width: 720px; }`;
|
||||||
|
|
||||||
|
frappe.dom.set_style(style, "custom-print-style");
|
||||||
|
preview_dialog.show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
@ -60,7 +60,7 @@ def create_hsn_codes(data, code_field):
|
|||||||
|
|
||||||
def add_custom_roles_for_reports():
|
def add_custom_roles_for_reports():
|
||||||
for report_name in ('GST Sales Register', 'GST Purchase Register',
|
for report_name in ('GST Sales Register', 'GST Purchase Register',
|
||||||
'GST Itemised Sales Register', 'GST Itemised Purchase Register', 'Eway Bill'):
|
'GST Itemised Sales Register', 'GST Itemised Purchase Register', 'Eway Bill', 'E-Invoice Summary'):
|
||||||
|
|
||||||
if not frappe.db.get_value('Custom Role', dict(report=report_name)):
|
if not frappe.db.get_value('Custom Role', dict(report=report_name)):
|
||||||
frappe.get_doc(dict(
|
frappe.get_doc(dict(
|
||||||
@ -99,7 +99,7 @@ def add_custom_roles_for_reports():
|
|||||||
)).insert()
|
)).insert()
|
||||||
|
|
||||||
def add_permissions():
|
def add_permissions():
|
||||||
for doctype in ('GST HSN Code', 'GST Settings', 'GSTR 3B Report', 'Lower Deduction Certificate'):
|
for doctype in ('GST HSN Code', 'GST Settings', 'GSTR 3B Report', 'Lower Deduction Certificate', 'E Invoice Settings'):
|
||||||
add_permission(doctype, 'All', 0)
|
add_permission(doctype, 'All', 0)
|
||||||
for role in ('Accounts Manager', 'Accounts User', 'System Manager'):
|
for role in ('Accounts Manager', 'Accounts User', 'System Manager'):
|
||||||
add_permission(doctype, role, 0)
|
add_permission(doctype, role, 0)
|
||||||
@ -115,9 +115,11 @@ def add_permissions():
|
|||||||
def add_print_formats():
|
def add_print_formats():
|
||||||
frappe.reload_doc("regional", "print_format", "gst_tax_invoice")
|
frappe.reload_doc("regional", "print_format", "gst_tax_invoice")
|
||||||
frappe.reload_doc("accounts", "print_format", "gst_pos_invoice")
|
frappe.reload_doc("accounts", "print_format", "gst_pos_invoice")
|
||||||
|
frappe.reload_doc("accounts", "print_format", "GST E-Invoice")
|
||||||
|
|
||||||
frappe.db.set_value("Print Format", "GST POS Invoice", "disabled", 0)
|
frappe.db.set_value("Print Format", "GST POS Invoice", "disabled", 0)
|
||||||
frappe.db.set_value("Print Format", "GST Tax Invoice", "disabled", 0)
|
frappe.db.set_value("Print Format", "GST Tax Invoice", "disabled", 0)
|
||||||
|
frappe.db.set_value("Print Format", "GST E-Invoice", "disabled", 0)
|
||||||
|
|
||||||
def make_property_setters(patch=False):
|
def make_property_setters(patch=False):
|
||||||
# GST rules do not allow for an invoice no. bigger than 16 characters
|
# GST rules do not allow for an invoice no. bigger than 16 characters
|
||||||
@ -453,7 +455,7 @@ def get_custom_fields():
|
|||||||
'fieldname': 'ewaybill',
|
'fieldname': 'ewaybill',
|
||||||
'label': 'E-Way Bill No.',
|
'label': 'E-Way Bill No.',
|
||||||
'fieldtype': 'Data',
|
'fieldtype': 'Data',
|
||||||
'depends_on': 'eval:(doc.docstatus === 1)',
|
'depends_on': 'eval:((doc.docstatus === 1 || doc.ewaybill) && doc.eway_bill_cancelled === 0)',
|
||||||
'allow_on_submit': 1,
|
'allow_on_submit': 1,
|
||||||
'insert_after': 'tax_id',
|
'insert_after': 'tax_id',
|
||||||
'translatable': 0,
|
'translatable': 0,
|
||||||
@ -481,6 +483,46 @@ def get_custom_fields():
|
|||||||
fetch_from='customer_address.gstin', print_hide=1, read_only=1)
|
fetch_from='customer_address.gstin', print_hide=1, read_only=1)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
si_einvoice_fields = [
|
||||||
|
dict(fieldname='irn', label='IRN', fieldtype='Data', read_only=1, insert_after='customer', no_copy=1, print_hide=1,
|
||||||
|
depends_on='eval:in_list(["Registered Regular", "SEZ", "Overseas", "Deemed Export"], doc.gst_category) && doc.irn_cancelled === 0'),
|
||||||
|
|
||||||
|
dict(fieldname='irn_cancelled', label='IRN Cancelled', fieldtype='Check', no_copy=1, print_hide=1,
|
||||||
|
depends_on='eval: doc.irn', allow_on_submit=1, insert_after='customer'),
|
||||||
|
|
||||||
|
dict(fieldname='eway_bill_validity', label='E-Way Bill Validity', fieldtype='Data', no_copy=1, print_hide=1,
|
||||||
|
depends_on='ewaybill', read_only=1, allow_on_submit=1, insert_after='ewaybill'),
|
||||||
|
|
||||||
|
dict(fieldname='eway_bill_cancelled', label='E-Way Bill Cancelled', fieldtype='Check', no_copy=1, print_hide=1,
|
||||||
|
depends_on='eval:(doc.eway_bill_cancelled === 1)', read_only=1, allow_on_submit=1, insert_after='customer'),
|
||||||
|
|
||||||
|
dict(fieldname='einvoice_section', label='E-Invoice Fields', fieldtype='Section Break', insert_after='gst_vehicle_type',
|
||||||
|
print_hide=1, hidden=1),
|
||||||
|
|
||||||
|
dict(fieldname='ack_no', label='Ack. No.', fieldtype='Data', read_only=1, hidden=1, insert_after='einvoice_section',
|
||||||
|
no_copy=1, print_hide=1),
|
||||||
|
|
||||||
|
dict(fieldname='ack_date', label='Ack. Date', fieldtype='Data', read_only=1, hidden=1, insert_after='ack_no', no_copy=1, print_hide=1),
|
||||||
|
|
||||||
|
dict(fieldname='irn_cancel_date', label='Cancel Date', fieldtype='Data', read_only=1, hidden=1, insert_after='ack_date',
|
||||||
|
no_copy=1, print_hide=1),
|
||||||
|
|
||||||
|
dict(fieldname='signed_einvoice', label='Signed E-Invoice', fieldtype='Code', options='JSON', hidden=1, insert_after='irn_cancel_date',
|
||||||
|
no_copy=1, print_hide=1, read_only=1),
|
||||||
|
|
||||||
|
dict(fieldname='signed_qr_code', label='Signed QRCode', fieldtype='Code', options='JSON', hidden=1, insert_after='signed_einvoice',
|
||||||
|
no_copy=1, print_hide=1, read_only=1),
|
||||||
|
|
||||||
|
dict(fieldname='qrcode_image', label='QRCode', fieldtype='Attach Image', hidden=1, insert_after='signed_qr_code',
|
||||||
|
no_copy=1, print_hide=1, read_only=1),
|
||||||
|
|
||||||
|
dict(fieldname='einvoice_status', label='E-Invoice Status', fieldtype='Select', insert_after='qrcode_image',
|
||||||
|
options='\nPending\nGenerated\nCancelled\nFailed', default=None, hidden=1, no_copy=1, print_hide=1, read_only=1),
|
||||||
|
|
||||||
|
dict(fieldname='failure_description', label='E-Invoice Failure Description', fieldtype='Code', options='JSON',
|
||||||
|
hidden=1, insert_after='einvoice_status', no_copy=1, print_hide=1, read_only=1)
|
||||||
|
]
|
||||||
|
|
||||||
custom_fields = {
|
custom_fields = {
|
||||||
'Address': [
|
'Address': [
|
||||||
dict(fieldname='gstin', label='Party GSTIN', fieldtype='Data',
|
dict(fieldname='gstin', label='Party GSTIN', fieldtype='Data',
|
||||||
@ -493,7 +535,7 @@ def get_custom_fields():
|
|||||||
'Purchase Invoice': purchase_invoice_gst_category + invoice_gst_fields + purchase_invoice_itc_fields + purchase_invoice_gst_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 Order': purchase_invoice_gst_fields,
|
||||||
'Purchase Receipt': purchase_invoice_gst_fields,
|
'Purchase Receipt': purchase_invoice_gst_fields,
|
||||||
'Sales Invoice': sales_invoice_gst_category + invoice_gst_fields + sales_invoice_shipping_fields + sales_invoice_gst_fields + si_ewaybill_fields,
|
'Sales Invoice': sales_invoice_gst_category + invoice_gst_fields + sales_invoice_shipping_fields + sales_invoice_gst_fields + si_ewaybill_fields + si_einvoice_fields,
|
||||||
'POS Invoice': sales_invoice_gst_fields,
|
'POS Invoice': sales_invoice_gst_fields,
|
||||||
'Delivery Note': sales_invoice_gst_fields + ewaybill_fields + sales_invoice_shipping_fields + delivery_note_gst_category,
|
'Delivery Note': sales_invoice_gst_fields + ewaybill_fields + sales_invoice_shipping_fields + delivery_note_gst_category,
|
||||||
'Payment Entry': payment_entry_fields,
|
'Payment Entry': payment_entry_fields,
|
||||||
|
@ -0,0 +1,55 @@
|
|||||||
|
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
// For license information, please see license.txt
|
||||||
|
/* eslint-disable */
|
||||||
|
|
||||||
|
frappe.query_reports["E-Invoice Summary"] = {
|
||||||
|
"filters": [
|
||||||
|
{
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "Company",
|
||||||
|
"reqd": 1,
|
||||||
|
"fieldname": "company",
|
||||||
|
"label": __("Company"),
|
||||||
|
"default": frappe.defaults.get_user_default("Company"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "Customer",
|
||||||
|
"fieldname": "customer",
|
||||||
|
"label": __("Customer")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldtype": "Date",
|
||||||
|
"reqd": 1,
|
||||||
|
"fieldname": "from_date",
|
||||||
|
"label": __("From Date"),
|
||||||
|
"default": frappe.datetime.add_months(frappe.datetime.get_today(), -1),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldtype": "Date",
|
||||||
|
"reqd": 1,
|
||||||
|
"fieldname": "to_date",
|
||||||
|
"label": __("To Date"),
|
||||||
|
"default": frappe.datetime.get_today(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldtype": "Select",
|
||||||
|
"fieldname": "status",
|
||||||
|
"label": __("Status"),
|
||||||
|
"options": "\nPending\nGenerated\nCancelled\nFailed"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
"formatter": function (value, row, column, data, default_formatter) {
|
||||||
|
value = default_formatter(value, row, column, data);
|
||||||
|
|
||||||
|
if (column.fieldname == "einvoice_status" && value) {
|
||||||
|
if (value == 'Pending') value = `<span class="bold" style="color: var(--text-on-orange)">${value}</span>`;
|
||||||
|
else if (value == 'Generated') value = `<span class="bold" style="color: var(--text-on-green)">${value}</span>`;
|
||||||
|
else if (value == 'Cancelled') value = `<span class="bold" style="color: var(--text-on-red)">${value}</span>`;
|
||||||
|
else if (value == 'Failed') value = `<span class="bold" style="color: var(--text-on-red)">${value}</span>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
};
|
@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"add_total_row": 0,
|
||||||
|
"columns": [],
|
||||||
|
"creation": "2021-03-12 11:23:37.312294",
|
||||||
|
"disable_prepared_report": 0,
|
||||||
|
"disabled": 0,
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "Report",
|
||||||
|
"filters": [],
|
||||||
|
"idx": 0,
|
||||||
|
"is_standard": "Yes",
|
||||||
|
"json": "{}",
|
||||||
|
"letter_head": "Logo",
|
||||||
|
"modified": "2021-03-13 12:36:48.689413",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "Regional",
|
||||||
|
"name": "E-Invoice Summary",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"prepared_report": 0,
|
||||||
|
"ref_doctype": "Sales Invoice",
|
||||||
|
"report_name": "E-Invoice Summary",
|
||||||
|
"report_type": "Script Report",
|
||||||
|
"roles": [
|
||||||
|
{
|
||||||
|
"role": "Administrator"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
112
erpnext/regional/report/e_invoice_summary/e_invoice_summary.py
Normal file
112
erpnext/regional/report/e_invoice_summary/e_invoice_summary.py
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import frappe
|
||||||
|
from frappe import _
|
||||||
|
|
||||||
|
|
||||||
|
def execute(filters=None):
|
||||||
|
validate_filters(filters)
|
||||||
|
|
||||||
|
columns = get_columns()
|
||||||
|
data = get_data(filters)
|
||||||
|
|
||||||
|
return columns, data
|
||||||
|
|
||||||
|
def validate_filters(filters=None):
|
||||||
|
if filters is None:
|
||||||
|
filters = {}
|
||||||
|
filters = frappe._dict(filters)
|
||||||
|
|
||||||
|
if not filters.company:
|
||||||
|
frappe.throw(_('{} is mandatory for generating E-Invoice Summary Report').format(_('Company')), title=_('Invalid Filter'))
|
||||||
|
if filters.company:
|
||||||
|
# validate if company has e-invoicing enabled
|
||||||
|
pass
|
||||||
|
if not filters.from_date or not filters.to_date:
|
||||||
|
frappe.throw(_('From Date & To Date is mandatory for generating E-Invoice Summary Report'), title=_('Invalid Filter'))
|
||||||
|
if filters.from_date > filters.to_date:
|
||||||
|
frappe.throw(_('From Date must be before To Date'), title=_('Invalid Filter'))
|
||||||
|
|
||||||
|
def get_data(filters=None):
|
||||||
|
if filters is None:
|
||||||
|
filters = {}
|
||||||
|
query_filters = {
|
||||||
|
'posting_date': ['between', [filters.from_date, filters.to_date]],
|
||||||
|
'einvoice_status': ['is', 'set'],
|
||||||
|
'company': filters.company
|
||||||
|
}
|
||||||
|
if filters.customer:
|
||||||
|
query_filters['customer'] = filters.customer
|
||||||
|
if filters.status:
|
||||||
|
query_filters['einvoice_status'] = filters.status
|
||||||
|
|
||||||
|
data = frappe.get_all(
|
||||||
|
'Sales Invoice',
|
||||||
|
filters=query_filters,
|
||||||
|
fields=[d.get('fieldname') for d in get_columns()]
|
||||||
|
)
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
def get_columns():
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
"fieldtype": "Date",
|
||||||
|
"fieldname": "posting_date",
|
||||||
|
"label": _("Posting Date"),
|
||||||
|
"width": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"fieldname": "name",
|
||||||
|
"label": _("Sales Invoice"),
|
||||||
|
"options": "Sales Invoice",
|
||||||
|
"width": 140
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"fieldname": "einvoice_status",
|
||||||
|
"label": _("Status"),
|
||||||
|
"width": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"fieldname": "customer",
|
||||||
|
"options": "Customer",
|
||||||
|
"label": _("Customer")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"fieldname": "is_return",
|
||||||
|
"label": _("Is Return"),
|
||||||
|
"width": 85
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"fieldname": "ack_no",
|
||||||
|
"label": "Ack. No.",
|
||||||
|
"width": 145
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"fieldname": "ack_date",
|
||||||
|
"label": "Ack. Date",
|
||||||
|
"width": 165
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"fieldname": "irn",
|
||||||
|
"label": _("IRN No."),
|
||||||
|
"width": 250
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"options": "Company:company:default_currency",
|
||||||
|
"fieldname": "base_grand_total",
|
||||||
|
"label": _("Grand Total"),
|
||||||
|
"width": 120
|
||||||
|
}
|
||||||
|
]
|
Loading…
x
Reference in New Issue
Block a user