Merge branch 'develop' into hr-separation

This commit is contained in:
Rucha Mahabal 2022-07-07 13:46:54 +05:30
commit ef02e58859
192 changed files with 517 additions and 73374 deletions

View File

@ -66,6 +66,7 @@ ignore =
F841, F841,
E713, E713,
E712, E712,
B023
max-line-length = 200 max-line-length = 200

View File

@ -1 +0,0 @@
C Form (India specific only) - Will be deprecated.

View File

@ -1,43 +0,0 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt
//c-form js file
// -----------------------------
frappe.ui.form.on('C-Form', {
setup(frm) {
frm.fields_dict.invoices.grid.get_field("invoice_no").get_query = function(doc) {
return {
filters: {
"docstatus": 1,
"customer": doc.customer,
"company": doc.company,
"c_form_applicable": 'Yes',
"c_form_no": ''
}
};
}
frm.fields_dict.state.get_query = function() {
return {
filters: {
country: "India"
}
};
}
}
});
frappe.ui.form.on('C-Form Invoice Detail', {
invoice_no(frm, cdt, cdn) {
let d = frappe.get_doc(cdt, cdn);
if (d.invoice_no) {
frm.call('get_invoice_details', {
invoice_no: d.invoice_no
}).then(r => {
frappe.model.set_value(cdt, cdn, r.message);
});
}
}
});

View File

@ -1,511 +0,0 @@
{
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 1,
"allow_rename": 0,
"autoname": "naming_series:",
"beta": 0,
"creation": "2013-03-07 11:55:06",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"editable_grid": 0,
"fields": [
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "",
"fieldname": "naming_series",
"fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Series",
"length": 0,
"no_copy": 0,
"options": "ACC-CF-.YYYY.-",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 1,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "c_form_no",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "C-Form No",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "received_date",
"fieldtype": "Date",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Received Date",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "customer",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Customer",
"length": 0,
"no_copy": 0,
"options": "Customer",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break1",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"print_width": "50%",
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0,
"width": "50%"
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "company",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 1,
"label": "Company",
"length": 0,
"no_copy": 0,
"options": "Company",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "quarter",
"fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 1,
"label": "Quarter",
"length": 0,
"no_copy": 0,
"options": "\nI\nII\nIII\nIV",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "total_amount",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Total Amount",
"length": 0,
"no_copy": 0,
"options": "Company:company:default_currency",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "state",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "State",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "section_break0",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "invoices",
"fieldtype": "Table",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Invoices",
"length": 0,
"no_copy": 0,
"options": "C-Form Invoice Detail",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "total_invoiced_amount",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Total Invoiced Amount",
"length": 0,
"no_copy": 0,
"options": "Company:company:default_currency",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "amended_from",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 1,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Amended From",
"length": 0,
"no_copy": 1,
"options": "C-Form",
"permlevel": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"icon": "fa fa-file-text",
"idx": 1,
"image_view": 0,
"in_create": 0,
"is_submittable": 1,
"issingle": 0,
"istable": 0,
"max_attachments": 3,
"modified": "2018-08-21 14:44:30.558767",
"modified_by": "Administrator",
"module": "Accounts",
"name": "C-Form",
"owner": "Administrator",
"permissions": [
{
"amend": 0,
"cancel": 0,
"create": 1,
"delete": 0,
"email": 1,
"export": 0,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Accounts User",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"write": 1
},
{
"amend": 0,
"cancel": 0,
"create": 1,
"delete": 0,
"email": 1,
"export": 0,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Accounts Manager",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"write": 1
},
{
"amend": 0,
"cancel": 0,
"create": 0,
"delete": 0,
"email": 0,
"export": 0,
"if_owner": 0,
"import": 0,
"permlevel": 1,
"print": 0,
"read": 1,
"report": 1,
"role": "All",
"set_user_permissions": 0,
"share": 0,
"submit": 0,
"write": 0
}
],
"quick_entry": 0,
"read_only": 0,
"read_only_onload": 0,
"show_name_in_global_search": 0,
"sort_order": "DESC",
"timeline_field": "customer",
"track_changes": 0,
"track_seen": 0,
"track_views": 0
}

View File

@ -1,96 +0,0 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
import frappe
from frappe import _
from frappe.model.document import Document
from frappe.utils import flt
class CForm(Document):
def validate(self):
"""Validate invoice that c-form is applicable
and no other c-form is received for that"""
for d in self.get("invoices"):
if d.invoice_no:
inv = frappe.db.sql(
"""select c_form_applicable, c_form_no from
`tabSales Invoice` where name = %s and docstatus = 1""",
d.invoice_no,
)
if inv and inv[0][0] != "Yes":
frappe.throw(_("C-form is not applicable for Invoice: {0}").format(d.invoice_no))
elif inv and inv[0][1] and inv[0][1] != self.name:
frappe.throw(
_(
"""Invoice {0} is tagged in another C-form: {1}.
If you want to change C-form no for this invoice,
please remove invoice no from the previous c-form and then try again""".format(
d.invoice_no, inv[0][1]
)
)
)
elif not inv:
frappe.throw(
_(
"Row {0}: Invoice {1} is invalid, it might be cancelled / does not exist. \
Please enter a valid Invoice".format(
d.idx, d.invoice_no
)
)
)
def on_update(self):
"""Update C-Form No on invoices"""
self.set_total_invoiced_amount()
def on_submit(self):
self.set_cform_in_sales_invoices()
def before_cancel(self):
# remove cform reference
frappe.db.sql("""update `tabSales Invoice` set c_form_no=null where c_form_no=%s""", self.name)
def set_cform_in_sales_invoices(self):
inv = [d.invoice_no for d in self.get("invoices")]
if inv:
frappe.db.sql(
"""update `tabSales Invoice` set c_form_no=%s, modified=%s where name in (%s)"""
% ("%s", "%s", ", ".join(["%s"] * len(inv))),
tuple([self.name, self.modified] + inv),
)
frappe.db.sql(
"""update `tabSales Invoice` set c_form_no = null, modified = %s
where name not in (%s) and ifnull(c_form_no, '') = %s"""
% ("%s", ", ".join(["%s"] * len(inv)), "%s"),
tuple([self.modified] + inv + [self.name]),
)
else:
frappe.throw(_("Please enter atleast 1 invoice in the table"))
def set_total_invoiced_amount(self):
total = sum(flt(d.grand_total) for d in self.get("invoices"))
frappe.db.set(self, "total_invoiced_amount", total)
@frappe.whitelist()
def get_invoice_details(self, invoice_no):
"""Pull details from invoices for referrence"""
if invoice_no:
inv = frappe.db.get_value(
"Sales Invoice",
invoice_no,
["posting_date", "territory", "base_net_total", "base_grand_total"],
as_dict=True,
)
return {
"invoice_date": inv.posting_date,
"territory": inv.territory,
"net_total": inv.base_net_total,
"grand_total": inv.base_grand_total,
}

View File

@ -1,10 +0,0 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import unittest
# test_records = frappe.get_test_records('C-Form')
class TestCForm(unittest.TestCase):
pass

View File

@ -1 +0,0 @@
Invoice detail for parent C-Form.

View File

@ -1,168 +0,0 @@
{
"allow_copy": 0,
"allow_import": 0,
"allow_rename": 0,
"beta": 0,
"creation": "2013-02-22 01:27:38",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"editable_grid": 1,
"fields": [
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "invoice_no",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Invoice No",
"length": 0,
"no_copy": 0,
"options": "Sales Invoice",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"print_width": "160px",
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0,
"width": "160px"
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "invoice_date",
"fieldtype": "Date",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Invoice Date",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"print_width": "120px",
"read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0,
"width": "120px"
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"description": "",
"fieldname": "territory",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Territory",
"length": 0,
"no_copy": 0,
"options": "Territory",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"print_width": "120px",
"read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0,
"width": "120px"
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "net_total",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Net Total",
"length": 0,
"no_copy": 0,
"options": "Company:company:default_currency",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"print_width": "120px",
"read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0,
"width": "120px"
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "grand_total",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Grand Total",
"length": 0,
"no_copy": 0,
"options": "Company:company:default_currency",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"print_width": "120px",
"read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0,
"width": "120px"
}
],
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 1,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2016-07-11 03:27:58.768719",
"modified_by": "Administrator",
"module": "Accounts",
"name": "C-Form Invoice Detail",
"owner": "Administrator",
"permissions": [],
"quick_entry": 0,
"read_only": 0,
"read_only_onload": 0,
"track_seen": 0
}

View File

@ -1,9 +0,0 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
from frappe.model.document import Document
class CFormInvoiceDetail(Document):
pass

View File

@ -29,7 +29,6 @@ def test_create_test_data():
"item_name": "_Test Tesla Car", "item_name": "_Test Tesla Car",
"apply_warehouse_wise_reorder_level": 0, "apply_warehouse_wise_reorder_level": 0,
"warehouse": "Stores - _TC", "warehouse": "Stores - _TC",
"gst_hsn_code": "999800",
"valuation_rate": 5000, "valuation_rate": 5000,
"standard_rate": 5000, "standard_rate": 5000,
"item_defaults": [ "item_defaults": [

View File

@ -1,90 +0,0 @@
{
"actions": [],
"creation": "2018-01-02 15:48:58.768352",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"company",
"cgst_account",
"sgst_account",
"igst_account",
"cess_account",
"utgst_account",
"is_reverse_charge_account"
],
"fields": [
{
"columns": 1,
"fieldname": "company",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Company",
"options": "Company",
"reqd": 1
},
{
"columns": 2,
"fieldname": "cgst_account",
"fieldtype": "Link",
"in_list_view": 1,
"label": "CGST Account",
"options": "Account",
"reqd": 1
},
{
"columns": 2,
"fieldname": "sgst_account",
"fieldtype": "Link",
"in_list_view": 1,
"label": "SGST Account",
"options": "Account",
"reqd": 1
},
{
"columns": 2,
"fieldname": "igst_account",
"fieldtype": "Link",
"in_list_view": 1,
"label": "IGST Account",
"options": "Account",
"reqd": 1
},
{
"columns": 2,
"fieldname": "cess_account",
"fieldtype": "Link",
"in_list_view": 1,
"label": "CESS Account",
"options": "Account"
},
{
"columns": 1,
"default": "0",
"fieldname": "is_reverse_charge_account",
"fieldtype": "Check",
"in_list_view": 1,
"label": "Is Reverse Charge Account"
},
{
"fieldname": "utgst_account",
"fieldtype": "Link",
"label": "UTGST Account",
"options": "Account"
}
],
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
"modified": "2022-04-07 12:59:14.039768",
"modified_by": "Administrator",
"module": "Accounts",
"name": "GST Account",
"owner": "Administrator",
"permissions": [],
"quick_entry": 1,
"sort_field": "modified",
"sort_order": "DESC",
"states": [],
"track_changes": 1
}

View File

@ -1,9 +0,0 @@
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
from frappe.model.document import Document
class GSTAccount(Document):
pass

View File

@ -1,17 +0,0 @@
frappe.ui.form.on("Journal Entry", {
refresh: function(frm) {
frm.set_query('company_address', function(doc) {
if(!doc.company) {
frappe.throw(__('Please set Company'));
}
return {
query: 'frappe.contacts.doctype.address.address.address_query',
filters: {
link_doctype: 'Company',
link_name: doc.company
}
};
});
}
});

View File

@ -1,29 +0,0 @@
frappe.ui.form.on("Payment Entry", {
company: function(frm) {
frappe.call({
'method': 'frappe.contacts.doctype.address.address.get_default_address',
'args': {
'doctype': 'Company',
'name': frm.doc.company
},
'callback': function(r) {
frm.set_value('company_address', r.message);
}
});
},
party: function(frm) {
if (frm.doc.party_type == "Customer" && frm.doc.party) {
frappe.call({
'method': 'frappe.contacts.doctype.address.address.get_default_address',
'args': {
'doctype': 'Customer',
'name': frm.doc.party
},
'callback': function(r) {
frm.set_value('customer_address', r.message);
}
});
}
}
});

View File

@ -162,7 +162,7 @@ class PaymentReconciliation(Document):
{ {
"reference_type": inv.voucher_type, "reference_type": inv.voucher_type,
"reference_name": inv.voucher_no, "reference_name": inv.voucher_no,
"amount": -(inv.outstanding), "amount": -(inv.outstanding_in_account_currency),
"posting_date": inv.posting_date, "posting_date": inv.posting_date,
"currency": inv.currency, "currency": inv.currency,
} }

View File

@ -19,6 +19,7 @@ class TestPaymentReconciliation(FrappeTestCase):
self.create_company() self.create_company()
self.create_item() self.create_item()
self.create_customer() self.create_customer()
self.create_account()
self.clear_old_entries() self.clear_old_entries()
def tearDown(self): def tearDown(self):
@ -89,6 +90,38 @@ class TestPaymentReconciliation(FrappeTestCase):
customer.save() customer.save()
self.customer2 = customer.name self.customer2 = customer.name
if frappe.db.exists("Customer", "_Test PR Customer 3"):
self.customer3 = "_Test PR Customer 3"
else:
customer = frappe.new_doc("Customer")
customer.customer_name = "_Test PR Customer 3"
customer.type = "Individual"
customer.default_currency = "EUR"
customer.save()
self.customer3 = customer.name
def create_account(self):
account_name = "Debtors EUR"
if not frappe.db.get_value(
"Account", filters={"account_name": account_name, "company": self.company}
):
acc = frappe.new_doc("Account")
acc.account_name = account_name
acc.parent_account = "Accounts Receivable - _PR"
acc.company = self.company
acc.account_currency = "EUR"
acc.account_type = "Receivable"
acc.insert()
else:
name = frappe.db.get_value(
"Account",
filters={"account_name": account_name, "company": self.company},
fieldname="name",
pluck=True,
)
acc = frappe.get_doc("Account", name)
self.debtors_eur = acc.name
def create_sales_invoice( def create_sales_invoice(
self, qty=1, rate=100, posting_date=nowdate(), do_not_save=False, do_not_submit=False self, qty=1, rate=100, posting_date=nowdate(), do_not_save=False, do_not_submit=False
): ):
@ -118,7 +151,7 @@ class TestPaymentReconciliation(FrappeTestCase):
) )
return sinv return sinv
def create_payment_entry(self, amount=100, posting_date=nowdate()): def create_payment_entry(self, amount=100, posting_date=nowdate(), customer=None):
""" """
Helper function to populate default values in payment entry Helper function to populate default values in payment entry
""" """
@ -126,7 +159,7 @@ class TestPaymentReconciliation(FrappeTestCase):
company=self.company, company=self.company,
payment_type="Receive", payment_type="Receive",
party_type="Customer", party_type="Customer",
party=self.customer, party=customer or self.customer,
paid_from=self.debit_to, paid_from=self.debit_to,
paid_to=self.bank, paid_to=self.bank,
paid_amount=amount, paid_amount=amount,
@ -454,3 +487,59 @@ class TestPaymentReconciliation(FrappeTestCase):
self.assertEqual(len(pr.get("payments")), 1) self.assertEqual(len(pr.get("payments")), 1)
self.assertEqual(pr.get("invoices")[0].outstanding_amount, 20) self.assertEqual(pr.get("invoices")[0].outstanding_amount, 20)
self.assertEqual(pr.get("payments")[0].amount, 20) self.assertEqual(pr.get("payments")[0].amount, 20)
def test_pr_output_foreign_currency_and_amount(self):
# test for currency and amount invoices and payments
transaction_date = nowdate()
# In EUR
amount = 100
exchange_rate = 80
si = self.create_sales_invoice(
qty=1, rate=amount, posting_date=transaction_date, do_not_save=True, do_not_submit=True
)
si.customer = self.customer3
si.currency = "EUR"
si.conversion_rate = exchange_rate
si.debit_to = self.debtors_eur
si = si.save().submit()
cr_note = self.create_sales_invoice(
qty=-1, rate=amount, posting_date=transaction_date, do_not_save=True, do_not_submit=True
)
cr_note.customer = self.customer3
cr_note.is_return = 1
cr_note.currency = "EUR"
cr_note.conversion_rate = exchange_rate
cr_note.debit_to = self.debtors_eur
cr_note = cr_note.save().submit()
pr = self.create_payment_reconciliation()
pr.party = self.customer3
pr.receivable_payable_account = self.debtors_eur
pr.get_unreconciled_entries()
self.assertEqual(len(pr.invoices), 1)
self.assertEqual(len(pr.payments), 1)
self.assertEqual(pr.invoices[0].amount, amount)
self.assertEqual(pr.invoices[0].currency, "EUR")
self.assertEqual(pr.payments[0].amount, amount)
self.assertEqual(pr.payments[0].currency, "EUR")
cr_note.cancel()
pay = self.create_payment_entry(
amount=amount, posting_date=transaction_date, customer=self.customer3
)
pay.paid_from = self.debtors_eur
pay.paid_from_account_currency = "EUR"
pay.source_exchange_rate = exchange_rate
pay.received_amount = exchange_rate * amount
pay = pay.save().submit()
pr.get_unreconciled_entries()
self.assertEqual(len(pr.invoices), 1)
self.assertEqual(len(pr.payments), 1)
self.assertEqual(pr.payments[0].amount, amount)
self.assertEqual(pr.payments[0].currency, "EUR")

View File

@ -164,8 +164,6 @@
"debit_to", "debit_to",
"party_account_currency", "party_account_currency",
"is_opening", "is_opening",
"c_form_applicable",
"c_form_no",
"column_break8", "column_break8",
"remarks", "remarks",
"sales_team_section_break", "sales_team_section_break",
@ -1399,23 +1397,6 @@
"options": "No\nYes", "options": "No\nYes",
"print_hide": 1 "print_hide": 1
}, },
{
"fieldname": "c_form_applicable",
"fieldtype": "Select",
"label": "C-Form Applicable",
"no_copy": 1,
"options": "No\nYes",
"print_hide": 1
},
{
"fieldname": "c_form_no",
"fieldtype": "Link",
"label": "C-Form No",
"no_copy": 1,
"options": "C-Form",
"print_hide": 1,
"read_only": 1
},
{ {
"fieldname": "column_break8", "fieldname": "column_break8",
"fieldtype": "Column Break", "fieldtype": "Column Break",

View File

@ -539,7 +539,7 @@ frappe.ui.form.on("Purchase Invoice", {
}, },
add_custom_buttons: function(frm) { add_custom_buttons: function(frm) {
if (frm.doc.per_received < 100) { if (frm.doc.docstatus == 1 && frm.doc.per_received < 100) {
frm.add_custom_button(__('Purchase Receipt'), () => { frm.add_custom_button(__('Purchase Receipt'), () => {
frm.events.make_purchase_receipt(frm); frm.events.make_purchase_receipt(frm);
}, __('Create')); }, __('Create'));

View File

@ -1,3 +0,0 @@
{% include "erpnext/regional/india/taxes.js" %}
erpnext.setup_auto_gst_taxation('Purchase Invoice');

View File

@ -1474,15 +1474,30 @@ class TestPurchaseInvoice(unittest.TestCase, StockTestMixin):
def test_purchase_invoice_advance_taxes(self): def test_purchase_invoice_advance_taxes(self):
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
company = "_Test Company"
tds_account_args = {
"doctype": "Account",
"account_name": "TDS Payable",
"account_type": "Tax",
"parent_account": frappe.db.get_value(
"Account", {"account_name": "Duties and Taxes", "company": company}
),
"company": company,
}
tds_account = create_account(**tds_account_args)
tax_withholding_category = "Test TDS - 194 - Dividends - Individual"
# Update tax withholding category with current fiscal year and rate details
create_tax_witholding_category(tax_withholding_category, company, tds_account)
# create a new supplier to test # create a new supplier to test
supplier = create_supplier( supplier = create_supplier(
supplier_name="_Test TDS Advance Supplier", supplier_name="_Test TDS Advance Supplier",
tax_withholding_category="TDS - 194 - Dividends - Individual", tax_withholding_category=tax_withholding_category,
) )
# Update tax withholding category with current fiscal year and rate details
update_tax_witholding_category("_Test Company", "TDS Payable - _TC")
# Create Purchase Order with TDS applied # Create Purchase Order with TDS applied
po = create_purchase_order( po = create_purchase_order(
do_not_save=1, do_not_save=1,
@ -1498,7 +1513,7 @@ class TestPurchaseInvoice(unittest.TestCase, StockTestMixin):
payment_entry = get_payment_entry(dt="Purchase Order", dn=po.name) payment_entry = get_payment_entry(dt="Purchase Order", dn=po.name)
payment_entry.paid_from = "Cash - _TC" payment_entry.paid_from = "Cash - _TC"
payment_entry.apply_tax_withholding_amount = 1 payment_entry.apply_tax_withholding_amount = 1
payment_entry.tax_withholding_category = "TDS - 194 - Dividends - Individual" payment_entry.tax_withholding_category = tax_withholding_category
payment_entry.save() payment_entry.save()
payment_entry.submit() payment_entry.submit()
@ -1506,7 +1521,7 @@ class TestPurchaseInvoice(unittest.TestCase, StockTestMixin):
expected_gle = [ expected_gle = [
["Cash - _TC", 0, 27000], ["Cash - _TC", 0, 27000],
["Creditors - _TC", 30000, 0], ["Creditors - _TC", 30000, 0],
["TDS Payable - _TC", 0, 3000], [tds_account, 0, 3000],
] ]
gl_entries = frappe.db.sql( gl_entries = frappe.db.sql(
@ -1532,7 +1547,7 @@ class TestPurchaseInvoice(unittest.TestCase, StockTestMixin):
purchase_invoice.submit() purchase_invoice.submit()
# Check GLE for Purchase Invoice # Check GLE for Purchase Invoice
# Zero net effect on final TDS Payable on invoice # Zero net effect on final TDS payable on invoice
expected_gle = [["_Test Account Cost for Goods Sold - _TC", 30000], ["Creditors - _TC", -30000]] expected_gle = [["_Test Account Cost for Goods Sold - _TC", 30000], ["Creditors - _TC", -30000]]
gl_entries = frappe.db.sql( gl_entries = frappe.db.sql(
@ -1654,40 +1669,28 @@ def check_gl_entries(doc, voucher_no, expected_gle, posting_date):
doc.assertEqual(getdate(expected_gle[i][3]), gle.posting_date) doc.assertEqual(getdate(expected_gle[i][3]), gle.posting_date)
def update_tax_witholding_category(company, account): def create_tax_witholding_category(category_name, company, account):
from erpnext.accounts.utils import get_fiscal_year from erpnext.accounts.utils import get_fiscal_year
fiscal_year = get_fiscal_year(date=nowdate()) fiscal_year = get_fiscal_year(date=nowdate())
if not frappe.db.get_value( return frappe.get_doc(
"Tax Withholding Rate",
{ {
"parent": "TDS - 194 - Dividends - Individual", "doctype": "Tax Withholding Category",
"from_date": (">=", fiscal_year[1]), "name": category_name,
"to_date": ("<=", fiscal_year[2]), "category_name": category_name,
}, "accounts": [{"company": company, "account": account}],
): "rates": [
tds_category = frappe.get_doc("Tax Withholding Category", "TDS - 194 - Dividends - Individual") {
tds_category.set("rates", []) "from_date": fiscal_year[1],
"to_date": fiscal_year[2],
tds_category.append( "tax_withholding_rate": 10,
"rates", "single_threshold": 2500,
{ "cumulative_threshold": 0,
"from_date": fiscal_year[1], }
"to_date": fiscal_year[2], ],
"tax_withholding_rate": 10, }
"single_threshold": 2500, ).insert(ignore_if_duplicate=True)
"cumulative_threshold": 0,
},
)
tds_category.save()
if not frappe.db.get_value(
"Tax Withholding Account", {"parent": "TDS - 194 - Dividends - Individual", "account": account}
):
tds_category = frappe.get_doc("Tax Withholding Category", "TDS - 194 - Dividends - Individual")
tds_category.append("accounts", {"company": company, "account": account})
tds_category.save()
def unlink_payment_on_cancel_of_invoice(enable=1): def unlink_payment_on_cancel_of_invoice(enable=1):

View File

@ -1,53 +0,0 @@
{% 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) {
frm.set_query('transporter', function() {
return {
filters: {
'is_transporter': 1
}
};
});
frm.set_query('driver', function(doc) {
return {
filters: {
'transporter': doc.transporter
}
};
});
},
refresh: function(frm) {
if(frm.doc.docstatus == 1 && !frm.is_dirty()
&& !frm.doc.is_return && !frm.doc.ewaybill) {
frm.add_custom_button('E-Way Bill JSON', () => {
frappe.call({
method: 'erpnext.regional.india.utils.generate_ewb_json',
args: {
'dt': frm.doc.doctype,
'dn': [frm.doc.name]
},
callback: function(r) {
if (r.message) {
const args = {
cmd: 'erpnext.regional.india.utils.download_ewb_json',
data: r.message,
docname: frm.doc.name
};
open_url_post(frappe.request.url, args);
}
}
});
}, __("Create"));
}
}
});

View File

@ -1,174 +0,0 @@
var globalOnload = frappe.listview_settings['Sales Invoice'].onload;
frappe.listview_settings['Sales Invoice'].onload = function (list_view) {
// Provision in case onload event is added to sales_invoice.js in future
if (globalOnload) {
globalOnload(list_view);
}
const action = () => {
const selected_docs = list_view.get_checked_items();
const docnames = list_view.get_checked_items(true);
for (let doc of selected_docs) {
if (doc.docstatus !== 1) {
frappe.throw(__("E-Way Bill JSON can only be generated from a submitted document"));
}
}
frappe.call({
method: 'erpnext.regional.india.utils.generate_ewb_json',
args: {
'dt': list_view.doctype,
'dn': docnames
},
callback: function(r) {
if (r.message) {
const args = {
cmd: 'erpnext.regional.india.utils.download_ewb_json',
data: r.message,
docname: docnames
};
open_url_post(frappe.request.url, args);
}
}
});
};
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'
});
}
});
};

View File

@ -476,6 +476,13 @@ erpnext.accounts.SalesInvoiceController = class SalesInvoiceController extends e
this.frm.trigger("calculate_timesheet_totals"); this.frm.trigger("calculate_timesheet_totals");
} }
} }
is_cash_or_non_trade_discount() {
this.frm.set_df_property("additional_discount_account", "hidden", 1 - this.frm.doc.is_cash_or_non_trade_discount);
if (!this.frm.doc.is_cash_or_non_trade_discount) {
this.frm.set_value("additional_discount_account", "");
}
}
}; };
// for backward compatibility: combine new and previous states // for backward compatibility: combine new and previous states
@ -783,10 +790,6 @@ frappe.ui.form.on('Sales Invoice', {
} }
} }
// India related fields
if (frappe.boot.sysdefaults.country == 'India') unhide_field(['c_form_applicable', 'c_form_no']);
else hide_field(['c_form_applicable', 'c_form_no']);
frm.refresh_fields(); frm.refresh_fields();
}, },

View File

@ -106,6 +106,7 @@
"loyalty_redemption_cost_center", "loyalty_redemption_cost_center",
"section_break_49", "section_break_49",
"apply_discount_on", "apply_discount_on",
"is_cash_or_non_trade_discount",
"base_discount_amount", "base_discount_amount",
"additional_discount_account", "additional_discount_account",
"column_break_51", "column_break_51",
@ -174,8 +175,6 @@
"debit_to", "debit_to",
"party_account_currency", "party_account_currency",
"is_opening", "is_opening",
"c_form_applicable",
"c_form_no",
"column_break8", "column_break8",
"unrealized_profit_loss_account", "unrealized_profit_loss_account",
"remarks", "remarks",
@ -1716,28 +1715,6 @@
"options": "No\nYes", "options": "No\nYes",
"print_hide": 1 "print_hide": 1
}, },
{
"fieldname": "c_form_applicable",
"fieldtype": "Select",
"hide_days": 1,
"hide_seconds": 1,
"label": "C-Form Applicable",
"length": 4,
"no_copy": 1,
"options": "No\nYes",
"print_hide": 1
},
{
"fieldname": "c_form_no",
"fieldtype": "Link",
"hide_days": 1,
"hide_seconds": 1,
"label": "C-Form No",
"no_copy": 1,
"options": "C-Form",
"print_hide": 1,
"read_only": 1
},
{ {
"fieldname": "column_break8", "fieldname": "column_break8",
"fieldtype": "Column Break", "fieldtype": "Column Break",
@ -1790,8 +1767,6 @@
"width": "50%" "width": "50%"
}, },
{ {
"fetch_from": "sales_partner.commission_rate",
"fetch_if_empty": 1,
"fieldname": "commission_rate", "fieldname": "commission_rate",
"fieldtype": "Float", "fieldtype": "Float",
"hide_days": 1, "hide_days": 1,
@ -1990,7 +1965,7 @@
{ {
"fieldname": "additional_discount_account", "fieldname": "additional_discount_account",
"fieldtype": "Link", "fieldtype": "Link",
"label": "Additional Discount Account", "label": "Discount Account",
"options": "Account" "options": "Account"
}, },
{ {
@ -2028,6 +2003,13 @@
"fieldtype": "Currency", "fieldtype": "Currency",
"label": "Amount Eligible for Commission", "label": "Amount Eligible for Commission",
"read_only": 1 "read_only": 1
},
{
"default": "0",
"depends_on": "eval: doc.apply_discount_on == \"Grand Total\"",
"fieldname": "is_cash_or_non_trade_discount",
"fieldtype": "Check",
"label": "Is Cash or Non Trade Discount"
} }
], ],
"icon": "fa fa-file-text", "icon": "fa fa-file-text",
@ -2040,7 +2022,7 @@
"link_fieldname": "consolidated_invoice" "link_fieldname": "consolidated_invoice"
} }
], ],
"modified": "2022-06-10 03:52:51.409913", "modified": "2022-06-16 16:22:44.870575",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Sales Invoice", "name": "Sales Invoice",

View File

@ -151,7 +151,6 @@ class SalesInvoice(SellingController):
) )
self.set_against_income_account() self.set_against_income_account()
self.validate_c_form()
self.validate_time_sheets_are_submitted() self.validate_time_sheets_are_submitted()
self.validate_multiple_billing("Delivery Note", "dn_detail", "amount", "items") self.validate_multiple_billing("Delivery Note", "dn_detail", "amount", "items")
if not self.is_return: if not self.is_return:
@ -366,8 +365,6 @@ class SalesInvoice(SellingController):
self.update_billing_status_for_zero_amount_refdoc("Sales Order") self.update_billing_status_for_zero_amount_refdoc("Sales Order")
self.update_serial_no(in_cancel=True) self.update_serial_no(in_cancel=True)
self.validate_c_form_on_cancel()
# Updating stock ledger should always be called after updating prevdoc status, # Updating stock ledger should always be called after updating prevdoc status,
# because updating reserved qty in bin depends upon updated delivered qty in SO # because updating reserved qty in bin depends upon updated delivered qty in SO
if self.update_stock == 1: if self.update_stock == 1:
@ -815,25 +812,6 @@ class SalesInvoice(SellingController):
if flt(self.change_amount) and not self.account_for_change_amount: if flt(self.change_amount) and not self.account_for_change_amount:
msgprint(_("Please enter Account for Change Amount"), raise_exception=1) msgprint(_("Please enter Account for Change Amount"), raise_exception=1)
def validate_c_form(self):
"""Blank C-form no if C-form applicable marked as 'No'"""
if self.amended_from and self.c_form_applicable == "No" and self.c_form_no:
frappe.db.sql(
"""delete from `tabC-Form Invoice Detail` where invoice_no = %s
and parent = %s""",
(self.amended_from, self.c_form_no),
)
frappe.db.set(self, "c_form_no", "")
def validate_c_form_on_cancel(self):
"""Display message if C-Form no exists on cancellation of Sales Invoice"""
if self.c_form_applicable == "Yes" and self.c_form_no:
msgprint(
_("Please remove this Invoice {0} from C-Form {1}").format(self.name, self.c_form_no),
raise_exception=1,
)
def validate_dropship_item(self): def validate_dropship_item(self):
for item in self.items: for item in self.items:
if item.sales_order: if item.sales_order:
@ -1030,7 +1008,7 @@ class SalesInvoice(SellingController):
) )
if grand_total and not self.is_internal_transfer(): if grand_total and not self.is_internal_transfer():
# Didnot use base_grand_total to book rounding loss gle # Did not use base_grand_total to book rounding loss gle
gl_entries.append( gl_entries.append(
self.get_gl_dict( self.get_gl_dict(
{ {
@ -1055,6 +1033,22 @@ class SalesInvoice(SellingController):
) )
) )
if self.apply_discount_on == "Grand Total" and self.get("is_cash_or_discount_account"):
gl_entries.append(
self.get_gl_dict(
{
"account": self.additional_discount_account,
"against": self.debit_to,
"debit": self.base_discount_amount,
"debit_in_account_currency": self.discount_amount,
"cost_center": self.cost_center,
"project": self.project,
},
self.currency,
item=self,
)
)
def make_tax_gl_entries(self, gl_entries): def make_tax_gl_entries(self, gl_entries):
enable_discount_accounting = cint( enable_discount_accounting = cint(
frappe.db.get_single_value("Selling Settings", "enable_discount_accounting") frappe.db.get_single_value("Selling Settings", "enable_discount_accounting")
@ -1512,9 +1506,7 @@ class SalesInvoice(SellingController):
frappe.get_doc("Delivery Note", dn).update_billing_percentage(update_modified=update_modified) frappe.get_doc("Delivery Note", dn).update_billing_percentage(update_modified=update_modified)
def on_recurring(self, reference_doc, auto_repeat_doc): def on_recurring(self, reference_doc, auto_repeat_doc):
for fieldname in ("c_form_applicable", "c_form_no", "write_off_amount"): self.set("write_off_amount", reference_doc.get("write_off_amount"))
self.set(fieldname, reference_doc.get(fieldname))
self.due_date = None self.due_date = None
def update_serial_no(self, in_cancel=False): def update_serial_no(self, in_cancel=False):
@ -2117,6 +2109,8 @@ def make_inter_company_transaction(doctype, source_name, target_doc=None):
source_document_warehouse_field = "from_warehouse" source_document_warehouse_field = "from_warehouse"
target_document_warehouse_field = "target_warehouse" target_document_warehouse_field = "target_warehouse"
received_items = get_received_items(source_name, target_doctype, target_detail_field)
validate_inter_company_transaction(source_doc, doctype) validate_inter_company_transaction(source_doc, doctype)
details = get_inter_company_details(source_doc, doctype) details = get_inter_company_details(source_doc, doctype)
@ -2181,12 +2175,17 @@ def make_inter_company_transaction(doctype, source_name, target_doc=None):
shipping_address_name=target_doc.shipping_address_name, shipping_address_name=target_doc.shipping_address_name,
) )
def update_item(source, target, source_parent):
target.qty = flt(source.qty) - received_items.get(source.name, 0.0)
item_field_map = { item_field_map = {
"doctype": target_doctype + " Item", "doctype": target_doctype + " Item",
"field_no_map": ["income_account", "expense_account", "cost_center", "warehouse"], "field_no_map": ["income_account", "expense_account", "cost_center", "warehouse"],
"field_map": { "field_map": {
"rate": "rate", "rate": "rate",
}, },
"postprocess": update_item,
"condition": lambda doc: doc.qty > 0,
} }
if doctype in ["Sales Invoice", "Sales Order"]: if doctype in ["Sales Invoice", "Sales Order"]:
@ -2224,6 +2223,28 @@ def make_inter_company_transaction(doctype, source_name, target_doc=None):
return doclist return doclist
def get_received_items(reference_name, doctype, reference_fieldname):
target_doctypes = frappe.get_all(
doctype,
filters={"inter_company_invoice_reference": reference_name, "docstatus": 1},
as_list=True,
)
if target_doctypes:
target_doctypes = list(target_doctypes[0])
received_items_map = frappe._dict(
frappe.get_all(
doctype + " Item",
filters={"parent": ("in", target_doctypes)},
fields=[reference_fieldname, "qty"],
as_list=1,
)
)
return received_items_map
def set_purchase_references(doc): def set_purchase_references(doc):
# add internal PO or PR links if any # add internal PO or PR links if any
if doc.is_internal_transfer(): if doc.is_internal_transfer():

View File

@ -11,6 +11,7 @@ def get_data():
"Payment Request": "reference_name", "Payment Request": "reference_name",
"Sales Invoice": "return_against", "Sales Invoice": "return_against",
"Auto Repeat": "reference_document", "Auto Repeat": "reference_document",
"Purchase Invoice": "inter_company_invoice_reference",
}, },
"internal_links": { "internal_links": {
"Sales Order": ["items", "sales_order"], "Sales Order": ["items", "sales_order"],
@ -30,5 +31,6 @@ def get_data():
{"label": _("Reference"), "items": ["Timesheet", "Delivery Note", "Sales Order"]}, {"label": _("Reference"), "items": ["Timesheet", "Delivery Note", "Sales Order"]},
{"label": _("Returns"), "items": ["Sales Invoice"]}, {"label": _("Returns"), "items": ["Sales Invoice"]},
{"label": _("Subscription"), "items": ["Auto Repeat"]}, {"label": _("Subscription"), "items": ["Auto Repeat"]},
{"label": _("Internal Transfers"), "items": ["Purchase Invoice"]},
], ],
} }

View File

@ -24,7 +24,6 @@ from erpnext.assets.doctype.asset.test_asset import create_asset, create_asset_d
from erpnext.controllers.accounts_controller import update_invoice_status from erpnext.controllers.accounts_controller import update_invoice_status
from erpnext.controllers.taxes_and_totals import get_itemised_tax_breakup_data from erpnext.controllers.taxes_and_totals import get_itemised_tax_breakup_data
from erpnext.exceptions import InvalidAccountCurrency, InvalidCurrency from erpnext.exceptions import InvalidAccountCurrency, InvalidCurrency
from erpnext.regional.india.utils import get_ewb_data
from erpnext.stock.doctype.delivery_note.delivery_note import make_sales_invoice from erpnext.stock.doctype.delivery_note.delivery_note import make_sales_invoice
from erpnext.stock.doctype.item.test_item import create_item from erpnext.stock.doctype.item.test_item import create_item
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import make_purchase_receipt from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import make_purchase_receipt
@ -1845,24 +1844,7 @@ class TestSalesInvoice(unittest.TestCase):
for i, k in enumerate(expected_values["keys"]): for i, k in enumerate(expected_values["keys"]):
self.assertEqual(d.get(k), expected_values[d.item_code][i]) self.assertEqual(d.get(k), expected_values[d.item_code][i])
def test_item_wise_tax_breakup_india(self): def test_item_wise_tax_breakup(self):
frappe.flags.country = "India"
si = self.create_si_to_test_tax_breakup()
itemised_tax, itemised_taxable_amount = get_itemised_tax_breakup_data(si)
expected_itemised_tax = {
"_Test Item": {"Service Tax": {"tax_rate": 10.0, "tax_amount": 1000.0}},
"_Test Item 2": {"Service Tax": {"tax_rate": 10.0, "tax_amount": 500.0}},
}
expected_itemised_taxable_amount = {"_Test Item": 10000.0, "_Test Item 2": 5000.0}
self.assertEqual(itemised_tax, expected_itemised_tax)
self.assertEqual(itemised_taxable_amount, expected_itemised_taxable_amount)
frappe.flags.country = None
def test_item_wise_tax_breakup_outside_india(self):
frappe.flags.country = "United States" frappe.flags.country = "United States"
si = self.create_si_to_test_tax_breakup() si = self.create_si_to_test_tax_breakup()
@ -1886,7 +1868,6 @@ class TestSalesInvoice(unittest.TestCase):
"items", "items",
{ {
"item_code": "_Test Item", "item_code": "_Test Item",
"gst_hsn_code": "999800",
"warehouse": "_Test Warehouse - _TC", "warehouse": "_Test Warehouse - _TC",
"qty": 100, "qty": 100,
"rate": 50, "rate": 50,
@ -1899,7 +1880,6 @@ class TestSalesInvoice(unittest.TestCase):
"items", "items",
{ {
"item_code": "_Test Item 2", "item_code": "_Test Item 2",
"gst_hsn_code": "999800",
"warehouse": "_Test Warehouse - _TC", "warehouse": "_Test Warehouse - _TC",
"qty": 100, "qty": 100,
"rate": 50, "rate": 50,
@ -1986,7 +1966,6 @@ class TestSalesInvoice(unittest.TestCase):
"items", "items",
{ {
"item_code": "_Test Item", "item_code": "_Test Item",
"gst_hsn_code": "999800",
"warehouse": "_Test Warehouse - _TC", "warehouse": "_Test Warehouse - _TC",
"qty": 1, "qty": 1,
"rate": rate, "rate": rate,
@ -2659,78 +2638,6 @@ class TestSalesInvoice(unittest.TestCase):
check_gl_entries(self, target_doc.name, pi_gl_entries, add_days(nowdate(), -1)) check_gl_entries(self, target_doc.name, pi_gl_entries, add_days(nowdate(), -1))
def test_eway_bill_json(self):
si = make_sales_invoice_for_ewaybill()
si.submit()
data = get_ewb_data("Sales Invoice", [si.name])
self.assertEqual(data["version"], "1.0.0421")
self.assertEqual(data["billLists"][0]["fromGstin"], "27AAECE4835E1ZR")
self.assertEqual(data["billLists"][0]["fromTrdName"], "_Test Company")
self.assertEqual(data["billLists"][0]["toTrdName"], "_Test Customer")
self.assertEqual(data["billLists"][0]["vehicleType"], "R")
self.assertEqual(data["billLists"][0]["totalValue"], 60000)
self.assertEqual(data["billLists"][0]["cgstValue"], 5400)
self.assertEqual(data["billLists"][0]["sgstValue"], 5400)
self.assertEqual(data["billLists"][0]["vehicleNo"], "KA12KA1234")
self.assertEqual(data["billLists"][0]["itemList"][0]["taxableAmount"], 60000)
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
einvoice_settings.save()
frappe.flags.country = country
def test_einvoice_json(self):
from erpnext.regional.india.e_invoice.utils import make_einvoice, validate_totals
si = get_sales_invoice_for_e_invoice()
si.discount_amount = 100
si.save()
einvoice = make_einvoice(si)
self.assertTrue(einvoice["EwbDtls"])
validate_totals(einvoice)
si.apply_discount_on = "Net Total"
si.save()
einvoice = make_einvoice(si)
validate_totals(einvoice)
[d.set("included_in_print_rate", 1) for d in si.taxes]
si.save()
einvoice = make_einvoice(si)
validate_totals(einvoice)
def test_item_tax_net_range(self): def test_item_tax_net_range(self):
item = create_item("T Shirt") item = create_item("T Shirt")
@ -3201,7 +3108,8 @@ class TestSalesInvoice(unittest.TestCase):
def test_sales_invoice_with_disabled_account(self): def test_sales_invoice_with_disabled_account(self):
try: try:
account = frappe.get_doc("Account", "VAT 5% - _TC") account_name = "Sales Expenses - _TC"
account = frappe.get_doc("Account", account_name)
account.disabled = 1 account.disabled = 1
account.save() account.save()
@ -3213,10 +3121,10 @@ class TestSalesInvoice(unittest.TestCase):
"taxes", "taxes",
{ {
"charge_type": "On Net Total", "charge_type": "On Net Total",
"account_head": "VAT 5% - _TC", "account_head": account_name,
"cost_center": "Main - _TC", "cost_center": "Main - _TC",
"description": "VAT @ 5.0", "description": "Commission",
"rate": 9, "rate": 5,
}, },
) )
si.save() si.save()
@ -3324,177 +3232,6 @@ def get_sales_invoice_for_e_invoice():
return si return si
def make_test_address_for_ewaybill():
if not frappe.db.exists("Address", "_Test Address for Eway bill-Billing"):
address = frappe.get_doc(
{
"address_line1": "_Test Address Line 1",
"address_line2": "_Test Address Line 2",
"address_title": "_Test Address for Eway bill",
"address_type": "Billing",
"city": "_Test City",
"state": "Test State",
"country": "India",
"doctype": "Address",
"is_primary_address": 1,
"phone": "+910000000000",
"gstin": "27AAECE4835E1ZR",
"gst_state": "Maharashtra",
"gst_state_number": "27",
"pincode": "401108",
}
).insert()
address.append("links", {"link_doctype": "Company", "link_name": "_Test Company"})
address.save()
if not frappe.db.exists("Address", "_Test Customer-Address for Eway bill-Billing"):
address = frappe.get_doc(
{
"address_line1": "_Test Address Line 1",
"address_line2": "_Test Address Line 2",
"address_title": "_Test Customer-Address for Eway bill",
"address_type": "Billing",
"city": "_Test City",
"state": "Test State",
"country": "India",
"doctype": "Address",
"is_primary_address": 1,
"phone": "+910000000000",
"gstin": "27AACCM7806M1Z3",
"gst_state": "Maharashtra",
"gst_state_number": "27",
"pincode": "410038",
}
).insert()
address.append("links", {"link_doctype": "Customer", "link_name": "_Test Customer"})
address.save()
if not frappe.db.exists("Address", "_Test Customer-Address for Eway bill-Shipping"):
address = frappe.get_doc(
{
"address_line1": "_Test Address Line 1",
"address_line2": "_Test Address Line 2",
"address_title": "_Test Customer-Address for Eway bill",
"address_type": "Shipping",
"city": "_Test City",
"state": "Test State",
"country": "India",
"doctype": "Address",
"is_primary_address": 1,
"phone": "+910000000000",
"gst_state": "Maharashtra",
"gst_state_number": "27",
"pincode": "410098",
}
).insert()
address.append("links", {"link_doctype": "Customer", "link_name": "_Test Customer"})
address.save()
if not frappe.db.exists("Address", "_Test Dispatch-Address for Eway bill-Shipping"):
address = frappe.get_doc(
{
"address_line1": "_Test Dispatch Address Line 1",
"address_line2": "_Test Dispatch Address Line 2",
"address_title": "_Test Dispatch-Address for Eway bill",
"address_type": "Shipping",
"city": "_Test City",
"state": "Test State",
"country": "India",
"doctype": "Address",
"is_primary_address": 0,
"phone": "+910000000000",
"gstin": "07AAACC1206D1ZI",
"gst_state": "Delhi",
"gst_state_number": "07",
"pincode": "1100101",
}
).insert()
address.save()
def make_test_transporter_for_ewaybill():
if not frappe.db.exists("Supplier", "_Test Transporter"):
frappe.get_doc(
{
"doctype": "Supplier",
"supplier_name": "_Test Transporter",
"country": "India",
"supplier_group": "_Test Supplier Group",
"supplier_type": "Company",
"is_transporter": 1,
}
).insert()
def make_sales_invoice_for_ewaybill():
make_test_address_for_ewaybill()
make_test_transporter_for_ewaybill()
gst_settings = frappe.get_doc("GST Settings")
gst_account = frappe.get_all(
"GST Account",
fields=["cgst_account", "sgst_account", "igst_account"],
filters={"company": "_Test Company"},
)
if not gst_account:
gst_settings.append(
"gst_accounts",
{
"company": "_Test Company",
"cgst_account": "Output Tax CGST - _TC",
"sgst_account": "Output Tax SGST - _TC",
"igst_account": "Output Tax IGST - _TC",
},
)
gst_settings.save()
si = create_sales_invoice(do_not_save=1, rate="60000")
si.distance = 2000
si.company_address = "_Test Address for Eway bill-Billing"
si.customer_address = "_Test Customer-Address for Eway bill-Billing"
si.shipping_address_name = "_Test Customer-Address for Eway bill-Shipping"
si.dispatch_address_name = "_Test Dispatch-Address for Eway bill-Shipping"
si.vehicle_no = "KA12KA1234"
si.gst_category = "Registered Regular"
si.mode_of_transport = "Road"
si.transporter = "_Test Transporter"
si.append(
"taxes",
{
"charge_type": "On Net Total",
"account_head": "Output Tax CGST - _TC",
"cost_center": "Main - _TC",
"description": "CGST @ 9.0",
"rate": 9,
},
)
si.append(
"taxes",
{
"charge_type": "On Net Total",
"account_head": "Output Tax SGST - _TC",
"cost_center": "Main - _TC",
"description": "SGST @ 9.0",
"rate": 9,
},
)
return si
def check_gl_entries(doc, voucher_no, expected_gle, posting_date): def check_gl_entries(doc, voucher_no, expected_gle, posting_date):
gl_entries = frappe.db.sql( gl_entries = frappe.db.sql(
"""select account, debit, credit, posting_date """select account, debit, credit, posting_date
@ -3537,7 +3274,6 @@ def create_sales_invoice(**args):
"item_code": args.item or args.item_code or "_Test Item", "item_code": args.item or args.item_code or "_Test Item",
"item_name": args.item_name or "_Test Item", "item_name": args.item_name or "_Test Item",
"description": args.description or "_Test Item", "description": args.description or "_Test Item",
"gst_hsn_code": "999800",
"warehouse": args.warehouse or "_Test Warehouse - _TC", "warehouse": args.warehouse or "_Test Warehouse - _TC",
"qty": args.qty or 1, "qty": args.qty or 1,
"uom": args.uom or "Nos", "uom": args.uom or "Nos",
@ -3590,7 +3326,6 @@ def create_sales_invoice_against_cost_center(**args):
"items", "items",
{ {
"item_code": args.item or args.item_code or "_Test Item", "item_code": args.item or args.item_code or "_Test Item",
"gst_hsn_code": "999800",
"warehouse": args.warehouse or "_Test Warehouse - _TC", "warehouse": args.warehouse or "_Test Warehouse - _TC",
"qty": args.qty or 1, "qty": args.qty or 1,
"rate": args.rate or 100, "rate": args.rate or 100,

View File

@ -1,180 +0,0 @@
{%- from "templates/print_formats/standard_macros.html" import add_header, render_field, print_value -%}
<div class="page-break">
{% if doc.signed_einvoice %}
{%- set einvoice = json.loads(doc.signed_einvoice) -%}
<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;">Shipped From</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>
{%- if einvoice.DispDtls -%}
{%- set dispatch = einvoice.DispDtls -%}
<h5 style="margin-bottom: 5px;">Dispatched From</h5>
{%- if dispatch.Gstin -%} <p>{{ dispatch.Gstin }}</p> {% endif %}
<p>{{ dispatch.LglNm }}</p>
<p>{{ dispatch.Addr1 }}</p>
{%- if dispatch.Addr2 -%} <p>{{ dispatch.Addr2 }}</p> {% endif %}
<p>{{ dispatch.Loc }}</p>
<p>{{ frappe.db.get_value("Address", doc.dispatch_address_name, "gst_state") }} - {{ dispatch.Pin }}</p>
{% endif %}
</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>
{% else %}
<div class="text-center" style="color: var(--gray-500); font-size: 14px;">
You must generate IRN before you can preview GST E-Invoice.
</div>
{% endif %}
</div>

View File

@ -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"
}

File diff suppressed because one or more lines are too long

View File

@ -856,8 +856,8 @@ def get_outstanding_invoices(
) )
for d in invoice_list: for d in invoice_list:
payment_amount = d.invoice_amount - d.outstanding payment_amount = d.invoice_amount_in_account_currency - d.outstanding_in_account_currency
outstanding_amount = d.outstanding outstanding_amount = d.outstanding_in_account_currency
if outstanding_amount > 0.5 / (10**precision): if outstanding_amount > 0.5 / (10**precision):
if ( if (
min_outstanding min_outstanding
@ -873,7 +873,7 @@ def get_outstanding_invoices(
"voucher_no": d.voucher_no, "voucher_no": d.voucher_no,
"voucher_type": d.voucher_type, "voucher_type": d.voucher_type,
"posting_date": d.posting_date, "posting_date": d.posting_date,
"invoice_amount": flt(d.invoice_amount), "invoice_amount": flt(d.invoice_amount_in_account_currency),
"payment_amount": payment_amount, "payment_amount": payment_amount,
"outstanding_amount": outstanding_amount, "outstanding_amount": outstanding_amount,
"due_date": d.due_date, "due_date": d.due_date,
@ -1413,7 +1413,7 @@ def create_payment_ledger_entry(
if gle.against_voucher_type if gle.against_voucher_type
else gle.voucher_type, else gle.voucher_type,
"against_voucher_no": gle.against_voucher if gle.against_voucher else gle.voucher_no, "against_voucher_no": gle.against_voucher if gle.against_voucher else gle.voucher_no,
"currency": gle.currency, "account_currency": gle.account_currency,
"amount": dr_or_cr, "amount": dr_or_cr,
"amount_in_account_currency": dr_or_cr_account_currency, "amount_in_account_currency": dr_or_cr_account_currency,
"delinked": True if cancel else False, "delinked": True if cancel else False,

View File

@ -5,7 +5,7 @@
"label": "Profit and Loss" "label": "Profit and Loss"
} }
], ],
"content": "[{\"type\":\"onboarding\",\"data\":{\"onboarding_name\":\"Accounts\",\"col\":12}},{\"type\":\"chart\",\"data\":{\"chart_name\":\"Profit and Loss\",\"col\":12}},{\"type\":\"spacer\",\"data\":{\"col\":12}},{\"type\":\"header\",\"data\":{\"text\":\"<span class=\\\"h4\\\"><b>Your Shortcuts</b></span>\",\"col\":12}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Chart of Accounts\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Sales Invoice\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Purchase Invoice\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Journal Entry\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Payment Entry\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Accounts Receivable\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"General Ledger\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Trial Balance\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Dashboard\",\"col\":3}},{\"type\":\"spacer\",\"data\":{\"col\":12}},{\"type\":\"header\",\"data\":{\"text\":\"<span class=\\\"h4\\\"><b>Reports & Masters</b></span>\",\"col\":12}},{\"type\":\"card\",\"data\":{\"card_name\":\"Accounting Masters\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"General Ledger\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Accounts Receivable\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Accounts Payable\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Reports\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Financial Statements\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Multi Currency\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Settings\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Bank Statement\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Subscription Management\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Goods and Services Tax (GST India)\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Share Management\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Cost Center and Budgeting\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Opening and Closing\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Taxes\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Profitability\",\"col\":4}}]", "content": "[{\"type\":\"onboarding\",\"data\":{\"onboarding_name\":\"Accounts\",\"col\":12}},{\"type\":\"chart\",\"data\":{\"chart_name\":\"Profit and Loss\",\"col\":12}},{\"type\":\"spacer\",\"data\":{\"col\":12}},{\"type\":\"header\",\"data\":{\"text\":\"<span class=\\\"h4\\\"><b>Your Shortcuts</b></span>\",\"col\":12}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Chart of Accounts\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Sales Invoice\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Purchase Invoice\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Journal Entry\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Payment Entry\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Accounts Receivable\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"General Ledger\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Trial Balance\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Dashboard\",\"col\":3}},{\"type\":\"spacer\",\"data\":{\"col\":12}},{\"type\":\"header\",\"data\":{\"text\":\"<span class=\\\"h4\\\"><b>Reports & Masters</b></span>\",\"col\":12}},{\"type\":\"card\",\"data\":{\"card_name\":\"Accounting Masters\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"General Ledger\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Accounts Receivable\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Accounts Payable\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Reports\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Financial Statements\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Multi Currency\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Settings\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Bank Statement\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Subscription Management\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Share Management\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Cost Center and Budgeting\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Opening and Closing\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Taxes\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Profitability\",\"col\":4}}]",
"creation": "2020-03-02 15:41:59.515192", "creation": "2020-03-02 15:41:59.515192",
"docstatus": 0, "docstatus": 0,
"doctype": "Workspace", "doctype": "Workspace",
@ -777,147 +777,6 @@
"onboard": 0, "onboard": 0,
"type": "Link" "type": "Link"
}, },
{
"hidden": 0,
"is_query_report": 0,
"label": "Goods and Services Tax (GST India)",
"link_count": 0,
"onboard": 0,
"only_for": "India",
"type": "Card Break"
},
{
"dependencies": "",
"hidden": 0,
"is_query_report": 0,
"label": "GST Settings",
"link_count": 0,
"link_to": "GST Settings",
"link_type": "DocType",
"onboard": 0,
"only_for": "India",
"type": "Link"
},
{
"dependencies": "",
"hidden": 0,
"is_query_report": 0,
"label": "GST HSN Code",
"link_count": 0,
"link_to": "GST HSN Code",
"link_type": "DocType",
"onboard": 0,
"only_for": "India",
"type": "Link"
},
{
"dependencies": "",
"hidden": 0,
"is_query_report": 1,
"label": "GSTR-1",
"link_count": 0,
"link_to": "GSTR-1",
"link_type": "Report",
"onboard": 0,
"only_for": "India",
"type": "Link"
},
{
"dependencies": "",
"hidden": 0,
"is_query_report": 1,
"label": "GSTR-2",
"link_count": 0,
"link_to": "GSTR-2",
"link_type": "Report",
"onboard": 0,
"only_for": "India",
"type": "Link"
},
{
"dependencies": "",
"hidden": 0,
"is_query_report": 0,
"label": "GSTR 3B Report",
"link_count": 0,
"link_to": "GSTR 3B Report",
"link_type": "DocType",
"onboard": 0,
"only_for": "India",
"type": "Link"
},
{
"dependencies": "",
"hidden": 0,
"is_query_report": 1,
"label": "GST Sales Register",
"link_count": 0,
"link_to": "GST Sales Register",
"link_type": "Report",
"onboard": 0,
"only_for": "India",
"type": "Link"
},
{
"dependencies": "",
"hidden": 0,
"is_query_report": 1,
"label": "GST Purchase Register",
"link_count": 0,
"link_to": "GST Purchase Register",
"link_type": "Report",
"onboard": 0,
"only_for": "India",
"type": "Link"
},
{
"dependencies": "",
"hidden": 0,
"is_query_report": 1,
"label": "GST Itemised Sales Register",
"link_count": 0,
"link_to": "GST Itemised Sales Register",
"link_type": "Report",
"onboard": 0,
"only_for": "India",
"type": "Link"
},
{
"dependencies": "",
"hidden": 0,
"is_query_report": 1,
"label": "GST Itemised Purchase Register",
"link_count": 0,
"link_to": "GST Itemised Purchase Register",
"link_type": "Report",
"onboard": 0,
"only_for": "India",
"type": "Link"
},
{
"dependencies": "",
"hidden": 0,
"is_query_report": 0,
"label": "C-Form",
"link_count": 0,
"link_to": "C-Form",
"link_type": "DocType",
"onboard": 0,
"only_for": "India",
"type": "Link"
},
{
"dependencies": "",
"hidden": 0,
"is_query_report": 0,
"label": "Lower Deduction Certificate",
"link_count": 0,
"link_to": "Lower Deduction Certificate",
"link_type": "DocType",
"onboard": 0,
"only_for": "India",
"type": "Link"
},
{ {
"hidden": 0, "hidden": 0,
"is_query_report": 0, "is_query_report": 0,
@ -1159,6 +1018,17 @@
"onboard": 0, "onboard": 0,
"type": "Link" "type": "Link"
}, },
{
"hidden": 0,
"is_query_report": 0,
"label": "Lower Deduction Certificate",
"link_count": 0,
"link_to": "Lower Deduction Certificate",
"link_type": "DocType",
"onboard": 0,
"only_for": "India",
"type": "Link"
},
{ {
"hidden": 0, "hidden": 0,
"is_query_report": 0, "is_query_report": 0,
@ -1223,7 +1093,7 @@
"type": "Link" "type": "Link"
} }
], ],
"modified": "2022-06-10 15:49:42.990860", "modified": "2022-06-24 05:41:09.236458",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Accounting", "name": "Accounting",

View File

@ -740,51 +740,6 @@ class TestDepreciationMethods(AssetSetup):
self.assertEqual(schedules, expected_schedules) self.assertEqual(schedules, expected_schedules)
def test_discounted_wdv_depreciation_rate_for_indian_region(self):
# set indian company
company_flag = frappe.flags.company
frappe.flags.company = "_Test Company"
finance_book = frappe.new_doc("Finance Book")
finance_book.finance_book_name = "Income Tax"
finance_book.for_income_tax = 1
finance_book.insert(ignore_if_duplicate=True)
asset = create_asset(
calculate_depreciation=1,
available_for_use_date="2030-07-12",
purchase_date="2030-01-01",
finance_book=finance_book.name,
depreciation_method="Written Down Value",
expected_value_after_useful_life=12500,
depreciation_start_date="2030-12-31",
total_number_of_depreciations=3,
frequency_of_depreciation=12,
)
self.assertEqual(asset.finance_books[0].rate_of_depreciation, 50.0)
expected_schedules = [
["2030-12-31", 11849.32, 11849.32],
["2031-12-31", 44075.34, 55924.66],
["2032-12-31", 22037.67, 77962.33],
["2033-07-12", 9537.67, 87500.0],
]
schedules = [
[
cstr(d.schedule_date),
flt(d.depreciation_amount, 2),
flt(d.accumulated_depreciation_amount, 2),
]
for d in asset.get("schedules")
]
self.assertEqual(schedules, expected_schedules)
# reset indian company
frappe.flags.company = company_flag
class TestDepreciationBasics(AssetSetup): class TestDepreciationBasics(AssetSetup):
def test_depreciation_without_pro_rata(self): def test_depreciation_without_pro_rata(self):

View File

@ -12,9 +12,6 @@ from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (
) )
from erpnext.assets.doctype.asset.asset import get_depreciation_amount from erpnext.assets.doctype.asset.asset import get_depreciation_amount
from erpnext.assets.doctype.asset.depreciation import get_depreciation_accounts from erpnext.assets.doctype.asset.depreciation import get_depreciation_accounts
from erpnext.regional.india.utils import (
get_depreciation_amount as get_depreciation_amount_for_india,
)
class AssetValueAdjustment(Document): class AssetValueAdjustment(Document):
@ -133,10 +130,7 @@ class AssetValueAdjustment(Document):
depreciation_amount = days * rate_per_day depreciation_amount = days * rate_per_day
from_date = data.schedule_date from_date = data.schedule_date
else: else:
if country == "India": depreciation_amount = get_depreciation_amount(asset, value_after_depreciation, d)
depreciation_amount = get_depreciation_amount_for_india(asset, value_after_depreciation, d)
else:
depreciation_amount = get_depreciation_amount(asset, value_after_depreciation, d)
if depreciation_amount: if depreciation_amount:
value_after_depreciation -= flt(depreciation_amount) value_after_depreciation -= flt(depreciation_amount)

View File

@ -1,3 +0,0 @@
{% include "erpnext/regional/india/taxes.js" %}
erpnext.setup_auto_gst_taxation('Purchase Order');

View File

@ -1,3 +0,0 @@
{% include "erpnext/regional/india/party.js" %}
erpnext.setup_gst_reminder_button('Supplier');

View File

@ -300,7 +300,7 @@ class BuyingController(StockController, Subcontracting):
raise_error_if_no_rate=False, raise_error_if_no_rate=False,
) )
rate = flt(outgoing_rate * d.conversion_factor, d.precision("rate")) rate = flt(outgoing_rate * (d.conversion_factor or 1), d.precision("rate"))
else: else:
rate = frappe.db.get_value(ref_doctype, d.get(frappe.scrub(ref_doctype)), "rate") rate = frappe.db.get_value(ref_doctype, d.get(frappe.scrub(ref_doctype)), "rate")

View File

@ -500,6 +500,9 @@ class calculate_taxes_and_totals(object):
else: else:
self.doc.grand_total = flt(self.doc.net_total) self.doc.grand_total = flt(self.doc.net_total)
if self.doc.apply_discount_on == "Grand Total" and self.doc.get("is_cash_or_non_trade_discount"):
self.doc.grand_total -= self.doc.discount_amount
if self.doc.get("taxes"): if self.doc.get("taxes"):
self.doc.total_taxes_and_charges = flt( self.doc.total_taxes_and_charges = flt(
self.doc.grand_total - self.doc.net_total - flt(self.doc.rounding_adjustment), self.doc.grand_total - self.doc.net_total - flt(self.doc.rounding_adjustment),
@ -594,6 +597,12 @@ class calculate_taxes_and_totals(object):
if not self.doc.apply_discount_on: if not self.doc.apply_discount_on:
frappe.throw(_("Please select Apply Discount On")) frappe.throw(_("Please select Apply Discount On"))
if self.doc.apply_discount_on == "Grand Total" and self.doc.get(
"is_cash_or_non_trade_discount"
):
self.discount_amount_applied = True
return
self.doc.base_discount_amount = flt( self.doc.base_discount_amount = flt(
self.doc.discount_amount * self.doc.conversion_rate, self.doc.precision("base_discount_amount") self.doc.discount_amount * self.doc.conversion_rate, self.doc.precision("base_discount_amount")
) )

View File

@ -309,7 +309,6 @@ doc_events = {
"Sales Taxes and Charges Template": { "Sales Taxes and Charges Template": {
"on_update": "erpnext.e_commerce.doctype.e_commerce_settings.e_commerce_settings.validate_cart_settings" "on_update": "erpnext.e_commerce.doctype.e_commerce_settings.e_commerce_settings.validate_cart_settings"
}, },
"Tax Category": {"validate": "erpnext.regional.india.utils.validate_tax_category"},
"Sales Invoice": { "Sales Invoice": {
"on_submit": [ "on_submit": [
"erpnext.regional.create_transaction_log", "erpnext.regional.create_transaction_log",
@ -323,24 +322,15 @@ doc_events = {
"erpnext.regional.saudi_arabia.utils.delete_qr_code_file", "erpnext.regional.saudi_arabia.utils.delete_qr_code_file",
], ],
"on_trash": "erpnext.regional.check_deletion_permission", "on_trash": "erpnext.regional.check_deletion_permission",
"validate": [
"erpnext.regional.india.utils.validate_document_name",
"erpnext.regional.india.utils.update_taxable_values",
"erpnext.regional.india.utils.validate_sez_and_export_invoices",
],
}, },
"POS Invoice": {"on_submit": ["erpnext.regional.saudi_arabia.utils.create_qr_code"]}, "POS Invoice": {"on_submit": ["erpnext.regional.saudi_arabia.utils.create_qr_code"]},
"Purchase Invoice": { "Purchase Invoice": {
"validate": [ "validate": [
"erpnext.regional.india.utils.validate_reverse_charge_transaction",
"erpnext.regional.india.utils.update_itc_availed_fields",
"erpnext.regional.united_arab_emirates.utils.update_grand_total_for_rcm", "erpnext.regional.united_arab_emirates.utils.update_grand_total_for_rcm",
"erpnext.regional.united_arab_emirates.utils.validate_returns", "erpnext.regional.united_arab_emirates.utils.validate_returns",
"erpnext.regional.india.utils.update_taxable_values",
] ]
}, },
"Payment Entry": { "Payment Entry": {
"validate": "erpnext.regional.india.utils.update_place_of_supply",
"on_submit": [ "on_submit": [
"erpnext.regional.create_transaction_log", "erpnext.regional.create_transaction_log",
"erpnext.accounts.doctype.payment_request.payment_request.update_payment_req_status", "erpnext.accounts.doctype.payment_request.payment_request.update_payment_req_status",
@ -350,20 +340,9 @@ doc_events = {
}, },
"Address": { "Address": {
"validate": [ "validate": [
"erpnext.regional.india.utils.validate_gstin_for_india",
"erpnext.regional.italy.utils.set_state_code", "erpnext.regional.italy.utils.set_state_code",
"erpnext.regional.india.utils.update_gst_category",
], ],
}, },
"Supplier": {"validate": "erpnext.regional.india.utils.validate_pan_for_india"},
(
"Sales Invoice",
"Sales Order",
"Delivery Note",
"Purchase Invoice",
"Purchase Order",
"Purchase Receipt",
): {"validate": ["erpnext.regional.india.utils.set_place_of_supply"]},
"Contact": { "Contact": {
"on_trash": "erpnext.support.doctype.issue.issue.update_issue", "on_trash": "erpnext.support.doctype.issue.issue.update_issue",
"after_insert": "erpnext.telephony.doctype.call_log.call_log.link_existing_conversations", "after_insert": "erpnext.telephony.doctype.call_log.call_log.link_existing_conversations",
@ -375,12 +354,7 @@ doc_events = {
("Quotation", "Sales Order", "Sales Invoice"): { ("Quotation", "Sales Order", "Sales Invoice"): {
"validate": ["erpnext.erpnext_integrations.taxjar_integration.set_sales_tax"] "validate": ["erpnext.erpnext_integrations.taxjar_integration.set_sales_tax"]
}, },
"Company": { "Company": {"on_trash": ["erpnext.regional.saudi_arabia.utils.delete_vat_settings_for_company"]},
"on_trash": [
"erpnext.regional.india.utils.delete_gst_settings_for_company",
"erpnext.regional.saudi_arabia.utils.delete_vat_settings_for_company",
]
},
"Integration Request": { "Integration Request": {
"validate": "erpnext.accounts.doctype.payment_request.payment_request.validate_payment" "validate": "erpnext.accounts.doctype.payment_request.payment_request.validate_payment"
}, },
@ -554,16 +528,6 @@ regional_overrides = {
"France": { "France": {
"erpnext.tests.test_regional.test_method": "erpnext.regional.france.utils.test_method" "erpnext.tests.test_regional.test_method": "erpnext.regional.france.utils.test_method"
}, },
"India": {
"erpnext.tests.test_regional.test_method": "erpnext.regional.india.utils.test_method",
"erpnext.controllers.taxes_and_totals.get_itemised_tax_breakup_header": "erpnext.regional.india.utils.get_itemised_tax_breakup_header",
"erpnext.controllers.taxes_and_totals.get_itemised_tax_breakup_data": "erpnext.regional.india.utils.get_itemised_tax_breakup_data",
"erpnext.accounts.party.get_regional_address_details": "erpnext.regional.india.utils.get_regional_address_details",
"erpnext.controllers.taxes_and_totals.get_regional_round_off_accounts": "erpnext.regional.india.utils.get_regional_round_off_accounts",
"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",
},
"United Arab Emirates": { "United Arab Emirates": {
"erpnext.controllers.taxes_and_totals.update_itemised_tax_data": "erpnext.regional.united_arab_emirates.utils.update_itemised_tax_data", "erpnext.controllers.taxes_and_totals.update_itemised_tax_data": "erpnext.regional.united_arab_emirates.utils.update_itemised_tax_data",
"erpnext.accounts.doctype.purchase_invoice.purchase_invoice.make_regional_gl_entries": "erpnext.regional.united_arab_emirates.utils.make_regional_gl_entries", "erpnext.accounts.doctype.purchase_invoice.purchase_invoice.make_regional_gl_entries": "erpnext.regional.united_arab_emirates.utils.make_regional_gl_entries",

View File

@ -1243,7 +1243,7 @@ class TestWorkOrder(FrappeTestCase):
ste_doc.insert() ste_doc.insert()
ste_doc.submit() ste_doc.submit()
batch_list = [row.batch_no for row in ste_doc.items] batch_list = sorted([row.batch_no for row in ste_doc.items])
wo_doc = make_wo_order_test_record(production_item=fg_item, qty=4) wo_doc = make_wo_order_test_record(production_item=fg_item, qty=4)
transferred_ste_doc = frappe.get_doc( transferred_ste_doc = frappe.get_doc(

View File

@ -9,9 +9,7 @@ execute:frappe.reload_doc("accounts", "doctype", "POS Payment Method") #2020-05-
erpnext.patches.v4_2.update_requested_and_ordered_qty #2021-03-31 erpnext.patches.v4_2.update_requested_and_ordered_qty #2021-03-31
erpnext.patches.v5_7.update_item_description_based_on_item_master erpnext.patches.v5_7.update_item_description_based_on_item_master
erpnext.patches.v4_2.repost_reserved_qty #2021-03-31 erpnext.patches.v4_2.repost_reserved_qty #2021-03-31
erpnext.patches.v8_1.setup_gst_india #2017-06-27
erpnext.patches.v8_1.removed_roles_from_gst_report_non_indian_account #16-08-2018 erpnext.patches.v8_1.removed_roles_from_gst_report_non_indian_account #16-08-2018
erpnext.patches.v8_7.sync_india_custom_fields
erpnext.patches.v10_0.fichier_des_ecritures_comptables_for_france erpnext.patches.v10_0.fichier_des_ecritures_comptables_for_france
erpnext.patches.v10_0.rename_price_to_rate_in_pricing_rule erpnext.patches.v10_0.rename_price_to_rate_in_pricing_rule
erpnext.patches.v10_0.set_currency_in_pricing_rule erpnext.patches.v10_0.set_currency_in_pricing_rule
@ -38,7 +36,6 @@ erpnext.patches.v11_0.check_buying_selling_in_currency_exchange
erpnext.patches.v11_0.move_item_defaults_to_child_table_for_multicompany #02-07-2018 #19-06-2019 erpnext.patches.v11_0.move_item_defaults_to_child_table_for_multicompany #02-07-2018 #19-06-2019
erpnext.patches.v11_0.rename_overproduction_percent_field erpnext.patches.v11_0.rename_overproduction_percent_field
erpnext.patches.v11_0.update_backflush_subcontract_rm_based_on_bom erpnext.patches.v11_0.update_backflush_subcontract_rm_based_on_bom
erpnext.patches.v11_0.inter_state_field_for_gst
erpnext.patches.v11_0.rename_members_with_naming_series #04-06-2018 erpnext.patches.v11_0.rename_members_with_naming_series #04-06-2018
erpnext.patches.v11_0.set_update_field_and_value_in_workflow_state erpnext.patches.v11_0.set_update_field_and_value_in_workflow_state
erpnext.patches.v11_0.update_total_qty_field erpnext.patches.v11_0.update_total_qty_field
@ -58,18 +55,13 @@ execute:frappe.delete_doc_if_exists("Page", "sales-analytics")
execute:frappe.delete_doc_if_exists("Page", "purchase-analytics") execute:frappe.delete_doc_if_exists("Page", "purchase-analytics")
execute:frappe.delete_doc_if_exists("Page", "stock-analytics") execute:frappe.delete_doc_if_exists("Page", "stock-analytics")
execute:frappe.delete_doc_if_exists("Page", "production-analytics") execute:frappe.delete_doc_if_exists("Page", "production-analytics")
erpnext.patches.v11_0.ewaybill_fields_gst_india #2018-11-13 #2019-01-09 #2019-04-01 #2019-04-26 #2019-05-03
erpnext.patches.v10_0.item_barcode_childtable_migrate # 16-02-2019 erpnext.patches.v10_0.item_barcode_childtable_migrate # 16-02-2019
erpnext.patches.v11_0.update_delivery_trip_status erpnext.patches.v11_0.update_delivery_trip_status
erpnext.patches.v11_0.set_missing_gst_hsn_code
erpnext.patches.v11_0.rename_bom_wo_fields erpnext.patches.v11_0.rename_bom_wo_fields
erpnext.patches.v12_0.set_default_homepage_type erpnext.patches.v12_0.set_default_homepage_type
erpnext.patches.v11_0.renamed_from_to_fields_in_project erpnext.patches.v11_0.renamed_from_to_fields_in_project
erpnext.patches.v11_0.add_permissions_in_gst_settings #2020-04-04
erpnext.patches.v11_1.setup_guardian_role erpnext.patches.v11_1.setup_guardian_role
execute:frappe.delete_doc('DocType', 'Notification Control') execute:frappe.delete_doc('DocType', 'Notification Control')
erpnext.patches.v12_0.set_gst_category
erpnext.patches.v12_0.update_gst_category
erpnext.patches.v11_0.remove_barcodes_field_from_copy_fields_to_variants erpnext.patches.v11_0.remove_barcodes_field_from_copy_fields_to_variants
erpnext.patches.v12_0.set_task_status erpnext.patches.v12_0.set_task_status
erpnext.patches.v11_0.make_italian_localization_fields # 26-03-2019 erpnext.patches.v11_0.make_italian_localization_fields # 26-03-2019
@ -105,7 +97,6 @@ execute:frappe.delete_doc("DocType", "Project Task")
erpnext.patches.v11_1.update_default_supplier_in_item_defaults erpnext.patches.v11_1.update_default_supplier_in_item_defaults
erpnext.patches.v12_0.update_due_date_in_gle erpnext.patches.v12_0.update_due_date_in_gle
erpnext.patches.v12_0.add_default_buying_selling_terms_in_company erpnext.patches.v12_0.add_default_buying_selling_terms_in_company
erpnext.patches.v12_0.update_ewaybill_field_position
erpnext.patches.v12_0.create_accounting_dimensions_in_missing_doctypes #2020-05-11 erpnext.patches.v12_0.create_accounting_dimensions_in_missing_doctypes #2020-05-11
erpnext.patches.v11_1.set_status_for_material_request_type_manufacture erpnext.patches.v11_1.set_status_for_material_request_type_manufacture
erpnext.patches.v12_0.move_plaid_settings_to_doctype erpnext.patches.v12_0.move_plaid_settings_to_doctype
@ -127,13 +118,11 @@ erpnext.patches.v12_0.replace_accounting_with_accounts_in_home_settings
erpnext.patches.v12_0.set_automatically_process_deferred_accounting_in_accounts_settings erpnext.patches.v12_0.set_automatically_process_deferred_accounting_in_accounts_settings
erpnext.patches.v12_0.set_payment_entry_status erpnext.patches.v12_0.set_payment_entry_status
erpnext.patches.v12_0.update_owner_fields_in_acc_dimension_custom_fields erpnext.patches.v12_0.update_owner_fields_in_acc_dimension_custom_fields
erpnext.patches.v12_0.add_export_type_field_in_party_master
erpnext.patches.v12_0.update_price_or_product_discount erpnext.patches.v12_0.update_price_or_product_discount
erpnext.patches.v12_0.set_production_capacity_in_workstation erpnext.patches.v12_0.set_production_capacity_in_workstation
erpnext.patches.v12_0.set_employee_preferred_emails erpnext.patches.v12_0.set_employee_preferred_emails
erpnext.patches.v12_0.set_against_blanket_order_in_sales_and_purchase_order erpnext.patches.v12_0.set_against_blanket_order_in_sales_and_purchase_order
erpnext.patches.v12_0.set_cost_center_in_child_table_of_expense_claim erpnext.patches.v12_0.set_cost_center_in_child_table_of_expense_claim
erpnext.patches.v12_0.add_eway_bill_in_delivery_note
erpnext.patches.v12_0.set_lead_title_field erpnext.patches.v12_0.set_lead_title_field
erpnext.patches.v12_0.set_permission_einvoicing erpnext.patches.v12_0.set_permission_einvoicing
erpnext.patches.v12_0.create_irs_1099_field_united_states erpnext.patches.v12_0.create_irs_1099_field_united_states
@ -174,12 +163,10 @@ erpnext.patches.v12_0.set_italian_import_supplier_invoice_permissions
erpnext.patches.v13_0.update_subscription erpnext.patches.v13_0.update_subscription
erpnext.patches.v12_0.unhide_cost_center_field erpnext.patches.v12_0.unhide_cost_center_field
erpnext.patches.v13_0.update_sla_enhancements erpnext.patches.v13_0.update_sla_enhancements
erpnext.patches.v12_0.update_address_template_for_india
erpnext.patches.v13_0.update_deferred_settings erpnext.patches.v13_0.update_deferred_settings
erpnext.patches.v12_0.set_multi_uom_in_rfq erpnext.patches.v12_0.set_multi_uom_in_rfq
erpnext.patches.v13_0.delete_old_sales_reports erpnext.patches.v13_0.delete_old_sales_reports
execute:frappe.delete_doc_if_exists("DocType", "Bank Reconciliation") execute:frappe.delete_doc_if_exists("DocType", "Bank Reconciliation")
erpnext.patches.v12_0.create_itc_reversal_custom_fields
execute:frappe.reload_doc("regional", "doctype", "e_invoice_settings") execute:frappe.reload_doc("regional", "doctype", "e_invoice_settings")
erpnext.patches.v13_0.loyalty_points_entry_for_pos_invoice #22-07-2020 erpnext.patches.v13_0.loyalty_points_entry_for_pos_invoice #22-07-2020
erpnext.patches.v12_0.add_taxjar_integration_field erpnext.patches.v12_0.add_taxjar_integration_field
@ -189,17 +176,14 @@ erpnext.patches.v12_0.update_item_tax_template_company
erpnext.patches.v13_0.move_branch_code_to_bank_account erpnext.patches.v13_0.move_branch_code_to_bank_account
erpnext.patches.v13_0.add_standard_navbar_items #2021-03-24 erpnext.patches.v13_0.add_standard_navbar_items #2021-03-24
erpnext.patches.v13_0.stock_entry_enhancements erpnext.patches.v13_0.stock_entry_enhancements
erpnext.patches.v12_0.update_state_code_for_daman_and_diu
erpnext.patches.v12_0.rename_lost_reason_detail erpnext.patches.v12_0.rename_lost_reason_detail
erpnext.patches.v13_0.drop_razorpay_payload_column erpnext.patches.v13_0.drop_razorpay_payload_column
erpnext.patches.v13_0.setting_custom_roles_for_some_regional_reports
erpnext.patches.v13_0.rename_issue_doctype_fields erpnext.patches.v13_0.rename_issue_doctype_fields
erpnext.patches.v13_0.change_default_pos_print_format erpnext.patches.v13_0.change_default_pos_print_format
erpnext.patches.v13_0.set_youtube_video_id erpnext.patches.v13_0.set_youtube_video_id
erpnext.patches.v13_0.set_app_name erpnext.patches.v13_0.set_app_name
erpnext.patches.v13_0.print_uom_after_quantity_patch erpnext.patches.v13_0.print_uom_after_quantity_patch
erpnext.patches.v13_0.set_payment_channel_in_payment_gateway_account erpnext.patches.v13_0.set_payment_channel_in_payment_gateway_account
erpnext.patches.v12_0.setup_einvoice_fields #2020-12-02
execute:frappe.delete_doc("Report", "Quoted Item Comparison") execute:frappe.delete_doc("Report", "Quoted Item Comparison")
erpnext.patches.v13_0.update_member_email_address erpnext.patches.v13_0.update_member_email_address
erpnext.patches.v13_0.update_pos_closing_entry_in_merge_log erpnext.patches.v13_0.update_pos_closing_entry_in_merge_log
@ -211,25 +195,18 @@ erpnext.patches.v13_0.update_project_template_tasks
erpnext.patches.v13_0.convert_qi_parameter_to_link_field erpnext.patches.v13_0.convert_qi_parameter_to_link_field
erpnext.patches.v13_0.add_naming_series_to_old_projects # 1-02-2021 erpnext.patches.v13_0.add_naming_series_to_old_projects # 1-02-2021
erpnext.patches.v13_0.update_payment_terms_outstanding erpnext.patches.v13_0.update_payment_terms_outstanding
erpnext.patches.v12_0.add_state_code_for_ladakh
erpnext.patches.v13_0.item_reposting_for_incorrect_sl_and_gl erpnext.patches.v13_0.item_reposting_for_incorrect_sl_and_gl
erpnext.patches.v13_0.delete_old_bank_reconciliation_doctypes erpnext.patches.v13_0.delete_old_bank_reconciliation_doctypes
erpnext.patches.v13_0.update_vehicle_no_reqd_condition erpnext.patches.v13_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.rename_membership_settings_to_non_profit_settings
erpnext.patches.v13_0.setup_gratuity_rule_for_india_and_uae erpnext.patches.v13_0.setup_gratuity_rule_for_india_and_uae
erpnext.patches.v13_0.setup_uae_vat_fields erpnext.patches.v13_0.setup_uae_vat_fields
execute:frappe.db.set_value('System Settings', None, 'app_name', 'ERPNext') execute:frappe.db.set_value('System Settings', None, 'app_name', 'ERPNext')
erpnext.patches.v12_0.create_taxable_value_field
erpnext.patches.v12_0.add_gst_category_in_delivery_note
erpnext.patches.v12_0.purchase_receipt_status erpnext.patches.v12_0.purchase_receipt_status
erpnext.patches.v13_0.fix_non_unique_represents_company erpnext.patches.v13_0.fix_non_unique_represents_company
erpnext.patches.v12_0.add_document_type_field_for_italy_einvoicing erpnext.patches.v12_0.add_document_type_field_for_italy_einvoicing
erpnext.patches.v13_0.update_shipment_status erpnext.patches.v13_0.update_shipment_status
erpnext.patches.v13_0.remove_attribute_field_from_item_variant_setting erpnext.patches.v13_0.remove_attribute_field_from_item_variant_setting
erpnext.patches.v12_0.add_ewaybill_validity_field
erpnext.patches.v13_0.set_pos_closing_as_failed erpnext.patches.v13_0.set_pos_closing_as_failed
execute:frappe.rename_doc("Workspace", "Loan Management", "Loans", force=True) execute:frappe.rename_doc("Workspace", "Loan Management", "Loans", force=True)
erpnext.patches.v13_0.update_timesheet_changes erpnext.patches.v13_0.update_timesheet_changes
@ -241,9 +218,7 @@ erpnext.patches.v13_0.update_job_card_details
erpnext.patches.v13_0.add_missing_fg_item_for_stock_entry erpnext.patches.v13_0.add_missing_fg_item_for_stock_entry
erpnext.patches.v13_0.update_subscription_status_in_memberships erpnext.patches.v13_0.update_subscription_status_in_memberships
erpnext.patches.v13_0.update_amt_in_work_order_required_items erpnext.patches.v13_0.update_amt_in_work_order_required_items
erpnext.patches.v12_0.show_einvoice_irn_cancelled_field
erpnext.patches.v13_0.delete_orphaned_tables erpnext.patches.v13_0.delete_orphaned_tables
erpnext.patches.v13_0.update_export_type_for_gst #2021-08-16
erpnext.patches.v13_0.update_tds_check_field #3 erpnext.patches.v13_0.update_tds_check_field #3
erpnext.patches.v13_0.add_custom_field_for_south_africa #2 erpnext.patches.v13_0.add_custom_field_for_south_africa #2
erpnext.patches.v13_0.update_recipient_email_digest erpnext.patches.v13_0.update_recipient_email_digest
@ -264,9 +239,7 @@ erpnext.patches.v13_0.make_homepage_products_website_items
erpnext.patches.v13_0.replace_supplier_item_group_with_party_specific_item erpnext.patches.v13_0.replace_supplier_item_group_with_party_specific_item
erpnext.patches.v13_0.update_dates_in_tax_withholding_category erpnext.patches.v13_0.update_dates_in_tax_withholding_category
erpnext.patches.v14_0.update_opportunity_currency_fields erpnext.patches.v14_0.update_opportunity_currency_fields
erpnext.patches.v13_0.gst_fields_for_pos_invoice
erpnext.patches.v13_0.create_accounting_dimensions_in_pos_doctypes erpnext.patches.v13_0.create_accounting_dimensions_in_pos_doctypes
erpnext.patches.v13_0.trim_sales_invoice_custom_field_length
erpnext.patches.v13_0.create_custom_field_for_finance_book erpnext.patches.v13_0.create_custom_field_for_finance_book
erpnext.patches.v13_0.modify_invalid_gain_loss_gl_entries #2 erpnext.patches.v13_0.modify_invalid_gain_loss_gl_entries #2
erpnext.patches.v13_0.fix_additional_cost_in_mfg_stock_entry erpnext.patches.v13_0.fix_additional_cost_in_mfg_stock_entry
@ -279,7 +252,6 @@ erpnext.patches.v12_0.update_production_plan_status
erpnext.patches.v13_0.healthcare_deprecation_warning erpnext.patches.v13_0.healthcare_deprecation_warning
erpnext.patches.v13_0.item_naming_series_not_mandatory erpnext.patches.v13_0.item_naming_series_not_mandatory
erpnext.patches.v13_0.update_category_in_ltds_certificate erpnext.patches.v13_0.update_category_in_ltds_certificate
erpnext.patches.v13_0.create_pan_field_for_india #2
erpnext.patches.v13_0.fetch_thumbnail_in_website_items erpnext.patches.v13_0.fetch_thumbnail_in_website_items
erpnext.patches.v13_0.update_maintenance_schedule_field_in_visit erpnext.patches.v13_0.update_maintenance_schedule_field_in_visit
erpnext.patches.v13_0.create_ksa_vat_custom_fields # 07-01-2022 erpnext.patches.v13_0.create_ksa_vat_custom_fields # 07-01-2022
@ -287,7 +259,6 @@ erpnext.patches.v14_0.migrate_crm_settings
erpnext.patches.v13_0.rename_ksa_qr_field erpnext.patches.v13_0.rename_ksa_qr_field
erpnext.patches.v13_0.wipe_serial_no_field_for_0_qty erpnext.patches.v13_0.wipe_serial_no_field_for_0_qty
erpnext.patches.v13_0.disable_ksa_print_format_for_others # 16-12-2021 erpnext.patches.v13_0.disable_ksa_print_format_for_others # 16-12-2021
erpnext.patches.v13_0.update_tax_category_for_rcm
erpnext.patches.v13_0.agriculture_deprecation_warning erpnext.patches.v13_0.agriculture_deprecation_warning
erpnext.patches.v13_0.hospitality_deprecation_warning erpnext.patches.v13_0.hospitality_deprecation_warning
erpnext.patches.v13_0.update_asset_quantity_field erpnext.patches.v13_0.update_asset_quantity_field
@ -295,6 +266,7 @@ erpnext.patches.v13_0.delete_bank_reconciliation_detail
erpnext.patches.v13_0.enable_provisional_accounting erpnext.patches.v13_0.enable_provisional_accounting
erpnext.patches.v13_0.non_profit_deprecation_warning erpnext.patches.v13_0.non_profit_deprecation_warning
erpnext.patches.v13_0.enable_ksa_vat_docs #1 erpnext.patches.v13_0.enable_ksa_vat_docs #1
erpnext.patches.v13_0.show_india_localisation_deprecation_warning
[post_model_sync] [post_model_sync]
execute:frappe.delete_doc_if_exists('Workspace', 'ERPNext Integrations Settings') execute:frappe.delete_doc_if_exists('Workspace', 'ERPNext Integrations Settings')
@ -307,9 +279,7 @@ erpnext.patches.v14_0.delete_agriculture_doctypes # 15-06-2022
erpnext.patches.v14_0.delete_education_doctypes erpnext.patches.v14_0.delete_education_doctypes
erpnext.patches.v14_0.delete_datev_doctypes erpnext.patches.v14_0.delete_datev_doctypes
erpnext.patches.v14_0.rearrange_company_fields erpnext.patches.v14_0.rearrange_company_fields
erpnext.patches.v14_0.restore_einvoice_fields
erpnext.patches.v13_0.update_sane_transfer_against erpnext.patches.v13_0.update_sane_transfer_against
erpnext.patches.v12_0.add_company_link_to_einvoice_settings
erpnext.patches.v14_0.migrate_cost_center_allocations erpnext.patches.v14_0.migrate_cost_center_allocations
erpnext.patches.v13_0.convert_to_website_item_in_item_card_group_template erpnext.patches.v13_0.convert_to_website_item_in_item_card_group_template
erpnext.patches.v13_0.shopping_cart_to_ecommerce erpnext.patches.v13_0.shopping_cart_to_ecommerce
@ -324,7 +294,6 @@ erpnext.patches.v14_0.delete_non_profit_doctypes
erpnext.patches.v13_0.add_cost_center_in_loans erpnext.patches.v13_0.add_cost_center_in_loans
erpnext.patches.v13_0.set_return_against_in_pos_invoice_references erpnext.patches.v13_0.set_return_against_in_pos_invoice_references
erpnext.patches.v13_0.remove_unknown_links_to_prod_plan_items # 24-03-2022 erpnext.patches.v13_0.remove_unknown_links_to_prod_plan_items # 24-03-2022
erpnext.patches.v13_0.create_gst_custom_fields_in_quotation
erpnext.patches.v13_0.copy_custom_field_filters_to_website_item erpnext.patches.v13_0.copy_custom_field_filters_to_website_item
erpnext.patches.v13_0.change_default_item_manufacturer_fieldtype erpnext.patches.v13_0.change_default_item_manufacturer_fieldtype
erpnext.patches.v13_0.requeue_recoverable_reposts erpnext.patches.v13_0.requeue_recoverable_reposts
@ -335,4 +304,5 @@ execute:frappe.delete_doc("DocType", "Naming Series")
erpnext.patches.v13_0.job_card_status_on_hold erpnext.patches.v13_0.job_card_status_on_hold
erpnext.patches.v14_0.migrate_gl_to_payment_ledger erpnext.patches.v14_0.migrate_gl_to_payment_ledger
erpnext.patches.v14_0.crm_ux_cleanup erpnext.patches.v14_0.crm_ux_cleanup
erpnext.patches.v14_0.remove_india_localisation
erpnext.patches.v14_0.delete_hr_payroll_doctypes erpnext.patches.v14_0.delete_hr_payroll_doctypes

View File

@ -1,13 +0,0 @@
import frappe
from erpnext.regional.india.setup import add_permissions
def execute():
company = frappe.get_all("Company", filters={"country": "India"})
if not company:
return
frappe.reload_doc("regional", "doctype", "lower_deduction_certificate")
frappe.reload_doc("regional", "doctype", "gstr_3b_report")
add_permissions()

View File

@ -1,11 +0,0 @@
import frappe
from erpnext.regional.india.setup import make_custom_fields
def execute():
company = frappe.get_all("Company", filters={"country": "India"})
if not company:
return
make_custom_fields()

View File

@ -1,98 +0,0 @@
import frappe
from erpnext.regional.india.setup import make_custom_fields
def execute():
company = frappe.get_all("Company", filters={"country": "India"})
if not company:
return
frappe.reload_doc("Payroll", "doctype", "Employee Tax Exemption Declaration")
frappe.reload_doc("Payroll", "doctype", "Employee Tax Exemption Proof Submission")
frappe.reload_doc("hr", "doctype", "Employee Grade")
frappe.reload_doc("hr", "doctype", "Leave Policy")
frappe.reload_doc("accounts", "doctype", "Bank Account")
frappe.reload_doc("accounts", "doctype", "Tax Withholding Category")
frappe.reload_doc("accounts", "doctype", "Allowed To Transact With")
frappe.reload_doc("accounts", "doctype", "Finance Book")
frappe.reload_doc("accounts", "doctype", "Loyalty Program")
frappe.reload_doc("stock", "doctype", "Item Barcode")
make_custom_fields()
frappe.reload_doc("accounts", "doctype", "sales_taxes_and_charges")
frappe.reload_doc("accounts", "doctype", "purchase_taxes_and_charges")
frappe.reload_doc("accounts", "doctype", "sales_taxes_and_charges_template")
frappe.reload_doc("accounts", "doctype", "purchase_taxes_and_charges_template")
# set is_inter_state in Taxes And Charges Templates
if frappe.db.has_column(
"Sales Taxes and Charges Template", "is_inter_state"
) and frappe.db.has_column("Purchase Taxes and Charges Template", "is_inter_state"):
igst_accounts = set(
frappe.db.sql_list(
'''SELECT igst_account from `tabGST Account` WHERE parent = "GST Settings"'''
)
)
cgst_accounts = set(
frappe.db.sql_list(
'''SELECT cgst_account FROM `tabGST Account` WHERE parenttype = "GST Settings"'''
)
)
when_then_sales = get_formatted_data("Sales Taxes and Charges", igst_accounts, cgst_accounts)
when_then_purchase = get_formatted_data(
"Purchase Taxes and Charges", igst_accounts, cgst_accounts
)
if when_then_sales:
frappe.db.sql(
"""update `tabSales Taxes and Charges Template`
set is_inter_state = Case {when_then} Else 0 End
""".format(
when_then=" ".join(when_then_sales)
)
)
if when_then_purchase:
frappe.db.sql(
"""update `tabPurchase Taxes and Charges Template`
set is_inter_state = Case {when_then} Else 0 End
""".format(
when_then=" ".join(when_then_purchase)
)
)
def get_formatted_data(doctype, igst_accounts, cgst_accounts):
# fetch all the rows data from child table
all_details = frappe.db.sql(
'''
select parent, account_head from `tab{doctype}`
where parenttype="{doctype} Template"'''.format(
doctype=doctype
),
as_dict=True,
)
# group the data in the form "parent: [list of accounts]""
group_detail = {}
for i in all_details:
if not i["parent"] in group_detail:
group_detail[i["parent"]] = []
for j in all_details:
if i["parent"] == j["parent"]:
group_detail[i["parent"]].append(j["account_head"])
# form when_then condition based on - if list of accounts for a document
# matches any account in igst_accounts list and not matches any in cgst_accounts list
when_then = []
for i in group_detail:
temp = set(group_detail[i])
if not temp.isdisjoint(igst_accounts) and temp.isdisjoint(cgst_accounts):
when_then.append("""When name='{name}' Then 1""".format(name=i))
return when_then

View File

@ -12,7 +12,6 @@ doctype_series_map = {
"Attendance": "HR-ATT-.YYYY.-", "Attendance": "HR-ATT-.YYYY.-",
"Auto Repeat": "SYS-ARP-.YYYY.-", "Auto Repeat": "SYS-ARP-.YYYY.-",
"Blanket Order": "MFG-BLR-.YYYY.-", "Blanket Order": "MFG-BLR-.YYYY.-",
"C-Form": "ACC-CF-.YYYY.-",
"Campaign": "SAL-CAM-.YYYY.-", "Campaign": "SAL-CAM-.YYYY.-",
"Course Schedule": "EDU-CSH-.YYYY.-", "Course Schedule": "EDU-CSH-.YYYY.-",
"Customer": "CUST-.YYYY.-", "Customer": "CUST-.YYYY.-",

View File

@ -1,64 +0,0 @@
import frappe
from erpnext.controllers.taxes_and_totals import get_itemised_tax_breakup_html
def execute():
company = frappe.db.sql_list("select name from tabCompany where country = 'India'")
if not company:
return
doctypes = [
"Quotation",
"Sales Order",
"Delivery Note",
"Sales Invoice",
"Supplier Quotation",
"Purchase Order",
"Purchase Receipt",
"Purchase Invoice",
]
for dt in doctypes:
date_field = "posting_date"
if dt in ["Quotation", "Sales Order", "Supplier Quotation", "Purchase Order"]:
date_field = "transaction_date"
transactions = frappe.db.sql(
"""
select dt.name, dt_item.name as child_name
from `tab{dt}` dt, `tab{dt} Item` dt_item
where dt.name = dt_item.parent
and dt.`{date_field}` > '2018-06-01'
and dt.docstatus = 1
and ifnull(dt_item.gst_hsn_code, '') = ''
and ifnull(dt_item.item_code, '') != ''
and dt.company in ({company})
""".format(
dt=dt, date_field=date_field, company=", ".join(["%s"] * len(company))
),
tuple(company),
as_dict=1,
)
if not transactions:
continue
transaction_rows_name = [d.child_name for d in transactions]
frappe.db.sql(
"""
update `tab{dt} Item` dt_item
set dt_item.gst_hsn_code = (select gst_hsn_code from tabItem where name=dt_item.item_code)
where dt_item.name in ({rows_name})
""".format(
dt=dt, rows_name=", ".join(["%s"] * len(transaction_rows_name))
),
tuple(transaction_rows_name),
)
parent = set([d.name for d in transactions])
for t in list(parent):
trans_doc = frappe.get_doc(dt, t)
hsnwise_tax = get_itemised_tax_breakup_html(trans_doc)
frappe.db.set_value(dt, t, "other_charges_calculation", hsnwise_tax, update_modified=False)

View File

@ -1,21 +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])

View File

@ -1,160 +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,
)

View File

@ -1,20 +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()

View File

@ -1,23 +0,0 @@
import frappe
from frappe.custom.doctype.custom_field.custom_field import create_custom_field
def execute():
company = frappe.get_all("Company", filters={"country": "India"})
if not company:
return
create_custom_field(
"Delivery Note",
{
"fieldname": "ewaybill",
"label": "E-Way Bill No.",
"fieldtype": "Data",
"depends_on": "eval:(doc.docstatus === 1)",
"allow_on_submit": 1,
"insert_after": "customer_name_in_arabic",
"translatable": 0,
"owner": "Administrator",
},
)

View File

@ -1,27 +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)

View File

@ -1,42 +0,0 @@
import frappe
from erpnext.regional.india.setup import make_custom_fields
def execute():
company = frappe.get_all("Company", filters={"country": "India"})
if not company:
return
make_custom_fields()
frappe.reload_doctype("Tax Category")
frappe.reload_doctype("Sales Taxes and Charges Template")
frappe.reload_doctype("Purchase Taxes and Charges Template")
# Create tax category with inter state field checked
tax_category = frappe.db.get_value("Tax Category", {"name": "OUT OF STATE"}, "name")
if not tax_category:
inter_state_category = frappe.get_doc(
{"doctype": "Tax Category", "title": "OUT OF STATE", "is_inter_state": 1}
).insert()
tax_category = inter_state_category.name
for doctype in ("Sales Taxes and Charges Template", "Purchase Taxes and Charges Template"):
if not frappe.get_meta(doctype).has_field("is_inter_state"):
continue
template = frappe.db.get_value(doctype, {"is_inter_state": 1, "disabled": 0}, ["name"])
if template:
frappe.db.set_value(doctype, template, "tax_category", tax_category)
frappe.db.sql(
"""
DELETE FROM `tabCustom Field`
WHERE fieldname = 'is_inter_state'
AND dt IN ('Sales Taxes and Charges Template', 'Purchase Taxes and Charges Template')
"""
)

View File

@ -1,25 +0,0 @@
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 = {
"Delivery Note": [
dict(
fieldname="gst_category",
label="GST Category",
fieldtype="Select",
insert_after="gst_vehicle_type",
print_hide=1,
options="\nRegistered Regular\nRegistered Composition\nUnregistered\nSEZ\nOverseas\nConsumer\nDeemed Export\nUIN Holders",
fetch_from="customer.gst_category",
fetch_if_empty=1,
),
]
}
create_custom_fields(custom_fields, update=True)

View File

@ -1,19 +0,0 @@
import frappe
from erpnext.regional.india import states
def execute():
company = frappe.get_all("Company", filters={"country": "India"})
if not company:
return
custom_fields = ["Address-gst_state", "Tax Category-gst_state"]
# Update options in gst_state custom fields
for field in custom_fields:
if frappe.db.exists("Custom Field", field):
gst_state_field = frappe.get_doc("Custom Field", field)
gst_state_field.options = "\n".join(states)
gst_state_field.save()

View File

@ -1,167 +0,0 @@
import frappe
from frappe.custom.doctype.custom_field.custom_field import create_custom_fields
from frappe.custom.doctype.property_setter.property_setter import make_property_setter
from erpnext.regional.india.utils import get_gst_accounts
def execute():
company = frappe.get_all("Company", filters={"country": "India"}, fields=["name"])
if not company:
return
frappe.reload_doc("regional", "doctype", "gst_settings")
frappe.reload_doc("accounts", "doctype", "gst_account")
journal_entry_types = frappe.get_meta("Journal Entry").get_options("voucher_type").split("\n") + [
"Reversal Of ITC"
]
make_property_setter(
"Journal Entry", "voucher_type", "options", "\n".join(journal_entry_types), ""
)
custom_fields = {
"Journal Entry": [
dict(
fieldname="reversal_type",
label="Reversal Type",
fieldtype="Select",
insert_after="voucher_type",
print_hide=1,
options="As per rules 42 & 43 of CGST Rules\nOthers",
depends_on="eval:doc.voucher_type=='Reversal Of ITC'",
mandatory_depends_on="eval:doc.voucher_type=='Reversal Of ITC'",
),
dict(
fieldname="company_address",
label="Company Address",
fieldtype="Link",
options="Address",
insert_after="reversal_type",
print_hide=1,
depends_on="eval:doc.voucher_type=='Reversal Of ITC'",
mandatory_depends_on="eval:doc.voucher_type=='Reversal Of ITC'",
),
dict(
fieldname="company_gstin",
label="Company GSTIN",
fieldtype="Data",
read_only=1,
insert_after="company_address",
print_hide=1,
fetch_from="company_address.gstin",
depends_on="eval:doc.voucher_type=='Reversal Of ITC'",
mandatory_depends_on="eval:doc.voucher_type=='Reversal Of ITC'",
),
],
"Purchase Invoice": [
dict(
fieldname="eligibility_for_itc",
label="Eligibility For ITC",
fieldtype="Select",
insert_after="reason_for_issuing_document",
print_hide=1,
options="Input Service Distributor\nImport Of Service\nImport Of Capital Goods\nITC on Reverse Charge\nIneligible As Per Section 17(5)\nIneligible Others\nAll Other ITC",
default="All Other ITC",
)
],
"Purchase Invoice Item": [
dict(
fieldname="taxable_value",
label="Taxable Value",
fieldtype="Currency",
insert_after="base_net_amount",
hidden=1,
options="Company:company:default_currency",
print_hide=1,
)
],
}
create_custom_fields(custom_fields, update=True)
# Patch ITC Availed fields from Data to Currency
# Patch Availed ITC for current fiscal_year
gst_accounts = get_gst_accounts(only_non_reverse_charge=1)
frappe.db.sql(
"""
UPDATE `tabCustom Field` SET fieldtype='Currency', options='Company:company:default_currency'
WHERE dt = 'Purchase Invoice' and fieldname in ('itc_integrated_tax', 'itc_state_tax', 'itc_central_tax',
'itc_cess_amount')
"""
)
frappe.db.sql(
"""UPDATE `tabPurchase Invoice` set itc_integrated_tax = '0'
WHERE trim(coalesce(itc_integrated_tax, '')) = '' """
)
frappe.db.sql(
"""UPDATE `tabPurchase Invoice` set itc_state_tax = '0'
WHERE trim(coalesce(itc_state_tax, '')) = '' """
)
frappe.db.sql(
"""UPDATE `tabPurchase Invoice` set itc_central_tax = '0'
WHERE trim(coalesce(itc_central_tax, '')) = '' """
)
frappe.db.sql(
"""UPDATE `tabPurchase Invoice` set itc_cess_amount = '0'
WHERE trim(coalesce(itc_cess_amount, '')) = '' """
)
# Get purchase invoices
invoices = frappe.get_all(
"Purchase Invoice",
{"posting_date": (">=", "2021-04-01"), "eligibility_for_itc": ("!=", "Ineligible")},
["name"],
)
amount_map = {}
if invoices:
invoice_list = set([d.name for d in invoices])
# Get GST applied
amounts = frappe.db.sql(
"""
SELECT parent, account_head, sum(base_tax_amount_after_discount_amount) as amount
FROM `tabPurchase Taxes and Charges`
where parent in %s
GROUP BY parent, account_head
""",
(invoice_list),
as_dict=1,
)
for d in amounts:
amount_map.setdefault(
d.parent,
{"itc_integrated_tax": 0, "itc_state_tax": 0, "itc_central_tax": 0, "itc_cess_amount": 0},
)
if not gst_accounts:
continue
if d.account_head in gst_accounts.get("igst_account"):
amount_map[d.parent]["itc_integrated_tax"] += d.amount
if d.account_head in gst_accounts.get("cgst_account"):
amount_map[d.parent]["itc_central_tax"] += d.amount
if d.account_head in gst_accounts.get("sgst_account"):
amount_map[d.parent]["itc_state_tax"] += d.amount
if d.account_head in gst_accounts.get("cess_account"):
amount_map[d.parent]["itc_cess_amount"] += d.amount
for invoice, values in amount_map.items():
frappe.db.set_value(
"Purchase Invoice",
invoice,
{
"itc_integrated_tax": values.get("itc_integrated_tax"),
"itc_central_tax": values.get("itc_central_tax"),
"itc_state_tax": values["itc_state_tax"],
"itc_cess_amount": values["itc_cess_amount"],
},
)

View File

@ -1,24 +0,0 @@
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 Item": [
dict(
fieldname="taxable_value",
label="Taxable Value",
fieldtype="Currency",
insert_after="base_net_amount",
hidden=1,
options="Company:company:default_currency",
print_hide=1,
)
]
}
create_custom_fields(custom_fields, update=True)

View File

@ -1,66 +0,0 @@
import frappe
from erpnext.regional.india.setup import make_custom_fields
def execute():
company = frappe.get_all("Company", filters={"country": "India"})
if not company:
return
frappe.reload_doc("accounts", "doctype", "Tax Category")
make_custom_fields()
for doctype in ["Sales Invoice", "Purchase Invoice"]:
has_column = frappe.db.has_column(doctype, "invoice_type")
if has_column:
update_map = {
"Regular": "Registered Regular",
"Export": "Overseas",
"SEZ": "SEZ",
"Deemed Export": "Deemed Export",
}
for old, new in update_map.items():
frappe.db.sql(
"UPDATE `tab{doctype}` SET gst_category = %s where invoice_type = %s".format(doctype=doctype),
(new, old),
) # nosec
frappe.delete_doc("Custom Field", "Sales Invoice-invoice_type")
frappe.delete_doc("Custom Field", "Purchase Invoice-invoice_type")
itc_update_map = {
"ineligible": "Ineligible",
"input service": "Input Service Distributor",
"capital goods": "Import Of Capital Goods",
"input": "All Other ITC",
}
has_gst_fields = frappe.db.has_column("Purchase Invoice", "eligibility_for_itc")
if has_gst_fields:
for old, new in itc_update_map.items():
frappe.db.sql(
"UPDATE `tabPurchase Invoice` SET eligibility_for_itc = %s where eligibility_for_itc = %s ",
(new, old),
)
for doctype in ["Customer", "Supplier"]:
frappe.db.sql(
""" UPDATE `tab{doctype}` t1, `tabAddress` t2, `tabDynamic Link` t3 SET t1.gst_category = "Registered Regular"
where t3.link_name = t1.name and t3.parent = t2.name and t2.gstin IS NOT NULL and t2.gstin != '' """.format(
doctype=doctype
)
) # nosec
frappe.db.sql(
""" UPDATE `tab{doctype}` t1, `tabAddress` t2, `tabDynamic Link` t3 SET t1.gst_category = "Overseas"
where t3.link_name = t1.name and t3.parent = t2.name and t2.country != 'India' """.format(
doctype=doctype
)
) # nosec

View File

@ -1,134 +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)

View File

@ -1,16 +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)

View File

@ -1,14 +0,0 @@
# Copyright (c) 2020, Frappe and Contributors
# License: GNU General Public License v3. See license.txt
import frappe
from erpnext.regional.address_template.setup import set_up_address_templates
def execute():
if frappe.db.get_value("Company", {"country": "India"}, "name"):
address_template = frappe.db.get_value("Address Template", "India", "template")
if not address_template or "gstin" not in address_template:
set_up_address_templates(default_country="India")

View File

@ -1,29 +0,0 @@
import frappe
def execute():
company = frappe.get_all("Company", filters={"country": "India"})
if not company:
return
field = frappe.db.get_value("Custom Field", {"dt": "Sales Invoice", "fieldname": "ewaybill"})
if field:
ewaybill_field = frappe.get_doc("Custom Field", field)
ewaybill_field.flags.ignore_validate = True
ewaybill_field.update(
{
"fieldname": "ewaybill",
"label": "e-Way Bill No.",
"fieldtype": "Data",
"depends_on": "eval:(doc.docstatus === 1)",
"allow_on_submit": 1,
"insert_after": "tax_id",
"translatable": 0,
}
)
ewaybill_field.save()

View File

@ -1,23 +0,0 @@
import frappe
def execute():
company = frappe.get_all("Company", filters={"country": "India"})
if not company:
return
frappe.db.sql(
""" UPDATE `tabSales Invoice` set gst_category = 'Unregistered'
where gst_category = 'Registered Regular'
and ifnull(customer_gstin, '')=''
and ifnull(billing_address_gstin,'')=''
"""
)
frappe.db.sql(
""" UPDATE `tabPurchase Invoice` set gst_category = 'Unregistered'
where gst_category = 'Registered Regular'
and ifnull(supplier_gstin, '')=''
"""
)

View File

@ -1,26 +0,0 @@
import frappe
from erpnext.regional.india import states
def execute():
company = frappe.get_all("Company", filters={"country": "India"})
if not company:
return
# Update options in gst_state custom field
gst_state = frappe.get_doc("Custom Field", "Address-gst_state")
gst_state.options = "\n".join(states)
gst_state.save()
# Update gst_state and state code in existing address
frappe.db.sql(
"""
UPDATE `tabAddress`
SET
gst_state = 'Dadra and Nagar Haveli and Daman and Diu',
gst_state_number = 26
WHERE gst_state = 'Daman and Diu'
"""
)

View File

@ -1,53 +0,0 @@
import frappe
from frappe.custom.doctype.custom_field.custom_field import create_custom_fields
def execute():
company = frappe.get_all("Company", filters={"country": "India"}, fields=["name"])
if not company:
return
sales_invoice_gst_fields = [
dict(
fieldname="billing_address_gstin",
label="Billing Address GSTIN",
fieldtype="Data",
insert_after="customer_address",
read_only=1,
fetch_from="customer_address.gstin",
print_hide=1,
length=15,
),
dict(
fieldname="customer_gstin",
label="Customer GSTIN",
fieldtype="Data",
insert_after="shipping_address_name",
fetch_from="shipping_address_name.gstin",
print_hide=1,
length=15,
),
dict(
fieldname="place_of_supply",
label="Place of Supply",
fieldtype="Data",
insert_after="customer_gstin",
print_hide=1,
read_only=1,
length=50,
),
dict(
fieldname="company_gstin",
label="Company GSTIN",
fieldtype="Data",
insert_after="company_address",
fetch_from="company_address.gstin",
print_hide=1,
read_only=1,
length=15,
),
]
custom_fields = {"Quotation": sales_invoice_gst_fields}
create_custom_fields(custom_fields, update=True)

View File

@ -2,79 +2,19 @@
# License: GNU General Public License v3. See license.txt # License: GNU General Public License v3. See license.txt
import frappe import frappe
from frappe.custom.doctype.custom_field.custom_field import create_custom_fields
# Patch kept for users outside India
def execute(): def execute():
frappe.reload_doc("accounts", "doctype", "advance_taxes_and_charges")
frappe.reload_doc("accounts", "doctype", "payment_entry")
if frappe.db.exists("Company", {"country": "India"}): if frappe.db.exists("Company", {"country": "India"}):
custom_fields = { return
"Payment Entry": [
dict(
fieldname="gst_section",
label="GST Details",
fieldtype="Section Break",
insert_after="deductions",
print_hide=1,
collapsible=1,
),
dict(
fieldname="company_address",
label="Company Address",
fieldtype="Link",
insert_after="gst_section",
print_hide=1,
options="Address",
),
dict(
fieldname="company_gstin",
label="Company GSTIN",
fieldtype="Data",
insert_after="company_address",
fetch_from="company_address.gstin",
print_hide=1,
read_only=1,
),
dict(
fieldname="place_of_supply",
label="Place of Supply",
fieldtype="Data",
insert_after="company_gstin",
print_hide=1,
read_only=1,
),
dict(
fieldname="customer_address",
label="Customer Address",
fieldtype="Link",
insert_after="place_of_supply",
print_hide=1,
options="Address",
depends_on='eval:doc.party_type == "Customer"',
),
dict(
fieldname="customer_gstin",
label="Customer GSTIN",
fieldtype="Data",
insert_after="customer_address",
fetch_from="customer_address.gstin",
print_hide=1,
read_only=1,
),
]
}
create_custom_fields(custom_fields, update=True) for field in (
else: "gst_section",
fields = [ "company_address",
"gst_section", "company_gstin",
"company_address", "place_of_supply",
"company_gstin", "customer_address",
"place_of_supply", "customer_gstin",
"customer_address", ):
"customer_gstin", frappe.delete_doc_if_exists("Custom Field", f"Payment Entry-{field}")
]
for field in fields:
frappe.delete_doc_if_exists("Custom Field", f"Payment Entry-{field}")

View File

@ -1,19 +0,0 @@
import frappe
from frappe.custom.doctype.custom_field.custom_field import create_custom_fields
def execute():
frappe.reload_doc("buying", "doctype", "supplier", force=True)
frappe.reload_doc("selling", "doctype", "customer", force=True)
frappe.reload_doc("core", "doctype", "doctype", force=True)
custom_fields = {
"Supplier": [
{"fieldname": "pan", "label": "PAN", "fieldtype": "Data", "insert_after": "supplier_type"}
],
"Customer": [
{"fieldname": "pan", "label": "PAN", "fieldtype": "Data", "insert_after": "customer_type"}
],
}
create_custom_fields(custom_fields, update=True)

View File

@ -1,87 +0,0 @@
import frappe
from frappe.custom.doctype.custom_field.custom_field import create_custom_fields
def execute():
company = frappe.get_all("Company", filters={"country": "India"}, fields=["name"])
if not company:
return
hsn_sac_field = dict(
fieldname="gst_hsn_code",
label="HSN/SAC",
fieldtype="Data",
fetch_from="item_code.gst_hsn_code",
insert_after="description",
allow_on_submit=1,
print_hide=1,
fetch_if_empty=1,
)
nil_rated_exempt = dict(
fieldname="is_nil_exempt",
label="Is Nil Rated or Exempted",
fieldtype="Check",
fetch_from="item_code.is_nil_exempt",
insert_after="gst_hsn_code",
print_hide=1,
)
is_non_gst = dict(
fieldname="is_non_gst",
label="Is Non GST",
fieldtype="Check",
fetch_from="item_code.is_non_gst",
insert_after="is_nil_exempt",
print_hide=1,
)
taxable_value = dict(
fieldname="taxable_value",
label="Taxable Value",
fieldtype="Currency",
insert_after="base_net_amount",
hidden=1,
options="Company:company:default_currency",
print_hide=1,
)
sales_invoice_gst_fields = [
dict(
fieldname="billing_address_gstin",
label="Billing Address GSTIN",
fieldtype="Data",
insert_after="customer_address",
read_only=1,
fetch_from="customer_address.gstin",
print_hide=1,
),
dict(
fieldname="customer_gstin",
label="Customer GSTIN",
fieldtype="Data",
insert_after="shipping_address_name",
fetch_from="shipping_address_name.gstin",
print_hide=1,
),
dict(
fieldname="place_of_supply",
label="Place of Supply",
fieldtype="Data",
insert_after="customer_gstin",
print_hide=1,
read_only=1,
),
dict(
fieldname="company_gstin",
label="Company GSTIN",
fieldtype="Data",
insert_after="company_address",
fetch_from="company_address.gstin",
print_hide=1,
read_only=1,
),
]
custom_fields = {
"POS Invoice": sales_invoice_gst_fields,
"POS Invoice Item": [hsn_sac_field, nil_rated_exempt, is_non_gst, taxable_value],
}
create_custom_fields(custom_fields, update=True)

View File

@ -1,11 +0,0 @@
import frappe
from erpnext.regional.india.setup import add_custom_roles_for_reports
def execute():
company = frappe.get_all("Company", filters={"country": "India"})
if not company:
return
add_custom_roles_for_reports()

View File

@ -1,16 +0,0 @@
import frappe
from erpnext.regional.india.setup import make_custom_fields
def execute():
if frappe.get_all("Company", filters={"country": "India"}):
frappe.reload_doc("accounts", "doctype", "POS Invoice")
frappe.reload_doc("accounts", "doctype", "POS Invoice Item")
make_custom_fields()
if not frappe.db.exists("Party Type", "Donor"):
frappe.get_doc(
{"doctype": "Party Type", "party_type": "Donor", "account_type": "Receivable"}
).insert(ignore_permissions=True)

View File

@ -0,0 +1,15 @@
import click
import frappe
def execute():
if not frappe.db.exists("Company", {"country": "India"}):
return
click.secho(
"India-specific regional features have been moved to a separate app"
" and will be removed from ERPNext in Version 14."
" Please install India Compliance after upgrading to Version 14:\n"
"https://github.com/resilient-tech/india-compliance",
fg="yellow",
)

View File

@ -1,16 +0,0 @@
# Copyright (c) 2020, Frappe and Contributors
# License: GNU General Public License v3. See license.txt
import frappe
from erpnext.regional.india.setup import create_custom_fields, get_custom_fields
def execute():
company = frappe.get_all("Company", filters={"country": "India"})
if not company:
return
custom_fields = {"Sales Invoice": get_custom_fields().get("Sales Invoice")}
create_custom_fields(custom_fields, update=True)

View File

@ -1,40 +0,0 @@
import frappe
def execute():
company = frappe.get_all("Company", filters={"country": "India"})
if not company:
return
# Update custom fields
fieldname = frappe.db.get_value("Custom Field", {"dt": "Customer", "fieldname": "export_type"})
if fieldname:
frappe.db.set_value(
"Custom Field",
fieldname,
{
"default": "",
"mandatory_depends_on": 'eval:in_list(["SEZ", "Overseas", "Deemed Export"], doc.gst_category)',
},
)
fieldname = frappe.db.get_value("Custom Field", {"dt": "Supplier", "fieldname": "export_type"})
if fieldname:
frappe.db.set_value(
"Custom Field",
fieldname,
{"default": "", "mandatory_depends_on": 'eval:in_list(["SEZ", "Overseas"], doc.gst_category)'},
)
# Update Customer/Supplier Masters
frappe.db.sql(
"""
UPDATE `tabCustomer` set export_type = '' WHERE gst_category NOT IN ('SEZ', 'Overseas', 'Deemed Export')
"""
)
frappe.db.sql(
"""
UPDATE `tabSupplier` set export_type = '' WHERE gst_category NOT IN ('SEZ', 'Overseas')
"""
)

View File

@ -1,50 +0,0 @@
import frappe
from frappe.custom.doctype.custom_field.custom_field import create_custom_fields
from erpnext.regional.india import states
def execute():
company = frappe.get_all("Company", filters={"country": "India"})
if not company:
return
create_custom_fields(
{
"Tax Category": [
dict(
fieldname="is_inter_state",
label="Is Inter State",
fieldtype="Check",
insert_after="disabled",
print_hide=1,
),
dict(
fieldname="is_reverse_charge",
label="Is Reverse Charge",
fieldtype="Check",
insert_after="is_inter_state",
print_hide=1,
),
dict(
fieldname="tax_category_column_break",
fieldtype="Column Break",
insert_after="is_reverse_charge",
),
dict(
fieldname="gst_state",
label="Source State",
fieldtype="Select",
options="\n".join(states),
insert_after="company",
),
]
},
update=True,
)
tax_category = frappe.qb.DocType("Tax Category")
frappe.qb.update(tax_category).set(tax_category.is_reverse_charge, 1).where(
tax_category.name.isin(["Reverse Charge Out-State", "Reverse Charge In-State"])
).run()

View File

@ -0,0 +1,54 @@
import click
import frappe
def execute():
to_delete = {
"DocType": [
"C-Form",
"C-Form Invoice Detail",
"GST Account",
"E Invoice Request Log",
"E Invoice Settings",
"E Invoice User",
"GST HSN Code",
"GST Settings",
"GSTR 3B Report",
],
"Print Format": [
"GST E-Invoice",
"GST Purchase Invoice",
"GST Tax Invoice",
"GST POS Invoice",
],
"Report": [
"E-Invoice Summary",
"Eway Bill",
"GST Itemised Purchase Register",
"GST Itemised Sales Register",
"GST Purchase Register",
"GST Sales Register",
"GSTR-1",
"GSTR-2",
"HSN-wise-summary of outward supplies",
],
}
for doctype, names in to_delete.items():
frappe.delete_doc(
doctype,
names,
force=True,
ignore_permissions=True,
ignore_missing=True,
)
if not frappe.db.exists("Company", {"country": "India"}):
return
click.secho(
"India-specific regional features have been moved to a separate app."
" Please install India Compliance to continue using these features:"
" https://github.com/resilient-tech/india-compliance",
fg="yellow",
)

View File

@ -1,41 +0,0 @@
import frappe
from frappe.custom.doctype.custom_field.custom_field import create_custom_fields
from erpnext.regional.india.setup import add_permissions, add_print_formats
def execute():
# restores back the 2 custom fields that was deleted while removing e-invoicing from v14
company = frappe.get_all("Company", filters={"country": "India"})
if not company:
return
custom_fields = {
"Sales Invoice": [
dict(
fieldname="irn_cancelled",
label="IRN Cancelled",
fieldtype="Check",
no_copy=1,
print_hide=1,
depends_on="eval:(doc.irn_cancelled === 1)",
read_only=1,
allow_on_submit=1,
insert_after="customer",
),
dict(
fieldname="eway_bill_cancelled",
label="E-Way Bill Cancelled",
fieldtype="Check",
no_copy=1,
print_hide=1,
depends_on="eval:(doc.eway_bill_cancelled === 1)",
read_only=1,
allow_on_submit=1,
insert_after="customer",
),
]
}
create_custom_fields(custom_fields, update=True)
add_permissions()
add_print_formats()

View File

@ -6,16 +6,17 @@ import frappe
def execute(): def execute():
frappe.reload_doc("core", "doctype", "has_role") if frappe.db.exists("Company", {"country": "India"}):
company = frappe.get_all("Company", filters={"country": "India"}) return
if not company: frappe.reload_doc("core", "doctype", "has_role")
frappe.db.sql( frappe.db.sql(
""" """
delete from delete from
`tabHas Role` `tabHas Role`
where where
parenttype = 'Report' and parent in('GST Sales Register', parenttype = 'Report' and parent in('GST Sales Register',
'GST Purchase Register', 'GST Itemised Sales Register', 'GST Purchase Register', 'GST Itemised Sales Register',
'GST Itemised Purchase Register', 'Eway Bill')""" 'GST Itemised Purchase Register', 'Eway Bill')
) """
)

View File

@ -1,64 +0,0 @@
import frappe
from frappe.email import sendmail_to_system_managers
def execute():
frappe.reload_doc("stock", "doctype", "item")
frappe.reload_doc("stock", "doctype", "customs_tariff_number")
frappe.reload_doc("accounts", "doctype", "payment_terms_template")
frappe.reload_doc("accounts", "doctype", "payment_schedule")
company = frappe.get_all("Company", filters={"country": "India"})
if not company:
return
frappe.reload_doc("regional", "doctype", "gst_settings")
frappe.reload_doc("regional", "doctype", "gst_hsn_code")
for report_name in (
"GST Sales Register",
"GST Purchase Register",
"GST Itemised Sales Register",
"GST Itemised Purchase Register",
):
frappe.reload_doc("regional", "report", frappe.scrub(report_name))
from erpnext.regional.india.setup import setup
delete_custom_field_tax_id_if_exists()
setup(patch=True)
send_gst_update_email()
def delete_custom_field_tax_id_if_exists():
for field in frappe.db.sql_list(
"""select name from `tabCustom Field` where fieldname='tax_id'
and dt in ('Sales Order', 'Sales Invoice', 'Delivery Note')"""
):
frappe.delete_doc("Custom Field", field, ignore_permissions=True)
frappe.db.commit()
def send_gst_update_email():
message = """Hello,
<p>ERPNext is now GST Ready!</p>
<p>To start making GST Invoices from 1st of July, you just need to create new Tax Accounts,
Templates and update your Customer's and Supplier's GST Numbers.</p>
<p>Please refer {gst_document_link} to know more about how to setup and implement GST in ERPNext.</p>
<p>Please contact us at support@erpnext.com, if you have any questions.</p>
<p>Thanks,</p>
ERPNext Team.
""".format(
gst_document_link="<a href='http://frappe.github.io/erpnext/user/manual/en/regional/india/'> ERPNext GST Document </a>"
)
try:
sendmail_to_system_managers("[Important] ERPNext GST updates", message)
except Exception as e:
pass

View File

@ -1,36 +0,0 @@
import frappe
from erpnext.regional.india.setup import make_custom_fields
def execute():
company = frappe.get_all("Company", filters={"country": "India"})
if not company:
return
frappe.reload_doc("accounts", "doctype", "tax_category")
for doctype in ["Sales Invoice", "Delivery Note", "Purchase Invoice"]:
frappe.db.sql(
"""delete from `tabCustom Field` where dt = %s
and fieldname in ('port_code', 'shipping_bill_number', 'shipping_bill_date')""",
doctype,
)
make_custom_fields()
frappe.db.sql(
"""
update `tabCustom Field`
set reqd = 0, `default` = ''
where fieldname = 'reason_for_issuing_document'
"""
)
frappe.db.sql(
"""
update tabAddress
set gst_state_number=concat("0", gst_state_number)
where ifnull(gst_state_number, '') != '' and gst_state_number<10
"""
)

View File

@ -1107,9 +1107,25 @@ erpnext.TransactionController = class TransactionController extends erpnext.taxe
} }
} }
is_a_mapped_document(item) {
const mapped_item_field_map = {
"Delivery Note Item": ["si_detail", "so_detail", "dn_detail"],
"Sales Invoice Item": ["dn_detail", "so_detail", "sales_invoice_item"],
"Purchase Receipt Item": ["purchase_order_item", "purchase_invoice_item", "purchase_receipt_item"],
"Purchase Invoice Item": ["purchase_order_item", "pr_detail", "po_detail"],
};
const mappped_fields = mapped_item_field_map[item.doctype] || [];
return mappped_fields
.map((field) => item[field])
.filter(Boolean).length > 0;
}
batch_no(doc, cdt, cdn) { batch_no(doc, cdt, cdn) {
let item = frappe.get_doc(cdt, cdn); let item = frappe.get_doc(cdt, cdn);
this.apply_price_list(item, true); if (!this.is_a_mapped_document(item)) {
this.apply_price_list(item, true);
}
} }
toggle_conversion_factor(item) { toggle_conversion_factor(item) {
@ -1483,48 +1499,46 @@ erpnext.TransactionController = class TransactionController extends erpnext.taxe
} }
_set_values_for_item_list(children) { _set_values_for_item_list(children) {
var me = this; const items_rule_dict = {};
var items_rule_dict = {};
for(var i=0, l=children.length; i<l; i++) { for (const child of children) {
var d = children[i] ; const existing_pricing_rule = frappe.model.get_value(child.doctype, child.name, "pricing_rules");
let item_row = frappe.get_doc(d.doctype, d.name);
var existing_pricing_rule = frappe.model.get_value(d.doctype, d.name, "pricing_rules"); for (const [key, value] of Object.entries(child)) {
for(var k in d) { if (!["doctype", "name"].includes(key)) {
var v = d[k]; if (key === "price_list_rate") {
if (["doctype", "name"].indexOf(k)===-1) { frappe.model.set_value(child.doctype, child.name, "rate", value);
if(k=="price_list_rate") {
item_row['rate'] = v;
} }
if (k !== 'free_item_data') { if (key !== "free_item_data") {
item_row[k] = v; frappe.model.set_value(child.doctype, child.name, key, value);
} }
} }
} }
frappe.model.round_floats_in(item_row, ["price_list_rate", "discount_percentage"]); frappe.model.round_floats_in(
frappe.get_doc(child.doctype, child.name),
["price_list_rate", "discount_percentage"],
);
// if pricing rule set as blank from an existing value, apply price_list // if pricing rule set as blank from an existing value, apply price_list
if(!me.frm.doc.ignore_pricing_rule && existing_pricing_rule && !d.pricing_rules) { if (!this.frm.doc.ignore_pricing_rule && existing_pricing_rule && !child.pricing_rules) {
me.apply_price_list(frappe.get_doc(d.doctype, d.name)); this.apply_price_list(frappe.get_doc(child.doctype, child.name));
} else if(!d.pricing_rules) { } else if (!child.pricing_rules) {
me.remove_pricing_rule(frappe.get_doc(d.doctype, d.name)); this.remove_pricing_rule(frappe.get_doc(child.doctype, child.name));
} }
if (d.free_item_data.length > 0) { if (child.free_item_data.length > 0) {
me.apply_product_discount(d); this.apply_product_discount(child);
} }
if (d.apply_rule_on_other_items) { if (child.apply_rule_on_other_items) {
items_rule_dict[d.name] = d; items_rule_dict[child.name] = child;
} }
} }
me.frm.refresh_field('items'); this.apply_rule_on_other_items(items_rule_dict);
me.apply_rule_on_other_items(items_rule_dict); this.calculate_taxes_and_totals();
me.calculate_taxes_and_totals();
} }
apply_rule_on_other_items(args) { apply_rule_on_other_items(args) {

View File

@ -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) {
// }
});

View File

@ -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"
}

View File

@ -1,10 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
# import frappe
from frappe.model.document import Document
class EInvoiceRequestLog(Document):
pass

View File

@ -1,11 +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

View File

@ -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>`])
);
}
});

View File

@ -1,97 +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",
"advanced_settings_section",
"client_id",
"column_break_8",
"client_secret",
"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
},
{
"collapsible": 1,
"fieldname": "advanced_settings_section",
"fieldtype": "Section Break",
"label": "Advanced Settings"
},
{
"fieldname": "client_id",
"fieldtype": "Data",
"label": "Client ID"
},
{
"fieldname": "client_secret",
"fieldtype": "Password",
"label": "Client Secret"
},
{
"fieldname": "column_break_8",
"fieldtype": "Column Break"
}
],
"index_web_pages_for_search": 1,
"issingle": 1,
"links": [],
"modified": "2021-11-16 19:50:28.029517",
"modified_by": "Administrator",
"module": "Regional",
"name": "E Invoice Settings",
"owner": "Administrator",
"permissions": [],
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1
}

View File

@ -1,13 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
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."))

View File

@ -1,11 +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

View File

@ -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
}

View File

@ -1,10 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
# import frappe
from frappe.model.document import Document
class EInvoiceUser(Document):
pass

View File

@ -1,28 +0,0 @@
// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
frappe.ui.form.on('GST HSN Code', {
refresh: function(frm) {
if(! frm.doc.__islocal && frm.doc.taxes.length){
frm.add_custom_button(__('Update Taxes for Items'), function(){
frappe.confirm(
'Are you sure? It will overwrite taxes for all items with HSN Code <b>'+frm.doc.name+'</b>.',
function(){
frappe.call({
args:{
taxes: frm.doc.taxes,
hsn_code: frm.doc.name
},
method: 'erpnext.regional.doctype.gst_hsn_code.gst_hsn_code.update_taxes_in_item_master',
callback: function(r) {
if(r.message){
frappe.show_alert(__('Item taxes updated'));
}
}
});
}
);
});
}
}
});

View File

@ -1,63 +0,0 @@
{
"actions": [],
"autoname": "field:hsn_code",
"creation": "2017-06-21 10:48:56.422086",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"hsn_code",
"description",
"gst_rates",
"taxes"
],
"fields": [
{
"fieldname": "hsn_code",
"fieldtype": "Data",
"in_list_view": 1,
"label": "HSN Code",
"reqd": 1,
"show_days": 1,
"show_seconds": 1,
"unique": 1
},
{
"fieldname": "description",
"fieldtype": "Small Text",
"in_list_view": 1,
"label": "Description",
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "taxes",
"fieldtype": "Table",
"label": "Taxes",
"options": "Item Tax",
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "gst_rates",
"fieldtype": "Table",
"label": "GST Rates",
"options": "HSN Tax Rate",
"show_days": 1,
"show_seconds": 1
}
],
"links": [],
"modified": "2022-05-11 13:42:27.286643",
"modified_by": "Administrator",
"module": "Regional",
"name": "GST HSN Code",
"owner": "Administrator",
"permissions": [],
"quick_entry": 1,
"search_fields": "hsn_code, description",
"sort_field": "modified",
"sort_order": "DESC",
"title_field": "hsn_code",
"track_changes": 1
}

Some files were not shown because too many files have changed in this diff Show More