mirror of
https://github.com/frappe/erpnext.git
synced 2026-03-18 06:22:12 +00:00
Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com> fix(Quotation): calculate row values for alternative items (#43054)
This commit is contained in:
@@ -40,7 +40,7 @@ class calculate_taxes_and_totals:
|
|||||||
return items
|
return items
|
||||||
|
|
||||||
def calculate(self):
|
def calculate(self):
|
||||||
if not len(self._items):
|
if not len(self.doc.items):
|
||||||
return
|
return
|
||||||
|
|
||||||
self.discount_amount_applied = False
|
self.discount_amount_applied = False
|
||||||
@@ -95,7 +95,7 @@ class calculate_taxes_and_totals:
|
|||||||
if self.doc.get("is_return") and self.doc.get("return_against"):
|
if self.doc.get("is_return") and self.doc.get("return_against"):
|
||||||
return
|
return
|
||||||
|
|
||||||
for item in self._items:
|
for item in self.doc.items:
|
||||||
if item.item_code and item.get("item_tax_template"):
|
if item.item_code and item.get("item_tax_template"):
|
||||||
item_doc = frappe.get_cached_doc("Item", item.item_code)
|
item_doc = frappe.get_cached_doc("Item", item.item_code)
|
||||||
args = {
|
args = {
|
||||||
@@ -154,7 +154,7 @@ class calculate_taxes_and_totals:
|
|||||||
return
|
return
|
||||||
|
|
||||||
if not self.discount_amount_applied:
|
if not self.discount_amount_applied:
|
||||||
for item in self._items:
|
for item in self.doc.items:
|
||||||
self.doc.round_floats_in(item)
|
self.doc.round_floats_in(item)
|
||||||
|
|
||||||
if item.discount_percentage == 100:
|
if item.discount_percentage == 100:
|
||||||
@@ -258,7 +258,7 @@ class calculate_taxes_and_totals:
|
|||||||
if not any(cint(tax.included_in_print_rate) for tax in self.doc.get("taxes")):
|
if not any(cint(tax.included_in_print_rate) for tax in self.doc.get("taxes")):
|
||||||
return
|
return
|
||||||
|
|
||||||
for item in self._items:
|
for item in self.doc.items:
|
||||||
item_tax_map = self._load_item_tax_rate(item.item_tax_rate)
|
item_tax_map = self._load_item_tax_rate(item.item_tax_rate)
|
||||||
cumulated_tax_fraction = 0
|
cumulated_tax_fraction = 0
|
||||||
total_inclusive_tax_amount_per_qty = 0
|
total_inclusive_tax_amount_per_qty = 0
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ erpnext.taxes_and_totals = class TaxesAndTotals extends erpnext.payments {
|
|||||||
calculate_item_values() {
|
calculate_item_values() {
|
||||||
var me = this;
|
var me = this;
|
||||||
if (!this.discount_amount_applied) {
|
if (!this.discount_amount_applied) {
|
||||||
for (const item of this.frm._items || []) {
|
for (const item of this.frm.doc.items || []) {
|
||||||
frappe.model.round_floats_in(item);
|
frappe.model.round_floats_in(item);
|
||||||
item.net_rate = item.rate;
|
item.net_rate = item.rate;
|
||||||
item.qty = item.qty === undefined ? (me.frm.doc.is_return ? -1 : 1) : item.qty;
|
item.qty = item.qty === undefined ? (me.frm.doc.is_return ? -1 : 1) : item.qty;
|
||||||
@@ -227,7 +227,7 @@ erpnext.taxes_and_totals = class TaxesAndTotals extends erpnext.payments {
|
|||||||
});
|
});
|
||||||
if(has_inclusive_tax==false) return;
|
if(has_inclusive_tax==false) return;
|
||||||
|
|
||||||
$.each(me.frm._items || [], function(n, item) {
|
$.each(this.frm.doc.items || [], function(n, item) {
|
||||||
var item_tax_map = me._load_item_tax_rate(item.item_tax_rate);
|
var item_tax_map = me._load_item_tax_rate(item.item_tax_rate);
|
||||||
var cumulated_tax_fraction = 0.0;
|
var cumulated_tax_fraction = 0.0;
|
||||||
var total_inclusive_tax_amount_per_qty = 0;
|
var total_inclusive_tax_amount_per_qty = 0;
|
||||||
@@ -630,7 +630,7 @@ erpnext.taxes_and_totals = class TaxesAndTotals extends erpnext.payments {
|
|||||||
|
|
||||||
_cleanup() {
|
_cleanup() {
|
||||||
this.frm.doc.base_in_words = this.frm.doc.in_words = "";
|
this.frm.doc.base_in_words = this.frm.doc.in_words = "";
|
||||||
let items = this.frm._items;
|
let items = this.frm.doc.items;
|
||||||
|
|
||||||
if(items && items.length) {
|
if(items && items.length) {
|
||||||
if(!frappe.meta.get_docfield(items[0].doctype, "item_tax_amount", this.frm.doctype)) {
|
if(!frappe.meta.get_docfield(items[0].doctype, "item_tax_amount", this.frm.doctype)) {
|
||||||
|
|||||||
@@ -561,12 +561,50 @@ class TestQuotation(FrappeTestCase):
|
|||||||
"description": "VAT",
|
"description": "VAT",
|
||||||
"doctype": "Sales Taxes and Charges",
|
"doctype": "Sales Taxes and Charges",
|
||||||
"rate": 10,
|
"rate": 10,
|
||||||
|
"included_in_print_rate": 1,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
quotation.submit()
|
quotation.submit()
|
||||||
|
|
||||||
self.assertEqual(quotation.net_total, 290)
|
self.assertEqual(round(quotation.items[1].net_rate, 2), 136.36)
|
||||||
self.assertEqual(quotation.grand_total, 319)
|
self.assertEqual(round(quotation.items[1].amount, 2), 150)
|
||||||
|
|
||||||
|
self.assertEqual(round(quotation.items[2].net_rate, 2), 163.64)
|
||||||
|
self.assertEqual(round(quotation.items[2].amount, 2), 180)
|
||||||
|
|
||||||
|
self.assertEqual(round(quotation.net_total, 2), 263.64)
|
||||||
|
self.assertEqual(round(quotation.total_taxes_and_charges, 2), 26.36)
|
||||||
|
self.assertEqual(quotation.grand_total, 290)
|
||||||
|
|
||||||
|
def test_amount_calculation_for_alternative_items(self):
|
||||||
|
"""Make sure that the amount is calculated correctly for alternative items when the qty is changed."""
|
||||||
|
from erpnext.stock.doctype.item.test_item import make_item
|
||||||
|
|
||||||
|
item_list = []
|
||||||
|
stock_items = {
|
||||||
|
"_Test Simple Item 1": 100,
|
||||||
|
"_Test Alt 1": 120,
|
||||||
|
}
|
||||||
|
|
||||||
|
for item, rate in stock_items.items():
|
||||||
|
make_item(item, {"is_stock_item": 0})
|
||||||
|
item_list.append(
|
||||||
|
{
|
||||||
|
"item_code": item,
|
||||||
|
"qty": 1,
|
||||||
|
"rate": rate,
|
||||||
|
"is_alternative": "Alt" in item,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
quotation = make_quotation(item_list=item_list, do_not_submit=1)
|
||||||
|
|
||||||
|
self.assertEqual(quotation.items[1].amount, 120)
|
||||||
|
|
||||||
|
quotation.items[1].qty = 2
|
||||||
|
quotation.save()
|
||||||
|
|
||||||
|
self.assertEqual(quotation.items[1].amount, 240)
|
||||||
|
|
||||||
def test_alternative_items_sales_order_mapping_with_stock_items(self):
|
def test_alternative_items_sales_order_mapping_with_stock_items(self):
|
||||||
from erpnext.selling.doctype.quotation.quotation import make_sales_order
|
from erpnext.selling.doctype.quotation.quotation import make_sales_order
|
||||||
|
|||||||
Reference in New Issue
Block a user