[FIX] point_of_sale,pos_self_order: correct component prices
In this commit, we are changing the way prices of the components of a combo product is calculated. The idea is that a combo product's price should behave similarly as normal products. This results to a simpler logic in calculating the prices of the components. In order to get the fraction that will be used to scale the prices of the component products, the lst_price of the combo product is divided by the total of the pos.combo.base_price. This ratio is then multiplied to each pos.combo.base_price to get the pro-rated unit price of each component. We then proceed to normal calculation of taxes based on the tax configuration of the selected products. Furthermore, we are now taking into account the extra prices from the selected attributes. If the orderline is a component of a combo (menu) product, the extra prices of the attributes are added on top of the prorated unit price, just like we do with the `pos.combo.line`'s `combo_price`. E.g.: ``` product.product.1 -> lst_price = 10 A1 -> price_extra = 5 A3 -> price_extra = 3 pos.order.line.1, product.product.1, attributes=[A1,A3] -> price_unit = 10 + 5 + 3 = 18 ``` One more thing, there is a regression in the combo configurator popup where the total price of the selection is removed. It should be restored in the future with calculation that properly follows the description above. closes odoo/odoo#139915 Signed-off-by: Adrien Guilliams (adgu) <adgu@odoo.com>
This commit is contained in:
@@ -1638,7 +1638,10 @@ class PosSession(models.Model):
|
||||
for key, group in groupby(sorted(product_template_attribute_values, key=key1), key=key2):
|
||||
attribute_line_id, attribute = key
|
||||
values = [{**ptav.product_attribute_value_id.read(['name', 'is_custom', 'html_color', 'image'])[0],
|
||||
'price_extra': ptav.price_extra} for ptav in list(group)]
|
||||
'price_extra': ptav.price_extra,
|
||||
# id of a value should be from the "product.template.attribute.value" record
|
||||
'id': ptav.id,
|
||||
} for ptav in list(group)]
|
||||
res[attribute_line_id] = {
|
||||
'id': attribute_line_id,
|
||||
'name': attribute.name,
|
||||
|
||||
-9
@@ -17,15 +17,6 @@ export class ComboConfiguratorPopup extends AbstractAwaitablePopup {
|
||||
});
|
||||
}
|
||||
|
||||
getTotalPrice() {
|
||||
const selectedComponents = this.getPayload();
|
||||
const extraPrice = selectedComponents.reduce((acc, x) => {
|
||||
const product = this.pos.db.product_by_id[x.product_id[0]];
|
||||
return acc + product.get_display_price({ price: x.combo_price });
|
||||
}, 0);
|
||||
return this.props.product.lst_price + extraPrice;
|
||||
}
|
||||
|
||||
areAllCombosSelected() {
|
||||
return Object.values(this.state.combo).every((x) => Boolean(x));
|
||||
}
|
||||
|
||||
+7
-3
@@ -34,16 +34,20 @@
|
||||
</div>
|
||||
</main>
|
||||
<footer class="footer footer-flex modal-footer">
|
||||
<t t-set="_allSelected" t-value="areAllCombosSelected()" />
|
||||
<button class="button highlight confirm btn btn-lg btn-primary"
|
||||
t-att-disabled="!areAllCombosSelected()"
|
||||
t-att-disabled="!_allSelected"
|
||||
t-on-click="confirm">
|
||||
Add to order
|
||||
</button>
|
||||
<button class="button cancel btn btn-lg btn-secondary" t-on-click="cancel">
|
||||
Discard
|
||||
</button>
|
||||
<div class="ms-auto total-amount">
|
||||
Total <t t-esc="env.utils.formatCurrency(getTotalPrice())"/>
|
||||
<div class="ms-auto">
|
||||
<!-- TODO: Restore the feature the shows the price of the selection. -->
|
||||
<t t-if="!_allSelected">
|
||||
Complete the selection to proceed
|
||||
</t>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
@@ -2027,49 +2027,44 @@ export class Order extends PosModel {
|
||||
}
|
||||
}
|
||||
async addComboLines(comboParent, options) {
|
||||
const originalPrices = {};
|
||||
|
||||
let originalTotal = 0;
|
||||
for (const comboLine of options.comboLines) {
|
||||
const product = this.pos.db.product_by_id[comboLine.product_id[0]];
|
||||
const parentLstPrice = comboParent.product.lst_price;
|
||||
const originalTotal = options.comboLines.reduce((acc, comboLine) => {
|
||||
const originalPrice = this.pos.db.combo_by_id[comboLine.combo_id[0]].base_price;
|
||||
originalTotal += product.get_display_price({ price: originalPrice });
|
||||
return acc + originalPrice;
|
||||
}, 0);
|
||||
|
||||
// Keep track of the original price of each product for the subsequent for loop.
|
||||
originalPrices[product.id] = originalPrice;
|
||||
}
|
||||
let remainingTotal = parentLstPrice;
|
||||
|
||||
const targetPrice = comboParent.product.lst_price;
|
||||
const childPriceFactor = targetPrice / originalTotal;
|
||||
for (const comboLine of options.comboLines) {
|
||||
for (let i = 0; i < options.comboLines.length; i++) {
|
||||
const comboLine = options.comboLines[i];
|
||||
const product = this.pos.db.product_by_id[comboLine.product_id[0]];
|
||||
const childUnitPrice = originalPrices[product.id] * childPriceFactor;
|
||||
const combo = this.pos.db.combo_by_id[comboLine.combo_id[0]];
|
||||
let priceUnit = round_di(
|
||||
(combo.base_price * parentLstPrice) / originalTotal,
|
||||
this.pos.dp["Product Price"]
|
||||
);
|
||||
remainingTotal -= priceUnit;
|
||||
if (i == options.comboLines.length - 1) {
|
||||
priceUnit += remainingTotal;
|
||||
}
|
||||
await this.pos.addProductToCurrentOrder(product, {
|
||||
price: childUnitPrice,
|
||||
price: priceUnit,
|
||||
comboParent,
|
||||
});
|
||||
}
|
||||
|
||||
// Adjust the price of the last combo line to make sure the total price of the combo
|
||||
// is the same as the target price.
|
||||
// Take into account the extra prices.
|
||||
const childLines = this.get_orderlines().filter(
|
||||
(l) => l.comboParent?.uuid === comboParent.uuid
|
||||
);
|
||||
const totalComboPrice = childLines.reduce((acc, l) => acc + l.get_display_price(), 0);
|
||||
const diff = targetPrice - totalComboPrice;
|
||||
if (!this.env.utils.floatIsZero(diff)) {
|
||||
const lastLine = childLines[childLines.length - 1];
|
||||
lastLine.set_unit_price(lastLine.get_unit_price() + diff);
|
||||
}
|
||||
|
||||
// Finally, take into account the combo price for each combo line.
|
||||
for (const comboLine of options.comboLines) {
|
||||
if (this.env.utils.floatIsZero(comboLine.combo_price)) {
|
||||
continue;
|
||||
}
|
||||
const presentLine = childLines.find((l) => l.product.id === comboLine.product_id[0]);
|
||||
if (presentLine) {
|
||||
presentLine.set_unit_price(presentLine.get_unit_price() + comboLine.combo_price);
|
||||
const attributesPriceExtra = (presentLine.attribute_value_ids ?? [])
|
||||
.map((id) => this.pos.db.attribute_value_by_id[id]?.price_extra || 0)
|
||||
.reduce((acc, price) => acc + price, 0);
|
||||
const totalPriceExtra = attributesPriceExtra + comboLine.combo_price;
|
||||
presentLine.set_unit_price(presentLine.get_unit_price() + totalPriceExtra);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,19 +34,14 @@ registry.category("web_tour.tours").add("PosComboPriceTaxIncludedTour", {
|
||||
combo.select("Combo Product 8"),
|
||||
combo.isSelected("Combo Product 8"),
|
||||
combo.isNotSelected("Combo Product 7"),
|
||||
{
|
||||
content: "check that the total amount is properly displayed",
|
||||
trigger: `.combo-configurator-popup .total-amount:contains("59.60")`,
|
||||
isCheck: true,
|
||||
},
|
||||
combo.confirm(),
|
||||
...ProductScreen.selectedOrderlineHas("Office Combo"),
|
||||
...ProductScreen.clickOrderline("Combo Product 3"),
|
||||
...ProductScreen.selectedOrderlineHas("Combo Product 3", "1.0", "12.92"),
|
||||
...ProductScreen.selectedOrderlineHas("Combo Product 3", "1.0", "13.43"),
|
||||
...ProductScreen.clickOrderline("Combo Product 5"),
|
||||
...ProductScreen.selectedOrderlineHas("Combo Product 5", "1.0", "17.87"),
|
||||
...ProductScreen.selectedOrderlineHas("Combo Product 5", "1.0", "18.67"),
|
||||
...ProductScreen.clickOrderline("Combo Product 8"),
|
||||
...ProductScreen.selectedOrderlineHas("Combo Product 8", "1.0", "28.81"),
|
||||
...ProductScreen.selectedOrderlineHas("Combo Product 8", "1.0", "30.00"),
|
||||
|
||||
// check that you cannot change the quantity of a combo product
|
||||
...ProductScreen.pressNumpad("2"),
|
||||
@@ -61,7 +56,7 @@ registry.category("web_tour.tours").add("PosComboPriceTaxIncludedTour", {
|
||||
combo.select("Combo Product 5"),
|
||||
combo.select("Combo Product 8"),
|
||||
combo.confirm(),
|
||||
...ProductScreen.totalAmountIs("59.60"),
|
||||
...ProductScreen.totalAmountIs("62.10"),
|
||||
...ProductScreen.clickPayButton(),
|
||||
...PaymentScreen.clickPaymentMethod("Bank"),
|
||||
...PaymentScreen.clickValidate(),
|
||||
@@ -74,8 +69,8 @@ registry.category("web_tour.tours").add("PosComboPriceTaxIncludedTour", {
|
||||
combo.select("Combo Product 4"),
|
||||
combo.select("Combo Product 6"),
|
||||
combo.confirm(),
|
||||
...ProductScreen.totalAmountIs("50.00"),
|
||||
...inLeftSide(Order.hasTax("8.92")),
|
||||
...ProductScreen.totalAmountIs("59.17"),
|
||||
...inLeftSide(Order.hasTax("10.56")),
|
||||
// the split screen is tested in `pos_restaurant`
|
||||
],
|
||||
});
|
||||
|
||||
@@ -170,7 +170,7 @@ registry.category("web_tour.tours").add("SplitBillScreenTour4PosCombo", {
|
||||
...SplitBillScreen.orderlineHas("Combo Product 4", "1", "0"),
|
||||
...SplitBillScreen.orderlineHas("Combo Product 7", "1", "0"),
|
||||
|
||||
...SplitBillScreen.subtotalIs("52.13"),
|
||||
...SplitBillScreen.subtotalIs("54.13"),
|
||||
...SplitBillScreen.clickPay(),
|
||||
...PaymentScreen.clickPaymentMethod("Bank"),
|
||||
...PaymentScreen.clickValidate(),
|
||||
@@ -181,11 +181,11 @@ registry.category("web_tour.tours").add("SplitBillScreenTour4PosCombo", {
|
||||
...ProductScreen.selectedOrderlineHas("Minute Maid", "1.0"),
|
||||
...ProductScreen.clickOrderline("Office Combo"),
|
||||
...ProductScreen.clickOrderline("Combo Product 2"),
|
||||
...ProductScreen.selectedOrderlineHas("Combo Product 2", "1.0", "6.15", "Office Combo"),
|
||||
...ProductScreen.selectedOrderlineHas("Combo Product 2", "1.0", "6.67", "Office Combo"),
|
||||
...ProductScreen.clickOrderline("Combo Product 4"),
|
||||
...ProductScreen.selectedOrderlineHas("Combo Product 4", "1.0", "13.54", "Office Combo"),
|
||||
...ProductScreen.selectedOrderlineHas("Combo Product 4", "1.0", "14.66", "Office Combo"),
|
||||
...ProductScreen.clickOrderline("Combo Product 7"),
|
||||
...ProductScreen.selectedOrderlineHas("Combo Product 7", "1.0", "20.31", "Office Combo"),
|
||||
...ProductScreen.totalAmountIs("42.53"),
|
||||
...ProductScreen.selectedOrderlineHas("Combo Product 7", "1.0", "22.00", "Office Combo"),
|
||||
...ProductScreen.totalAmountIs("45.86"),
|
||||
],
|
||||
});
|
||||
|
||||
@@ -4,6 +4,7 @@ import uuid
|
||||
from datetime import timedelta
|
||||
from odoo import http, fields
|
||||
from odoo.http import request
|
||||
from odoo.tools import float_round
|
||||
from werkzeug.exceptions import NotFound, BadRequest, Unauthorized
|
||||
|
||||
class PosSelfOrderController(http.Controller):
|
||||
@@ -202,57 +203,57 @@ class PosSelfOrderController(http.Controller):
|
||||
appended_uuid = []
|
||||
newLines = []
|
||||
pricelist = pos_config.pricelist_id
|
||||
if take_away and pos_config.self_ordering_mode == 'kiosk':
|
||||
config_fiscal_pos = pos_config.self_ordering_alternative_fp_id
|
||||
else:
|
||||
config_fiscal_pos = pos_config.default_fiscal_position_id
|
||||
sale_price_digits = pos_config.env['decimal.precision'].precision_get('Product Price')
|
||||
|
||||
combo_line_ids = [line['combo_line_id'] for line in lines if line.get('combo_line_id')]
|
||||
combo_lines = pos_config.env['pos.combo.line'].search([('id', 'in', combo_line_ids)])
|
||||
attribute_value_ids = sum([line.get('attribute_value_ids', []) for line in lines], [])
|
||||
fetched_attributes = pos_config.env['product.template.attribute.value'].search([('id', 'in', attribute_value_ids)])
|
||||
|
||||
fiscal_pos = pos_config.default_fiscal_position_id
|
||||
|
||||
if take_away and pos_config.self_ordering_alternative_fp_id:
|
||||
fiscal_pos = pos_config.self_ordering_alternative_fp_id
|
||||
|
||||
for line in lines:
|
||||
if line.get('uuid') in appended_uuid or not line.get('product_id'):
|
||||
continue
|
||||
|
||||
line_qty = line.get('qty')
|
||||
product = pos_config.env['product.product'].browse(int(line.get('product_id')))
|
||||
# todo take into account the price extra
|
||||
price_unit = pricelist._get_product_price(product, quantity=line.get('qty')) if pricelist else product.lst_price
|
||||
selected_account_tax = config_fiscal_pos.map_tax(product.taxes_id) if config_fiscal_pos else product.taxes_id
|
||||
lst_price = pricelist._get_product_price(product, quantity=line_qty) if pricelist else product.lst_price
|
||||
|
||||
# parent_product_taxe_ids = None
|
||||
children = [l for l in lines if l.get('combo_parent_uuid') == line.get('uuid')]
|
||||
pos_combo_lines = combo_lines.browse([child.get('combo_line_id') for child in children])
|
||||
|
||||
if len(children) > 0:
|
||||
total_price = 0
|
||||
unit_price_by_id = {}
|
||||
for child in children:
|
||||
product = pos_config.env['product.product'].browse(int(child.get('product_id')))
|
||||
child_selected_account_tax = config_fiscal_pos.map_tax(product.taxes_id) if config_fiscal_pos else product.taxes_id
|
||||
tax_results = child_selected_account_tax.compute_all(
|
||||
pricelist._get_product_price(product, quantity=line.get('qty')) if pricelist else product.lst_price,
|
||||
pos_config.currency_id,
|
||||
child.get('qty'),
|
||||
product,
|
||||
)
|
||||
unit_price_by_id[child['uuid']] = pricelist._get_product_price(product, quantity=line.get('qty')) if pricelist else product.lst_price
|
||||
total_price += tax_results.get('total_included') if pos_config.iface_tax_included == 'total' else tax_results.get('total_excluded')
|
||||
ratio = (price_unit * line.get('qty') / total_price)
|
||||
for child in children:
|
||||
child_line_combo = pos_config.env['pos.combo'].browse(int(child.get('combo_id')))
|
||||
child_line_combo_line = child_line_combo.combo_line_ids.filtered(lambda l: l.product_id.id == child.get('product_id'))[0]
|
||||
child_product = pos_config.env["product.product"].browse(int(child.get('product_id')))
|
||||
child_price_unit = ratio * unit_price_by_id[child['uuid']] + child_line_combo_line.combo_price
|
||||
child_selected_account_tax = config_fiscal_pos.map_tax(child_product.taxes_id) if config_fiscal_pos else child_product.taxes_id
|
||||
child_tax_results = child_selected_account_tax.compute_all(
|
||||
child_price_unit,
|
||||
pos_config.currency_id,
|
||||
child.get('qty'),
|
||||
child_product,
|
||||
)
|
||||
original_total = sum(pos_combo_lines.mapped("combo_id.base_price"))
|
||||
remaining_total = lst_price
|
||||
factor = lst_price / original_total
|
||||
|
||||
for i, child in enumerate(children):
|
||||
child_product = pos_config.env['product.product'].browse(int(child.get('product_id')))
|
||||
pos_combo_line = pos_combo_lines.browse(child.get('combo_line_id'))
|
||||
price_unit = float_round(pos_combo_line.combo_id.base_price * factor, precision_digits=sale_price_digits)
|
||||
remaining_total -= price_unit
|
||||
if i == len(children) - 1:
|
||||
price_unit += remaining_total
|
||||
|
||||
selected_attributes = fetched_attributes.browse(child.get('attribute_value_ids', []))
|
||||
price_unit += pos_combo_line.combo_price + sum([attr.price_extra for attr in selected_attributes])
|
||||
|
||||
price_unit_fp = child_product._get_price_unit_after_fp(price_unit, pos_config.currency_id, fiscal_pos)
|
||||
taxes = fiscal_pos.map_tax(child_product.taxes_id) if fiscal_pos else child_product.taxes_id
|
||||
pdetails = taxes.compute_all(price_unit_fp, pos_config.currency_id, line_qty, child_product)
|
||||
|
||||
newLines.append({
|
||||
'price_unit': child_price_unit,
|
||||
'price_subtotal': child_tax_results.get('total_excluded'),
|
||||
'price_subtotal_incl': child_tax_results.get('total_included'),
|
||||
'price_unit': price_unit_fp,
|
||||
'price_subtotal': pdetails.get('total_excluded'),
|
||||
'price_subtotal_incl': pdetails.get('total_included'),
|
||||
'custom_attribute_value_ids': [[0, 0, cAttr] for cAttr in child.get('custom_attribute_value_ids')] if child.get('custom_attribute_value_ids') else [],
|
||||
'id': child.get('id'),
|
||||
'order_id': pos_order_id,
|
||||
'tax_ids': product.taxes_id,
|
||||
'tax_ids': child_product.taxes_id,
|
||||
'uuid': child.get('uuid'),
|
||||
'product_id': child.get('product_id'),
|
||||
'qty': child.get('qty'),
|
||||
@@ -263,25 +264,23 @@ class PosSelfOrderController(http.Controller):
|
||||
'combo_id': child.get('combo_id'),
|
||||
})
|
||||
appended_uuid.append(child.get('uuid'))
|
||||
price_unit = 0
|
||||
|
||||
tax_results = selected_account_tax.compute_all(
|
||||
price_unit,
|
||||
pos_config.currency_id,
|
||||
line.get('qty'),
|
||||
product,
|
||||
)
|
||||
lst_price = 0
|
||||
|
||||
price_unit_fp = product._get_price_unit_after_fp(lst_price, pos_config.currency_id, fiscal_pos)
|
||||
taxes_after_fp = fiscal_pos.map_tax(product.taxes_id) if fiscal_pos else product.taxes_id
|
||||
pdetails = taxes_after_fp.compute_all(price_unit_fp, pos_config.currency_id, line_qty, product)
|
||||
|
||||
newLines.append({
|
||||
'price_unit': price_unit,
|
||||
'price_subtotal': tax_results.get('total_excluded'),
|
||||
'price_subtotal_incl': tax_results.get('total_included'),
|
||||
'price_unit': price_unit_fp,
|
||||
'price_subtotal': pdetails.get('total_excluded'),
|
||||
'price_subtotal_incl': pdetails.get('total_included'),
|
||||
'id': line.get('id'),
|
||||
'order_id': pos_order_id,
|
||||
'tax_ids': product.taxes_id,
|
||||
'uuid': line.get('uuid'),
|
||||
'product_id': line.get('product_id'),
|
||||
'qty': line.get('qty'),
|
||||
'qty': line_qty,
|
||||
'customer_note': line.get('customer_note'),
|
||||
'attribute_value_ids': line.get('attribute_value_ids') or [],
|
||||
'custom_attribute_value_ids': [[0, 0, cAttr] for cAttr in line.get('custom_attribute_value_ids')] if line.get('custom_attribute_value_ids') else [],
|
||||
|
||||
@@ -348,6 +348,7 @@ class PosConfig(models.Model):
|
||||
"custom_links": self._get_self_order_custom_links(),
|
||||
"currency_id": self.currency_id.id,
|
||||
"pos_payment_methods": payment_methods if self.self_ordering_mode == "kiosk" else [],
|
||||
"currency_decimals": self.currency_id.decimal_places,
|
||||
"pos_category": self._get_available_categories().read(["name", "sequence", "has_image"]),
|
||||
"products": self._get_available_products()._get_self_order_data(self),
|
||||
"combos": self._get_combos_data(),
|
||||
|
||||
+19
@@ -4,6 +4,7 @@ import { Component, useState } from "@odoo/owl";
|
||||
import { ProductCustomAttribute } from "@point_of_sale/app/store/models/product_custom_attribute";
|
||||
import { useSelfOrder } from "@pos_self_order/app/self_order_service";
|
||||
import { attributeFlatter, attributeFormatter } from "@pos_self_order/app/utils";
|
||||
import { floatIsZero } from "@web/core/utils/numbers";
|
||||
|
||||
export class AttributeSelection extends Component {
|
||||
static template = "pos_self_order.AttributeSelection";
|
||||
@@ -90,4 +91,22 @@ export class AttributeSelection extends Component {
|
||||
? this.selectedValues[attribute.id][value.id]
|
||||
: parseInt(this.selectedValues[attribute.id]) === value.id;
|
||||
}
|
||||
|
||||
_getPriceExtra(value) {
|
||||
const isTakeAway = this.selfOrder.take_away;
|
||||
const priceExtra = isTakeAway
|
||||
? value.price_extra.display_price_default
|
||||
: value.price_extra.display_price_alternative;
|
||||
return priceExtra;
|
||||
}
|
||||
|
||||
shouldShowPriceExtra(value) {
|
||||
const priceExtra = this._getPriceExtra(value);
|
||||
return !floatIsZero(priceExtra, this.selfOrder.config.currency_decimals);
|
||||
}
|
||||
|
||||
getfPriceExtra(value) {
|
||||
const priceExtra = this._getPriceExtra(value);
|
||||
return this.selfOrder.formatMonetary(priceExtra);
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -14,8 +14,8 @@
|
||||
d-flex align-items-center justify-content-center h-100 rounded border ratio ratio-16x9">
|
||||
<div class="name position-relative d-flex flex-column justify-content-center align-items-center flex-grow-1 w-100 p-4 text-center">
|
||||
<span t-out="value.name"/>
|
||||
<span t-if="value.price_extra.list_price">
|
||||
+ <t t-out="selfOrder.formatMonetary(value.price_extra.list_price)" />
|
||||
<span t-if="shouldShowPriceExtra(value)">
|
||||
+ <t t-out="getfPriceExtra(value)" />
|
||||
</span>
|
||||
</div>
|
||||
</label>
|
||||
|
||||
@@ -14,6 +14,11 @@ export class ComboSelection extends Component {
|
||||
}
|
||||
|
||||
productClicked(lineId) {
|
||||
// Keep track of the current combo line id.
|
||||
// It servers as additional info for each line so that when calculating prices,
|
||||
// no need to look for the specific combo line the product belongs to.
|
||||
this.env.currentComboLineId.value = lineId;
|
||||
|
||||
const comboLine = this.props.combo.combo_line_ids.find((line) => line.id == lineId);
|
||||
const productSelected = this.selfOrder.productByIds[comboLine.product_id[0]];
|
||||
if (!productSelected.self_order_available) {
|
||||
|
||||
@@ -18,6 +18,7 @@ export class Line extends Reactive {
|
||||
custom_attribute_value_ids,
|
||||
combo_parent_uuid,
|
||||
combo_id,
|
||||
combo_line_id,
|
||||
child_lines,
|
||||
}) {
|
||||
super();
|
||||
@@ -39,6 +40,7 @@ export class Line extends Reactive {
|
||||
this.custom_attribute_value_ids = line.custom_attribute_value_ids || [];
|
||||
this.combo_parent_uuid = line.combo_parent_uuid || null;
|
||||
this.combo_id = line.combo_id || null;
|
||||
this.combo_line_id = line.combo_line_id || null;
|
||||
this.child_lines = line.child_lines || [];
|
||||
|
||||
this.initCustomAttribute();
|
||||
|
||||
@@ -17,7 +17,14 @@ export class ComboPage extends Component {
|
||||
this.selfOrder = useSelfOrder();
|
||||
this.selfOrder.lastEditedProductId = this.props.product.id;
|
||||
this.router = useService("router");
|
||||
useSubEnv({ selectedValues: {}, customValues: {}, editable: this.editableProductLine });
|
||||
useSubEnv({
|
||||
selectedValues: {},
|
||||
customValues: {},
|
||||
editable: this.editableProductLine,
|
||||
currentComboLineId: {
|
||||
value: null,
|
||||
},
|
||||
});
|
||||
|
||||
if (!this.props.product) {
|
||||
this.router.navigate("productList");
|
||||
@@ -79,28 +86,21 @@ export class ComboPage extends Component {
|
||||
next() {
|
||||
const combo = this.currentCombo;
|
||||
const index = this.state.selectedCombos.findIndex((c) => c.id === combo.id);
|
||||
const selectedCombo = {
|
||||
id: combo.id,
|
||||
name: combo.name,
|
||||
combo_line_id: this.env.currentComboLineId.value,
|
||||
product: {
|
||||
id: this.state.selectedProduct.id,
|
||||
name: this.state.selectedProduct.name,
|
||||
variants: { ...this.env.selectedValues },
|
||||
customValues: { ...this.env.customValues },
|
||||
},
|
||||
};
|
||||
if (index !== -1) {
|
||||
this.state.selectedCombos[index] = {
|
||||
id: combo.id,
|
||||
name: combo.name,
|
||||
product: {
|
||||
id: this.state.selectedProduct.id,
|
||||
name: this.state.selectedProduct.name,
|
||||
variants: { ...this.env.selectedValues },
|
||||
customValues: { ...this.env.customValues },
|
||||
},
|
||||
};
|
||||
this.state.selectedCombos[index] = selectedCombo;
|
||||
} else {
|
||||
this.state.selectedCombos.push({
|
||||
id: combo.id,
|
||||
name: combo.name,
|
||||
product: {
|
||||
id: this.state.selectedProduct.id,
|
||||
name: this.state.selectedProduct.name,
|
||||
variants: { ...this.env.selectedValues },
|
||||
customValues: { ...this.env.customValues },
|
||||
},
|
||||
});
|
||||
this.state.selectedCombos.push(selectedCombo);
|
||||
}
|
||||
this.resetState();
|
||||
if (this.state.editMode) {
|
||||
@@ -156,6 +156,7 @@ export class ComboPage extends Component {
|
||||
custom_attribute_value_ids: Object.values(combo.product.customValues),
|
||||
combo_parent_uuid: parent_line.uuid,
|
||||
combo_id: combo.id,
|
||||
combo_line_id: combo.combo_line_id,
|
||||
});
|
||||
child_line.full_product_name = constructFullProductName(
|
||||
child_line,
|
||||
|
||||
Reference in New Issue
Block a user