[IMP] point_of_sale, pos_*: overall improvements and fixes
List of improvements: - Add `Is a Kiosk` field when creating a new POS config - Add category and change the image of the combo demo product - Hide useless settings when kiosk mode is enabled List of fixes: - Fix bootstrap carousel traceback when no image is set - Changed the warning sentence concerning adyen payments - Fix start category in kiosk - Fix sync between Self Order mobile and PoS restaurant, now new Lines from restaurant are added to the mobile order - Fix product reminder when adding something in PoS mobile closes odoo/odoo#134508 Signed-off-by: Robin Heinz (rhe) <rhe@odoo.com>
This commit is contained in:
@@ -467,8 +467,9 @@
|
||||
<field name="pos_categ_ids" eval="[(6, 0, [ref('pos_category_desks')])]"/>
|
||||
<field name="uom_id" ref="uom.product_uom_unit"/>
|
||||
<field name="uom_po_id" ref="uom.product_uom_unit"/>
|
||||
<field name="image_1920" type="base64" file="point_of_sale/static/img/office_combo.png"/>
|
||||
<field name="image_1920" type="base64" file="point_of_sale/static/img/office_combo.jpg"/>
|
||||
<field name="combo_ids" eval="[(6, 0, [ref('desks_combo'), ref('chairs_combo'), ref('desk_accessories_combo')])]"/>
|
||||
<field name="pos_categ_ids" eval="[(6, 0, [ref('pos_category_miscellaneous')])]"/>
|
||||
<field name="taxes_id" eval="[(5,)]"/> <!-- no taxes -->
|
||||
</record>
|
||||
|
||||
|
||||
@@ -888,7 +888,7 @@
|
||||
<record id="chairs_combo" model="pos.combo">
|
||||
<field name="name">Chairs Combo</field>
|
||||
<field name="combo_line_ids" eval="[(6, 0, [ref('product_11_combo_line'), ref('product_11b_combo_line'), ref('product_12_combo_line')])]"/>
|
||||
</record>
|
||||
</record>
|
||||
|
||||
<record id="office_combo" model="product.product">
|
||||
<field name="available_in_pos">True</field>
|
||||
@@ -898,7 +898,7 @@
|
||||
<field name="categ_id" ref="product.product_category_1"/>
|
||||
<field name="uom_id" ref="uom.product_uom_unit"/>
|
||||
<field name="uom_po_id" ref="uom.product_uom_unit"/>
|
||||
<field name="image_1920" type="base64" file="point_of_sale/static/img/office_combo.png"/>
|
||||
<field name="image_1920" type="base64" file="point_of_sale/static/img/office_combo.jpg"/>
|
||||
<field name="combo_ids" eval="[(6, 0, [ref('desks_combo'), ref('chairs_combo'), ref('desk_accessories_combo')])]"/>
|
||||
<field name="taxes_id" eval="[(5,)]"/> <!-- no taxes -->
|
||||
<field name="pos_categ_ids" eval="[(6, 0, [ref('pos_category_miscellaneous')])]"/>
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 68 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 6.3 KiB |
@@ -363,6 +363,7 @@ export class ProductScreen extends ControlButtonsMixin(Component) {
|
||||
*/
|
||||
get animationKey() {
|
||||
return [
|
||||
this.currentOrder.get_selected_orderline()?.uuid,
|
||||
this.selectedOrderlineQuantity,
|
||||
this.selectedOrderlineDisplayName,
|
||||
this.selectedOrderlineTotal,
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
</div>
|
||||
|
||||
<!-- SHOW this div in create_mode (when '+ New Shop' is clicked in the general settings.) -->
|
||||
<div class="row mt16 o_settings_container" invisible="not context.get('pos_config_create_mode', False)">
|
||||
<div id="restaurant_on_create" class="row mt16 o_settings_container" invisible="not context.get('pos_config_create_mode', False)">
|
||||
<setting>
|
||||
<field name="module_pos_restaurant" />
|
||||
</setting>
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
<setting string="Automatically validate order" help="Automatically validates orders paid with a payment terminal.">
|
||||
<field name="pos_auto_validate_terminal_payment"/>
|
||||
</setting>
|
||||
<setting string="Cash Rounding" documentation="/applications/sales/point_of_sale/pricing/cash_rounding.html" help="Define the smallest coinage of the currency used to pay by cash">
|
||||
<setting string="Cash Rounding" invisible="is_kiosk_mode" documentation="/applications/sales/point_of_sale/pricing/cash_rounding.html" help="Define the smallest coinage of the currency used to pay by cash">
|
||||
<field name="pos_cash_rounding"/>
|
||||
<div class="content-group mt16" invisible="not pos_cash_rounding">
|
||||
<div class="row mt16">
|
||||
@@ -128,13 +128,13 @@
|
||||
<button name="%(product_pos_category_action)d" icon="oi-arrow-right" type="action" string="PoS Product Categories" class="btn-link"/>
|
||||
</div>
|
||||
</setting>
|
||||
<setting help="Improve navigation for imprecise industrial touchscreens">
|
||||
<setting invisible="is_kiosk_mode" help="Improve navigation for imprecise industrial touchscreens">
|
||||
<field name="pos_iface_big_scrollbars"/>
|
||||
</setting>
|
||||
<setting id="margin_and_cost" string="Margins & Costs" help="Show margins & costs on product information">
|
||||
<field name="pos_is_margins_costs_accessible_to_every_user"/>
|
||||
</setting>
|
||||
<setting string="Share Open Orders" help="Allow to access each other's active orders" id="is_order_shared" invisible="pos_module_pos_restaurant">
|
||||
<setting string="Share Open Orders" help="Allow to access each other's active orders" id="is_order_shared" invisible="pos_module_pos_restaurant or is_kiosk_mode">
|
||||
<div class="content-group">
|
||||
<div class="row mt16">
|
||||
<label string="Trusted POS" for="pos_trusted_config_ids" class="col-lg-3 o_light_label" />
|
||||
|
||||
@@ -50,7 +50,7 @@ class PosSelfOrderController(http.Controller):
|
||||
}
|
||||
|
||||
# Save the order in the database to get the id
|
||||
posted_order_id = pos_config.env['pos.order'].create_from_ui([order], draft=True)[0].get('id')
|
||||
posted_order_id = pos_config.env['pos.order'].with_context(from_self=True).create_from_ui([order], draft=True)[0].get('id')
|
||||
|
||||
# Process the lines and get their prices computed
|
||||
lines = self._process_lines(lines, pos_config, posted_order_id, order.get('take_away'))
|
||||
@@ -199,8 +199,9 @@ class PosSelfOrderController(http.Controller):
|
||||
config_fiscal_pos = pos_config.default_fiscal_position_id
|
||||
|
||||
for line in lines:
|
||||
if line.get('uuid') in appended_uuid:
|
||||
if line.get('uuid') in appended_uuid or not line.get('product_id'):
|
||||
continue
|
||||
|
||||
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
|
||||
|
||||
@@ -36,7 +36,7 @@ class PosConfig(models.Model):
|
||||
)
|
||||
self_order_kiosk_url = fields.Char(compute="_compute_self_order_kiosk_url")
|
||||
self_order_kiosk = fields.Boolean(
|
||||
string="Kiosk",
|
||||
string="Is a Kiosk",
|
||||
help="Enable the kiosk mode for the Point of Sale",
|
||||
)
|
||||
self_order_kiosk_takeaway = fields.Boolean(
|
||||
|
||||
@@ -54,7 +54,10 @@ class PosOrder(models.Model):
|
||||
def create_from_ui(self, orders, draft=False):
|
||||
orders = super().create_from_ui(orders, draft)
|
||||
order_ids = self.env['pos.order'].browse([order['id'] for order in orders])
|
||||
self._send_notification(order_ids)
|
||||
|
||||
if self.env.context.get('from_self') is not True:
|
||||
self._send_notification(order_ids)
|
||||
|
||||
return orders
|
||||
|
||||
@api.model
|
||||
@@ -80,6 +83,10 @@ class PosOrder(models.Model):
|
||||
'access_token': order.access_token,
|
||||
'state': order.state
|
||||
})
|
||||
else:
|
||||
self.env['bus.bus']._sendone(f'self_order-{order.access_token}', 'ORDER_CHANGED', {
|
||||
'order': order._export_for_self_order()
|
||||
})
|
||||
|
||||
def _export_for_self_order(self) -> Dict:
|
||||
self.ensure_one()
|
||||
|
||||
@@ -103,12 +103,24 @@ export class Order extends Reactive {
|
||||
}
|
||||
}
|
||||
|
||||
const foundLines = [];
|
||||
for (const lines of this.lines) {
|
||||
const lineFound = data.lines.find((line) => line.uuid === lines.uuid);
|
||||
|
||||
if (lineFound) {
|
||||
lines.updateDataFromServer(lineFound);
|
||||
foundLines.push(lines);
|
||||
}
|
||||
}
|
||||
|
||||
for (const lines of data.lines) {
|
||||
const lineFound = foundLines.find((line) => line.uuid === lines.uuid);
|
||||
|
||||
if (!lineFound) {
|
||||
foundLines.push(new Line(lines));
|
||||
}
|
||||
}
|
||||
|
||||
this.lines = foundLines;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,12 +29,15 @@ export class LandingPage extends Component {
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
// used to init carousel after components mount / unmount
|
||||
const carousel = new Carousel(this.carouselRef.el);
|
||||
if (this.selfOrder.kiosk_image_home.length > 1) {
|
||||
// used to init carousel after components mount / unmount
|
||||
const carousel = new Carousel(this.carouselRef.el);
|
||||
|
||||
this.carouselInterval = setInterval(() => {
|
||||
carousel.next();
|
||||
}, 5000);
|
||||
// prevent traceback when no image is set
|
||||
this.carouselInterval = setInterval(() => {
|
||||
carousel.next();
|
||||
}, 5000);
|
||||
}
|
||||
});
|
||||
|
||||
onWillUnmount(() => {
|
||||
|
||||
@@ -31,8 +31,7 @@ export class selfOrder extends selfOrderCommon {
|
||||
}
|
||||
|
||||
this.cookie.setCookie("frontend_lang", this.currentLanguage.code);
|
||||
|
||||
this.currentCategory = this.pos_category.length > 0 ? this.pos_category[0].name : null;
|
||||
this.currentCategory = this.pos_category.length > 0 ? [...this.categoryList][0].name : null;
|
||||
// required information to send an order
|
||||
this.paymentError = false;
|
||||
this.tablePadNumber = null;
|
||||
|
||||
@@ -37,12 +37,18 @@ export class SelfOrderBus {
|
||||
dispatch(message) {
|
||||
if (message.type === "ORDER_STATE_CHANGED") {
|
||||
this.ws_changeOrderState(message.payload.access_token, message.payload.state);
|
||||
} else if (message.type === "ORDER_CHANGED") {
|
||||
this.ws_syncOrder(message.payload.order);
|
||||
}
|
||||
}
|
||||
|
||||
ws_changeOrderState(access_token, state) {
|
||||
this.selfOrder.changeOrderState(access_token, state);
|
||||
}
|
||||
|
||||
ws_syncOrder(order, state) {
|
||||
this.selfOrder.updateOrdersFromServer([order], [order.access_token]);
|
||||
}
|
||||
}
|
||||
|
||||
export const SelfOrderBusService = {
|
||||
|
||||
@@ -155,13 +155,15 @@ export class SelfOrder extends selfOrderCommon {
|
||||
}
|
||||
}
|
||||
|
||||
updateOrdersFromServer(orders, localAccessToken) {
|
||||
updateOrdersFromServer(ordersFromServer, localAccessToken) {
|
||||
//FIXME, if the user refresh the page with not sent, we will lost this data.
|
||||
const accessTokensFromServer = orders.map((order) => order.access_token);
|
||||
const accessTokensFromServer = ordersFromServer.map((order) => order.access_token);
|
||||
|
||||
for (const order of this.orders) {
|
||||
if (order.access_token) {
|
||||
const orderFromServer = orders.find((o) => o.access_token === order.access_token);
|
||||
const orderFromServer = ordersFromServer.find(
|
||||
(o) => o.access_token === order.access_token
|
||||
);
|
||||
if (orderFromServer) {
|
||||
order.updateDataFromServer(orderFromServer);
|
||||
}
|
||||
|
||||
@@ -10,4 +10,17 @@
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="pos_self_config_view_form" model="ir.ui.view">
|
||||
<field name="name">pos.config.form.view</field>
|
||||
<field name="model">pos.config</field>
|
||||
<field name="inherit_id" ref="point_of_sale.pos_config_view_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[@id='restaurant_on_create']//setting" position="after">
|
||||
<setting>
|
||||
<field name="self_order_kiosk" />
|
||||
</setting>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
</block>
|
||||
<xpath expr="//setting[@id='payment_methods_new']" position="before">
|
||||
<div class="o_notification_alert alert alert-warning" role="alert" invisible="not is_kiosk_mode">
|
||||
<span>Please note that only Adyen payment methods are supported by the kiosk.</span>
|
||||
<span>Please note that the kiosk only works with Adyen terminals</span>
|
||||
</div>
|
||||
</xpath>
|
||||
<block id="restaurant_section" position="after">
|
||||
|
||||
Reference in New Issue
Block a user