[Feature] Shipping Rule Calculation based on Net Weight (#11770)

* [new] Calculate shipping tax based on weight

* [fix] Change field name weight to weight_per_unit in SI Item

* [new] Shipping Rule based tax for selling module

* [new] Shipping rule based on weight added to Buying module

* [fix] Conflict in jsons

* [fix] Removed Redudant add_fetch

* [fix] Codacy fixed

* [fix] Print hide added
This commit is contained in:
Vishal Dhayagude 2017-11-29 16:09:59 +05:30 committed by Nabin Hait
parent 2d1cbd0b2e
commit d42242df22
24 changed files with 32124 additions and 30853 deletions

File diff suppressed because it is too large Load Diff

View File

@ -158,7 +158,7 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
}) })
}, __("Get items from")); }, __("Get items from"));
}, },
quotation_btn: function() { quotation_btn: function() {
var me = this; var me = this;
this.$quotation_btn = this.frm.add_custom_button(__('Quotation'), this.$quotation_btn = this.frm.add_custom_button(__('Quotation'),

File diff suppressed because it is too large Load Diff

View File

@ -51,6 +51,10 @@ class ShippingRule(Document):
value = doc.base_net_total value = doc.base_net_total
by_value = True by_value = True
elif self.calculate_based_on == 'Net Weight':
value = doc.total_net_weight
by_value = True
elif self.calculate_based_on == 'Fixed': elif self.calculate_based_on == 'Fixed':
shipping_amount = self.shipping_amount shipping_amount = self.shipping_amount

File diff suppressed because it is too large Load Diff

View File

@ -24,7 +24,7 @@ class calculate_taxes_and_totals(object):
if self.doc.doctype in ["Sales Invoice", "Purchase Invoice"]: if self.doc.doctype in ["Sales Invoice", "Purchase Invoice"]:
self.calculate_total_advance() self.calculate_total_advance()
if self.doc.meta.get_field("other_charges_calculation"): if self.doc.meta.get_field("other_charges_calculation"):
self.set_item_wise_tax_breakup() self.set_item_wise_tax_breakup()
@ -70,6 +70,7 @@ class calculate_taxes_and_totals(object):
item.net_rate = item.rate item.net_rate = item.rate
item.amount = flt(item.rate * item.qty, item.precision("amount")) item.amount = flt(item.rate * item.qty, item.precision("amount"))
item.net_amount = item.amount item.net_amount = item.amount
item.total_weight = flt(item.weight_per_unit * item.qty)
self._set_in_company_currency(item, ["price_list_rate", "rate", "net_rate", "amount", "net_amount"]) self._set_in_company_currency(item, ["price_list_rate", "rate", "net_rate", "amount", "net_amount"])
@ -163,13 +164,13 @@ class calculate_taxes_and_totals(object):
return tax.rate return tax.rate
def calculate_net_total(self): def calculate_net_total(self):
self.doc.total = self.doc.base_total = self.doc.net_total = self.doc.base_net_total = 0.0 self.doc.total = self.doc.base_total = self.doc.net_total = self.doc.base_net_total = self.doc.total_net_weight= 0.0
for item in self.doc.get("items"): for item in self.doc.get("items"):
self.doc.total += item.amount self.doc.total += item.amount
self.doc.base_total += item.base_amount self.doc.base_total += item.base_amount
self.doc.net_total += item.net_amount self.doc.net_total += item.net_amount
self.doc.base_net_total += item.base_net_amount self.doc.base_net_total += item.base_net_amount
self.doc.total_net_weight += item.total_weight
self.doc.round_floats_in(self.doc, ["total", "base_total", "net_total", "base_net_total"]) self.doc.round_floats_in(self.doc, ["total", "base_total", "net_total", "base_net_total"])
@ -279,7 +280,7 @@ class calculate_taxes_and_totals(object):
def round_off_totals(self, tax): def round_off_totals(self, tax):
tax.tax_amount = flt(tax.tax_amount, tax.precision("tax_amount")) tax.tax_amount = flt(tax.tax_amount, tax.precision("tax_amount"))
tax.tax_amount_after_discount_amount = flt(tax.tax_amount_after_discount_amount, tax.tax_amount_after_discount_amount = flt(tax.tax_amount_after_discount_amount,
tax.precision("tax_amount")) tax.precision("tax_amount"))
def manipulate_grand_total_for_inclusive_tax(self): def manipulate_grand_total_for_inclusive_tax(self):
@ -416,14 +417,14 @@ class calculate_taxes_and_totals(object):
self.doc.total_advance = flt(total_allocated_amount, self.doc.precision("total_advance")) self.doc.total_advance = flt(total_allocated_amount, self.doc.precision("total_advance"))
if self.doc.party_account_currency == self.doc.currency: if self.doc.party_account_currency == self.doc.currency:
invoice_total = flt(self.doc.grand_total - flt(self.doc.write_off_amount), invoice_total = flt(self.doc.grand_total - flt(self.doc.write_off_amount),
self.doc.precision("grand_total")) self.doc.precision("grand_total"))
else: else:
base_write_off_amount = flt(flt(self.doc.write_off_amount) * self.doc.conversion_rate, base_write_off_amount = flt(flt(self.doc.write_off_amount) * self.doc.conversion_rate,
self.doc.precision("base_write_off_amount")) self.doc.precision("base_write_off_amount"))
invoice_total = flt(self.doc.grand_total * self.doc.conversion_rate, invoice_total = flt(self.doc.grand_total * self.doc.conversion_rate,
self.doc.precision("grand_total")) - base_write_off_amount self.doc.precision("grand_total")) - base_write_off_amount
if invoice_total > 0 and self.doc.total_advance > invoice_total: if invoice_total > 0 and self.doc.total_advance > invoice_total:
frappe.throw(_("Advance amount cannot be greater than {0} {1}") frappe.throw(_("Advance amount cannot be greater than {0} {1}")
.format(self.doc.party_account_currency, invoice_total)) .format(self.doc.party_account_currency, invoice_total))
@ -523,12 +524,12 @@ class calculate_taxes_and_totals(object):
def set_item_wise_tax_breakup(self): def set_item_wise_tax_breakup(self):
self.doc.other_charges_calculation = get_itemised_tax_breakup_html(self.doc) self.doc.other_charges_calculation = get_itemised_tax_breakup_html(self.doc)
def get_itemised_tax_breakup_html(doc): def get_itemised_tax_breakup_html(doc):
if not doc.taxes: if not doc.taxes:
return return
frappe.flags.company = doc.company frappe.flags.company = doc.company
# get headers # get headers
tax_accounts = [] tax_accounts = []
for tax in doc.taxes: for tax in doc.taxes:
@ -538,14 +539,14 @@ def get_itemised_tax_breakup_html(doc):
tax_accounts.append(tax.description) tax_accounts.append(tax.description)
headers = get_itemised_tax_breakup_header(doc.doctype + " Item", tax_accounts) headers = get_itemised_tax_breakup_header(doc.doctype + " Item", tax_accounts)
# get tax breakup data # get tax breakup data
itemised_tax, itemised_taxable_amount = get_itemised_tax_breakup_data(doc) itemised_tax, itemised_taxable_amount = get_itemised_tax_breakup_data(doc)
get_rounded_tax_amount(itemised_tax, doc.precision("tax_amount", "taxes")) get_rounded_tax_amount(itemised_tax, doc.precision("tax_amount", "taxes"))
frappe.flags.company = None frappe.flags.company = None
return frappe.render_template( return frappe.render_template(
"templates/includes/itemised_tax_breakup.html", dict( "templates/includes/itemised_tax_breakup.html", dict(
headers=headers, headers=headers,
@ -578,7 +579,7 @@ def get_itemised_tax(taxes):
if item_tax_map: if item_tax_map:
for item_code, tax_data in item_tax_map.items(): for item_code, tax_data in item_tax_map.items():
itemised_tax.setdefault(item_code, frappe._dict()) itemised_tax.setdefault(item_code, frappe._dict())
if isinstance(tax_data, list): if isinstance(tax_data, list):
itemised_tax[item_code][tax.description] = frappe._dict(dict( itemised_tax[item_code][tax.description] = frappe._dict(dict(
tax_rate=flt(tax_data[0]), tax_rate=flt(tax_data[0]),

View File

@ -92,6 +92,7 @@ erpnext.taxes_and_totals = erpnext.payments.extend({
item.amount = flt(item.rate * item.qty, precision("amount", item)); item.amount = flt(item.rate * item.qty, precision("amount", item));
item.net_amount = item.amount; item.net_amount = item.amount;
item.item_tax_amount = 0.0; item.item_tax_amount = 0.0;
item.total_weight = flt(item.weight_per_unit * item.qty);
me.set_in_company_currency(item, ["price_list_rate", "rate", "amount", "net_rate", "net_amount"]); me.set_in_company_currency(item, ["price_list_rate", "rate", "amount", "net_rate", "net_amount"]);
}); });
@ -199,15 +200,17 @@ erpnext.taxes_and_totals = erpnext.payments.extend({
calculate_net_total: function() { calculate_net_total: function() {
var me = this; var me = this;
this.frm.doc.total = this.frm.doc.base_total = this.frm.doc.net_total = this.frm.doc.base_net_total = 0.0; this.frm.doc.total = this.frm.doc.base_total = this.frm.doc.net_total = this.frm.doc.base_net_total = this.frm.doc.total_net_weight= 0.0;
$.each(this.frm.doc["items"] || [], function(i, item) { $.each(this.frm.doc["items"] || [], function(i, item) {
me.frm.doc.total += item.amount; me.frm.doc.total += item.amount;
me.frm.doc.base_total += item.base_amount; me.frm.doc.base_total += item.base_amount;
me.frm.doc.net_total += item.net_amount; me.frm.doc.net_total += item.net_amount;
me.frm.doc.base_net_total += item.base_net_amount; me.frm.doc.base_net_total += item.base_net_amount;
me.frm.doc.total_net_weight += item.total_weight;
}); });
frappe.model.round_floats_in(this.frm.doc, ["total", "base_total", "net_total", "base_net_total"]); frappe.model.round_floats_in(this.frm.doc, ["total", "base_total", "net_total", "base_net_total"]);
}, },

View File

@ -36,8 +36,11 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
cur_frm.cscript.set_gross_profit(item); cur_frm.cscript.set_gross_profit(item);
cur_frm.cscript.calculate_taxes_and_totals(); cur_frm.cscript.calculate_taxes_and_totals();
}); });
frappe.ui.form.on(this.frm.cscript.tax_table, "rate", function(frm, cdt, cdn) { frappe.ui.form.on(this.frm.cscript.tax_table, "rate", function(frm, cdt, cdn) {
cur_frm.cscript.calculate_taxes_and_totals(); cur_frm.cscript.calculate_taxes_and_totals();
}); });
@ -220,6 +223,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
erpnext.hide_company(); erpnext.hide_company();
this.set_dynamic_labels(); this.set_dynamic_labels();
this.setup_sms(); this.setup_sms();
}, },
apply_default_taxes: function() { apply_default_taxes: function() {
@ -323,6 +327,8 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
qty: item.qty || 1, qty: item.qty || 1,
stock_qty: item.stock_qty, stock_qty: item.stock_qty,
conversion_factor: item.conversion_factor, conversion_factor: item.conversion_factor,
weight_per_unit: item.weight_per_unit,
weight_uom: item.weight_uom,
pos_profile: me.frm.doc.doctype == 'Sales Invoice' ? me.frm.doc.pos_profile : '' pos_profile: me.frm.doc.doctype == 'Sales Invoice' ? me.frm.doc.pos_profile : ''
} }
}, },
@ -673,6 +679,15 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
qty: function(doc, cdt, cdn) { qty: function(doc, cdt, cdn) {
this.conversion_factor(doc, cdt, cdn, true); this.conversion_factor(doc, cdt, cdn, true);
this.apply_pricing_rule(frappe.get_doc(cdt, cdn), true); this.apply_pricing_rule(frappe.get_doc(cdt, cdn), true);
this.calculate_total_weight(doc, cdt, cdn, true);
},
calculate_total_weight: function(doc, cdt, cdn){
if(frappe.meta.get_docfield(cdt, "weight_per_unit", cdn)) {
var item = frappe.get_doc(cdt, cdn);
item.total_weight = flt(item.qty * item.weight_per_unit);
refresh_field("total_weight", item.name, item.parentfield);
}
}, },
set_dynamic_labels: function() { set_dynamic_labels: function() {

View File

@ -1289,6 +1289,36 @@
"set_only_once": 0, "set_only_once": 0,
"unique": 0 "unique": 0
}, },
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "total_net_weight",
"fieldtype": "Float",
"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 Net Weight",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"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,
"unique": 0
},
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
@ -2851,7 +2881,7 @@
"istable": 0, "istable": 0,
"max_attachments": 1, "max_attachments": 1,
"menu_index": 0, "menu_index": 0,
"modified": "2017-11-23 12:39:36.234663", "modified": "2017-11-29 14:10:44.067669",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Selling", "module": "Selling",
"name": "Quotation", "name": "Quotation",

File diff suppressed because it is too large Load Diff

View File

@ -34,7 +34,7 @@ frappe.ui.form.on("Sales Order", {
erpnext.queries.setup_warehouse_query(frm); erpnext.queries.setup_warehouse_query(frm);
}, },
delivery_date: function(frm) { delivery_date: function(frm) {
$.each(frm.doc.items || [], function(i, d) { $.each(frm.doc.items || [], function(i, d) {
if(!d.delivery_date) d.delivery_date = frm.doc.delivery_date; if(!d.delivery_date) d.delivery_date = frm.doc.delivery_date;
@ -52,7 +52,7 @@ frappe.ui.form.on("Sales Order Item", {
if(!frm.doc.delivery_date) { if(!frm.doc.delivery_date) {
erpnext.utils.copy_value_in_all_row(frm.doc, cdt, cdn, "items", "delivery_date"); erpnext.utils.copy_value_in_all_row(frm.doc, cdt, cdn, "items", "delivery_date");
} }
} }
}); });
erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend({ erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend({
@ -278,21 +278,21 @@ erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend(
make_delivery_note_based_on_delivery_date: function() { make_delivery_note_based_on_delivery_date: function() {
var me = this; var me = this;
var delivery_dates = []; var delivery_dates = [];
$.each(this.frm.doc.items || [], function(i, d) { $.each(this.frm.doc.items || [], function(i, d) {
if(!delivery_dates.includes(d.delivery_date)) { if(!delivery_dates.includes(d.delivery_date)) {
delivery_dates.push(d.delivery_date); delivery_dates.push(d.delivery_date);
} }
}); });
var item_grid = this.frm.fields_dict["items"].grid; var item_grid = this.frm.fields_dict["items"].grid;
if(!item_grid.get_selected().length && delivery_dates.length > 1) { if(!item_grid.get_selected().length && delivery_dates.length > 1) {
var dialog = new frappe.ui.Dialog({ var dialog = new frappe.ui.Dialog({
title: __("Select Items based on Delivery Date"), title: __("Select Items based on Delivery Date"),
fields: [{fieldtype: "HTML", fieldname: "dates_html"}] fields: [{fieldtype: "HTML", fieldname: "dates_html"}]
}); });
var html = $(` var html = $(`
<div style="border: 1px solid #d1d8dd"> <div style="border: 1px solid #d1d8dd">
<div class="list-item list-item--head"> <div class="list-item list-item--head">
@ -321,7 +321,7 @@ erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend(
.map((i, el) => $(el).attr('data-date')).toArray(); .map((i, el) => $(el).attr('data-date')).toArray();
if(!dates) return; if(!dates) return;
$.each(dates, function(i, d) { $.each(dates, function(i, d) {
$.each(item_grid.grid_rows || [], function(j, row) { $.each(item_grid.grid_rows || [], function(j, row) {
if(row.doc.delivery_date == d) { if(row.doc.delivery_date == d) {

View File

@ -1371,6 +1371,36 @@
"set_only_once": 0, "set_only_once": 0,
"unique": 0 "unique": 0
}, },
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "total_net_weight",
"fieldtype": "Float",
"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 Net Weight",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"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,
"unique": 0
},
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
@ -3499,7 +3529,7 @@
"issingle": 0, "issingle": 0,
"istable": 0, "istable": 0,
"max_attachments": 0, "max_attachments": 0,
"modified": "2017-11-23 12:39:24.362238", "modified": "2017-11-29 13:43:33.076893",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Selling", "module": "Selling",
"name": "Sales Order", "name": "Sales Order",

File diff suppressed because it is too large Load Diff

View File

@ -1499,6 +1499,36 @@
"set_only_once": 0, "set_only_once": 0,
"unique": 0 "unique": 0
}, },
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "total_net_weight",
"fieldtype": "Float",
"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 Net Weight",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"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,
"unique": 0
},
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
@ -3611,7 +3641,7 @@
"istable": 0, "istable": 0,
"max_attachments": 0, "max_attachments": 0,
"menu_index": 0, "menu_index": 0,
"modified": "2017-11-15 01:03:14.856512", "modified": "2017-11-29 14:13:32.770027",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Stock", "module": "Stock",
"name": "Delivery Note", "name": "Delivery Note",

View File

@ -934,7 +934,7 @@
"columns": 0, "columns": 0,
"depends_on": "is_stock_item", "depends_on": "is_stock_item",
"description": "", "description": "",
"fieldname": "net_weight", "fieldname": "weight_per_unit",
"fieldtype": "Float", "fieldtype": "Float",
"hidden": 0, "hidden": 0,
"ignore_user_permissions": 0, "ignore_user_permissions": 0,
@ -943,7 +943,7 @@
"in_global_search": 0, "in_global_search": 0,
"in_list_view": 0, "in_list_view": 0,
"in_standard_filter": 0, "in_standard_filter": 0,
"label": "Net Weight", "label": "Weight Per Unit",
"length": 0, "length": 0,
"no_copy": 0, "no_copy": 0,
"permlevel": 0, "permlevel": 0,
@ -3360,7 +3360,7 @@
"issingle": 0, "issingle": 0,
"istable": 0, "istable": 0,
"max_attachments": 1, "max_attachments": 1,
"modified": "2017-11-13 15:49:13.213990", "modified": "2017-11-20 12:18:07.259756",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Stock", "module": "Stock",
"name": "Item", "name": "Item",

File diff suppressed because it is too large Load Diff

View File

@ -242,7 +242,9 @@ def get_basic_details(args, item):
"supplier": item.default_supplier, "supplier": item.default_supplier,
"update_stock": args.get("update_stock") if args.get('doctype') in ['Sales Invoice', 'Purchase Invoice'] else 0, "update_stock": args.get("update_stock") if args.get('doctype') in ['Sales Invoice', 'Purchase Invoice'] else 0,
"delivered_by_supplier": item.delivered_by_supplier if args.get("doctype") in ["Sales Order", "Sales Invoice"] else 0, "delivered_by_supplier": item.delivered_by_supplier if args.get("doctype") in ["Sales Order", "Sales Invoice"] else 0,
"is_fixed_asset": item.is_fixed_asset "is_fixed_asset": item.is_fixed_asset,
"weight_per_unit":item.weight_per_unit,
"weight_uom":item.weight_uom,
}) })
# calculate conversion factor # calculate conversion factor