Merge pull request #4012 from saurabh6790/cart
Taxation for Shopping Cart based on Tax Rule template
This commit is contained in:
commit
e3401182c8
@ -2375,4 +2375,4 @@
|
|||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
"title_field": "title"
|
"title_field": "title"
|
||||||
}
|
}
|
@ -504,7 +504,7 @@
|
|||||||
"is_submittable": 0,
|
"is_submittable": 0,
|
||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"modified": "2015-08-19 12:46:32.687299",
|
"modified": "2015-08-28 02:57:08.769473",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Purchase Taxes and Charges",
|
"name": "Purchase Taxes and Charges",
|
||||||
|
@ -456,7 +456,7 @@
|
|||||||
"is_submittable": 0,
|
"is_submittable": 0,
|
||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"modified": "2015-08-19 12:46:33.165519",
|
"modified": "2015-08-28 02:57:00.766305",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Sales Taxes and Charges",
|
"name": "Sales Taxes and Charges",
|
||||||
|
@ -153,5 +153,95 @@
|
|||||||
"territory": "_Test Territory Rest Of The World"
|
"territory": "_Test Territory Rest Of The World"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"company": "_Test Company",
|
||||||
|
"doctype": "Sales Taxes and Charges Template",
|
||||||
|
"taxes": [
|
||||||
|
{
|
||||||
|
"account_head": "_Test Account VAT - _TC",
|
||||||
|
"charge_type": "On Net Total",
|
||||||
|
"description": "VAT",
|
||||||
|
"doctype": "Sales Taxes and Charges",
|
||||||
|
"parentfield": "taxes",
|
||||||
|
"rate": 12
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"account_head": "_Test Account Service Tax - _TC",
|
||||||
|
"charge_type": "On Net Total",
|
||||||
|
"description": "Service Tax",
|
||||||
|
"doctype": "Sales Taxes and Charges",
|
||||||
|
"parentfield": "taxes",
|
||||||
|
"rate": 4
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"title": "_Test Sales Taxes and Charges Template 1",
|
||||||
|
"territories": [
|
||||||
|
{
|
||||||
|
"doctype": "Applicable Territory",
|
||||||
|
"parentfield": "territories",
|
||||||
|
"territory": "_Test Territory Rest Of The World"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"company": "_Test Company",
|
||||||
|
"doctype": "Sales Taxes and Charges Template",
|
||||||
|
"taxes": [
|
||||||
|
{
|
||||||
|
"account_head": "_Test Account VAT - _TC",
|
||||||
|
"charge_type": "On Net Total",
|
||||||
|
"description": "VAT",
|
||||||
|
"doctype": "Sales Taxes and Charges",
|
||||||
|
"parentfield": "taxes",
|
||||||
|
"rate": 12
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"account_head": "_Test Account Service Tax - _TC",
|
||||||
|
"charge_type": "On Net Total",
|
||||||
|
"description": "Service Tax",
|
||||||
|
"doctype": "Sales Taxes and Charges",
|
||||||
|
"parentfield": "taxes",
|
||||||
|
"rate": 4
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"title": "_Test Sales Taxes and Charges Template 2",
|
||||||
|
"territories": [
|
||||||
|
{
|
||||||
|
"doctype": "Applicable Territory",
|
||||||
|
"parentfield": "territories",
|
||||||
|
"territory": "_Test Territory Rest Of The World"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"doctype" : "Sales Taxes and Charges Template",
|
||||||
|
"title": "_Test Tax 1",
|
||||||
|
"company": "_Test Company",
|
||||||
|
"taxes":[{
|
||||||
|
"charge_type": "Actual",
|
||||||
|
"account_head": "Sales Expenses - _TC",
|
||||||
|
"cost_center": "Main - _TC",
|
||||||
|
"description": "Test Shopping cart taxes with Tax Rule",
|
||||||
|
"tax_amount": 1000
|
||||||
|
}],
|
||||||
|
"territories":[{
|
||||||
|
"territory" : "All Territories"
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"doctype" : "Sales Taxes and Charges Template",
|
||||||
|
"title": "_Test Tax 2",
|
||||||
|
"company": "_Test Company",
|
||||||
|
"taxes":[{
|
||||||
|
"charge_type": "Actual",
|
||||||
|
"account_head": "Sales Expenses - _TC",
|
||||||
|
"cost_center": "Main - _TC",
|
||||||
|
"description": "Test Shopping cart taxes with Tax Rule",
|
||||||
|
"tax_amount": 200
|
||||||
|
}],
|
||||||
|
"territories":[{
|
||||||
|
"territory" : "All Territories"
|
||||||
|
}]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
60
erpnext/accounts/doctype/tax_rule/tax_rule.js
Normal file
60
erpnext/accounts/doctype/tax_rule/tax_rule.js
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
|
// License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
|
cur_frm.add_fetch("customer", "customer_group", "customer_group" );
|
||||||
|
cur_frm.add_fetch("supplier", "supplier_type", "supplier_type" );
|
||||||
|
|
||||||
|
cur_frm.toggle_reqd("sales_tax_template", cur_frm.doc.tax_type=="Sales");
|
||||||
|
cur_frm.toggle_reqd("purchase_tax_template", cur_frm.doc.tax_type=="Purchase");
|
||||||
|
|
||||||
|
|
||||||
|
frappe.ui.form.on("Tax Rule", "onload", function(frm) {
|
||||||
|
if(frm.doc.__islocal){
|
||||||
|
frm.set_value("use_for_shopping_cart", 1);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
frappe.ui.form.on("Tax Rule", "use_for_shopping_cart", function(frm) {
|
||||||
|
if(!frm.doc.use_for_shopping_cart && (frappe.get_list("Tax Rule", {"use_for_shopping_cart":1}).length == 0)){
|
||||||
|
frappe.model.get_value("Shopping Cart Settings", "Shopping Cart Settings", "enabled", function(docfield) {
|
||||||
|
if(docfield.enabled){
|
||||||
|
frm.set_value("use_for_shopping_cart", 1);
|
||||||
|
frappe.throw(__("Shopping Cart is enabled"));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
frappe.ui.form.on("Tax Rule", "customer", function(frm) {
|
||||||
|
frappe.call({
|
||||||
|
method:"erpnext.accounts.doctype.tax_rule.tax_rule.get_party_details",
|
||||||
|
args: {
|
||||||
|
"party": frm.doc.customer,
|
||||||
|
"party_type": "customer"
|
||||||
|
},
|
||||||
|
callback: function(r) {
|
||||||
|
if(!r.exc) {
|
||||||
|
$.each(r.message, function(k, v) {
|
||||||
|
frm.set_value(k, v);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
frappe.ui.form.on("Tax Rule", "supplier", function(frm) {
|
||||||
|
frappe.call({
|
||||||
|
method:"erpnext.accounts.doctype.tax_rule.tax_rule.get_party_details",
|
||||||
|
args: {
|
||||||
|
"party": frm.doc.supplier,
|
||||||
|
"party_type": "supplier"
|
||||||
|
},
|
||||||
|
callback: function(r) {
|
||||||
|
if(!r.exc) {
|
||||||
|
$.each(r.message, function(k, v) {
|
||||||
|
frm.set_value(k, v);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
615
erpnext/accounts/doctype/tax_rule/tax_rule.json
Normal file
615
erpnext/accounts/doctype/tax_rule/tax_rule.json
Normal file
@ -0,0 +1,615 @@
|
|||||||
|
{
|
||||||
|
"allow_copy": 0,
|
||||||
|
"allow_import": 1,
|
||||||
|
"allow_rename": 0,
|
||||||
|
"autoname": "TR.####",
|
||||||
|
"creation": "2015-08-07 02:33:52.670866",
|
||||||
|
"custom": 0,
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "DocType",
|
||||||
|
"document_type": "Setup",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"default": "Sales",
|
||||||
|
"fieldname": "tax_type",
|
||||||
|
"fieldtype": "Select",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "Tax Type",
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "Sales\nPurchase",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"fieldname": "use_for_shopping_cart",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"label": "Use for Shopping Cart",
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"fieldname": "column_break_1",
|
||||||
|
"fieldtype": "Column Break",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"depends_on": "eval:doc.tax_type==\"Sales\"",
|
||||||
|
"fieldname": "sales_tax_template",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"label": "Sales Tax Template",
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "Sales Taxes and Charges Template",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"depends_on": "eval:doc.tax_type==\"Purchase\"",
|
||||||
|
"fieldname": "purchase_tax_template",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"label": "Purchase Tax Template",
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "Purchase Taxes and Charges Template",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"fieldname": "filters",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"label": "Filters",
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"depends_on": "eval:doc.tax_type==\"Sales\"",
|
||||||
|
"fieldname": "customer",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"label": "Customer",
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "Customer",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"depends_on": "eval:doc.tax_type==\"Purchase\"",
|
||||||
|
"fieldname": "supplier",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"label": "Supplier",
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "Supplier",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"fieldname": "billing_city",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"label": "Billing City",
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"fieldname": "billing_state",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"label": "Billing State",
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"fieldname": "billing_country",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"label": "Billing Country",
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "Country",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"fieldname": "column_break_2",
|
||||||
|
"fieldtype": "Column Break",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"depends_on": "eval:doc.tax_type==\"Sales\"",
|
||||||
|
"fieldname": "customer_group",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"label": "Customer Group",
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "Customer Group",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"depends_on": "eval:doc.tax_type==\"Purchase\"",
|
||||||
|
"fieldname": "supplier_type",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"label": "Supplier Type",
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "Supplier Type",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"fieldname": "shipping_city",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"label": "Shipping City",
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"fieldname": "shipping_state",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"label": "Shipping State",
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"fieldname": "shipping_country",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"label": "Shipping Country",
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "Country",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"fieldname": "section_break_4",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"label": "Validity",
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"fieldname": "from_date",
|
||||||
|
"fieldtype": "Date",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"label": "From Date",
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"fieldname": "column_break_7",
|
||||||
|
"fieldtype": "Column Break",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"fieldname": "to_date",
|
||||||
|
"fieldtype": "Date",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"label": "To Date",
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"fieldname": "section_break_6",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"default": "1",
|
||||||
|
"fieldname": "priority",
|
||||||
|
"fieldtype": "Int",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"label": "Priority",
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"fieldname": "column_break_20",
|
||||||
|
"fieldtype": "Column Break",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"fieldname": "company",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"label": "Company",
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "Company",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"unique": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"hide_heading": 0,
|
||||||
|
"hide_toolbar": 0,
|
||||||
|
"in_create": 0,
|
||||||
|
"in_dialog": 0,
|
||||||
|
"is_submittable": 0,
|
||||||
|
"issingle": 0,
|
||||||
|
"istable": 0,
|
||||||
|
"modified": "2015-09-15 12:29:34.435839",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "Accounts",
|
||||||
|
"name": "Tax Rule",
|
||||||
|
"name_case": "",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"permissions": [
|
||||||
|
{
|
||||||
|
"amend": 0,
|
||||||
|
"apply_user_permissions": 0,
|
||||||
|
"cancel": 0,
|
||||||
|
"create": 1,
|
||||||
|
"delete": 1,
|
||||||
|
"email": 1,
|
||||||
|
"export": 1,
|
||||||
|
"if_owner": 0,
|
||||||
|
"import": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"report": 1,
|
||||||
|
"role": "Administrator",
|
||||||
|
"set_user_permissions": 0,
|
||||||
|
"share": 1,
|
||||||
|
"submit": 0,
|
||||||
|
"write": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"read_only": 0,
|
||||||
|
"read_only_onload": 0,
|
||||||
|
"sort_field": "modified",
|
||||||
|
"sort_order": "DESC"
|
||||||
|
}
|
134
erpnext/accounts/doctype/tax_rule/tax_rule.py
Normal file
134
erpnext/accounts/doctype/tax_rule/tax_rule.py
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
import frappe
|
||||||
|
from frappe import _
|
||||||
|
from frappe.model.document import Document
|
||||||
|
from frappe.utils import cstr
|
||||||
|
|
||||||
|
class IncorrectCustomerGroup(frappe.ValidationError): pass
|
||||||
|
class IncorrectSupplierType(frappe.ValidationError): pass
|
||||||
|
class ConflictingTaxRule(frappe.ValidationError): pass
|
||||||
|
|
||||||
|
class TaxRule(Document):
|
||||||
|
def validate(self):
|
||||||
|
self.validate_tax_template()
|
||||||
|
self.validate_customer_group()
|
||||||
|
self.validate_supplier_type()
|
||||||
|
self.validate_date()
|
||||||
|
self.validate_filters()
|
||||||
|
|
||||||
|
def validate_tax_template(self):
|
||||||
|
if self.tax_type== "Sales":
|
||||||
|
self.purchase_tax_template = self.supplier = self.supplier_type= None
|
||||||
|
else:
|
||||||
|
self.sales_tax_template= self.customer = self.customer_group= None
|
||||||
|
|
||||||
|
if not (self.sales_tax_template or self.purchase_tax_template):
|
||||||
|
frappe.throw(_("Tax Template is mandatory."))
|
||||||
|
|
||||||
|
def validate_customer_group(self):
|
||||||
|
if self.customer and self.customer_group:
|
||||||
|
if not frappe.db.get_value("Customer", self.customer, "customer_group") == self.customer_group:
|
||||||
|
frappe.throw(_("Customer {0} does not belong to customer group {1}"). \
|
||||||
|
format(self.customer, self.customer_group), IncorrectCustomerGroup)
|
||||||
|
|
||||||
|
def validate_supplier_type(self):
|
||||||
|
if self.supplier and self.supplier_type:
|
||||||
|
if not frappe.db.get_value("Supplier", self.supplier, "supplier_type") == self.supplier_type:
|
||||||
|
frappe.throw(_("Supplier {0} does not belong to Supplier Type {1}"). \
|
||||||
|
format(self.supplier, self.supplier_type), IncorrectSupplierType)
|
||||||
|
|
||||||
|
def validate_date(self):
|
||||||
|
if self.from_date and self.to_date and self.from_date > self.to_date:
|
||||||
|
frappe.throw(_("From Date cannot be greater than To Date"))
|
||||||
|
|
||||||
|
def validate_filters(self):
|
||||||
|
filters = {
|
||||||
|
"tax_type": self.tax_type,
|
||||||
|
"customer": self.customer,
|
||||||
|
"customer_group": self.customer_group,
|
||||||
|
"supplier": self.supplier,
|
||||||
|
"supplier_type": self.supplier_type,
|
||||||
|
"billing_city": self.billing_city,
|
||||||
|
"billing_state": self.billing_state,
|
||||||
|
"billing_country": self.billing_country,
|
||||||
|
"shipping_city": self.shipping_city,
|
||||||
|
"shipping_state": self.shipping_state,
|
||||||
|
"shipping_country": self.shipping_country,
|
||||||
|
"company": self.company
|
||||||
|
}
|
||||||
|
|
||||||
|
conds=""
|
||||||
|
for d in filters:
|
||||||
|
if conds:
|
||||||
|
conds += " and "
|
||||||
|
conds += """ifnull({0}, '') = '{1}'""".format(d, frappe.db.escape(cstr(filters[d])))
|
||||||
|
|
||||||
|
if self.from_date and self.to_date:
|
||||||
|
conds += """ and ((from_date > '{from_date}' and from_date < '{to_date}') or
|
||||||
|
(to_date > '{from_date}' and to_date < '{to_date}') or
|
||||||
|
('{from_date}' > from_date and '{from_date}' < to_date) or
|
||||||
|
('{from_date}' = from_date and '{to_date}' = to_date))""".format(from_date=self.from_date, to_date=self.to_date)
|
||||||
|
|
||||||
|
elif self.from_date and not self.to_date:
|
||||||
|
conds += """ and to_date > '{from_date}'""".format(from_date = self.from_date)
|
||||||
|
|
||||||
|
elif self.to_date and not self.from_date:
|
||||||
|
conds += """ and from_date < '{to_date}'""".format(to_date = self.to_date)
|
||||||
|
|
||||||
|
tax_rule = frappe.db.sql("select name, priority \
|
||||||
|
from `tabTax Rule` where {0} and name != '{1}'".format(conds, self.name), as_dict=1)
|
||||||
|
|
||||||
|
if tax_rule:
|
||||||
|
if tax_rule[0].priority == self.priority:
|
||||||
|
frappe.throw(_("Tax Rule Conflicts with {0}".format(tax_rule[0].name)), ConflictingTaxRule)
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def get_party_details(party, party_type, args=None):
|
||||||
|
out = {}
|
||||||
|
if args:
|
||||||
|
billing_filters= {"name": args.get("billing_address")}
|
||||||
|
shipping_filters= {"name": args.get("shipping_address")}
|
||||||
|
else:
|
||||||
|
billing_filters= {party_type: party, "is_primary_address": 1}
|
||||||
|
shipping_filters= {party_type:party, "is_shipping_address": 1}
|
||||||
|
|
||||||
|
billing_address= frappe.get_all("Address", fields=["city", "state", "country"], filters= billing_filters)
|
||||||
|
shipping_address= frappe.get_all("Address", fields=["city", "state", "country"], filters= shipping_filters)
|
||||||
|
|
||||||
|
if billing_address:
|
||||||
|
out["billing_city"]= billing_address[0].city
|
||||||
|
out["billing_state"]= billing_address[0].state
|
||||||
|
out["billing_country"]= billing_address[0].country
|
||||||
|
|
||||||
|
if shipping_address:
|
||||||
|
out["shipping_city"]= shipping_address[0].city
|
||||||
|
out["shipping_state"]= shipping_address[0].state
|
||||||
|
out["shipping_country"]= shipping_address[0].country
|
||||||
|
|
||||||
|
return out
|
||||||
|
|
||||||
|
def get_tax_template(posting_date, args):
|
||||||
|
"""Get matching tax rule"""
|
||||||
|
args = frappe._dict(args)
|
||||||
|
conditions = []
|
||||||
|
|
||||||
|
for key, value in args.iteritems():
|
||||||
|
conditions.append("ifnull({0}, '') in ('', '{1}')".format(key, frappe.db.escape(cstr(value))))
|
||||||
|
|
||||||
|
matching = frappe.db.sql("""select * from `tabTax Rule`
|
||||||
|
where {0}""".format(" and ".join(conditions)), as_dict = True)
|
||||||
|
|
||||||
|
if not matching:
|
||||||
|
return None
|
||||||
|
|
||||||
|
for rule in matching:
|
||||||
|
rule.no_of_keys_matched = 0
|
||||||
|
for key in args:
|
||||||
|
if rule.get(key): rule.no_of_keys_matched += 1
|
||||||
|
|
||||||
|
rule = sorted(matching, lambda b, a: cmp(a.no_of_keys_matched, b.no_of_keys_matched) or cmp(a.priority, b.priority))[0]
|
||||||
|
return rule.sales_tax_template or rule.purchase_tax_template
|
28
erpnext/accounts/doctype/tax_rule/test_records.json
Normal file
28
erpnext/accounts/doctype/tax_rule/test_records.json
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"doctype": "Tax Rule",
|
||||||
|
"tax_type" : "Sales",
|
||||||
|
"sales_tax_template": "_Test Tax 1",
|
||||||
|
"use_for_shopping_cart": 1,
|
||||||
|
"billing_city": "_Test City",
|
||||||
|
"billing_state": "Test State",
|
||||||
|
"billing_country": "India",
|
||||||
|
"shipping_city": "_Test City",
|
||||||
|
"shipping_country": "India",
|
||||||
|
"priority": 1,
|
||||||
|
"company": "_Test Company"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"doctype": "Tax Rule",
|
||||||
|
"tax_type" : "Sales",
|
||||||
|
"sales_tax_template": "_Test Tax 2",
|
||||||
|
"use_for_shopping_cart": 0,
|
||||||
|
"billing_city": "_Test City",
|
||||||
|
"billing_country": "India",
|
||||||
|
"shipping_city": "_Test City",
|
||||||
|
"shipping_state": "Test State",
|
||||||
|
"shipping_country": "India",
|
||||||
|
"priority": 2,
|
||||||
|
"company": "_Test Company"
|
||||||
|
}
|
||||||
|
]
|
141
erpnext/accounts/doctype/tax_rule/test_tax_rule.py
Normal file
141
erpnext/accounts/doctype/tax_rule/test_tax_rule.py
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
|
# See license.txt
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import frappe
|
||||||
|
import unittest
|
||||||
|
from erpnext.accounts.doctype.tax_rule.tax_rule import IncorrectCustomerGroup, IncorrectSupplierType, ConflictingTaxRule, get_tax_template
|
||||||
|
|
||||||
|
test_records = frappe.get_test_records('Tax Rule')
|
||||||
|
|
||||||
|
class TestTaxRule(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
frappe.db.sql("delete from `tabTax Rule` where use_for_shopping_cart <> 1")
|
||||||
|
|
||||||
|
def test_customer_group(self):
|
||||||
|
tax_rule = make_tax_rule(customer= "_Test Customer", customer_group= "_Test Customer Group 1",
|
||||||
|
sales_tax_template = "_Test Sales Taxes and Charges Template")
|
||||||
|
self.assertRaises(IncorrectCustomerGroup, tax_rule.save)
|
||||||
|
|
||||||
|
def test_supplier_type(self):
|
||||||
|
tax_rule = make_tax_rule(tax_type= "Purchase", supplier= "_Test Supplier", supplier_type= "_Test Supplier Type 1",
|
||||||
|
purchase_tax_template = "_Test Purchase Taxes and Charges Template")
|
||||||
|
self.assertRaises(IncorrectSupplierType, tax_rule.save)
|
||||||
|
|
||||||
|
def test_conflict(self):
|
||||||
|
tax_rule1 = make_tax_rule(customer= "_Test Customer",
|
||||||
|
sales_tax_template = "_Test Sales Taxes and Charges Template", priority = 1)
|
||||||
|
tax_rule1.save()
|
||||||
|
|
||||||
|
tax_rule2 = make_tax_rule(customer= "_Test Customer",
|
||||||
|
sales_tax_template = "_Test Sales Taxes and Charges Template", priority = 1)
|
||||||
|
|
||||||
|
self.assertRaises(ConflictingTaxRule, tax_rule2.save)
|
||||||
|
|
||||||
|
def test_conflict_with_non_overlapping_dates(self):
|
||||||
|
tax_rule1 = make_tax_rule(customer= "_Test Customer",
|
||||||
|
sales_tax_template = "_Test Sales Taxes and Charges Template", priority = 1, from_date = "2015-01-01")
|
||||||
|
tax_rule1.save()
|
||||||
|
|
||||||
|
tax_rule2 = make_tax_rule(customer= "_Test Customer",
|
||||||
|
sales_tax_template = "_Test Sales Taxes and Charges Template", priority = 1, to_date = "2013-01-01")
|
||||||
|
|
||||||
|
tax_rule2.save()
|
||||||
|
self.assertTrue(tax_rule2.name)
|
||||||
|
|
||||||
|
def test_conflict_with_overlapping_dates(self):
|
||||||
|
tax_rule1 = make_tax_rule(customer= "_Test Customer",
|
||||||
|
sales_tax_template = "_Test Sales Taxes and Charges Template", priority = 1, from_date = "2015-01-01", to_date = "2015-01-05")
|
||||||
|
tax_rule1.save()
|
||||||
|
|
||||||
|
tax_rule2 = make_tax_rule(customer= "_Test Customer",
|
||||||
|
sales_tax_template = "_Test Sales Taxes and Charges Template", priority = 1, from_date = "2015-01-03", to_date = "2015-01-09")
|
||||||
|
|
||||||
|
self.assertRaises(ConflictingTaxRule, tax_rule2.save)
|
||||||
|
|
||||||
|
def test_tax_template(self):
|
||||||
|
tax_rule = make_tax_rule()
|
||||||
|
self.assertEquals(tax_rule.purchase_tax_template, None)
|
||||||
|
|
||||||
|
|
||||||
|
def test_select_tax_rule_based_on_customer(self):
|
||||||
|
make_tax_rule(customer= "_Test Customer",
|
||||||
|
sales_tax_template = "_Test Sales Taxes and Charges Template", save=1)
|
||||||
|
|
||||||
|
make_tax_rule(customer= "_Test Customer 1",
|
||||||
|
sales_tax_template = "_Test Sales Taxes and Charges Template 1", save=1)
|
||||||
|
|
||||||
|
make_tax_rule(customer= "_Test Customer 2",
|
||||||
|
sales_tax_template = "_Test Sales Taxes and Charges Template 2", save=1)
|
||||||
|
|
||||||
|
self.assertEquals(get_tax_template("2015-01-01", {"customer":"_Test Customer 2"}),
|
||||||
|
"_Test Sales Taxes and Charges Template 2")
|
||||||
|
|
||||||
|
def test_select_tax_rule_based_on_better_match(self):
|
||||||
|
make_tax_rule(customer= "_Test Customer", billing_city = "Test City", billing_state = "Test State",
|
||||||
|
sales_tax_template = "_Test Sales Taxes and Charges Template", save=1)
|
||||||
|
|
||||||
|
make_tax_rule(customer= "_Test Customer", billing_city = "Test City1", billing_state = "Test State",
|
||||||
|
sales_tax_template = "_Test Sales Taxes and Charges Template 1", save=1)
|
||||||
|
|
||||||
|
self.assertEquals(get_tax_template("2015-01-01", {"customer":"_Test Customer", "billing_city": "Test City", "billing_state": "Test State"}),
|
||||||
|
"_Test Sales Taxes and Charges Template")
|
||||||
|
|
||||||
|
def test_select_tax_rule_based_on_state_match(self):
|
||||||
|
make_tax_rule(customer= "_Test Customer", shipping_state = "Test State",
|
||||||
|
sales_tax_template = "_Test Sales Taxes and Charges Template", save=1)
|
||||||
|
|
||||||
|
make_tax_rule(customer= "_Test Customer", shipping_state = "Test State12",
|
||||||
|
sales_tax_template = "_Test Sales Taxes and Charges Template 1", priority=2, save=1)
|
||||||
|
|
||||||
|
self.assertEquals(get_tax_template("2015-01-01", {"customer":"_Test Customer", "shipping_state": "Test State"}),
|
||||||
|
"_Test Sales Taxes and Charges Template")
|
||||||
|
|
||||||
|
def test_select_tax_rule_based_on_better_priority(self):
|
||||||
|
make_tax_rule(customer= "_Test Customer", billing_city = "Test City",
|
||||||
|
sales_tax_template = "_Test Sales Taxes and Charges Template", priority=1, save=1)
|
||||||
|
|
||||||
|
make_tax_rule(customer= "_Test Customer", billing_city = "Test City",
|
||||||
|
sales_tax_template = "_Test Sales Taxes and Charges Template 1", priority=2, save=1)
|
||||||
|
|
||||||
|
self.assertEquals(get_tax_template("2015-01-01", {"customer":"_Test Customer", "billing_city": "Test City"}),
|
||||||
|
"_Test Sales Taxes and Charges Template 1")
|
||||||
|
|
||||||
|
def test_select_tax_rule_based_cross_matching_keys(self):
|
||||||
|
make_tax_rule(customer= "_Test Customer", billing_city = "Test City",
|
||||||
|
sales_tax_template = "_Test Sales Taxes and Charges Template", save=1)
|
||||||
|
|
||||||
|
make_tax_rule(customer= "_Test Customer 1", billing_city = "Test City 1",
|
||||||
|
sales_tax_template = "_Test Sales Taxes and Charges Template 1", save=1)
|
||||||
|
|
||||||
|
self.assertEquals(get_tax_template("2015-01-01", {"customer":"_Test Customer", "billing_city": "Test City 1"}),
|
||||||
|
None)
|
||||||
|
|
||||||
|
def test_select_tax_rule_based_cross_partially_keys(self):
|
||||||
|
make_tax_rule(customer= "_Test Customer", billing_city = "Test City",
|
||||||
|
sales_tax_template = "_Test Sales Taxes and Charges Template", save=1)
|
||||||
|
|
||||||
|
make_tax_rule(billing_city = "Test City 1",
|
||||||
|
sales_tax_template = "_Test Sales Taxes and Charges Template 1", save=1)
|
||||||
|
|
||||||
|
self.assertEquals(get_tax_template("2015-01-01", {"customer":"_Test Customer", "billing_city": "Test City 1"}),
|
||||||
|
"_Test Sales Taxes and Charges Template 1")
|
||||||
|
|
||||||
|
|
||||||
|
def make_tax_rule(**args):
|
||||||
|
args = frappe._dict(args)
|
||||||
|
|
||||||
|
tax_rule = frappe.new_doc("Tax Rule")
|
||||||
|
|
||||||
|
for key, val in args.iteritems():
|
||||||
|
if key != "save":
|
||||||
|
tax_rule.set(key, val)
|
||||||
|
|
||||||
|
tax_rule.company = args.company or "_Test Company"
|
||||||
|
|
||||||
|
if args.save:
|
||||||
|
tax_rule.insert()
|
||||||
|
|
||||||
|
return tax_rule
|
||||||
|
|
@ -43,6 +43,7 @@ def _get_party_details(party=None, account=None, party_type="Customer", company=
|
|||||||
set_contact_details(out, party, party_type)
|
set_contact_details(out, party, party_type)
|
||||||
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["taxes_and_charges"] = set_taxes(party.name, party_type, posting_date, company, out.customer_group, out.supplier_type)
|
||||||
|
|
||||||
if not out.get("currency"):
|
if not out.get("currency"):
|
||||||
out["currency"] = currency
|
out["currency"] = currency
|
||||||
@ -99,7 +100,7 @@ def set_other_values(out, party, party_type):
|
|||||||
out[f] = party.get(f)
|
out[f] = party.get(f)
|
||||||
|
|
||||||
# fields prepended with default in Customer doctype
|
# fields prepended with default in Customer doctype
|
||||||
for f in ['currency', 'taxes_and_charges'] \
|
for f in ['currency'] \
|
||||||
+ (['sales_partner', 'commission_rate'] if party_type=="Customer" else []):
|
+ (['sales_partner', 'commission_rate'] if party_type=="Customer" else []):
|
||||||
if party.get("default_" + f):
|
if party.get("default_" + f):
|
||||||
out[f] = party.get("default_" + f)
|
out[f] = party.get("default_" + f)
|
||||||
@ -274,4 +275,31 @@ def validate_due_date(posting_date, due_date, party_type, party, company):
|
|||||||
msgprint(_("Note: Due / Reference Date exceeds allowed customer credit days by {0} day(s)")
|
msgprint(_("Note: Due / Reference Date exceeds allowed customer credit days by {0} day(s)")
|
||||||
.format(date_diff(due_date, default_due_date)))
|
.format(date_diff(due_date, default_due_date)))
|
||||||
else:
|
else:
|
||||||
frappe.throw(_("Due / Reference Date cannot be after {0}").format(formatdate(default_due_date)))
|
frappe.throw(_("Due / Reference Date cannot be after {0}").format(formatdate(default_due_date)))
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def set_taxes(party, party_type, posting_date, company, customer_group=None, supplier_type=None,
|
||||||
|
billing_address=None, shipping_address=None, use_for_shopping_cart=None):
|
||||||
|
from erpnext.accounts.doctype.tax_rule.tax_rule import get_tax_template, get_party_details
|
||||||
|
args = {
|
||||||
|
party_type: party,
|
||||||
|
"customer_group": customer_group,
|
||||||
|
"supplier_type": supplier_type,
|
||||||
|
"company": company
|
||||||
|
}
|
||||||
|
|
||||||
|
if billing_address or shipping_address:
|
||||||
|
args.update(get_party_details(party, party_type, {"billing_address": billing_address, \
|
||||||
|
"shipping_address": shipping_address }))
|
||||||
|
else:
|
||||||
|
args.update(get_party_details(party, party_type))
|
||||||
|
|
||||||
|
if party_type=="Customer":
|
||||||
|
args.update({"tax_type": "Sales"})
|
||||||
|
else:
|
||||||
|
args.update({"tax_type": "Purchase"})
|
||||||
|
|
||||||
|
if use_for_shopping_cart:
|
||||||
|
args.update({"use_for_shopping_cart": use_for_shopping_cart})
|
||||||
|
|
||||||
|
return get_tax_template(posting_date, args)
|
@ -106,6 +106,11 @@ def get_data():
|
|||||||
"name": "Accounts Settings",
|
"name": "Accounts Settings",
|
||||||
"description": _("Default settings for accounting transactions.")
|
"description": _("Default settings for accounting transactions.")
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "doctype",
|
||||||
|
"name": "Tax Rule",
|
||||||
|
"description": _("Tax Rule for transactions.")
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "doctype",
|
"type": "doctype",
|
||||||
"name": "Sales Taxes and Charges Template",
|
"name": "Sales Taxes and Charges Template",
|
||||||
|
27
erpnext/patches/v5_8/tax_rule.py
Normal file
27
erpnext/patches/v5_8/tax_rule.py
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
|
||||||
|
# License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
import frappe
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
customers = frappe.db.sql("""select name, default_taxes_and_charges from tabCustomer where
|
||||||
|
ifnull(default_taxes_and_charges, '') != '' """, as_dict=1)
|
||||||
|
|
||||||
|
for d in customers:
|
||||||
|
tr = frappe.new_doc("Tax Rule")
|
||||||
|
tr.tax_type = "Sales"
|
||||||
|
tr.customer = d.name
|
||||||
|
tr.sales_tax_template = d.default_taxes_and_charges
|
||||||
|
tr.save()
|
||||||
|
|
||||||
|
|
||||||
|
suppliers = frappe.db.sql("""select name, default_taxes_and_charges from tabSupplier where
|
||||||
|
ifnull(default_taxes_and_charges, '') != '' """, as_dict=1)
|
||||||
|
|
||||||
|
for d in suppliers:
|
||||||
|
tr = frappe.new_doc("Tax Rule")
|
||||||
|
tr.tax_type = "Purchase"
|
||||||
|
tr.supplier = d.name
|
||||||
|
tr.purchase_tax_template = d.default_taxes_and_charges
|
||||||
|
tr.save()
|
@ -20,6 +20,7 @@ erpnext.utils.get_party_details = function(frm, method, args, callback) {
|
|||||||
price_list: frm.doc.buying_price_list
|
price_list: frm.doc.buying_price_list
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
args.posting_date = frm.doc.transaction_date;
|
||||||
}
|
}
|
||||||
if(!args) return;
|
if(!args) return;
|
||||||
|
|
||||||
@ -42,6 +43,7 @@ erpnext.utils.get_party_details = function(frm, method, args, callback) {
|
|||||||
|
|
||||||
erpnext.utils.get_address_display = function(frm, address_field, display_field) {
|
erpnext.utils.get_address_display = function(frm, address_field, display_field) {
|
||||||
if(frm.updating_party_details) return;
|
if(frm.updating_party_details) return;
|
||||||
|
|
||||||
if(!address_field) {
|
if(!address_field) {
|
||||||
if(frm.doc.customer) {
|
if(frm.doc.customer) {
|
||||||
address_field = "customer_address";
|
address_field = "customer_address";
|
||||||
@ -49,14 +51,32 @@ erpnext.utils.get_address_display = function(frm, address_field, display_field)
|
|||||||
address_field = "supplier_address";
|
address_field = "supplier_address";
|
||||||
} else return;
|
} else return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!display_field) display_field = "address_display";
|
if(!display_field) display_field = "address_display";
|
||||||
if(frm.doc[address_field]) {
|
if(frm.doc[address_field]) {
|
||||||
frappe.call({
|
frappe.call({
|
||||||
method: "erpnext.utilities.doctype.address.address.get_address_display",
|
method: "erpnext.utilities.doctype.address.address.get_address_display",
|
||||||
args: {"address_dict": frm.doc[address_field] },
|
args: {"address_dict": frm.doc[address_field] },
|
||||||
callback: function(r) {
|
callback: function(r) {
|
||||||
if(r.message)
|
if(r.message){
|
||||||
frm.set_value(display_field, r.message)
|
frm.set_value(display_field, r.message)
|
||||||
|
}
|
||||||
|
frappe.call({
|
||||||
|
method: "erpnext.accounts.party.set_taxes",
|
||||||
|
args: {
|
||||||
|
"party": frm.doc.customer || frm.doc.supplier,
|
||||||
|
"party_type": (frm.doc.customer ? "Customer" : "Supplier"),
|
||||||
|
"posting_date": frm.doc.posting_date || frm.doc.transaction_date,
|
||||||
|
"company": frm.doc.company,
|
||||||
|
"billing_address": ((frm.doc.customer) ? (frm.doc.customer_address) : (frm.doc.supplier_address)),
|
||||||
|
"shipping_address": frm.doc.shipping_address_name
|
||||||
|
},
|
||||||
|
callback: function(r) {
|
||||||
|
if(r.message){
|
||||||
|
frm.set_value("taxes_and_charges", r.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -4,5 +4,11 @@
|
|||||||
"doctype": "Customer Group",
|
"doctype": "Customer Group",
|
||||||
"is_group": "No",
|
"is_group": "No",
|
||||||
"parent_customer_group": "All Customer Groups"
|
"parent_customer_group": "All Customer Groups"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"customer_group_name": "_Test Customer Group 1",
|
||||||
|
"doctype": "Customer Group",
|
||||||
|
"is_group": "No",
|
||||||
|
"parent_customer_group": "All Customer Groups"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -266,12 +266,18 @@ def _set_price_list(quotation, cart_settings, billing_territory):
|
|||||||
|
|
||||||
def set_taxes(quotation, cart_settings, billing_territory):
|
def set_taxes(quotation, cart_settings, billing_territory):
|
||||||
"""set taxes based on billing territory"""
|
"""set taxes based on billing territory"""
|
||||||
quotation.taxes_and_charges = cart_settings.get_tax_master(billing_territory)
|
from erpnext.accounts.party import set_taxes
|
||||||
|
|
||||||
# clear table
|
customer_group = frappe.db.get_value("Customer", quotation.customer, "customer_group")
|
||||||
|
|
||||||
|
quotation.taxes_and_charges = set_taxes(quotation.customer, "Customer", \
|
||||||
|
quotation.transaction_date, quotation.company, customer_group, None, \
|
||||||
|
quotation.customer_address, quotation.shipping_address_name, 1)
|
||||||
|
#
|
||||||
|
# # clear table
|
||||||
quotation.set("taxes", [])
|
quotation.set("taxes", [])
|
||||||
|
#
|
||||||
# append taxes
|
# # append taxes
|
||||||
quotation.append_taxes_from_master()
|
quotation.append_taxes_from_master()
|
||||||
|
|
||||||
def get_lead_or_customer():
|
def get_lead_or_customer():
|
||||||
|
@ -200,6 +200,27 @@
|
|||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"fieldname": "column_break_10",
|
||||||
|
"fieldtype": "Column Break",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
@ -221,48 +242,6 @@
|
|||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
|
||||||
{
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"fieldname": "column_break_10",
|
|
||||||
"fieldtype": "Column Break",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print_hide": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"fieldname": "sales_taxes_and_charges_masters",
|
|
||||||
"fieldtype": "Table",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"label": "Taxes and Charges",
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Shopping Cart Taxes and Charges Master",
|
|
||||||
"permlevel": 0,
|
|
||||||
"print_hide": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"hide_heading": 0,
|
"hide_heading": 0,
|
||||||
@ -274,7 +253,7 @@
|
|||||||
"is_submittable": 0,
|
"is_submittable": 0,
|
||||||
"issingle": 1,
|
"issingle": 1,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"modified": "2015-02-05 05:11:46.714019",
|
"modified": "2015-09-11 19:03:54.750937",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Shopping Cart",
|
"module": "Shopping Cart",
|
||||||
"name": "Shopping Cart Settings",
|
"name": "Shopping Cart Settings",
|
||||||
|
@ -20,9 +20,9 @@ class ShoppingCartSettings(Document):
|
|||||||
def validate(self):
|
def validate(self):
|
||||||
if self.enabled:
|
if self.enabled:
|
||||||
self.validate_price_lists()
|
self.validate_price_lists()
|
||||||
self.validate_tax_masters()
|
|
||||||
self.validate_exchange_rates_exist()
|
self.validate_exchange_rates_exist()
|
||||||
|
self.validate_tax_rule()
|
||||||
|
|
||||||
def validate_overlapping_territories(self, parentfield, fieldname):
|
def validate_overlapping_territories(self, parentfield, fieldname):
|
||||||
# for displaying message
|
# for displaying message
|
||||||
doctype = self.meta.get_field(parentfield).options
|
doctype = self.meta.get_field(parentfield).options
|
||||||
@ -48,20 +48,14 @@ class ShoppingCartSettings(Document):
|
|||||||
msgprint(_("Please specify a Price List which is valid for Territory") +
|
msgprint(_("Please specify a Price List which is valid for Territory") +
|
||||||
": " + self.default_territory, raise_exception=ShoppingCartSetupError)
|
": " + self.default_territory, raise_exception=ShoppingCartSetupError)
|
||||||
|
|
||||||
def validate_tax_masters(self):
|
|
||||||
self.validate_overlapping_territories("sales_taxes_and_charges_masters",
|
|
||||||
"sales_taxes_and_charges_master")
|
|
||||||
|
|
||||||
def get_territory_name_map(self, parentfield, fieldname):
|
def get_territory_name_map(self, parentfield, fieldname):
|
||||||
territory_name_map = {}
|
territory_name_map = {}
|
||||||
|
|
||||||
# entries in table
|
# entries in table
|
||||||
names = [doc.get(fieldname) for doc in self.get(parentfield)]
|
names = [doc.get(fieldname) for doc in self.get(parentfield)]
|
||||||
|
|
||||||
if names:
|
if names:
|
||||||
# for condition in territory check
|
# for condition in territory check
|
||||||
parenttype = frappe.get_meta(self.meta.get_options(parentfield)).get_options(fieldname)
|
parenttype = frappe.get_meta(self.meta.get_options(parentfield)).get_options(fieldname)
|
||||||
|
|
||||||
# to validate territory overlap
|
# to validate territory overlap
|
||||||
# make a map of territory: [list of names]
|
# make a map of territory: [list of names]
|
||||||
# if list against each territory has more than one element, raise exception
|
# if list against each territory has more than one element, raise exception
|
||||||
@ -75,7 +69,6 @@ class ShoppingCartSettings(Document):
|
|||||||
|
|
||||||
if len(territory_name_map[territory]) > 1:
|
if len(territory_name_map[territory]) > 1:
|
||||||
territory_name_map[territory].sort(key=lambda val: names.index(val))
|
territory_name_map[territory].sort(key=lambda val: names.index(val))
|
||||||
|
|
||||||
return territory_name_map
|
return territory_name_map
|
||||||
|
|
||||||
def validate_exchange_rates_exist(self):
|
def validate_exchange_rates_exist(self):
|
||||||
@ -112,7 +105,6 @@ class ShoppingCartSettings(Document):
|
|||||||
def get_name_from_territory(self, territory, parentfield, fieldname):
|
def get_name_from_territory(self, territory, parentfield, fieldname):
|
||||||
name = None
|
name = None
|
||||||
territory_name_map = self.get_territory_name_map(parentfield, fieldname)
|
territory_name_map = self.get_territory_name_map(parentfield, fieldname)
|
||||||
|
|
||||||
if territory_name_map.get(territory):
|
if territory_name_map.get(territory):
|
||||||
name = territory_name_map.get(territory)
|
name = territory_name_map.get(territory)
|
||||||
else:
|
else:
|
||||||
@ -131,7 +123,11 @@ class ShoppingCartSettings(Document):
|
|||||||
"price_lists", "selling_price_list")
|
"price_lists", "selling_price_list")
|
||||||
|
|
||||||
return price_list and price_list[0] or None
|
return price_list and price_list[0] or None
|
||||||
|
|
||||||
|
def validate_tax_rule(self):
|
||||||
|
if not frappe.db.get_value("Tax Rule", {"use_for_shopping_cart" : 1}, "name"):
|
||||||
|
frappe.throw(frappe._("Set Tax Rule for shopping cart"), ShoppingCartSetupError)
|
||||||
|
|
||||||
def get_tax_master(self, billing_territory):
|
def get_tax_master(self, billing_territory):
|
||||||
tax_master = self.get_name_from_territory(billing_territory, "sales_taxes_and_charges_masters",
|
tax_master = self.get_name_from_territory(billing_territory, "sales_taxes_and_charges_masters",
|
||||||
"sales_taxes_and_charges_master")
|
"sales_taxes_and_charges_master")
|
||||||
@ -167,52 +163,4 @@ def get_default_territory():
|
|||||||
def check_shopping_cart_enabled():
|
def check_shopping_cart_enabled():
|
||||||
if not get_shopping_cart_settings().enabled:
|
if not get_shopping_cart_settings().enabled:
|
||||||
frappe.throw(_("You need to enable Shopping Cart"), ShoppingCartSetupError)
|
frappe.throw(_("You need to enable Shopping Cart"), ShoppingCartSetupError)
|
||||||
|
|
||||||
def apply_shopping_cart_settings(quotation, method):
|
|
||||||
"""Called via a validate hook on Quotation"""
|
|
||||||
from erpnext.shopping_cart import get_party
|
|
||||||
if quotation.order_type != "Shopping Cart":
|
|
||||||
return
|
|
||||||
|
|
||||||
quotation.billing_territory = (get_territory_from_address(quotation.customer_address)
|
|
||||||
or get_party(quotation.contact_email).territory or get_default_territory())
|
|
||||||
quotation.shipping_territory = (get_territory_from_address(quotation.shipping_address_name)
|
|
||||||
or get_party(quotation.contact_email).territory or get_default_territory())
|
|
||||||
|
|
||||||
set_price_list(quotation)
|
|
||||||
set_taxes_and_charges(quotation)
|
|
||||||
quotation.calculate_taxes_and_totals()
|
|
||||||
set_shipping_rule(quotation)
|
|
||||||
|
|
||||||
def set_price_list(quotation):
|
|
||||||
previous_selling_price_list = quotation.selling_price_list
|
|
||||||
quotation.selling_price_list = get_shopping_cart_settings().get_price_list(quotation.billing_territory)
|
|
||||||
|
|
||||||
if not quotation.selling_price_list:
|
|
||||||
quotation.selling_price_list = get_shopping_cart_settings().get_price_list(get_default_territory())
|
|
||||||
|
|
||||||
if previous_selling_price_list != quotation.selling_price_list:
|
|
||||||
quotation.price_list_currency = quotation.currency = quotation.plc_conversion_rate = quotation.conversion_rate = None
|
|
||||||
for d in quotation.get("items"):
|
|
||||||
d.price_list_rate = d.discount_percentage = d.rate = d.amount = None
|
|
||||||
|
|
||||||
quotation.set_price_list_and_item_details()
|
|
||||||
|
|
||||||
def set_taxes_and_charges(quotation):
|
|
||||||
previous_taxes_and_charges = quotation.taxes_and_charges
|
|
||||||
quotation.taxes_and_charges = get_shopping_cart_settings().get_tax_master(quotation.billing_territory)
|
|
||||||
|
|
||||||
if previous_taxes_and_charges != quotation.taxes_and_charges:
|
|
||||||
quotation.set_other_charges()
|
|
||||||
|
|
||||||
def set_shipping_rule(quotation):
|
|
||||||
shipping_rules = get_shopping_cart_settings().get_shipping_rules(quotation.shipping_territory)
|
|
||||||
if not shipping_rules:
|
|
||||||
quotation.remove_shipping_charge()
|
|
||||||
return
|
|
||||||
|
|
||||||
if quotation.shipping_rule not in shipping_rules:
|
|
||||||
quotation.remove_shipping_charge()
|
|
||||||
quotation.shipping_rule = shipping_rules[0]
|
|
||||||
|
|
||||||
quotation.apply_shipping_rule()
|
|
||||||
|
@ -12,7 +12,6 @@ class TestShoppingCartSettings(unittest.TestCase):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
frappe.db.sql("""delete from `tabSingles` where doctype="Shipping Cart Settings" """)
|
frappe.db.sql("""delete from `tabSingles` where doctype="Shipping Cart Settings" """)
|
||||||
frappe.db.sql("""delete from `tabShopping Cart Price List`""")
|
frappe.db.sql("""delete from `tabShopping Cart Price List`""")
|
||||||
frappe.db.sql("""delete from `tabShopping Cart Taxes and Charges Master`""")
|
|
||||||
frappe.db.sql("""delete from `tabShopping Cart Shipping Rule`""")
|
frappe.db.sql("""delete from `tabShopping Cart Shipping Rule`""")
|
||||||
|
|
||||||
def get_cart_settings(self):
|
def get_cart_settings(self):
|
||||||
@ -43,28 +42,6 @@ class TestShoppingCartSettings(unittest.TestCase):
|
|||||||
|
|
||||||
return cart_settings
|
return cart_settings
|
||||||
|
|
||||||
def test_taxes_territory_overlap(self):
|
|
||||||
cart_settings = self.get_cart_settings()
|
|
||||||
|
|
||||||
def _add_tax_master(tax_master):
|
|
||||||
cart_settings.append("sales_taxes_and_charges_masters", {
|
|
||||||
"doctype": "Shopping Cart Taxes and Charges Master",
|
|
||||||
"sales_taxes_and_charges_master": tax_master
|
|
||||||
})
|
|
||||||
|
|
||||||
for tax_master in ("_Test Sales Taxes and Charges Template", "_Test India Tax Master"):
|
|
||||||
_add_tax_master(tax_master)
|
|
||||||
|
|
||||||
controller = cart_settings
|
|
||||||
controller.validate_overlapping_territories("sales_taxes_and_charges_masters",
|
|
||||||
"sales_taxes_and_charges_master")
|
|
||||||
|
|
||||||
_add_tax_master("_Test Sales Taxes and Charges Template - Rest of the World")
|
|
||||||
|
|
||||||
controller = cart_settings
|
|
||||||
self.assertRaises(ShoppingCartSetupError, controller.validate_overlapping_territories,
|
|
||||||
"sales_taxes_and_charges_masters", "sales_taxes_and_charges_master")
|
|
||||||
|
|
||||||
def test_exchange_rate_exists(self):
|
def test_exchange_rate_exists(self):
|
||||||
frappe.db.sql("""delete from `tabCurrency Exchange`""")
|
frappe.db.sql("""delete from `tabCurrency Exchange`""")
|
||||||
|
|
||||||
@ -77,3 +54,12 @@ class TestShoppingCartSettings(unittest.TestCase):
|
|||||||
frappe.get_doc(currency_exchange_records[0]).insert()
|
frappe.get_doc(currency_exchange_records[0]).insert()
|
||||||
controller.validate_exchange_rates_exist()
|
controller.validate_exchange_rates_exist()
|
||||||
|
|
||||||
|
def test_tax_rule_validation(self):
|
||||||
|
frappe.db.sql("update `tabTax Rule` set use_for_shopping_cart = 0")
|
||||||
|
frappe.db.commit()
|
||||||
|
|
||||||
|
cart_settings = self.get_cart_settings()
|
||||||
|
cart_settings.enabled = 1
|
||||||
|
if not frappe.db.get_value("Tax Rule", {"use_for_shopping_cart": 1}, "name"):
|
||||||
|
self.assertRaises(ShoppingCartSetupError, cart_settings.validate_tax_rule)
|
||||||
|
|
||||||
|
@ -1,49 +0,0 @@
|
|||||||
{
|
|
||||||
"allow_copy": 0,
|
|
||||||
"allow_import": 0,
|
|
||||||
"allow_rename": 0,
|
|
||||||
"creation": "2013-06-20 16:57:03",
|
|
||||||
"custom": 0,
|
|
||||||
"docstatus": 0,
|
|
||||||
"doctype": "DocType",
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"fieldname": "sales_taxes_and_charges_master",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"label": "Tax Master",
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Sales Taxes and Charges Template",
|
|
||||||
"permlevel": 0,
|
|
||||||
"print_hide": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"hide_heading": 0,
|
|
||||||
"hide_toolbar": 0,
|
|
||||||
"idx": 1,
|
|
||||||
"in_create": 0,
|
|
||||||
"in_dialog": 0,
|
|
||||||
"is_submittable": 0,
|
|
||||||
"issingle": 0,
|
|
||||||
"istable": 1,
|
|
||||||
"modified": "2013-12-20 19:30:47",
|
|
||||||
"modified_by": "Administrator",
|
|
||||||
"module": "Shopping Cart",
|
|
||||||
"name": "Shopping Cart Taxes and Charges Master",
|
|
||||||
"owner": "Administrator",
|
|
||||||
"permissions": [],
|
|
||||||
"read_only": 0,
|
|
||||||
"read_only_onload": 0
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
|
||||||
# License: GNU General Public License v3. See license.txt
|
|
||||||
|
|
||||||
# For license information, please see license.txt
|
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
import frappe
|
|
||||||
|
|
||||||
from frappe.model.document import Document
|
|
||||||
|
|
||||||
class ShoppingCartTaxesandChargesMaster(Document):
|
|
||||||
pass
|
|
@ -4,7 +4,7 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import unittest
|
import unittest
|
||||||
import frappe
|
import frappe
|
||||||
from erpnext.shopping_cart import get_quotation, set_item_in_cart
|
from erpnext.shopping_cart import get_quotation, set_item_in_cart, get_party
|
||||||
|
|
||||||
class TestShoppingCart(unittest.TestCase):
|
class TestShoppingCart(unittest.TestCase):
|
||||||
"""
|
"""
|
||||||
@ -109,6 +109,53 @@ class TestShoppingCart(unittest.TestCase):
|
|||||||
quotation = self.test_get_cart_lead()
|
quotation = self.test_get_cart_lead()
|
||||||
self.assertEquals(quotation.net_total, 0)
|
self.assertEquals(quotation.net_total, 0)
|
||||||
self.assertEquals(len(quotation.get("items")), 0)
|
self.assertEquals(len(quotation.get("items")), 0)
|
||||||
|
|
||||||
|
|
||||||
|
def test_taxe_rule(self):
|
||||||
|
self.login_as_customer()
|
||||||
|
quotation = self.create_quotation()
|
||||||
|
|
||||||
|
from erpnext.accounts.party import set_taxes
|
||||||
|
|
||||||
|
tax_rule_master = set_taxes(quotation.customer, "Customer", \
|
||||||
|
quotation.transaction_date, quotation.company, None, None, \
|
||||||
|
quotation.customer_address, quotation.shipping_address_name, 1)
|
||||||
|
|
||||||
|
self.assertEquals(quotation.taxes_and_charges, tax_rule_master)
|
||||||
|
self.assertEquals(quotation.total_taxes_and_charges, 1000.0)
|
||||||
|
|
||||||
|
self.remove_test_quotation(quotation)
|
||||||
|
|
||||||
|
def create_quotation(self):
|
||||||
|
quotation = frappe.new_doc("Quotation")
|
||||||
|
|
||||||
|
values = {
|
||||||
|
"doctype": "Quotation",
|
||||||
|
"quotation_to": "Customer",
|
||||||
|
"order_type": "Shopping Cart",
|
||||||
|
"customer": get_party(frappe.session.user).name,
|
||||||
|
"docstatus": 0,
|
||||||
|
"contact_email": frappe.session.user,
|
||||||
|
"selling_price_list": "_Test Price List Rest of the World",
|
||||||
|
"currency": "USD",
|
||||||
|
"taxes_and_charges" : "_Test Tax 1",
|
||||||
|
"items": [{
|
||||||
|
"item_code": "_Test Item",
|
||||||
|
"qty": 1
|
||||||
|
}],
|
||||||
|
"taxes": frappe.get_doc("Sales Taxes and Charges Template", "_Test Tax 1").taxes,
|
||||||
|
"company": "_Test Company"
|
||||||
|
}
|
||||||
|
|
||||||
|
quotation.update(values)
|
||||||
|
|
||||||
|
quotation.insert(ignore_permissions=True)
|
||||||
|
|
||||||
|
return quotation
|
||||||
|
|
||||||
|
def remove_test_quotation(self, quotation):
|
||||||
|
frappe.set_user("Administrator")
|
||||||
|
quotation.delete()
|
||||||
|
|
||||||
# helper functions
|
# helper functions
|
||||||
def enable_shopping_cart(self):
|
def enable_shopping_cart(self):
|
||||||
@ -131,15 +178,9 @@ class TestShoppingCart(unittest.TestCase):
|
|||||||
{"doctype": "Shopping Cart Price List", "parentfield": "price_lists",
|
{"doctype": "Shopping Cart Price List", "parentfield": "price_lists",
|
||||||
"selling_price_list": "_Test Price List Rest of the World"}
|
"selling_price_list": "_Test Price List Rest of the World"}
|
||||||
])
|
])
|
||||||
settings.set("sales_taxes_and_charges_masters", [
|
|
||||||
# tax masters
|
|
||||||
{"doctype": "Shopping Cart Taxes and Charges Master", "parentfield": "sales_taxes_and_charges_masters",
|
|
||||||
"sales_taxes_and_charges_master": "_Test India Tax Master"},
|
|
||||||
{"doctype": "Shopping Cart Taxes and Charges Master", "parentfield": "sales_taxes_and_charges_masters",
|
|
||||||
"sales_taxes_and_charges_master": "_Test Sales Taxes and Charges Template - Rest of the World"},
|
|
||||||
])
|
|
||||||
settings.set("shipping_rules", {"doctype": "Shopping Cart Shipping Rule", "parentfield": "shipping_rules",
|
settings.set("shipping_rules", {"doctype": "Shopping Cart Shipping Rule", "parentfield": "shipping_rules",
|
||||||
"shipping_rule": "_Test Shipping Rule - India"})
|
"shipping_rule": "_Test Shipping Rule - India"})
|
||||||
|
|
||||||
|
|
||||||
settings.save()
|
settings.save()
|
||||||
frappe.local.shopping_cart_settings = None
|
frappe.local.shopping_cart_settings = None
|
||||||
@ -203,7 +244,6 @@ class TestShoppingCart(unittest.TestCase):
|
|||||||
quotation = get_quotation()
|
quotation = get_quotation()
|
||||||
quotation.set("items", [])
|
quotation.set("items", [])
|
||||||
quotation.save(ignore_permissions=True)
|
quotation.save(ignore_permissions=True)
|
||||||
|
|
||||||
|
|
||||||
test_dependencies = ["Sales Taxes and Charges Template", "Price List", "Item Price", "Shipping Rule", "Currency Exchange",
|
test_dependencies = ["Sales Taxes and Charges Template", "Price List", "Item Price", "Shipping Rule", "Currency Exchange",
|
||||||
"Customer Group", "Lead", "Customer", "Contact", "Address", "Item"]
|
"Customer Group", "Lead", "Customer", "Contact", "Address", "Item", "Tax Rule"]
|
||||||
|
@ -3,7 +3,8 @@
|
|||||||
"address_line1": "_Test Address Line 1",
|
"address_line1": "_Test Address Line 1",
|
||||||
"address_title": "_Test Address",
|
"address_title": "_Test Address",
|
||||||
"address_type": "Office",
|
"address_type": "Office",
|
||||||
"city": "_Test City",
|
"city": "_Test City",
|
||||||
|
"state": "Test State",
|
||||||
"country": "India",
|
"country": "India",
|
||||||
"customer": "_Test Customer",
|
"customer": "_Test Customer",
|
||||||
"customer_name": "_Test Customer",
|
"customer_name": "_Test Customer",
|
||||||
|
Loading…
Reference in New Issue
Block a user