Merge branch 'develop' into common-party-acc
This commit is contained in:
commit
5395f56c88
@ -595,7 +595,8 @@
|
||||
{
|
||||
"fieldname": "scan_barcode",
|
||||
"fieldtype": "Data",
|
||||
"label": "Scan Barcode"
|
||||
"label": "Scan Barcode",
|
||||
"options": "Barcode"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 1,
|
||||
@ -1553,7 +1554,7 @@
|
||||
"icon": "fa fa-file-text",
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2021-07-29 13:37:20.636171",
|
||||
"modified": "2021-08-17 20:13:44.255437",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "POS Invoice",
|
||||
|
@ -106,7 +106,6 @@
|
||||
"depends_on": "eval:doc.rate_or_discount==\"Rate\"",
|
||||
"fieldname": "rate",
|
||||
"fieldtype": "Currency",
|
||||
"in_list_view": 1,
|
||||
"label": "Rate"
|
||||
},
|
||||
{
|
||||
@ -170,7 +169,7 @@
|
||||
"index_web_pages_for_search": 1,
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2021-03-07 11:56:23.424137",
|
||||
"modified": "2021-08-19 15:49:29.598727",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Promotional Scheme Price Discount",
|
||||
|
@ -668,8 +668,7 @@
|
||||
"fieldname": "scan_barcode",
|
||||
"fieldtype": "Data",
|
||||
"label": "Scan Barcode",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
"options": "Barcode"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 1,
|
||||
@ -1715,7 +1714,7 @@
|
||||
"idx": 204,
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2021-08-07 17:53:14.351439",
|
||||
"modified": "2021-08-17 20:16:12.737743",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Purchase Invoice",
|
||||
|
@ -1,8 +1,6 @@
|
||||
{% include "erpnext/regional/india/taxes.js" %}
|
||||
{% include "erpnext/regional/india/e_invoice/einvoice.js" %}
|
||||
|
||||
erpnext.setup_auto_gst_taxation('Sales Invoice');
|
||||
erpnext.setup_einvoice_actions('Sales Invoice')
|
||||
|
||||
frappe.ui.form.on("Sales Invoice", {
|
||||
setup: function(frm) {
|
||||
|
@ -36,139 +36,4 @@ frappe.listview_settings['Sales Invoice'].onload = function (list_view) {
|
||||
};
|
||||
|
||||
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'
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
@ -692,6 +692,7 @@
|
||||
{
|
||||
"fieldname": "scan_barcode",
|
||||
"fieldtype": "Data",
|
||||
"options": "Barcode",
|
||||
"hide_days": 1,
|
||||
"hide_seconds": 1,
|
||||
"label": "Scan Barcode"
|
||||
@ -2013,7 +2014,7 @@
|
||||
"link_fieldname": "consolidated_invoice"
|
||||
}
|
||||
],
|
||||
"modified": "2021-08-17 19:00:32.230701",
|
||||
"modified": "2021-08-17 20:16:12.737743",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Sales Invoice",
|
||||
|
@ -287,8 +287,6 @@ class SalesInvoice(SellingController):
|
||||
|
||||
def before_cancel(self):
|
||||
self.check_if_consolidated_invoice()
|
||||
|
||||
super(SalesInvoice, self).before_cancel()
|
||||
self.update_time_sheet(None)
|
||||
|
||||
def on_cancel(self):
|
||||
|
@ -2027,54 +2027,6 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
self.assertEqual(data['billLists'][0]['actualFromStateCode'],7)
|
||||
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):
|
||||
item = create_item("T Shirt")
|
||||
|
||||
|
@ -1,162 +0,0 @@
|
||||
{%- 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>
|
@ -1,24 +0,0 @@
|
||||
{
|
||||
"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"
|
||||
}
|
@ -565,6 +565,7 @@
|
||||
"fieldname": "scan_barcode",
|
||||
"fieldtype": "Data",
|
||||
"label": "Scan Barcode",
|
||||
"options": "Barcode",
|
||||
"show_days": 1,
|
||||
"show_seconds": 1
|
||||
},
|
||||
@ -1378,7 +1379,7 @@
|
||||
"idx": 105,
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2021-05-30 15:17:53.663648",
|
||||
"modified": "2021-08-17 20:16:12.737743",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Buying",
|
||||
"name": "Purchase Order",
|
||||
|
@ -135,14 +135,9 @@ class AccountsController(TransactionBase):
|
||||
|
||||
validate_regional(self)
|
||||
|
||||
validate_einvoice_fields(self)
|
||||
|
||||
if self.doctype != 'Material Request':
|
||||
apply_pricing_rule_on_transaction(self)
|
||||
|
||||
def before_cancel(self):
|
||||
validate_einvoice_fields(self)
|
||||
|
||||
def on_trash(self):
|
||||
# delete sl and gl entries on deletion of transaction
|
||||
if frappe.db.get_single_value('Accounts Settings', 'delete_linked_ledger_entries'):
|
||||
@ -2035,7 +2030,3 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil
|
||||
@erpnext.allow_regional
|
||||
def validate_regional(doc):
|
||||
pass
|
||||
|
||||
@erpnext.allow_regional
|
||||
def validate_einvoice_fields(doc):
|
||||
pass
|
||||
|
@ -251,7 +251,7 @@ doc_events = {
|
||||
"erpnext.support.doctype.issue.issue.set_first_response_time"
|
||||
]
|
||||
},
|
||||
("Sales Taxes and Charges Template", 'Price List'): {
|
||||
"Sales Taxes and Charges Template": {
|
||||
"on_update": "erpnext.shopping_cart.doctype.shopping_cart_settings.shopping_cart_settings.validate_cart_settings"
|
||||
},
|
||||
"Website Settings": {
|
||||
@ -308,6 +308,9 @@ doc_events = {
|
||||
},
|
||||
('Quotation', 'Sales Order', 'Sales Invoice'): {
|
||||
'validate': ["erpnext.erpnext_integrations.taxjar_integration.set_sales_tax"]
|
||||
},
|
||||
"Company": {
|
||||
"on_trash": "erpnext.regional.india.utils.delete_gst_settings_for_company"
|
||||
}
|
||||
}
|
||||
|
||||
@ -436,7 +439,6 @@ regional_overrides = {
|
||||
'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_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.stock.doctype.item.item.set_item_tax_from_hsn_code': 'erpnext.regional.india.utils.set_item_tax_from_hsn_code'
|
||||
},
|
||||
|
@ -235,7 +235,7 @@ frappe.ui.form.on("BOM", {
|
||||
reqd: 1,
|
||||
},
|
||||
{
|
||||
fieldname: "varint_item_code",
|
||||
fieldname: "variant_item_code",
|
||||
options: "Item",
|
||||
label: __("Variant Item"),
|
||||
fieldtype: "Link",
|
||||
@ -287,7 +287,7 @@ frappe.ui.form.on("BOM", {
|
||||
let variant_items = data.items || [];
|
||||
|
||||
variant_items.forEach(d => {
|
||||
if (!d.varint_item_code) {
|
||||
if (!d.variant_item_code) {
|
||||
frappe.throw(__("Select variant item code for the template item {0}", [d.item_code]));
|
||||
}
|
||||
})
|
||||
@ -299,7 +299,7 @@ frappe.ui.form.on("BOM", {
|
||||
has_template_rm.forEach(d => {
|
||||
dialog.fields_dict.items.df.data.push({
|
||||
"item_code": d.item_code,
|
||||
"varint_item_code": "",
|
||||
"variant_item_code": "",
|
||||
"qty": d.qty,
|
||||
"source_warehouse": d.source_warehouse,
|
||||
"operation": d.operation
|
||||
|
@ -346,6 +346,7 @@ class ProductionPlan(Document):
|
||||
"production_plan" : self.name,
|
||||
"production_plan_item" : d.name,
|
||||
"product_bundle_item" : d.product_bundle_item,
|
||||
"planned_start_date" : d.planned_start_date,
|
||||
"make_work_order_for_sub_assembly_items": d.get("make_work_order_for_sub_assembly_items", 0)
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@ from __future__ import unicode_literals
|
||||
|
||||
import frappe
|
||||
import unittest
|
||||
from frappe.utils import nowdate, now_datetime, flt
|
||||
from frappe.utils import nowdate, now_datetime, flt, add_to_date
|
||||
from erpnext.stock.doctype.item.test_item import create_item
|
||||
from erpnext.manufacturing.doctype.production_plan.production_plan import get_sales_orders
|
||||
from erpnext.stock.doctype.stock_reconciliation.test_stock_reconciliation import create_stock_reconciliation
|
||||
@ -61,6 +61,21 @@ class TestProductionPlan(unittest.TestCase):
|
||||
pln = frappe.get_doc('Production Plan', pln.name)
|
||||
pln.cancel()
|
||||
|
||||
def test_production_plan_start_date(self):
|
||||
planned_date = add_to_date(date=None, days=3)
|
||||
plan = create_production_plan(item_code='Test Production Item 1', planned_start_date=planned_date)
|
||||
plan.make_work_order()
|
||||
|
||||
work_orders = frappe.get_all('Work Order', fields = ['name', 'planned_start_date'],
|
||||
filters = {'production_plan': plan.name})
|
||||
|
||||
self.assertEqual(work_orders[0].planned_start_date, planned_date)
|
||||
|
||||
for wo in work_orders:
|
||||
frappe.delete_doc('Work Order', wo.name)
|
||||
|
||||
frappe.get_doc('Production Plan', plan.name).cancel()
|
||||
|
||||
def test_production_plan_for_existing_ordered_qty(self):
|
||||
sr1 = create_stock_reconciliation(item_code="Raw Material Item 1",
|
||||
target="_Test Warehouse - _TC", qty=1, rate=110)
|
||||
|
@ -602,7 +602,7 @@ class WorkOrder(Document):
|
||||
|
||||
if self.docstatus==1:
|
||||
# calculate transferred qty based on submitted stock entries
|
||||
self.update_transaferred_qty_for_required_items()
|
||||
self.update_transferred_qty_for_required_items()
|
||||
|
||||
# update in bin
|
||||
self.update_reserved_qty_for_production()
|
||||
@ -671,7 +671,7 @@ class WorkOrder(Document):
|
||||
|
||||
self.set_available_qty()
|
||||
|
||||
def update_transaferred_qty_for_required_items(self):
|
||||
def update_transferred_qty_for_required_items(self):
|
||||
'''update transferred qty from submitted stock entries for that item against
|
||||
the work order'''
|
||||
|
||||
@ -838,7 +838,7 @@ def add_variant_item(variant_items, wo_doc, bom_no, table_name="items"):
|
||||
|
||||
for item in variant_items:
|
||||
args = frappe._dict({
|
||||
"item_code": item.get("varint_item_code"),
|
||||
"item_code": item.get("variant_item_code"),
|
||||
"required_qty": item.get("qty"),
|
||||
"qty": item.get("qty"), # for bom
|
||||
"source_warehouse": item.get("source_warehouse"),
|
||||
@ -859,7 +859,7 @@ def add_variant_item(variant_items, wo_doc, bom_no, table_name="items"):
|
||||
}, bom_doc)
|
||||
|
||||
if not args.source_warehouse:
|
||||
args["source_warehouse"] = get_item_defaults(item.get("varint_item_code"),
|
||||
args["source_warehouse"] = get_item_defaults(item.get("variant_item_code"),
|
||||
wo_doc.company).default_warehouse
|
||||
|
||||
args["amount"] = flt(args.get("required_qty")) * flt(args.get("rate"))
|
||||
|
@ -214,7 +214,6 @@ erpnext.patches.v13_0.delete_old_sales_reports
|
||||
execute:frappe.delete_doc_if_exists("DocType", "Bank Reconciliation")
|
||||
erpnext.patches.v13_0.move_doctype_reports_and_notification_from_hr_to_payroll #22-06-2020
|
||||
erpnext.patches.v13_0.move_payroll_setting_separately_from_hr_settings #22-06-2020
|
||||
execute:frappe.reload_doc("regional", "doctype", "e_invoice_settings")
|
||||
erpnext.patches.v13_0.check_is_income_tax_component #22-06-2020
|
||||
erpnext.patches.v13_0.loyalty_points_entry_for_pos_invoice #22-07-2020
|
||||
erpnext.patches.v12_0.add_taxjar_integration_field
|
||||
@ -237,7 +236,6 @@ erpnext.patches.v13_0.set_app_name
|
||||
erpnext.patches.v13_0.print_uom_after_quantity_patch
|
||||
erpnext.patches.v13_0.set_payment_channel_in_payment_gateway_account
|
||||
erpnext.patches.v13_0.create_healthcare_custom_fields_in_stock_entry_detail
|
||||
erpnext.patches.v12_0.setup_einvoice_fields #2020-12-02
|
||||
erpnext.patches.v13_0.updates_for_multi_currency_payroll
|
||||
erpnext.patches.v13_0.update_reason_for_resignation_in_employee
|
||||
execute:frappe.delete_doc("Report", "Quoted Item Comparison")
|
||||
@ -259,14 +257,11 @@ erpnext.patches.v12_0.add_state_code_for_ladakh
|
||||
erpnext.patches.v13_0.item_reposting_for_incorrect_sl_and_gl
|
||||
erpnext.patches.v13_0.delete_old_bank_reconciliation_doctypes
|
||||
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.rename_membership_settings_to_non_profit_settings
|
||||
erpnext.patches.v13_0.setup_gratuity_rule_for_india_and_uae
|
||||
erpnext.patches.v13_0.setup_uae_vat_fields
|
||||
execute:frappe.db.set_value('System Settings', None, 'app_name', 'ERPNext')
|
||||
erpnext.patches.v12_0.add_company_link_to_einvoice_settings
|
||||
erpnext.patches.v13_0.rename_discharge_date_in_ip_record
|
||||
erpnext.patches.v12_0.create_taxable_value_field
|
||||
erpnext.patches.v12_0.add_gst_category_in_delivery_note
|
||||
@ -277,7 +272,6 @@ erpnext.patches.v12_0.add_document_type_field_for_italy_einvoicing
|
||||
erpnext.patches.v13_0.make_non_standard_user_type #13-04-2021
|
||||
erpnext.patches.v13_0.update_shipment_status
|
||||
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_fill_debtor_creditor_number
|
||||
erpnext.patches.v13_0.set_pos_closing_as_failed
|
||||
@ -294,10 +288,11 @@ erpnext.patches.v13_0.update_level_in_bom #1234sswef
|
||||
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_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.update_export_type_for_gst #2021-08-16
|
||||
erpnext.patches.v13_0.update_tds_check_field #3
|
||||
erpnext.patches.v13_0.add_custom_field_for_south_africa #2
|
||||
erpnext.patches.v13_0.update_recipient_email_digest
|
||||
erpnext.patches.v13_0.shopify_deprecation_warning
|
||||
erpnext.patches.v13_0.einvoicing_deprecation_warning
|
||||
erpnext.patches.v14_0.delete_einvoicing_doctypes
|
||||
|
@ -1,16 +0,0 @@
|
||||
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])
|
@ -1,69 +0,0 @@
|
||||
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)
|
@ -1,18 +0,0 @@
|
||||
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()
|
@ -1,16 +0,0 @@
|
||||
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)
|
@ -1,56 +0,0 @@
|
||||
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)
|
@ -1,12 +0,0 @@
|
||||
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)
|
9
erpnext/patches/v13_0/einvoicing_deprecation_warning.py
Normal file
9
erpnext/patches/v13_0/einvoicing_deprecation_warning.py
Normal file
@ -0,0 +1,9 @@
|
||||
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",
|
||||
)
|
9
erpnext/patches/v14_0/delete_einvoicing_doctypes.py
Normal file
9
erpnext/patches/v14_0/delete_einvoicing_doctypes.py
Normal file
@ -0,0 +1,9 @@
|
||||
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)
|
@ -342,30 +342,6 @@ erpnext.TransactionController = class TransactionController extends erpnext.taxe
|
||||
this.set_dynamic_labels();
|
||||
this.setup_sms();
|
||||
this.setup_quality_inspection();
|
||||
let scan_barcode_field = this.frm.get_field('scan_barcode');
|
||||
if (scan_barcode_field && scan_barcode_field.get_value()) {
|
||||
scan_barcode_field.set_value("");
|
||||
scan_barcode_field.set_new_description("");
|
||||
|
||||
if (frappe.is_mobile()) {
|
||||
if (scan_barcode_field.$input_wrapper.find('.input-group').length) return;
|
||||
|
||||
let $input_group = $('<div class="input-group">');
|
||||
scan_barcode_field.$input_wrapper.find('.control-input').append($input_group);
|
||||
$input_group.append(scan_barcode_field.$input);
|
||||
$(`<span class="input-group-btn" style="vertical-align: top">
|
||||
<button class="btn btn-default border" type="button">
|
||||
<i class="fa fa-camera text-muted"></i>
|
||||
</button>
|
||||
</span>`)
|
||||
.on('click', '.btn', () => {
|
||||
frappe.barcode.scan_barcode().then(barcode => {
|
||||
scan_barcode_field.set_value(barcode);
|
||||
});
|
||||
})
|
||||
.appendTo($input_group);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
scan_barcode() {
|
||||
|
@ -1,8 +0,0 @@
|
||||
// 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) {
|
||||
|
||||
// }
|
||||
});
|
@ -1,102 +0,0 @@
|
||||
{
|
||||
"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"
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
# -*- 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
|
@ -1,10 +0,0 @@
|
||||
# -*- 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
|
@ -1,11 +0,0 @@
|
||||
// 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>`])
|
||||
);
|
||||
}
|
||||
});
|
@ -1,73 +0,0 @@
|
||||
{
|
||||
"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
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
# -*- 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.'))
|
@ -1,10 +0,0 @@
|
||||
# -*- 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
|
@ -1,57 +0,0 @@
|
||||
{
|
||||
"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
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
# -*- 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
|
@ -1,31 +0,0 @@
|
||||
{{
|
||||
"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}"
|
||||
}}
|
||||
}}
|
@ -1,110 +0,0 @@
|
||||
{{
|
||||
"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}"
|
||||
}}
|
||||
}}
|
@ -1,957 +0,0 @@
|
||||
{
|
||||
"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"
|
||||
]
|
||||
}
|
@ -1,292 +0,0 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
@ -61,7 +61,7 @@ def create_hsn_codes(data, code_field):
|
||||
|
||||
def add_custom_roles_for_reports():
|
||||
for report_name in ('GST Sales Register', 'GST Purchase Register',
|
||||
'GST Itemised Sales Register', 'GST Itemised Purchase Register', 'Eway Bill', 'E-Invoice Summary'):
|
||||
'GST Itemised Sales Register', 'GST Itemised Purchase Register', 'Eway Bill'):
|
||||
|
||||
if not frappe.db.get_value('Custom Role', dict(report=report_name)):
|
||||
frappe.get_doc(dict(
|
||||
@ -100,7 +100,7 @@ def add_custom_roles_for_reports():
|
||||
)).insert()
|
||||
|
||||
def add_permissions():
|
||||
for doctype in ('GST HSN Code', 'GST Settings', 'GSTR 3B Report', 'Lower Deduction Certificate', 'E Invoice Settings'):
|
||||
for doctype in ('GST HSN Code', 'GST Settings', 'GSTR 3B Report', 'Lower Deduction Certificate'):
|
||||
add_permission(doctype, 'All', 0)
|
||||
for role in ('Accounts Manager', 'Accounts User', 'System Manager'):
|
||||
add_permission(doctype, role, 0)
|
||||
@ -116,11 +116,9 @@ def add_permissions():
|
||||
def add_print_formats():
|
||||
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 E-Invoice")
|
||||
|
||||
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 E-Invoice", "disabled", 0)
|
||||
|
||||
def make_property_setters(patch=False):
|
||||
# GST rules do not allow for an invoice no. bigger than 16 characters
|
||||
@ -445,53 +443,13 @@ def make_custom_fields(update=True):
|
||||
'fieldname': 'ewaybill',
|
||||
'label': 'E-Way Bill No.',
|
||||
'fieldtype': 'Data',
|
||||
'depends_on': 'eval:((doc.docstatus === 1 || doc.ewaybill) && doc.eway_bill_cancelled === 0)',
|
||||
'depends_on': 'eval:(doc.docstatus === 1)',
|
||||
'allow_on_submit': 1,
|
||||
'insert_after': 'tax_id',
|
||||
'translatable': 0
|
||||
}
|
||||
]
|
||||
|
||||
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 = {
|
||||
'Address': [
|
||||
dict(fieldname='gstin', label='Party GSTIN', fieldtype='Data',
|
||||
@ -504,7 +462,7 @@ def make_custom_fields(update=True):
|
||||
'Purchase Invoice': purchase_invoice_gst_category + invoice_gst_fields + purchase_invoice_itc_fields + purchase_invoice_gst_fields,
|
||||
'Purchase Order': 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 + si_einvoice_fields,
|
||||
'Sales Invoice': sales_invoice_gst_category + invoice_gst_fields + sales_invoice_shipping_fields + sales_invoice_gst_fields + si_ewaybill_fields,
|
||||
'Delivery Note': sales_invoice_gst_fields + ewaybill_fields + sales_invoice_shipping_fields + delivery_note_gst_category,
|
||||
'Journal Entry': journal_entry_fields,
|
||||
'Sales Order': sales_invoice_gst_fields,
|
||||
|
@ -871,3 +871,20 @@ def set_item_tax_from_hsn_code(item):
|
||||
'tax_category': tax.tax_category,
|
||||
'valid_from': tax.valid_from
|
||||
})
|
||||
|
||||
def delete_gst_settings_for_company(doc, method):
|
||||
if doc.country != 'India':
|
||||
return
|
||||
|
||||
gst_settings = frappe.get_doc("GST Settings")
|
||||
records_to_delete = []
|
||||
|
||||
for d in reversed(gst_settings.get('gst_accounts')):
|
||||
if d.company == doc.name:
|
||||
records_to_delete.append(d)
|
||||
|
||||
for d in records_to_delete:
|
||||
gst_settings.remove(d)
|
||||
|
||||
gst_settings.save()
|
||||
|
||||
|
@ -1,55 +0,0 @@
|
||||
// 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;
|
||||
}
|
||||
};
|
@ -1,28 +0,0 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
@ -1,106 +0,0 @@
|
||||
# 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={}):
|
||||
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={}):
|
||||
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
|
||||
}
|
||||
]
|
@ -571,7 +571,8 @@
|
||||
"fieldtype": "Data",
|
||||
"hide_days": 1,
|
||||
"hide_seconds": 1,
|
||||
"label": "Scan Barcode"
|
||||
"label": "Scan Barcode",
|
||||
"options": "Barcode"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 1,
|
||||
@ -1510,7 +1511,7 @@
|
||||
"idx": 105,
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2021-07-08 21:37:44.177493",
|
||||
"modified": "2021-08-17 20:15:26.531553",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Selling",
|
||||
"name": "Sales Order",
|
||||
|
@ -393,6 +393,10 @@ class Company(NestedSet):
|
||||
frappe.db.sql("delete from `tabPurchase Taxes and Charges Template` where company=%s", self.name)
|
||||
frappe.db.sql("delete from `tabItem Tax Template` where company=%s", self.name)
|
||||
|
||||
# delete Process Deferred Accounts if no GL Entry found
|
||||
if not frappe.db.get_value('GL Entry', {'company': self.name}):
|
||||
frappe.db.sql("delete from `tabProcess Deferred Accounting` where company=%s", self.name)
|
||||
|
||||
@frappe.whitelist()
|
||||
def enqueue_replace_abbr(company, old, new):
|
||||
kwargs = dict(queue="long", company=company, old=old, new=new)
|
||||
|
@ -6,7 +6,7 @@
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe import _, msgprint
|
||||
from frappe.utils import comma_and
|
||||
from frappe.utils import flt
|
||||
from frappe.model.document import Document
|
||||
from frappe.utils import get_datetime, get_datetime_str, now_datetime
|
||||
|
||||
@ -18,46 +18,35 @@ class ShoppingCartSettings(Document):
|
||||
|
||||
def validate(self):
|
||||
if self.enabled:
|
||||
self.validate_exchange_rates_exist()
|
||||
self.validate_price_list_exchange_rate()
|
||||
|
||||
def validate_price_list_exchange_rate(self):
|
||||
"Check if exchange rate exists for Price List currency (to Company's currency)."
|
||||
from erpnext.setup.utils import get_exchange_rate
|
||||
|
||||
if not self.enabled or not self.company or not self.price_list:
|
||||
return # this function is also called from hooks, check values again
|
||||
|
||||
company_currency = frappe.get_cached_value("Company", self.company, "default_currency")
|
||||
price_list_currency = frappe.db.get_value("Price List", self.price_list, "currency")
|
||||
|
||||
def validate_exchange_rates_exist(self):
|
||||
"""check if exchange rates exist for all Price List currencies (to company's currency)"""
|
||||
company_currency = frappe.get_cached_value('Company', self.company, "default_currency")
|
||||
if not company_currency:
|
||||
msgprint(_("Please specify currency in Company") + ": " + self.company,
|
||||
raise_exception=ShoppingCartSetupError)
|
||||
msg = f"Please specify currency in Company {self.company}"
|
||||
frappe.throw(_(msg), title=_("Missing Currency"), exc=ShoppingCartSetupError)
|
||||
|
||||
price_list_currency_map = frappe.db.get_values("Price List",
|
||||
[self.price_list], "currency")
|
||||
if not price_list_currency:
|
||||
msg = f"Please specify currency in Price List {frappe.bold(self.price_list)}"
|
||||
frappe.throw(_(msg), title=_("Missing Currency"), exc=ShoppingCartSetupError)
|
||||
|
||||
price_list_currency_map = dict(price_list_currency_map)
|
||||
if price_list_currency != company_currency:
|
||||
from_currency, to_currency = price_list_currency, company_currency
|
||||
|
||||
# check if all price lists have a currency
|
||||
for price_list, currency in price_list_currency_map.items():
|
||||
if not currency:
|
||||
frappe.throw(_("Currency is required for Price List {0}").format(price_list))
|
||||
# Get exchange rate checks Currency Exchange Records too
|
||||
exchange_rate = get_exchange_rate(from_currency, to_currency, args="for_selling")
|
||||
|
||||
expected_to_exist = [currency + "-" + company_currency
|
||||
for currency in price_list_currency_map.values()
|
||||
if currency != company_currency]
|
||||
|
||||
# manqala 20/09/2016: set up selection parameters for query from tabCurrency Exchange
|
||||
from_currency = [currency for currency in price_list_currency_map.values() if currency != company_currency]
|
||||
to_currency = company_currency
|
||||
# manqala end
|
||||
|
||||
if expected_to_exist:
|
||||
# manqala 20/09/2016: modify query so that it uses date in the selection from Currency Exchange.
|
||||
# exchange rates defined with date less than the date on which this document is being saved will be selected
|
||||
exists = frappe.db.sql_list("""select CONCAT(from_currency,'-',to_currency) from `tabCurrency Exchange`
|
||||
where from_currency in (%s) and to_currency = "%s" and date <= curdate()""" % (", ".join(["%s"]*len(from_currency)), to_currency), tuple(from_currency))
|
||||
# manqala end
|
||||
|
||||
missing = list(set(expected_to_exist).difference(exists))
|
||||
|
||||
if missing:
|
||||
msgprint(_("Missing Currency Exchange Rates for {0}").format(comma_and(missing)),
|
||||
raise_exception=ShoppingCartSetupError)
|
||||
if not flt(exchange_rate):
|
||||
msg = f"Missing Currency Exchange Rates for {from_currency}-{to_currency}"
|
||||
frappe.throw(_(msg), title=_("Missing"), exc=ShoppingCartSetupError)
|
||||
|
||||
def validate_tax_rule(self):
|
||||
if not frappe.db.get_value("Tax Rule", {"use_for_shopping_cart" : 1}, "name"):
|
||||
@ -71,7 +60,7 @@ class ShoppingCartSettings(Document):
|
||||
def get_shipping_rules(self, shipping_territory):
|
||||
return self.get_name_from_territory(shipping_territory, "shipping_rules", "shipping_rule")
|
||||
|
||||
def validate_cart_settings(doc, method):
|
||||
def validate_cart_settings(doc=None, method=None):
|
||||
frappe.get_doc("Shopping Cart Settings", "Shopping Cart Settings").run_method("validate")
|
||||
|
||||
def get_shopping_cart_settings():
|
||||
|
@ -16,17 +16,25 @@ class TestShoppingCartSettings(unittest.TestCase):
|
||||
return frappe.get_doc({"doctype": "Shopping Cart Settings",
|
||||
"company": "_Test Company"})
|
||||
|
||||
def test_exchange_rate_exists(self):
|
||||
frappe.db.sql("""delete from `tabCurrency Exchange`""")
|
||||
# NOTE: Exchangrate API has all enabled currencies that ERPNext supports.
|
||||
# We aren't checking just currency exchange record anymore
|
||||
# while validating price list currency exchange rate to that of company.
|
||||
# The API is being used to fetch the rate which again almost always
|
||||
# gives back a valid value (for valid currencies).
|
||||
# This makes the test obsolete.
|
||||
# Commenting because im not sure if there's a better test we can write
|
||||
|
||||
cart_settings = self.get_cart_settings()
|
||||
cart_settings.price_list = "_Test Price List Rest of the World"
|
||||
self.assertRaises(ShoppingCartSetupError, cart_settings.validate_exchange_rates_exist)
|
||||
# def test_exchange_rate_exists(self):
|
||||
# frappe.db.sql("""delete from `tabCurrency Exchange`""")
|
||||
|
||||
from erpnext.setup.doctype.currency_exchange.test_currency_exchange import test_records as \
|
||||
currency_exchange_records
|
||||
frappe.get_doc(currency_exchange_records[0]).insert()
|
||||
cart_settings.validate_exchange_rates_exist()
|
||||
# cart_settings = self.get_cart_settings()
|
||||
# cart_settings.price_list = "_Test Price List Rest of the World"
|
||||
# self.assertRaises(ShoppingCartSetupError, cart_settings.validate_price_list_exchange_rate)
|
||||
|
||||
# from erpnext.setup.doctype.currency_exchange.test_currency_exchange import test_records as \
|
||||
# currency_exchange_records
|
||||
# frappe.get_doc(currency_exchange_records[0]).insert()
|
||||
# cart_settings.validate_price_list_exchange_rate()
|
||||
|
||||
def test_tax_rule_validation(self):
|
||||
frappe.db.sql("update `tabTax Rule` set use_for_shopping_cart = 0")
|
||||
|
@ -515,7 +515,8 @@
|
||||
{
|
||||
"fieldname": "scan_barcode",
|
||||
"fieldtype": "Data",
|
||||
"label": "Scan Barcode"
|
||||
"label": "Scan Barcode",
|
||||
"options": "Barcode"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 1,
|
||||
@ -1305,7 +1306,7 @@
|
||||
"idx": 146,
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2021-07-08 21:37:20.802652",
|
||||
"modified": "2021-08-17 20:15:50.574966",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Delivery Note",
|
||||
|
@ -133,7 +133,8 @@
|
||||
{
|
||||
"fieldname": "scan_barcode",
|
||||
"fieldtype": "Data",
|
||||
"label": "Scan Barcode"
|
||||
"label": "Scan Barcode",
|
||||
"options": "Barcode"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 1,
|
||||
@ -181,7 +182,7 @@
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "status",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "\nDraft\nSubmitted\nStopped\nCancelled\nPending\nPartially Ordered\nPartially Received\nOrdered\nIssued\nTransferred\nReceived",
|
||||
"options": "\nDraft\nSubmitted\nStopped\nCancelled\nPending\nPartially Ordered\nOrdered\nIssued\nTransferred\nReceived",
|
||||
"print_hide": 1,
|
||||
"print_width": "100px",
|
||||
"read_only": 1,
|
||||
@ -314,7 +315,7 @@
|
||||
"idx": 70,
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2021-03-31 23:52:55.392512",
|
||||
"modified": "2021-08-17 20:16:12.737743",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Material Request",
|
||||
|
@ -13,6 +13,9 @@ class PriceList(Document):
|
||||
if not cint(self.buying) and not cint(self.selling):
|
||||
throw(_("Price List must be applicable for Buying or Selling"))
|
||||
|
||||
if not self.is_new():
|
||||
self.check_impact_on_shopping_cart()
|
||||
|
||||
def on_update(self):
|
||||
self.set_default_if_missing()
|
||||
self.update_item_price()
|
||||
@ -32,6 +35,17 @@ class PriceList(Document):
|
||||
buying=%s, selling=%s, modified=NOW() where price_list=%s""",
|
||||
(self.currency, cint(self.buying), cint(self.selling), self.name))
|
||||
|
||||
def check_impact_on_shopping_cart(self):
|
||||
"Check if Price List currency change impacts Shopping Cart."
|
||||
from erpnext.shopping_cart.doctype.shopping_cart_settings.shopping_cart_settings import validate_cart_settings
|
||||
|
||||
doc_before_save = self.get_doc_before_save()
|
||||
currency_changed = self.currency != doc_before_save.currency
|
||||
affects_cart = self.name == frappe.get_cached_value("Shopping Cart Settings", None, "price_list")
|
||||
|
||||
if currency_changed and affects_cart:
|
||||
validate_cart_settings()
|
||||
|
||||
def on_trash(self):
|
||||
self.delete_price_list_details_key()
|
||||
|
||||
|
@ -1098,7 +1098,8 @@
|
||||
{
|
||||
"fieldname": "scan_barcode",
|
||||
"fieldtype": "Data",
|
||||
"label": "Scan Barcode"
|
||||
"label": "Scan Barcode",
|
||||
"options": "Barcode"
|
||||
},
|
||||
{
|
||||
"fieldname": "billing_address",
|
||||
@ -1148,7 +1149,7 @@
|
||||
"idx": 261,
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2021-05-25 00:15:12.239017",
|
||||
"modified": "2021-08-17 20:16:40.849885",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Purchase Receipt",
|
||||
|
@ -355,6 +355,7 @@
|
||||
},
|
||||
{
|
||||
"fieldname": "scan_barcode",
|
||||
"options": "Barcode",
|
||||
"fieldtype": "Data",
|
||||
"label": "Scan Barcode"
|
||||
},
|
||||
@ -629,7 +630,7 @@
|
||||
"index_web_pages_for_search": 1,
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2021-05-26 17:07:58.015737",
|
||||
"modified": "2021-08-17 20:16:12.737743",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Stock Entry",
|
||||
|
@ -317,9 +317,6 @@ class StockEntry(StockController):
|
||||
d.s_warehouse = self.from_warehouse
|
||||
d.t_warehouse = self.to_warehouse
|
||||
|
||||
if not (d.s_warehouse or d.t_warehouse):
|
||||
frappe.throw(_("Atleast one warehouse is mandatory"))
|
||||
|
||||
if self.purpose in source_mandatory and not d.s_warehouse:
|
||||
if self.from_warehouse:
|
||||
d.s_warehouse = self.from_warehouse
|
||||
@ -332,6 +329,7 @@ class StockEntry(StockController):
|
||||
else:
|
||||
frappe.throw(_("Target warehouse is mandatory for row {0}").format(d.idx))
|
||||
|
||||
|
||||
if self.purpose == "Manufacture":
|
||||
if validate_for_manufacture:
|
||||
if d.is_finished_item or d.is_scrap_item:
|
||||
@ -346,6 +344,9 @@ class StockEntry(StockController):
|
||||
if cstr(d.s_warehouse) == cstr(d.t_warehouse) and not self.purpose == "Material Transfer for Manufacture":
|
||||
frappe.throw(_("Source and target warehouse cannot be same for row {0}").format(d.idx))
|
||||
|
||||
if not (d.s_warehouse or d.t_warehouse):
|
||||
frappe.throw(_("Atleast one warehouse is mandatory"))
|
||||
|
||||
def validate_work_order(self):
|
||||
if self.purpose in ("Manufacture", "Material Transfer for Manufacture", "Material Consumption for Manufacture"):
|
||||
# check if work order is entered
|
||||
|
@ -267,11 +267,15 @@ class TestServiceLevelAgreement(unittest.TestCase):
|
||||
)
|
||||
creation = datetime.datetime(2019, 3, 4, 12, 0)
|
||||
lead = make_lead(creation=creation, index=4)
|
||||
self.assertFalse(lead.service_level_agreement)
|
||||
applied_sla = frappe.db.get_value('Lead', lead.name, 'service_level_agreement')
|
||||
self.assertFalse(applied_sla)
|
||||
|
||||
source = frappe.get_doc(doctype='Lead Source', source_name='Test Source')
|
||||
source.insert(ignore_if_duplicate=True)
|
||||
lead.source = "Test Source"
|
||||
lead.save()
|
||||
self.assertEqual(lead.service_level_agreement, lead_sla.name)
|
||||
applied_sla = frappe.db.get_value('Lead', lead.name, 'service_level_agreement')
|
||||
self.assertEqual(applied_sla, lead_sla.name)
|
||||
|
||||
def tearDown(self):
|
||||
for d in frappe.get_all("Service Level Agreement"):
|
||||
|
Loading…
Reference in New Issue
Block a user