[IMP] point_of_sale: add tracking_number as searchable field in ticket_screen

In this commit, we add the tracking_number of an order as a searchable
field in the ticket_screen. This is useful when using pos_self_order
for example. If a mobile is made with service at table and pay at
cashier after each order, the cashier can search the order by its
tracking_number in the history of orders.

closes odoo/odoo#139187

Related: odoo/enterprise#49200
Signed-off-by: Vlad Stroia (vlst) <vlst@odoo.com>
This commit is contained in:
Adrien Guilliams (adgu)
2023-10-19 18:02:17 +00:00
parent 218fd1a854
commit 983a966365
10 changed files with 52 additions and 16 deletions
+13 -1
View File
@@ -328,7 +328,19 @@ class PosOrder(models.Model):
has_refundable_lines = fields.Boolean('Has Refundable Lines', compute='_compute_has_refundable_lines')
refunded_orders_count = fields.Integer(compute='_compute_refund_related_fields')
ticket_code = fields.Char(help='5 digits alphanumeric code to be used by portal user to request an invoice')
tracking_number = fields.Char(string="Short order number", compute='_compute_tracking_number')
tracking_number = fields.Char(string="Order Number", compute='_compute_tracking_number', search='_search_tracking_number')
def _search_tracking_number(self, operator, value):
#search is made over the pos_reference field
#The pos_reference field is like 'Order 00001-001-0001'
if operator in ['ilike', '='] and isinstance(value, str):
if value[0] == '%' and value[-1] == '%':
value = value[1:-1]
value = value.zfill(3)
search = '% ____' + value[0] + '-___-__' + value[1:]
return [('pos_reference', operator, search or '')]
else:
raise NotImplementedError(_("Unsupported search operation"))
@api.depends('lines.refund_orderline_ids', 'lines.refunded_orderline_id')
def _compute_refund_related_fields(self):
@@ -560,9 +560,11 @@ export class TicketScreen extends Component {
orderPartnerId,
tax_ids: orderline.get_taxes().map((tax) => tax.id),
discount: orderline.discount,
pack_lot_lines: orderline.pack_lot_lines ? orderline.pack_lot_lines.map(lot => {
return { lot_name: lot.lot_name };
}) : false,
pack_lot_lines: orderline.pack_lot_lines
? orderline.pack_lot_lines.map((lot) => {
return { lot_name: lot.lot_name };
})
: false,
},
destinationOrderUid: false,
};
@@ -595,7 +597,9 @@ export class TicketScreen extends Component {
*/
_prepareRefundOrderlineOptions(toRefundDetail) {
const { qty, orderline } = toRefundDetail;
const draftPackLotLines = orderline.pack_lot_lines ? { modifiedPackLotLines: [], newPackLotLines: orderline.pack_lot_lines} : false;
const draftPackLotLines = orderline.pack_lot_lines
? { modifiedPackLotLines: [], newPackLotLines: orderline.pack_lot_lines }
: false;
return {
quantity: -qty,
price: orderline.price,
@@ -604,7 +608,7 @@ export class TicketScreen extends Component {
refunded_orderline_id: orderline.id,
tax_ids: orderline.tax_ids,
discount: orderline.discount,
draftPackLotLines: draftPackLotLines
draftPackLotLines: draftPackLotLines,
};
}
_setOrder(order) {
@@ -627,6 +631,11 @@ export class TicketScreen extends Component {
*/
_getSearchFields() {
const fields = {
TRACKING_NUMBER: {
repr: (order) => order.trackingNumber,
displayName: _t("Order Number"),
modelField: "tracking_number",
},
RECEIPT_NUMBER: {
repr: (order) => order.name,
displayName: _t("Receipt Number"),
@@ -51,6 +51,7 @@
<div class="header-row d-flex text-bg-700 fw-bolder" t-att-class="{ 'd-none': ui.isSmall }">
<div class="col wide p-2">Date</div>
<div class="col wide p-2">Receipt Number</div>
<div class="col wide p-2">Order number</div>
<div class="col p-2">Customer</div>
<div class="col wide p-2" t-if="showCardholderName()">Cardholder Name</div>
<div class="col p-2">Cashier</div>
@@ -67,6 +68,9 @@
<div class="col wide p-2">
<div><t t-esc="order.name"></t></div>
</div>
<div class="col wide p-2">
<div><t t-esc="order.trackingNumber"></t></div>
</div>
<div class="col p-2">
<div><t t-esc="getPartner(order)"></t></div>
</div>
@@ -92,7 +96,7 @@
<div class="mobileOrderList order-row" t-att-class="{ 'highlight bg-primary text-white': isHighlighted(order) }"
t-on-click="() => this.onClickOrder(order)" t-on-dblclick="() => order.locked ? ()=>{} : this._setOrder(order)" >
<div class="col p-2 d-flex justify-content-between align-items-center">
<div><t t-esc="order.name"></t></div>
<div><t t-esc="order.name"></t> / <t t-esc="order.trackingNumber"></t></div>
<div><t t-esc="getTotal(order)"></t></div>
</div>
<div class="col p-2 d-flex justify-content-between align-items-center">
@@ -1451,6 +1451,7 @@ export class Order extends PosModel {
this.ticketCode = json.ticket_code || "";
this.lastOrderPrepaChange =
json.last_order_preparation_change && JSON.parse(json.last_order_preparation_change);
this.trackingNumber = json.tracking_number || "";
}
export_as_JSON() {
var orderLines, paymentLines;
@@ -148,6 +148,7 @@
</group>
<group string="Other Information">
<field name="pos_reference"/>
<field name="tracking_number"/>
<field name="company_id" groups="base.group_multi_company"/>
<field name="pricelist_id" groups="product.group_product_pricelist" readonly="state != 'draft'"/>
</group>
@@ -266,6 +267,7 @@
<field name="date_order"/>
<field name="config_id" />
<field name="pos_reference"/>
<field name="tracking_number" optional="hide"/>
<field name="partner_id"/>
<field string="Cashier" name="user_id" widget="many2one_avatar_user" readonly="state in ['done', 'invoiced']"/>
<field name="amount_total" sum="Amount total" widget="monetary" decoration-bf="1"/>
@@ -381,6 +383,7 @@
<field name="name"/>
<field name="pos_reference"/>
<field name="date_order"/>
<field name="tracking_number"/>
<field name="user_id"/>
<field name="partner_id"/>
<field name="session_id"/>
@@ -29,10 +29,17 @@ patch(OrderWidget.prototype, {
if (isOnlinePayment) {
return { label: buttonName, disabled: false };
} else {
return {
label: _t("Pay at cashier"),
disabled: false,
};
if (this.router.activeSlot === "product_list") {
return {
label: _t("Order"),
disabled: true,
};
} else {
return {
label: _t("Pay at cashier"),
disabled: false,
};
}
}
}
} else {
@@ -42,6 +42,7 @@ export class OrderWidget extends Component {
const kioskPayment = this.selfOrder.pos_payment_methods;
const isNoLine = this.selfOrder.currentOrder.lines.length === 0;
const hasNotAllLinesSent = this.selfOrder.currentOrder.hasNotAllLinesSent();
const isMobilePayment = this.selfOrder.pos_payment_methods.find((p) => p.is_mobile_payment);
let label = "";
let disabled = false;
@@ -53,8 +54,8 @@ export class OrderWidget extends Component {
label = _t("Order");
disabled = isNoLine;
} else {
label = kioskPayment ? _t("Pay") : _t("Pay at cashier");
disabled = false;
label = kioskPayment ? _t("Pay") : _t("Order");
disabled = !kioskPayment && !isMobilePayment;
}
return { label, disabled };
@@ -52,7 +52,6 @@ export class CartPage extends Component {
const type = this.selfOrder.config.self_ordering_mode;
const takeAway = this.selfOrder.currentOrder.take_away;
const mode = this.selfOrder.config.self_ordering_pay_after;
const isOnlinePayment = this.selfOrder.pos_payment_methods.find((p) => p.is_online_payment);
const order = this.selfOrder.currentOrder;
const isPaymentMethod = this.selfOrder.pos_payment_methods.length > 0;
@@ -13,7 +13,7 @@
<h1 t-else="" class="mb-4">We're preparing your order!</h1>
<h3 t-if="state.payment" class="mt-3 text-muted">Pay at the cashier <t t-esc="selfOrder.formatMonetary(confirmedOrder.amount_total)" /></h3>
<div class="d-inline-flex flex-column border rounded py-4 px-5 bg-view mb-3">
<span class="fs-2 text-muted">Your short order number</span>
<span class="fs-2 text-muted">Your order number</span>
<span class="number lh-1" t-esc="confirmedOrder.trackingNumber" />
</div>
<h3 t-if="selfOrder.table.name || confirmedOrder.table_stand_number" class="text-muted mb-3">
@@ -17,7 +17,7 @@
<div class="d-flex align-items-center justify-content-between">
<div class="d-flex flex-column">
<h6 class="m-0" t-esc="order.pos_reference"/>
<span class="text-muted">Short order number: <t t-esc="order.trackingNumber" /></span>
<span class="text-muted">Order number: <t t-esc="order.trackingNumber" /></span>
</div>
<span
class="badge py-2 rounded-pill text-capitalize"