diff --git a/addons/point_of_sale/static/src/js/Misc/MobileOrderWidget.js b/addons/point_of_sale/static/src/js/Misc/MobileOrderWidget.js index 8f215b51b4b..c4f08dbfc62 100644 --- a/addons/point_of_sale/static/src/js/Misc/MobileOrderWidget.js +++ b/addons/point_of_sale/static/src/js/Misc/MobileOrderWidget.js @@ -1,10 +1,15 @@ /** @odoo-module */ import { Component } from "@odoo/owl"; +import { usePos } from "@point_of_sale/app/pos_hook"; export class MobileOrderWidget extends Component { static template = "MobileOrderWidget"; + setup() { + super.setup(...arguments); + this.pos = usePos(); + } get order() { return this.env.pos.get_order(); } @@ -17,4 +22,11 @@ export class MobileOrderWidget extends Component { ? this.order.orderlines.reduce((items_number, line) => items_number + line.quantity, 0) : 0; } + clickPay() { + const order = this.pos.globalState.get_order(); + + if (order.orderlines.length) { + order.pay(); + } + } } diff --git a/addons/point_of_sale/static/src/js/Screens/ProductScreen/ActionpadWidget.js b/addons/point_of_sale/static/src/js/Screens/ProductScreen/ActionpadWidget.js index 2bd9d63250c..f7da3c8e6ef 100644 --- a/addons/point_of_sale/static/src/js/Screens/ProductScreen/ActionpadWidget.js +++ b/addons/point_of_sale/static/src/js/Screens/ProductScreen/ActionpadWidget.js @@ -19,4 +19,16 @@ export class ActionpadWidget extends Component { get isLongName() { return this.props.partner && this.props.partner.name.length > 10; } + + clickPay() { + const order = this.pos.globalState.get_order(); + + if (order.orderlines.length) { + order.pay(); + } + } + + get highlightPay() { + return this.pos.globalState.get_order()?.orderlines?.length; + } } diff --git a/addons/point_of_sale/static/src/js/Screens/ProductScreen/ProductScreen.js b/addons/point_of_sale/static/src/js/Screens/ProductScreen/ProductScreen.js index 307593bc885..283b9ddf05f 100644 --- a/addons/point_of_sale/static/src/js/Screens/ProductScreen/ProductScreen.js +++ b/addons/point_of_sale/static/src/js/Screens/ProductScreen/ProductScreen.js @@ -9,7 +9,6 @@ import { parse } from "web.field_utils"; import { NumberPopup } from "@point_of_sale/js/Popups/NumberPopup"; import { ErrorPopup } from "@point_of_sale/js/Popups/ErrorPopup"; import { ErrorBarcodePopup } from "@point_of_sale/js/Popups/ErrorBarcodePopup"; -import { ConfirmPopup } from "@point_of_sale/js/Popups/ConfirmPopup"; import { ControlButtonPopup } from "@point_of_sale/js/Popups/ControlButtonPopup"; import { ConnectionLostError } from "@web/core/network/rpc_service"; @@ -20,6 +19,7 @@ import { OrderWidget } from "./OrderWidget"; import { ProductsWidget } from "./ProductsWidget"; import { usePos } from "@point_of_sale/app/pos_hook"; import { Component, onMounted, useState } from "@odoo/owl"; +import { ConfirmPopup } from "@point_of_sale/js/Popups/ConfirmPopup"; export class ProductScreen extends ControlButtonsMixin(Component) { static template = "ProductScreen"; @@ -240,14 +240,15 @@ export class ProductScreen extends ControlButtonsMixin(Component) { this.env.pos.get_order().server_id, ]); if (isPaid) { - const searchDetails = { fieldName: "RECEIPT_NUMBER", searchTerm: this.env.pos.get_order().uid } + const searchDetails = { + fieldName: "RECEIPT_NUMBER", + searchTerm: this.env.pos.get_order().uid, + }; this.pos.showScreen("TicketScreen", { - ui: { filter: "SYNCED", searchDetails } + ui: { filter: "SYNCED", searchDetails }, }); this.notification.add( - _.str.sprintf( - this.env._t('The order has been already paid.') - ), + _.str.sprintf(this.env._t("The order has been already paid.")), 3000 ); this.env.pos.removeOrder(this.env.pos.get_order(), false); diff --git a/addons/point_of_sale/static/src/js/Screens/TicketScreen/TicketScreen.js b/addons/point_of_sale/static/src/js/Screens/TicketScreen/TicketScreen.js index 69791a06955..477c4962c96 100644 --- a/addons/point_of_sale/static/src/js/Screens/TicketScreen/TicketScreen.js +++ b/addons/point_of_sale/static/src/js/Screens/TicketScreen/TicketScreen.js @@ -223,7 +223,7 @@ export class TicketScreen extends IndependentToOrderScreen { async onDoRefund() { const order = this.getSelectedSyncedOrder(); - if (this._doesOrderHaveSoleItem(order)) { + if (order && this._doesOrderHaveSoleItem(order)) { if (!this._prepareAutoRefundOnOrder(order)) { // Don't proceed on refund if preparation returned false. return; diff --git a/addons/point_of_sale/static/src/js/models.js b/addons/point_of_sale/static/src/js/models.js index bea0c4c0f5f..fdaa350008b 100644 --- a/addons/point_of_sale/static/src/js/models.js +++ b/addons/point_of_sale/static/src/js/models.js @@ -12,6 +12,7 @@ import { ErrorPopup } from "./Popups/ErrorPopup"; import { ProductConfiguratorPopup } from "@point_of_sale/js/Popups/ProductConfiguratorPopup"; import { EditListPopup } from "@point_of_sale/js/Popups/EditListPopup"; import { markRaw, reactive } from "@odoo/owl"; +import { ConfirmPopup } from "@point_of_sale/js/Popups/ConfirmPopup"; import { escape } from "@web/core/utils/strings"; var QWeb = core.qweb; @@ -3115,6 +3116,28 @@ export class Order extends PosModel { return receipt; } + async pay() { + if ( + this.orderlines.some( + (line) => line.get_product().tracking !== "none" && !line.has_valid_product_lot() + ) && + (this.pos.picking_type.use_create_lots || this.pos.picking_type.use_existing_lots) + ) { + const { confirmed } = await this.pos.env.services.popup.add(ConfirmPopup, { + title: _t("Some Serial/Lot Numbers are missing"), + body: _t( + "You are trying to sell products with serial/lot numbers, but some of them are not set.\nWould you like to proceed anyway?" + ), + confirmText: _t("Yes"), + cancelText: _t("No"), + }); + if (confirmed) { + this.pos.env.services.pos.showScreen("PaymentScreen"); + } + } else { + this.pos.env.services.pos.showScreen("PaymentScreen"); + } + } is_empty() { return this.orderlines.length === 0; } diff --git a/addons/point_of_sale/static/src/scss/pos.scss b/addons/point_of_sale/static/src/scss/pos.scss index f8b7e60e666..852741fe119 100644 --- a/addons/point_of_sale/static/src/scss/pos.scss +++ b/addons/point_of_sale/static/src/scss/pos.scss @@ -604,6 +604,8 @@ td { .pos .control-buttons { display: flex; flex-flow: row wrap; + white-space: nowrap; + overflow: hidden; } .pos .popup-control-buttons .control-buttons { flex-direction: column; @@ -627,6 +629,7 @@ td { cursor: pointer; overflow: hidden; transition: all linear 150ms; + text-overflow: ellipsis; } .pos .control-button:hover { background: $gray-200; diff --git a/addons/point_of_sale/static/src/xml/Misc/MobileOrderWidget.xml b/addons/point_of_sale/static/src/xml/Misc/MobileOrderWidget.xml index cad9e75e362..b2ec0c37658 100644 --- a/addons/point_of_sale/static/src/xml/Misc/MobileOrderWidget.xml +++ b/addons/point_of_sale/static/src/xml/Misc/MobileOrderWidget.xml @@ -3,7 +3,7 @@
- diff --git a/addons/point_of_sale/static/src/xml/Screens/ProductScreen/ActionpadWidget.xml b/addons/point_of_sale/static/src/xml/Screens/ProductScreen/ActionpadWidget.xml index 3ecbd598754..003f837bb65 100644 --- a/addons/point_of_sale/static/src/xml/Screens/ProductScreen/ActionpadWidget.xml +++ b/addons/point_of_sale/static/src/xml/Screens/ProductScreen/ActionpadWidget.xml @@ -13,8 +13,8 @@ Customer - + + + !this.swapButton + + + + + + + + !this.swapButton + + + diff --git a/addons/pos_restaurant/static/src/xml/Screens/ProductScreen/ControlButtons/CustomerButton.xml b/addons/pos_restaurant/static/src/xml/Screens/ProductScreen/ControlButtons/CustomerButton.xml new file mode 100644 index 00000000000..8264c6a28bb --- /dev/null +++ b/addons/pos_restaurant/static/src/xml/Screens/ProductScreen/ControlButtons/CustomerButton.xml @@ -0,0 +1,12 @@ + + + +
+ + + + Customer + +
+
+
diff --git a/addons/pos_restaurant/static/src/xml/Screens/ProductScreen/ControlButtons/SubmitOrderButton.xml b/addons/pos_restaurant/static/src/xml/Screens/ProductScreen/ControlButtons/SubmitOrderButton.xml deleted file mode 100644 index 2f1f4a18b53..00000000000 --- a/addons/pos_restaurant/static/src/xml/Screens/ProductScreen/ControlButtons/SubmitOrderButton.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - Order - - - -