Merge branch 'develop' into fixed-time-out-error-reposting

This commit is contained in:
rohitwaghchaure 2022-07-05 19:23:46 +05:30 committed by GitHub
commit 96f46b220b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
173 changed files with 463 additions and 73633 deletions

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

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

@ -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", [])
tds_category.append(
"rates",
{ {
"from_date": fiscal_year[1], "from_date": fiscal_year[1],
"to_date": fiscal_year[2], "to_date": fiscal_year[2],
"tax_withholding_rate": 10, "tax_withholding_rate": 10,
"single_threshold": 2500, "single_threshold": 2500,
"cumulative_threshold": 0, "cumulative_threshold": 0,
}, }
) ],
tds_category.save() }
).insert(ignore_if_duplicate=True)
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

@ -790,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

@ -175,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",
@ -1717,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",

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:
@ -1528,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):

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,135 +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_einvoice_discounts(self):
from erpnext.regional.india.e_invoice.utils import make_einvoice, validate_totals
# Normal Itemized Discount
si = get_sales_invoice_for_e_invoice()
si.apply_discount_on = ""
si.items[0].discount_amount = 4000
si.items[1].discount_amount = 300
si.save()
einvoice = make_einvoice(si)
validate_totals(einvoice)
self.assertEqual(einvoice["ItemList"][0]["Discount"], 4000)
self.assertEqual(einvoice["ItemList"][1]["Discount"], 300)
self.assertEqual(einvoice["ValDtls"]["Discount"], 0)
# Invoice Discount on net total
si = get_sales_invoice_for_e_invoice()
si.apply_discount_on = "Net Total"
si.discount_amount = 400
si.save()
einvoice = make_einvoice(si)
validate_totals(einvoice)
self.assertEqual(einvoice["ItemList"][0]["Discount"], 316.83)
self.assertEqual(einvoice["ItemList"][1]["Discount"], 83.17)
self.assertEqual(einvoice["ValDtls"]["Discount"], 0)
# Invoice Discount on grand total (Itemized Discount)
si = get_sales_invoice_for_e_invoice()
si.apply_discount_on = "Grand Total"
si.discount_amount = 400
si.save()
einvoice = make_einvoice(si)
validate_totals(einvoice)
self.assertEqual(einvoice["ItemList"][0]["Discount"], 268.5)
self.assertEqual(einvoice["ItemList"][1]["Discount"], 70.48)
self.assertEqual(einvoice["ValDtls"]["Discount"], 0)
# Invoice Discount on grand total (Cash/Non-Trade Discount)
si = get_sales_invoice_for_e_invoice()
si.apply_discount_on = "Grand Total"
si.is_cash_or_non_trade_discount = 1
si.discount_amount = 400
si.save()
einvoice = make_einvoice(si)
validate_totals(einvoice)
self.assertEqual(einvoice["ItemList"][0]["Discount"], 0)
self.assertEqual(einvoice["ItemList"][1]["Discount"], 0)
self.assertEqual(einvoice["ValDtls"]["Discount"], 400)
def test_item_tax_net_range(self): def test_item_tax_net_range(self):
item = create_item("T Shirt") item = create_item("T Shirt")
@ -3258,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()
@ -3270,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()
@ -3381,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
@ -3594,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",
@ -3647,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

@ -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):
@ -132,9 +129,6 @@ class AssetValueAdjustment(Document):
days = date_diff(data.schedule_date, from_date) days = date_diff(data.schedule_date, from_date)
depreciation_amount = days * rate_per_day depreciation_amount = days * rate_per_day
from_date = data.schedule_date from_date = data.schedule_date
else:
if country == "India":
depreciation_amount = get_depreciation_amount_for_india(asset, value_after_depreciation, d)
else: else:
depreciation_amount = get_depreciation_amount(asset, value_after_depreciation, d) depreciation_amount = get_depreciation_amount(asset, value_after_depreciation, d)

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

@ -308,7 +308,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",
@ -322,24 +321,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",
@ -349,20 +339,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",
@ -374,12 +353,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"
}, },
@ -546,16 +520,8 @@ regional_overrides = {
"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": { "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.hr.utils.calculate_annual_eligible_hra_exemption": "erpnext.regional.india.utils.calculate_annual_eligible_hra_exemption", "erpnext.hr.utils.calculate_annual_eligible_hra_exemption": "erpnext.regional.india.utils.calculate_annual_eligible_hra_exemption",
"erpnext.hr.utils.calculate_hra_exemption_for_period": "erpnext.regional.india.utils.calculate_hra_exemption_for_period", "erpnext.hr.utils.calculate_hra_exemption_for_period": "erpnext.regional.india.utils.calculate_hra_exemption_for_period",
"erpnext.controllers.accounts_controller.validate_einvoice_fields": "erpnext.regional.india.e_invoice.utils.validate_einvoice_fields",
"erpnext.assets.doctype.asset.asset.get_depreciation_amount": "erpnext.regional.india.utils.get_depreciation_amount",
"erpnext.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",

View File

@ -11,9 +11,7 @@ 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
execute:frappe.reload_doc("Payroll", "doctype", "salary_slip") execute:frappe.reload_doc("Payroll", "doctype", "salary_slip")
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
@ -47,7 +45,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
@ -69,20 +66,15 @@ 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.v11_0.drop_column_max_days_allowed erpnext.patches.v11_0.drop_column_max_days_allowed
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.rename_additional_salary_component_additional_salary erpnext.patches.v11_0.rename_additional_salary_component_additional_salary
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
@ -119,7 +111,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
@ -142,14 +133,12 @@ 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.remove_denied_leaves_from_leave_ledger erpnext.patches.v12_0.remove_denied_leaves_from_leave_ledger
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.set_job_offer_applicant_email erpnext.patches.v12_0.set_job_offer_applicant_email
@ -197,14 +186,12 @@ 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.v13_0.move_doctype_reports_and_notification_from_hr_to_payroll #22-06-2020 erpnext.patches.v13_0.move_doctype_reports_and_notification_from_hr_to_payroll #22-06-2020
erpnext.patches.v13_0.move_payroll_setting_separately_from_hr_settings #22-06-2020 erpnext.patches.v13_0.move_payroll_setting_separately_from_hr_settings #22-06-2020
erpnext.patches.v12_0.create_itc_reversal_custom_fields
execute:frappe.reload_doc("regional", "doctype", "e_invoice_settings") execute:frappe.reload_doc("regional", "doctype", "e_invoice_settings")
erpnext.patches.v13_0.check_is_income_tax_component #22-06-2020 erpnext.patches.v13_0.check_is_income_tax_component #22-06-2020
erpnext.patches.v13_0.loyalty_points_entry_for_pos_invoice #22-07-2020 erpnext.patches.v13_0.loyalty_points_entry_for_pos_invoice #22-07-2020
@ -215,18 +202,15 @@ 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.update_start_end_date_for_old_shift_assignment erpnext.patches.v13_0.update_start_end_date_for_old_shift_assignment
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
erpnext.patches.v13_0.updates_for_multi_currency_payroll erpnext.patches.v13_0.updates_for_multi_currency_payroll
erpnext.patches.v13_0.update_reason_for_resignation_in_employee erpnext.patches.v13_0.update_reason_for_resignation_in_employee
execute:frappe.delete_doc("Report", "Quoted Item Comparison") execute:frappe.delete_doc("Report", "Quoted Item Comparison")
@ -241,26 +225,19 @@ erpnext.patches.v13_0.set_company_in_leave_ledger_entry
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.make_non_standard_user_type #13-04-2021 #17-01-2022 erpnext.patches.v13_0.make_non_standard_user_type #13-04-2021 #17-01-2022
erpnext.patches.v13_0.update_shipment_status erpnext.patches.v13_0.update_shipment_status
erpnext.patches.v13_0.remove_attribute_field_from_item_variant_setting erpnext.patches.v13_0.remove_attribute_field_from_item_variant_setting
erpnext.patches.v12_0.add_ewaybill_validity_field
erpnext.patches.v13_0.set_pos_closing_as_failed erpnext.patches.v13_0.set_pos_closing_as_failed
erpnext.patches.v13_0.rename_stop_to_send_birthday_reminders erpnext.patches.v13_0.rename_stop_to_send_birthday_reminders
execute:frappe.rename_doc("Workspace", "Loan Management", "Loans", force=True) execute:frappe.rename_doc("Workspace", "Loan Management", "Loans", force=True)
@ -274,9 +251,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
@ -297,9 +272,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
@ -313,7 +286,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
@ -321,7 +293,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.v14_0.set_payroll_cost_centers erpnext.patches.v14_0.set_payroll_cost_centers
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
@ -330,6 +301,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')
@ -344,9 +316,7 @@ 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.update_leave_notification_template erpnext.patches.v14_0.update_leave_notification_template
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
@ -363,7 +333,6 @@ 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.update_expense_claim_status_for_paid_advances erpnext.patches.v13_0.update_expense_claim_status_for_paid_advances
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
@ -376,3 +345,4 @@ erpnext.patches.v13_0.set_payroll_entry_status
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

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:
fields = [
"gst_section", "gst_section",
"company_address", "company_address",
"company_gstin", "company_gstin",
"place_of_supply", "place_of_supply",
"customer_address", "customer_address",
"customer_gstin", "customer_gstin",
] ):
for field in fields:
frappe.delete_doc_if_exists("Custom Field", f"Payment Entry-{field}") 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,10 +6,10 @@ 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
@ -17,5 +17,6 @@ def execute():
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,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
frappe.reload_doc("Payroll", "doctype", "payroll_period")
frappe.reload_doc("Payroll", "doctype", "employee_tax_exemption_declaration")
frappe.reload_doc("Payroll", "doctype", "employee_tax_exemption_proof_submission")
frappe.reload_doc("Payroll", "doctype", "employee_tax_exemption_declaration_category")
frappe.reload_doc("Payroll", "doctype", "employee_tax_exemption_proof_submission_detail")
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

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

View File

@ -1,36 +0,0 @@
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
import frappe
from frappe.model.document import Document
class GSTHSNCode(Document):
pass
@frappe.whitelist()
def update_taxes_in_item_master(taxes, hsn_code):
items = frappe.get_list("Item", filters={"gst_hsn_code": hsn_code})
taxes = frappe.parse_json(taxes)
frappe.enqueue(update_item_document, items=items, taxes=taxes)
return 1
def update_item_document(items, taxes):
for item in items:
item_to_be_updated = frappe.get_doc("Item", item.name)
item_to_be_updated.taxes = []
for tax in taxes:
tax = frappe._dict(tax)
item_to_be_updated.append(
"taxes",
{
"item_tax_template": tax.item_tax_template,
"tax_category": tax.tax_category,
"valid_from": tax.valid_from,
},
)
item_to_be_updated.save()

View File

@ -1,8 +0,0 @@
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import unittest
class TestGSTHSNCode(unittest.TestCase):
pass

View File

@ -1,50 +0,0 @@
// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
frappe.ui.form.on('GST Settings', {
refresh: function(frm) {
frm.add_custom_button(__('Send GST Update Reminder'), () => {
return new Promise((resolve) => {
return frappe.call({
method: 'erpnext.regional.doctype.gst_settings.gst_settings.send_reminder'
}).always(() => { resolve(); });
});
});
frm.add_custom_button(__('Sync HSN Codes'), () => {
frappe.call({
"method": "erpnext.regional.doctype.gst_settings.gst_settings.update_hsn_codes"
});
});
$(frm.fields_dict.gst_summary.wrapper).empty().html(
`<table class="table table-bordered">
<tbody>
<tr>
<td>Total Addresses</td><td>${frm.doc.__onload.data.total_addresses}</td>
</tr><tr>
<td>Total Addresses with GST</td><td>${frm.doc.__onload.data.total_addresses_with_gstin}</td>
</tr>
</tbody></table>`
);
},
setup: function(frm) {
$.each(["cgst_account", "sgst_account", "igst_account", "cess_account"], function(i, field) {
frm.events.filter_accounts(frm, field);
});
},
filter_accounts: function(frm, account_field) {
frm.set_query(account_field, "gst_accounts", function(doc, cdt, cdn) {
var row = locals[cdt][cdn];
return {
filters: {
company: row.company,
account_type: "Tax",
is_group: 0
}
};
});
}
});

View File

@ -1,85 +0,0 @@
{
"actions": [],
"creation": "2017-06-27 15:09:01.318003",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"gst_summary",
"gst_tax_settings_section",
"round_off_gst_values",
"column_break_4",
"hsn_wise_tax_breakup",
"gstin_email_sent_on",
"section_break_4",
"gst_accounts",
"b2c_limit"
],
"fields": [
{
"fieldname": "gst_summary",
"fieldtype": "HTML",
"label": "GST Summary"
},
{
"fieldname": "gstin_email_sent_on",
"fieldtype": "Date",
"label": "GSTIN Email Sent On",
"read_only": 1
},
{
"fieldname": "section_break_4",
"fieldtype": "Section Break"
},
{
"fieldname": "gst_accounts",
"fieldtype": "Table",
"label": "GST Accounts",
"options": "GST Account"
},
{
"default": "250000",
"description": "Set Invoice Value for B2C. B2CL and B2CS calculated based on this invoice value.",
"fieldname": "b2c_limit",
"fieldtype": "Data",
"in_list_view": 1,
"label": "B2C Limit",
"reqd": 1
},
{
"default": "0",
"description": "Enabling this option will round off individual GST components in all the Invoices",
"fieldname": "round_off_gst_values",
"fieldtype": "Check",
"label": "Round Off GST Values"
},
{
"default": "0",
"fieldname": "hsn_wise_tax_breakup",
"fieldtype": "Check",
"label": "Tax Breakup Table Based On HSN Code"
},
{
"fieldname": "gst_tax_settings_section",
"fieldtype": "Section Break",
"label": "GST Tax Settings"
},
{
"fieldname": "column_break_4",
"fieldtype": "Column Break"
}
],
"index_web_pages_for_search": 1,
"issingle": 1,
"links": [],
"modified": "2021-10-11 18:10:14.242614",
"modified_by": "Administrator",
"module": "Regional",
"name": "GST Settings",
"owner": "Administrator",
"permissions": [],
"quick_entry": 1,
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1
}

View File

@ -1,160 +0,0 @@
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
import json
import os
import frappe
from frappe import _
from frappe.contacts.doctype.contact.contact import get_default_contact
from frappe.model.document import Document
from frappe.utils import date_diff, flt, get_url, nowdate
class EmailMissing(frappe.ValidationError):
pass
class GSTSettings(Document):
def onload(self):
data = frappe._dict()
data.total_addresses = frappe.db.sql(
'''select count(*) from tabAddress where country = "India"'''
)
data.total_addresses_with_gstin = frappe.db.sql(
"""select distinct count(*)
from tabAddress where country = "India" and ifnull(gstin, '')!='' """
)
self.set_onload("data", data)
def validate(self):
# Validate duplicate accounts
self.validate_duplicate_accounts()
def validate_duplicate_accounts(self):
account_list = []
for account in self.get("gst_accounts"):
for fieldname in ["cgst_account", "sgst_account", "igst_account", "cess_account"]:
if account.get(fieldname) in account_list:
frappe.throw(
_("Account {0} appears multiple times").format(frappe.bold(account.get(fieldname)))
)
if account.get(fieldname):
account_list.append(account.get(fieldname))
@frappe.whitelist()
def send_reminder():
frappe.has_permission("GST Settings", throw=True)
last_sent = frappe.db.get_single_value("GST Settings", "gstin_email_sent_on")
if last_sent and date_diff(nowdate(), last_sent) < 3:
frappe.throw(_("Please wait 3 days before resending the reminder."))
frappe.db.set_value("GST Settings", "GST Settings", "gstin_email_sent_on", nowdate())
# enqueue if large number of customers, suppliser
frappe.enqueue(
"erpnext.regional.doctype.gst_settings.gst_settings.send_gstin_reminder_to_all_parties"
)
frappe.msgprint(_("Email Reminders will be sent to all parties with email contacts"))
def send_gstin_reminder_to_all_parties():
parties = []
for address_name in frappe.db.sql(
"""select name
from tabAddress where country = "India" and ifnull(gstin, '')='' """
):
address = frappe.get_doc("Address", address_name[0])
for link in address.links:
party = frappe.get_doc(link.link_doctype, link.link_name)
if link.link_doctype in ("Customer", "Supplier"):
t = (link.link_doctype, link.link_name, address.email_id)
if not t in parties:
parties.append(t)
sent_to = []
for party in parties:
# get email from default contact
try:
email_id = _send_gstin_reminder(party[0], party[1], party[2], sent_to)
sent_to.append(email_id)
except EmailMissing:
pass
@frappe.whitelist()
def send_gstin_reminder(party_type, party):
"""Send GSTIN reminder to one party (called from Customer, Supplier form)"""
frappe.has_permission(party_type, throw=True)
email = _send_gstin_reminder(party_type, party)
if email:
frappe.msgprint(_("Reminder to update GSTIN Sent"), title="Reminder sent", indicator="green")
def _send_gstin_reminder(party_type, party, default_email_id=None, sent_to=None):
"""Send GST Reminder email"""
email_id = frappe.db.get_value("Contact", get_default_contact(party_type, party), "email_id")
if not email_id:
# get email from address
email_id = default_email_id
if not email_id:
frappe.throw(_("Email not found in default contact"), exc=EmailMissing)
if sent_to and email_id in sent_to:
return
frappe.sendmail(
subject="Please update your GSTIN",
recipients=email_id,
message="""
<p>Hello,</p>
<p>Please help us send you GST Ready Invoices.</p>
<p>
<a href="{0}?party={1}">
Click here to update your GSTIN Number in our system
</a>
</p>
<p style="color: #aaa; font-size: 11px; margin-top: 30px;">
Get your GST Ready ERP system at <a href="https://erpnext.com">https://erpnext.com</a>
<br>
ERPNext is a free and open source ERP system.
</p>
""".format(
os.path.join(get_url(), "/regional/india/update-gstin"), party
),
)
return email_id
@frappe.whitelist()
def update_hsn_codes():
frappe.enqueue(enqueue_update)
frappe.msgprint(_("HSN/SAC Code sync started, this may take a few minutes..."))
def enqueue_update():
with open(os.path.join(os.path.dirname(__file__), "hsn_code_data.json"), "r") as f:
hsn_codes = json.loads(f.read())
for hsn_code in hsn_codes:
try:
hsn_code_doc = frappe.get_doc("GST HSN Code", hsn_code.get("hsn_code"))
hsn_code_doc.set("gst_rates", [])
for rate in hsn_code.get("gst_rates"):
hsn_code_doc.append(
"gst_rates",
{
"minimum_taxable_value": flt(hsn_code.get("minimum_taxable_value")),
"tax_rate": flt(rate.get("tax_rate")),
},
)
hsn_code_doc.save()
except Exception as e:
pass

View File

@ -1,8 +0,0 @@
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import unittest
class TestGSTSettings(unittest.TestCase):
pass

View File

@ -1,297 +0,0 @@
<style>
.print-format {
padding: 15mm;
font-size: 8.0pt !important;
font-family: Tahoma, sans-serif;
}
.disabled {
background-color: #d9d9d9;
}
</style>
<div>
<h3 class="text-center">{{ __("GSTR3B-Form")}}</h3>
<h5>{{__("GSTIN")}}: &nbsp {{ data.gstin }}</h5>
<h5>{{__("Period")}}: &nbsp {{ data.ret_period }}</h5>
</div>
<h5>3.1&nbsp&nbsp{{__("Details of Outward Supplies and inward supplies liable to reverse charge")}}</h5>
<table class="table table-bordered">
<thead>
<tr>
<th>{{__("Nature Of Supplies")}}</th>
<th>{{__("Total Taxable value")}}</th>
<th>{{__("Integrated Tax")}}</th>
<th>{{__("Central Tax")}}</th>
<th>{{__("State/UT Tax")}}</th>
<th>{{__("Cess")}}</th>
</tr>
</thead>
<tbody>
<tr>
<td>(a) {{__("Outward taxable supplies(other than zero rated, nil rated and exempted)")}}</td>
<td class="right">{{ flt(data.sup_details.osup_det.txval, 2) }}</td>
<td class="right">{{ flt(data.sup_details.osup_det.iamt, 2) }}</td>
<td class="right">{{ flt(data.sup_details.osup_det.camt, 2) }}</td>
<td class="right">{{ flt(data.sup_details.osup_det.samt, 2) }}</td>
<td class="right">{{ flt(data.sup_details.osup_det.csamt, 2) }}</td>
</tr>
<tr>
<td>(b) {{__("Outward taxable supplies(zero rated)")}}</td>
<td class="right">{{ flt(data.sup_details.osup_zero.txval, 2) }}</td>
<td class="right">{{ flt(data.sup_details.osup_zero.iamt, 2) }}</td>
<td class="disabled"></td>
<td class="disabled"></td>
<td class="right">{{ flt(data.sup_details.osup_zero.csamt, 2) }}</td>
</tr>
<tr>
<td>(b) {{__("Other outward supplies(Nil rated,Exempted)")}}</td>
<td class="right">{{ data.sup_details.osup_nil_exmp.txval }}</td>
<td class="disabled"></td>
<td class="disabled"></td>
<td class="disabled"></td>
<td class="disabled"></td>
<tr>
<td>(d) {{__("Inward Supplies(liable to reverse charge)")}}</td>
<td class="right">{{ flt(data.sup_details.isup_rev.txval, 2) }}</td>
<td class="right">{{ flt(data.sup_details.isup_rev.iamt, 2) }}</td>
<td class="right">{{ flt(data.sup_details.isup_rev.camt, 2) }}</td>
<td class="right">{{ flt(data.sup_details.isup_rev.samt, 2) }}</td>
<td class="right">{{ flt(data.sup_details.isup_rev.csamt,2) }}</td>
</tr>
<tr>
<td>(e) {{__("Non-GST outward supplies")}}</td>
<td class="right">{{ data.sup_details.osup_nongst.txval }}</td>
<td class="disabled"></td>
<td class="disabled"></td>
<td class="disabled"></td>
<td class="disabled"></td>
</tr>
</tbody>
</table>
<h5>
3.2&nbsp&nbsp{{__("Of the supplies shown in 3.1 (a) above, details of inter-State supplies made to unregisterd
persons, composition taxable persons and UIN holders")}}
</h5>
<table class="table table-bordered">
<thead>
<tr>
<th></th>
<th>{{__("Place Of Supply (State/UT)")}}</th>
<th>{{__("Total Taxable Value")}}</th>
<th>{{__("Amount of Integrated Tax")}}</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{__("Supplies made to Unregistered Persons")}}</td>
<td class="right">
{% for row in data.inter_sup.unreg_details %}
{% if row %}
{{ row.pos }}<br>
{% endif %}
{% endfor %}
</td>
<td class="right">
{% for row in data.inter_sup.unreg_details %}
{% if row %}
{{ flt(row.txval, 2) }}<br>
{% endif %}
{% endfor %}
</td>
<td class="right">
{% for row in data.inter_sup.unreg_details %}
{% if row %}
{{ flt(row.iamt, 2) }}<br>
{% endif %}
{% endfor %}
</td>
</tr>
<tr>
<td>{{__("Supplies made to Composition Taxable Persons")}}</td>
<td class="right">
{% for row in data.inter_sup.comp_details %}
{% if row %}
{{ row.pos }}<br>
{% endif %}
{% endfor %}
</td>
<td class="right">
{% for row in data.inter_sup.comp_details %}
{% if row %}
{{ flt(row.txval, 2) }}<br>
{% endif %}
{% endfor %}
</td>
<td class="right">
{% for row in data.inter_sup.comp_details %}
{% if row %}
{{ flt(row.iamt, 2) }}<br>
{% endif %}
{% endfor %}
</td>
</tr>
<tr>
<td>{{__("Supplies made to UIN holders")}}</td>
<td class="right">
{% for row in data.inter_sup.uin_details %}
{% if row %}
{{ row.pos }}<br>
{% endif %}
{% endfor %}
</td>
<td class="right">
{% for row in data.inter_sup.uin_details %}
{% if row %}
{{ flt(row.txval, 2) }}<br>
{% endif %}
{% endfor %}
</td>
<td class="right">
{% for row in data.inter_sup.uin_details %}
{% if row %}
{{ flt(row.iamt, 2) }}<br>
{% endif %}
{% endfor %}
</td>
</tr>
</tbody>
</table>
<h5>4. &nbsp {{__("Eligible ITC")}}</h5>
<table class="table table-bordered">
<thead>
<tr>
<th>Details</th>
<th>Integrated Tax</th>
<th>Central Tax</th>
<th>State/UT tax</th>
<th>Cess</th>
</tr>
</thead>
<tbody>
<tr>
<td><b>(A) {{__("ITC Available (whether in full or part)")}}</b></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>&nbsp (1) {{__("Import of goods")}} </td>
<td class="right">{{ flt(data.itc_elg.itc_avl[0].iamt, 2) }}</td>
<td class="right">{{ flt(data.itc_elg.itc_avl[0].camt, 2) }}</td>
<td class="right">{{ flt(data.itc_elg.itc_avl[0].samt, 2) }}</td>
<td class="right">{{ flt(data.itc_elg.itc_avl[0].csamt, 2) }}</td>
</tr>
<tr>
<td>&nbsp (2) {{__("Import of services")}}</td>
<td class="right">{{ flt(data.itc_elg.itc_avl[1].iamt, 2) }}</td>
<td class="right">{{ flt(data.itc_elg.itc_avl[1].camt, 2) }}</td>
<td class="right">{{ flt(data.itc_elg.itc_avl[1].samt, 2) }}</td>
<td class="right">{{ flt(data.itc_elg.itc_avl[1].csamt, 2) }}</td>
</tr>
<tr>
<td>&nbsp (3) {{__("Inward supplies liable to reverse charge (other than 1 & 2 above)")}}</td>
<td class="right">{{ flt(data.itc_elg.itc_avl[2].iamt, 2) }}</td>
<td class="right">{{ flt(data.itc_elg.itc_avl[2].camt, 2) }}</td>
<td class="right">{{ flt(data.itc_elg.itc_avl[2].samt, 2) }}</td>
<td class="right">{{ flt(data.itc_elg.itc_avl[2].csamt, 2) }}</td>
</tr>
<tr>
<td>&nbsp (4) {{__("Inward supplies from ISD")}}</td>
<td class="right">{{ flt(data.itc_elg.itc_avl[3].iamt, 2) }}</td>
<td class="right">{{ flt(data.itc_elg.itc_avl[3].camt, 2) }}</td>
<td class="right">{{ flt(data.itc_elg.itc_avl[3].samt, 2) }}</td>
<td class="right">{{ flt(data.itc_elg.itc_avl[3].csamt, 2) }}</td>
</tr>
<tr>
<td>&nbsp (5) {{__("All other ITC")}}</td>
<td class="right">{{ flt(data.itc_elg.itc_avl[4].iamt, 2) }}</td>
<td class="right">{{ flt(data.itc_elg.itc_avl[4].camt, 2) }}</td>
<td class="right">{{ flt(data.itc_elg.itc_avl[4].samt, 2) }}</td>
<td class="right">{{ flt(data.itc_elg.itc_avl[4].csamt, 2) }}</td>
</tr>
<tr>
<td><b>(B) {{__("ITC Reversed")}}</b></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>&nbsp (1) {{__("As per rules 42 & 43 of CGST Rules")}}</td>
<td class="right">{{ flt(data.itc_elg.itc_rev[0].iamt, 2) }}</td>
<td class="right">{{ flt(data.itc_elg.itc_rev[0].camt, 2) }}</td>
<td class="right">{{ flt(data.itc_elg.itc_rev[0].samt, 2) }}</td>
<td class="right">{{ flt(data.itc_elg.itc_rev[0].csamt, 2) }}</td>
</tr>
<tr>
<td>&nbsp (2) {{__("Others")}}</td>
<td class="right">{{ flt(data.itc_elg.itc_rev[1].iamt, 2) }}</td>
<td class="right">{{ flt(data.itc_elg.itc_rev[1].camt, 2) }}</td>
<td class="right">{{ flt(data.itc_elg.itc_rev[1].samt, 2) }}</td>
<td class="right">{{ flt(data.itc_elg.itc_rev[1].csamt, 2) }}</td>
</tr>
<tr>
<td><b>(C) {{__("Net ITC Available(A) - (B)")}}</b></td>
<td class="right">{{ flt(data.itc_elg.itc_net.iamt, 2) }}</td>
<td class="right">{{ flt(data.itc_elg.itc_net.camt, 2) }}</td>
<td class="right">{{ flt(data.itc_elg.itc_net.samt, 2) }}</td>
<td class="right">{{ flt(data.itc_elg.itc_net.csamt, 2) }}</td>
</tr>
<tr>
<td><b>(D) {{__("Ineligible ITC")}}</b></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>&nbsp (1) {{__("As per section 17(5)")}}</td>
<td class="right">{{ flt(data.itc_elg.itc_inelg[0].iamt, 2) }}</td>
<td class="right">{{ flt(data.itc_elg.itc_inelg[0].camt, 2) }}</td>
<td class="right">{{ flt(data.itc_elg.itc_inelg[0].samt, 2) }}</td>
<td class="right">{{ flt(data.itc_elg.itc_inelg[0].csamt, 2) }}</td>
</tr>
<tr>
<td>&nbsp (2) {{__("Others")}}</td>
<td class="right">{{ flt(data.itc_elg.itc_inelg[1].iamt, 2) }}</td>
<td class="right">{{ flt(data.itc_elg.itc_inelg[1].camt, 2) }}</td>
<td class="right">{{ flt(data.itc_elg.itc_inelg[1].samt, 2) }}</td>
<td class="right">{{ flt(data.itc_elg.itc_inelg[1].csamt, 2) }}</td>
</tr>
</tbody>
</table>
<h5>5. &nbsp&nbsp {{__("Values of exempt, nil rated and non-GST inward supplies")}}</h5>
<table class="table table-bordered">
<thead>
<tr>
<th>{{__("Nature of Supplies")}}</th>
<th>{{__("Inter-State Supplies")}}</th>
<th>{{__("Intra-State Supplies")}}</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{__("From a supplier under composition scheme, Exempt and Nil rated")}}</td>
<td class="right">{{ flt(data.inward_sup.isup_details[0].inter, 2) }}</td>
<td class="right">{{ flt(data.inward_sup.isup_details[0].intra, 2) }}</td>
</tr>
<tr>
<td>{{__("Non GST Inward Supplies")}}</td>
<td class="right">{{ flt(data.inward_sup.isup_details[1].inter, 2) }}</td>
<td class="right">{{ flt(data.inward_sup.isup_details[1].intra, 2) }}</td>
</tr>
</tbody>
</table>
<style>
.right{
text-align: right;
}
</style>

View File

@ -1,64 +0,0 @@
// Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
frappe.ui.form.on('GSTR 3B Report', {
refresh : function(frm) {
frm.doc.__unsaved = 1;
if(!frm.is_new()) {
frm.set_intro(__("Please save the report again to rebuild or update"));
frm.add_custom_button(__('Download JSON'), function() {
var w = window.open(
frappe.urllib.get_full_url(
"/api/method/erpnext.regional.doctype.gstr_3b_report.gstr_3b_report.make_json?"
+"name="+encodeURIComponent(frm.doc.name)));
if(!w) {
frappe.msgprint(__("Please enable pop-ups")); return;
}
});
frm.add_custom_button(__('View Form'), function() {
frappe.call({
"method" : "erpnext.regional.doctype.gstr_3b_report.gstr_3b_report.view_report",
"args" : {
name : frm.doc.name,
},
"callback" : function(r){
let data = r.message;
frappe.ui.get_print_settings(false, print_settings => {
frappe.render_grid({
template: 'gstr_3b_report',
title: __(this.doctype),
print_settings: print_settings,
data: data,
columns:[]
});
});
}
});
});
}
let current_year = new Date().getFullYear();
let options = [current_year, current_year-1, current_year-2];
frm.set_df_property('year', 'options', options);
},
setup: 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
}
};
});
},
});

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