feat: Tax Category based on Address
This commit is contained in:
parent
e414a92d55
commit
fd531a6b5e
58
erpnext/accounts/custom/address.json
Normal file
58
erpnext/accounts/custom/address.json
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
{
|
||||||
|
"custom_fields": [
|
||||||
|
{
|
||||||
|
"_assign": null,
|
||||||
|
"_comments": null,
|
||||||
|
"_liked_by": null,
|
||||||
|
"_user_tags": null,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"collapsible_depends_on": null,
|
||||||
|
"columns": 0,
|
||||||
|
"creation": "2018-12-28 22:29:21.828090",
|
||||||
|
"default": null,
|
||||||
|
"depends_on": null,
|
||||||
|
"description": null,
|
||||||
|
"docstatus": 0,
|
||||||
|
"dt": "Address",
|
||||||
|
"fetch_from": null,
|
||||||
|
"fieldname": "tax_category",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"hidden": 0,
|
||||||
|
"idx": 14,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"insert_after": "fax",
|
||||||
|
"label": "Tax Category",
|
||||||
|
"modified": "2018-12-28 22:29:21.828090",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"name": "Address-tax_category",
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "Tax Category",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"parent": null,
|
||||||
|
"parentfield": null,
|
||||||
|
"parenttype": null,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"print_width": null,
|
||||||
|
"read_only": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0,
|
||||||
|
"width": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"custom_perms": [],
|
||||||
|
"doctype": "Address",
|
||||||
|
"property_setters": [],
|
||||||
|
"sync_on_migrate": 1
|
||||||
|
}
|
@ -112,6 +112,41 @@
|
|||||||
"translatable": 0,
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"default": "Billing Address",
|
||||||
|
"description": "Address used to determine Tax Category in transactions.",
|
||||||
|
"fieldname": "determine_address_tax_category_from",
|
||||||
|
"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": "Determine Address Tax Category From",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "Billing Address\nShipping Address",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"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_bulk_edit": 0,
|
||||||
"allow_in_quick_entry": 0,
|
"allow_in_quick_entry": 0,
|
||||||
@ -674,7 +709,7 @@
|
|||||||
"issingle": 1,
|
"issingle": 1,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2018-12-28 04:30:38.835015",
|
"modified": "2018-12-28 23:18:29.863177",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Accounts Settings",
|
"name": "Accounts Settings",
|
||||||
|
@ -15,7 +15,9 @@ class AccountsSettings(Document):
|
|||||||
frappe.clear_cache()
|
frappe.clear_cache()
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
frappe.db.set_default("add_taxes_from_item_tax_template", self.get("add_taxes_from_item_tax_template", ""))
|
for f in ["add_taxes_from_item_tax_template"]:
|
||||||
|
frappe.db.set_default(f, self.get(f, ""))
|
||||||
|
|
||||||
self.validate_stale_days()
|
self.validate_stale_days()
|
||||||
self.enable_payment_schedule_in_print()
|
self.enable_payment_schedule_in_print()
|
||||||
self.enable_fields_for_cost_center_settings()
|
self.enable_fields_for_cost_center_settings()
|
||||||
|
@ -8,7 +8,7 @@ from frappe import _, msgprint, scrub
|
|||||||
from frappe.defaults import get_user_permissions
|
from frappe.defaults import get_user_permissions
|
||||||
from frappe.model.utils import get_fetch_values
|
from frappe.model.utils import get_fetch_values
|
||||||
from frappe.utils import (add_days, getdate, formatdate, date_diff,
|
from frappe.utils import (add_days, getdate, formatdate, date_diff,
|
||||||
add_years, get_timestamp, nowdate, flt, add_months, get_last_day)
|
add_years, get_timestamp, nowdate, flt, cstr, add_months, get_last_day)
|
||||||
from frappe.contacts.doctype.address.address import (get_address_display,
|
from frappe.contacts.doctype.address.address import (get_address_display,
|
||||||
get_default_address, get_company_address)
|
get_default_address, get_company_address)
|
||||||
from frappe.contacts.doctype.contact.contact import get_contact_details, get_default_contact
|
from frappe.contacts.doctype.contact.contact import get_contact_details, get_default_contact
|
||||||
@ -16,7 +16,7 @@ from erpnext.exceptions import PartyFrozen, PartyDisabled, InvalidAccountCurrenc
|
|||||||
from erpnext.accounts.utils import get_fiscal_year
|
from erpnext.accounts.utils import get_fiscal_year
|
||||||
from erpnext import get_default_currency, get_company_currency
|
from erpnext import get_default_currency, get_company_currency
|
||||||
|
|
||||||
from six import iteritems
|
from six import iteritems, string_types
|
||||||
|
|
||||||
class DuplicatePartyAccountError(frappe.ValidationError): pass
|
class DuplicatePartyAccountError(frappe.ValidationError): pass
|
||||||
|
|
||||||
@ -49,7 +49,8 @@ def _get_party_details(party=None, account=None, party_type="Customer", company=
|
|||||||
set_other_values(out, party, party_type)
|
set_other_values(out, party, party_type)
|
||||||
set_price_list(out, party, party_type, price_list)
|
set_price_list(out, party, party_type, price_list)
|
||||||
|
|
||||||
out["tax_category"] = get_tax_category(party, party_address, shipping_address)
|
out["tax_category"] = get_address_tax_category(party.get("tax_category"),
|
||||||
|
party_address, shipping_address if party_type != "Supplier" else party_address)
|
||||||
out["taxes_and_charges"] = set_taxes(party.name, party_type, posting_date, company, out.customer_group,
|
out["taxes_and_charges"] = set_taxes(party.name, party_type, posting_date, company, out.customer_group,
|
||||||
out.supplier_group, out.tax_category, party_address, shipping_address)
|
out.supplier_group, out.tax_category, party_address, shipping_address)
|
||||||
|
|
||||||
@ -355,8 +356,17 @@ def validate_due_date(posting_date, due_date, party_type, party, company=None, b
|
|||||||
frappe.throw(_("Due / Reference Date cannot be after {0}")
|
frappe.throw(_("Due / Reference Date cannot be after {0}")
|
||||||
.format(formatdate(default_due_date)))
|
.format(formatdate(default_due_date)))
|
||||||
|
|
||||||
def get_tax_category(party, billing_address, shipping_address):
|
@frappe.whitelist()
|
||||||
return party.get("tax_category")
|
def get_address_tax_category(tax_category, billing_address=None, shipping_address=None):
|
||||||
|
addr_tax_category_from = frappe.db.get_single_value("Accounts Settings", "determine_address_tax_category_from")
|
||||||
|
if addr_tax_category_from == "Shipping Address":
|
||||||
|
if shipping_address:
|
||||||
|
tax_category = frappe.db.get_value("Address", shipping_address, "tax_category") or tax_category
|
||||||
|
else:
|
||||||
|
if billing_address:
|
||||||
|
tax_category = frappe.db.get_value("Address", billing_address, "tax_category") or tax_category
|
||||||
|
|
||||||
|
return cstr(tax_category)
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def set_taxes(party, party_type, posting_date, company, customer_group=None, supplier_group=None, tax_category=None,
|
def set_taxes(party, party_type, posting_date, company, customer_group=None, supplier_group=None, tax_category=None,
|
||||||
|
@ -105,6 +105,7 @@ erpnext.buying.BuyingController = erpnext.TransactionController.extend({
|
|||||||
|
|
||||||
supplier_address: function() {
|
supplier_address: function() {
|
||||||
erpnext.utils.get_address_display(this.frm);
|
erpnext.utils.get_address_display(this.frm);
|
||||||
|
erpnext.utils.set_taxes_from_address(this.frm, "supplier_address", "supplier_address", "supplier_address");
|
||||||
},
|
},
|
||||||
|
|
||||||
buying_price_list: function() {
|
buying_price_list: function() {
|
||||||
|
@ -452,9 +452,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
|||||||
frappe.run_serially([
|
frappe.run_serially([
|
||||||
() => {
|
() => {
|
||||||
var d = locals[cdt][cdn];
|
var d = locals[cdt][cdn];
|
||||||
if(d.item_tax_template && d.item_tax_rate) {
|
me.add_taxes_from_item_tax_template(d.item_tax_rate);
|
||||||
me.add_taxes_from_item_tax_template(d.item_tax_rate);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
() => me.frm.script_manager.trigger("price_list_rate", cdt, cdn),
|
() => me.frm.script_manager.trigger("price_list_rate", cdt, cdn),
|
||||||
() => me.toggle_conversion_factor(item),
|
() => me.toggle_conversion_factor(item),
|
||||||
@ -482,7 +480,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
|||||||
add_taxes_from_item_tax_template: function(item_tax_map) {
|
add_taxes_from_item_tax_template: function(item_tax_map) {
|
||||||
let me = this;
|
let me = this;
|
||||||
|
|
||||||
if(cint(frappe.defaults.get_default("add_taxes_from_item_tax_template"))) {
|
if(item_tax_map && cint(frappe.defaults.get_default("add_taxes_from_item_tax_template"))) {
|
||||||
if(typeof (item_tax_map) == "string") {
|
if(typeof (item_tax_map) == "string") {
|
||||||
item_tax_map = JSON.parse(item_tax_map);
|
item_tax_map = JSON.parse(item_tax_map);
|
||||||
}
|
}
|
||||||
@ -1312,6 +1310,8 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
|||||||
|
|
||||||
tax_category: function() {
|
tax_category: function() {
|
||||||
var me = this;
|
var me = this;
|
||||||
|
if(me.frm.updating_party_details) return;
|
||||||
|
|
||||||
var item_codes = [];
|
var item_codes = [];
|
||||||
$.each(this.frm.doc.items || [], function(i, item) {
|
$.each(this.frm.doc.items || [], function(i, item) {
|
||||||
if(item.item_code) {
|
if(item.item_code) {
|
||||||
@ -1334,6 +1334,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
|||||||
if(item.item_code && r.message.hasOwnProperty(item.item_code)) {
|
if(item.item_code && r.message.hasOwnProperty(item.item_code)) {
|
||||||
item.item_tax_template = r.message[item.item_code].item_tax_template;
|
item.item_tax_template = r.message[item.item_code].item_tax_template;
|
||||||
item.item_tax_rate = r.message[item.item_code].item_tax_rate;
|
item.item_tax_rate = r.message[item.item_code].item_tax_rate;
|
||||||
|
me.add_taxes_from_item_tax_template(item.item_tax_rate);
|
||||||
} else {
|
} else {
|
||||||
item.item_tax_template = "";
|
item.item_tax_template = "";
|
||||||
item.item_tax_rate = "{}";
|
item.item_tax_rate = "{}";
|
||||||
@ -1351,6 +1352,8 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
|||||||
|
|
||||||
item_tax_template: function(doc, cdt, cdn) {
|
item_tax_template: function(doc, cdt, cdn) {
|
||||||
var me = this;
|
var me = this;
|
||||||
|
if(me.frm.updating_party_details) return;
|
||||||
|
|
||||||
var item = frappe.get_doc(cdt, cdn);
|
var item = frappe.get_doc(cdt, cdn);
|
||||||
|
|
||||||
if(item.item_tax_template) {
|
if(item.item_tax_template) {
|
||||||
|
@ -92,9 +92,6 @@ erpnext.utils.get_address_display = function(frm, address_field, display_field,
|
|||||||
if(r.message) {
|
if(r.message) {
|
||||||
frm.set_value(display_field, r.message)
|
frm.set_value(display_field, r.message)
|
||||||
}
|
}
|
||||||
if(frappe.meta.get_docfield(frm.doc.doctype, "taxes") && !is_your_company_address) {
|
|
||||||
erpnext.utils.set_taxes(frm, address_field);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
@ -102,6 +99,42 @@ erpnext.utils.get_address_display = function(frm, address_field, display_field,
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
erpnext.utils.set_taxes_from_address = function(frm, triggered_from_field, billing_address_field, shipping_address_field) {
|
||||||
|
if(frm.updating_party_details) return;
|
||||||
|
|
||||||
|
if(frappe.meta.get_docfield(frm.doc.doctype, "taxes")) {
|
||||||
|
if(!erpnext.utils.validate_mandatory(frm, "Lead/Customer/Supplier",
|
||||||
|
frm.doc.customer || frm.doc.supplier || frm.doc.lead, triggered_from_field)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!erpnext.utils.validate_mandatory(frm, "Posting/Transaction Date",
|
||||||
|
frm.doc.posting_date || frm.doc.transaction_date, triggered_from_field)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
frappe.call({
|
||||||
|
method: "erpnext.accounts.party.get_address_tax_category",
|
||||||
|
args: {
|
||||||
|
"tax_category": frm.doc.tax_category,
|
||||||
|
"billing_address": frm.doc[billing_address_field],
|
||||||
|
"shipping_address": frm.doc[shipping_address_field]
|
||||||
|
},
|
||||||
|
callback: function(r) {
|
||||||
|
if(!r.exc){
|
||||||
|
if(frm.doc.tax_category != r.message) {
|
||||||
|
frm.set_value("tax_category", r.message);
|
||||||
|
} else {
|
||||||
|
erpnext.utils.set_taxes(frm, triggered_from_field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
erpnext.utils.set_taxes = function(frm, triggered_from_field) {
|
erpnext.utils.set_taxes = function(frm, triggered_from_field) {
|
||||||
if(frappe.meta.get_docfield(frm.doc.doctype, "taxes")) {
|
if(frappe.meta.get_docfield(frm.doc.doctype, "taxes")) {
|
||||||
if(!erpnext.utils.validate_mandatory(frm, "Lead/Customer/Supplier",
|
if(!erpnext.utils.validate_mandatory(frm, "Lead/Customer/Supplier",
|
||||||
|
@ -103,10 +103,12 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({
|
|||||||
|
|
||||||
customer_address: function() {
|
customer_address: function() {
|
||||||
erpnext.utils.get_address_display(this.frm, "customer_address");
|
erpnext.utils.get_address_display(this.frm, "customer_address");
|
||||||
|
erpnext.utils.set_taxes_from_address(this.frm, "customer_address", "customer_address", "shipping_address_name");
|
||||||
},
|
},
|
||||||
|
|
||||||
shipping_address_name: function() {
|
shipping_address_name: function() {
|
||||||
erpnext.utils.get_address_display(this.frm, "shipping_address_name", "shipping_address");
|
erpnext.utils.get_address_display(this.frm, "shipping_address_name", "shipping_address");
|
||||||
|
erpnext.utils.set_taxes_from_address(this.frm, "shipping_address_name", "customer_address", "shipping_address_name");
|
||||||
},
|
},
|
||||||
|
|
||||||
sales_partner: function() {
|
sales_partner: function() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user