[FIX] point_of_sale: remove "willstart" for a performance issue
Before this commit: if the number of contacts is enormous, and the "Limited Partners Loading" with "Load all remaining partners in the background" is enabled, clicking on the product information button would take lots of time to reload. Also, it would cause the same issue for the "ClosePoSPopup". The problem is that when "willstart" takes time more than the background process it would call it again, and for every call. The solution is to prepare the "willstart" function's data and pass it to the constructor. opw-2956104 closes odoo/odoo#100177 X-original-commit: 940c72d0a058240f75d3f2673a4145e8c1a0921a Signed-off-by: Masereel Pierre <pim@odoo.com>
This commit is contained in:
committed by
Pierre Masereel
parent
1e09eaea73
commit
6da353d66f
@@ -13,7 +13,8 @@ odoo.define('l10n_fr_pos_cert.Chrome', function (require) {
|
||||
let limitDate = new Date(this.env.pos.pos_session.start_at);
|
||||
limitDate.setDate(limitDate.getDate() + 1);
|
||||
if (limitDate < now) {
|
||||
this.showPopup('ClosePosPopup');
|
||||
const info = await this.env.pos.getClosePosInfo();
|
||||
this.showPopup('ClosePosPopup', { info: info });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,8 +7,9 @@ odoo.define('point_of_sale.HeaderButton', function(require) {
|
||||
// Previously HeaderButtonWidget
|
||||
// This is the close session button
|
||||
class HeaderButton extends PosComponent {
|
||||
onClick() {
|
||||
this.showPopup('ClosePosPopup', { keepBehind: true });
|
||||
async onClick() {
|
||||
const info = await this.env.pos.getClosePosInfo();
|
||||
this.showPopup('ClosePosPopup', { info: info, keepBehind: true });
|
||||
}
|
||||
}
|
||||
HeaderButton.template = 'HeaderButton';
|
||||
|
||||
@@ -6,7 +6,7 @@ odoo.define('point_of_sale.ClosePosPopup', function(require) {
|
||||
const { identifyError } = require('point_of_sale.utils');
|
||||
const { ConnectionLostError, ConnectionAbortedError} = require('@web/core/network/rpc_service')
|
||||
|
||||
const { onWillStart, useState } = owl;
|
||||
const { useState } = owl;
|
||||
|
||||
/**
|
||||
* This popup needs to be self-dependent because it needs to be called from different place.
|
||||
@@ -21,48 +21,7 @@ odoo.define('point_of_sale.ClosePosPopup', function(require) {
|
||||
this.state = useState({
|
||||
displayMoneyDetailsPopup: false,
|
||||
});
|
||||
onWillStart(this.onWillStart);
|
||||
}
|
||||
async onWillStart() {
|
||||
try {
|
||||
const closingData = await this.rpc({
|
||||
model: 'pos.session',
|
||||
method: 'get_closing_control_data',
|
||||
args: [[this.env.pos.pos_session.id]]
|
||||
});
|
||||
this.ordersDetails = closingData.orders_details;
|
||||
this.paymentsAmount = closingData.payments_amount;
|
||||
this.payLaterAmount = closingData.pay_later_amount;
|
||||
this.openingNotes = closingData.opening_notes;
|
||||
this.defaultCashDetails = closingData.default_cash_details;
|
||||
this.otherPaymentMethods = closingData.other_payment_methods;
|
||||
this.isManager = closingData.is_manager;
|
||||
this.amountAuthorizedDiff = closingData.amount_authorized_diff;
|
||||
|
||||
// component state and refs definition
|
||||
const state = {notes: '', payments: {}};
|
||||
if (this.cashControl) {
|
||||
state.payments[this.defaultCashDetails.id] = {counted: 0, difference: -this.defaultCashDetails.amount, number: 0};
|
||||
}
|
||||
if (this.otherPaymentMethods.length > 0) {
|
||||
this.otherPaymentMethods.forEach(pm => {
|
||||
if (pm.type === 'bank') {
|
||||
state.payments[pm.id] = {counted: this.env.pos.round_decimals_currency(pm.amount), difference: 0, number: pm.number}
|
||||
}
|
||||
})
|
||||
}
|
||||
Object.assign(this.state, state);
|
||||
} catch (error) {
|
||||
super.cancel();
|
||||
if (identifyError(error) instanceof ConnectionLostError) {
|
||||
this.showPopup('ErrorPopup', {
|
||||
title: this.env._t('Network Error'),
|
||||
body: this.env._t('Please check your internet connection and try again.'),
|
||||
});
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
Object.assign(this, this.props.info);
|
||||
}
|
||||
//@override
|
||||
async confirm() {
|
||||
|
||||
@@ -3,8 +3,6 @@ odoo.define('point_of_sale.ProductInfoPopup', function(require) {
|
||||
|
||||
const AbstractAwaitablePopup = require('point_of_sale.AbstractAwaitablePopup');
|
||||
const Registries = require('point_of_sale.Registries');
|
||||
const { identifyError } = require('point_of_sale.utils');
|
||||
const { ConnectionLostError } = require('@web/core/network/rpc_service')
|
||||
|
||||
/**
|
||||
* This popup needs to be self-dependent because it needs to be called from different place. In order to avoid code
|
||||
@@ -17,47 +15,7 @@ odoo.define('point_of_sale.ProductInfoPopup', function(require) {
|
||||
class ProductInfoPopup extends AbstractAwaitablePopup {
|
||||
setup() {
|
||||
super.setup();
|
||||
owl.onWillStart(this.onWillStart);
|
||||
}
|
||||
async onWillStart() {
|
||||
const order = this.env.pos.get_order();
|
||||
try {
|
||||
// check back-end method `get_product_info_pos` to see what it returns
|
||||
// We do this so it's easier to override the value returned and use it in the component template later
|
||||
this.productInfo = await this.rpc({
|
||||
model: 'product.product',
|
||||
method: 'get_product_info_pos',
|
||||
args: [[this.props.product.id],
|
||||
this.props.product.get_price(order.pricelist, this.props.quantity),
|
||||
this.props.quantity,
|
||||
this.env.pos.config.id],
|
||||
kwargs: {context: this.env.session.user_context},
|
||||
});
|
||||
|
||||
const priceWithoutTax = this.productInfo['all_prices']['price_without_tax'];
|
||||
const margin = priceWithoutTax - this.props.product.standard_price;
|
||||
const orderPriceWithoutTax = order.get_total_without_tax();
|
||||
const orderCost = order.get_total_cost();
|
||||
const orderMargin = orderPriceWithoutTax - orderCost;
|
||||
|
||||
this.costCurrency = this.env.pos.format_currency(this.props.product.standard_price);
|
||||
this.marginCurrency = this.env.pos.format_currency(margin);
|
||||
this.marginPercent = priceWithoutTax ? Math.round(margin/priceWithoutTax * 10000) / 100 : 0;
|
||||
this.orderPriceWithoutTaxCurrency = this.env.pos.format_currency(orderPriceWithoutTax);
|
||||
this.orderCostCurrency = this.env.pos.format_currency(orderCost);
|
||||
this.orderMarginCurrency = this.env.pos.format_currency(orderMargin);
|
||||
this.orderMarginPercent = orderPriceWithoutTax ? Math.round(orderMargin/orderPriceWithoutTax * 10000) / 100 : 0;
|
||||
} catch (error) {
|
||||
this.cancel();
|
||||
if (identifyError(error) instanceof ConnectionLostError) {
|
||||
this.showPopup('ErrorPopup', {
|
||||
title: this.env._t('Network Error'),
|
||||
body: this.env._t('Cannot access product information screen if offline.'),
|
||||
});
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
Object.assign(this, this.props.info);
|
||||
}
|
||||
searchProduct(productName) {
|
||||
this.env.posbus.trigger('search-product-from-info-popup', productName);
|
||||
|
||||
+3
-2
@@ -11,12 +11,13 @@ odoo.define('point_of_sale.ProductInfoButton', function(require) {
|
||||
super.setup();
|
||||
useListener('click', this.onClick);
|
||||
}
|
||||
onClick() {
|
||||
async onClick() {
|
||||
const orderline = this.env.pos.get_order().get_selected_orderline();
|
||||
if (orderline) {
|
||||
const product = orderline.get_product();
|
||||
const quantity = orderline.get_quantity();
|
||||
this.showPopup('ProductInfoPopup', { product, quantity });
|
||||
const info = await this.env.pos.getProductInfo(product, quantity);
|
||||
this.showPopup('ProductInfoPopup', { info: info , product: product });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,8 +40,9 @@ odoo.define('point_of_sale.ProductItem', function(require) {
|
||||
return formattedUnitPrice;
|
||||
}
|
||||
}
|
||||
onProductInfoClick() {
|
||||
this.showPopup('ProductInfoPopup', { product: this.props.product, quantity: 1 });
|
||||
async onProductInfoClick() {
|
||||
const info = await this.env.pos.getProductInfo(this.props.product, 1);
|
||||
this.showPopup('ProductInfoPopup', { info: info , product: this.props.product });
|
||||
}
|
||||
}
|
||||
ProductItem.template = 'ProductItem';
|
||||
|
||||
@@ -545,6 +545,79 @@ class PosGlobalState extends PosModel {
|
||||
i += 1;
|
||||
} while(partners.length);
|
||||
}
|
||||
async getProductInfo(product, quantity) {
|
||||
const order = this.get_order();
|
||||
try {
|
||||
// check back-end method `get_product_info_pos` to see what it returns
|
||||
// We do this so it's easier to override the value returned and use it in the component template later
|
||||
const productInfo = await this.env.services.rpc({
|
||||
model: 'product.product',
|
||||
method: 'get_product_info_pos',
|
||||
args: [[product.id],
|
||||
product.get_price(order.pricelist, quantity),
|
||||
quantity,
|
||||
this.config.id],
|
||||
kwargs: {context: this.env.session.user_context},
|
||||
});
|
||||
|
||||
const priceWithoutTax = productInfo['all_prices']['price_without_tax'];
|
||||
const margin = priceWithoutTax - product.standard_price;
|
||||
const orderPriceWithoutTax = order.get_total_without_tax();
|
||||
const orderCost = order.get_total_cost();
|
||||
const orderMargin = orderPriceWithoutTax - orderCost;
|
||||
|
||||
const costCurrency = this.format_currency(product.standard_price);
|
||||
const marginCurrency = this.format_currency(margin);
|
||||
const marginPercent = priceWithoutTax ? Math.round(margin/priceWithoutTax * 10000) / 100 : 0;
|
||||
const orderPriceWithoutTaxCurrency = this.format_currency(orderPriceWithoutTax);
|
||||
const orderCostCurrency = this.format_currency(orderCost);
|
||||
const orderMarginCurrency = this.format_currency(orderMargin);
|
||||
const orderMarginPercent = orderPriceWithoutTax ? Math.round(orderMargin/orderPriceWithoutTax * 10000) / 100 : 0;
|
||||
return {
|
||||
costCurrency, marginCurrency, marginPercent, orderPriceWithoutTaxCurrency,
|
||||
orderCostCurrency, orderMarginCurrency, orderMarginPercent,productInfo
|
||||
}
|
||||
} catch (error) {
|
||||
return { error }
|
||||
}
|
||||
}
|
||||
async getClosePosInfo() {
|
||||
try {
|
||||
const closingData = await this.env.services.rpc({
|
||||
model: 'pos.session',
|
||||
method: 'get_closing_control_data',
|
||||
args: [[this.pos_session.id]]
|
||||
});
|
||||
const ordersDetails = closingData.orders_details;
|
||||
const paymentsAmount = closingData.payments_amount;
|
||||
const payLaterAmount = closingData.pay_later_amount;
|
||||
const openingNotes = closingData.opening_notes;
|
||||
const defaultCashDetails = closingData.default_cash_details;
|
||||
const otherPaymentMethods = closingData.other_payment_methods;
|
||||
const isManager = closingData.is_manager;
|
||||
const amountAuthorizedDiff = closingData.amount_authorized_diff;
|
||||
const cashControl = this.config.cash_control;
|
||||
|
||||
// component state and refs definition
|
||||
const state = {notes: '', payments: {}};
|
||||
if (cashControl) {
|
||||
state.payments[defaultCashDetails.id] = {counted: 0, difference: -defaultCashDetails.amount, number: 0};
|
||||
}
|
||||
if (otherPaymentMethods.length > 0) {
|
||||
otherPaymentMethods.forEach(pm => {
|
||||
if (pm.type === 'bank') {
|
||||
state.payments[pm.id] = {counted: this.round_decimals_currency(pm.amount), difference: 0, number: pm.number}
|
||||
}
|
||||
})
|
||||
}
|
||||
return {
|
||||
ordersDetails, paymentsAmount, payLaterAmount, openingNotes, defaultCashDetails, otherPaymentMethods,
|
||||
isManager, amountAuthorizedDiff, state, cashControl
|
||||
}
|
||||
} catch (error) {
|
||||
return { error }
|
||||
}
|
||||
}
|
||||
set_start_order(){
|
||||
if (this.orders.length && !this.selectedOrder) {
|
||||
this.selectedOrder = this.orders[0]
|
||||
|
||||
@@ -21,7 +21,9 @@ odoo.define('pos_sale_product_configurator.models', function (require) {
|
||||
}
|
||||
);
|
||||
if (isProductLoaded) {
|
||||
Gui.showPopup('ProductInfoPopup', {product, quantity: this.get_selected_orderline().get_quantity()});
|
||||
const quantity = this.get_selected_orderline().get_quantity();
|
||||
const info = await this.env.pos.getProductInfo(product, quantity);
|
||||
Gui.showPopup('ProductInfoPopup', {info: info , product: product});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user