[IMP] pos_self_order: send kiosk order to preparation display
This commit consist of adaptation of the pos_self_order module to send orders to preparation display. The main changes consist of sending the table stand number that the client put in to the backend to be shown in the preparation display. It also consist of moving the tracking number from the pos_self_order module to the point_of_sale module so that every number has a tracking number. closes odoo/odoo#134980 Task-id: 3495477 Related: odoo/enterprise#47203 Signed-off-by: David Monnom (moda) <moda@odoo.com>
This commit is contained in:
@@ -392,7 +392,7 @@ class PosConfig(models.Model):
|
||||
return pos_configs
|
||||
|
||||
def _reset_default_on_vals(self, vals):
|
||||
if 'tip_product_id' in vals and vals['iface_tipproduct'] and not vals['tip_product_id']:
|
||||
if 'tip_product_id' in vals and not vals['tip_product_id'] and 'iface_tipproduct' in vals and vals['iface_tipproduct']:
|
||||
default_product = self.env.ref('point_of_sale.product_product_tip', False)
|
||||
if default_product:
|
||||
vals['tip_product_id'] = default_product.id
|
||||
|
||||
@@ -59,7 +59,7 @@ class PosOrder(models.Model):
|
||||
'tip_amount': ui_order.get('tip_amount', 0),
|
||||
'access_token': ui_order.get('access_token', ''),
|
||||
'ticket_code': ui_order.get('ticket_code', ''),
|
||||
'last_order_preparation_change': ui_order.get('last_order_preparation_change', False),
|
||||
'last_order_preparation_change': ui_order.get('last_order_preparation_change', '{}'),
|
||||
}
|
||||
|
||||
@api.model
|
||||
@@ -113,9 +113,10 @@ class PosOrder(models.Model):
|
||||
|
||||
return new_session
|
||||
|
||||
def _get_tracking_ref(self):
|
||||
self.ensure_one()
|
||||
return str(self.session_id.id)[-1] + str(self.sequence_number)[-2:]
|
||||
@api.depends('sequence_number', 'session_id')
|
||||
def _compute_tracking_number(self):
|
||||
for record in self:
|
||||
record.tracking_number = str(record.session_id.id)[-1] + str(record.sequence_number)[-2:]
|
||||
|
||||
@api.model
|
||||
def _process_order(self, order, draft, existing_order):
|
||||
@@ -327,6 +328,7 @@ 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="Tracking Number", compute='_compute_tracking_number')
|
||||
|
||||
@api.depends('lines.refund_orderline_ids', 'lines.refunded_orderline_id')
|
||||
def _compute_refund_related_fields(self):
|
||||
@@ -1132,6 +1134,7 @@ class PosOrder(models.Model):
|
||||
'access_token': order.access_token,
|
||||
'ticket_code': order.ticket_code,
|
||||
'last_order_preparation_change': order.last_order_preparation_change,
|
||||
'tracking_number':order.tracking_number,
|
||||
}
|
||||
|
||||
@api.model
|
||||
|
||||
@@ -229,6 +229,18 @@ class PosSession(models.Model):
|
||||
sessions = super().create(vals_list)
|
||||
sessions.action_pos_session_open()
|
||||
|
||||
date_string = fields.Date.today().isoformat()
|
||||
ir_sequence = self.env['ir.sequence'].sudo().search([('code', '=', f'pos.order_{date_string}')])
|
||||
if not ir_sequence:
|
||||
self.env['ir.sequence'].sudo().create({
|
||||
'name': _("PoS Order"),
|
||||
'padding': 0,
|
||||
'code': f'pos.order_{date_string}',
|
||||
'number_next': 1,
|
||||
'number_increment': 1,
|
||||
'company_id': self.env.company.id,
|
||||
})
|
||||
|
||||
return sessions
|
||||
|
||||
def unlink(self):
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/** @odoo-module */
|
||||
|
||||
import { uuidv4 } from "@point_of_sale/utils";
|
||||
import { uuidv4, constructFullProductName } from "@point_of_sale/utils";
|
||||
// FIXME POSREF - unify use of native parseFloat and web's parseFloat. We probably don't need the native version.
|
||||
import { parseFloat as oParseFloat } from "@web/views/fields/parsers";
|
||||
import {
|
||||
@@ -567,27 +567,11 @@ export class Orderline extends PosModel {
|
||||
this.price_extra = parseFloat(price_extra) || 0.0;
|
||||
}
|
||||
set_full_product_name() {
|
||||
let attributeString = "";
|
||||
|
||||
if (this.attribute_value_ids && this.attribute_value_ids.length > 0) {
|
||||
for (const valId of this.attribute_value_ids) {
|
||||
const value = this.pos.db.attribute_value_by_id[valId];
|
||||
if (value.is_custom) {
|
||||
const customValue = this.custom_attribute_value_ids.find(
|
||||
(cus) => cus.custom_product_template_attribute_value_id == parseInt(valId)
|
||||
);
|
||||
attributeString += customValue
|
||||
? `${value.name}: ${customValue.custom_value}, `
|
||||
: `${value.name}, `;
|
||||
} else {
|
||||
attributeString += `${value.name}, `;
|
||||
}
|
||||
}
|
||||
attributeString = attributeString.slice(0, -2);
|
||||
attributeString = `(${attributeString})`;
|
||||
}
|
||||
|
||||
this.full_product_name = `${this.product.display_name} ${attributeString}`;
|
||||
this.full_product_name = constructFullProductName(
|
||||
this,
|
||||
this.pos.db.attribute_value_by_id,
|
||||
this.product.display_name
|
||||
);
|
||||
}
|
||||
get_price_extra() {
|
||||
return this.price_extra;
|
||||
|
||||
@@ -29,3 +29,27 @@ export function deduceUrl(url) {
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
export function constructFullProductName(line, attribute_value_by_id, display_name) {
|
||||
let attributeString = "";
|
||||
|
||||
if (line.attribute_value_ids && line.attribute_value_ids.length > 0) {
|
||||
for (const valId of line.attribute_value_ids) {
|
||||
const value = attribute_value_by_id[valId];
|
||||
if (value.is_custom) {
|
||||
const customValue = line.custom_attribute_value_ids.find(
|
||||
(cus) => cus.custom_product_template_attribute_value_id == parseInt(valId)
|
||||
);
|
||||
attributeString += customValue
|
||||
? `${value.name}: ${customValue.custom_value}, `
|
||||
: `${value.name}, `;
|
||||
} else {
|
||||
attributeString += `${value.name}, `;
|
||||
}
|
||||
}
|
||||
attributeString = attributeString.slice(0, -2);
|
||||
attributeString = `(${attributeString})`;
|
||||
}
|
||||
|
||||
return `${display_name} ${attributeString}`;
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ class PosAdyenController(http.Controller):
|
||||
_logger.info('notification received from adyen:\n%s', pprint.pformat(data))
|
||||
terminal_identifier = data['SaleToPOIResponse']['MessageHeader']['POIID']
|
||||
payment_method_sudo = request.env['pos.payment.method'].sudo().search([('adyen_terminal_identifier', '=', terminal_identifier)], limit=1)
|
||||
pos_session_id = int(data["SaleToPOIResponse"]["PaymentResponse"]["SaleData"]["SaleTransactionID"]["TransactionID"].split("--")[1])
|
||||
pos_session_id = int(data["SaleToPOIResponse"]["PaymentResponse"]["SaleData"]["SaleTransactionID"]["TransactionID"].split("-")[1])
|
||||
pos_session_sudo = request.env["pos.session"].sudo().browse(pos_session_id)
|
||||
|
||||
if payment_method_sudo:
|
||||
|
||||
@@ -8,25 +8,13 @@ from odoo.exceptions import ValidationError
|
||||
class PosConfig(models.Model):
|
||||
_inherit = 'pos.config'
|
||||
|
||||
self_order_online_payment_method_id = fields.Many2one('pos.payment.method', string='Self Online Payment', help="The online payment method to use when a customer pays a self-order online.", domain=[('is_online_payment', '=', True)], compute='_compute_self_order_online_payment_method_id', store=True, readonly=False)
|
||||
self_order_online_payment_method_id = fields.Many2one('pos.payment.method', string='Self Online Payment', help="The online payment method to use when a customer pays a self-order online.", domain=[('is_online_payment', '=', True)], store=True, readonly=False)
|
||||
|
||||
@api.constrains('self_order_online_payment_method_id')
|
||||
def _check_self_order_online_payment_method_id(self):
|
||||
if any(config.self_order_online_payment_method_id and not config.self_order_online_payment_method_id._get_online_payment_providers(config.id, error_if_invalid=True) for config in self):
|
||||
raise ValidationError(_("The online payment method used for self-order in a POS config must have at least one published payment provider supporting the currency of that POS config."))
|
||||
|
||||
@api.constrains('self_ordering_mode', 'self_ordering_pay_after', 'self_order_online_payment_method_id')
|
||||
def _check_self_order_pay_after_each(self):
|
||||
if any(config.self_ordering_mode == 'mobile' and config.self_ordering_pay_after == 'each' and not config.self_order_online_payment_method_id for config in self):
|
||||
raise ValidationError(_("The POS self-order mode with payment after each order requires an online payment method to be configured."))
|
||||
|
||||
@api.depends('company_id', 'self_ordering_mode', 'self_ordering_pay_after', 'self_order_online_payment_method_id')
|
||||
def _compute_self_order_online_payment_method_id(self):
|
||||
for config in self:
|
||||
if not config.self_ordering_mode == 'mobile':
|
||||
config.self_order_online_payment_method_id = False
|
||||
elif config.self_ordering_pay_after == 'each' and (not config.self_order_online_payment_method_id or not config.self_order_online_payment_method_id.is_online_payment):
|
||||
config.self_order_online_payment_method_id = self.env['pos.payment.method'].sudo()._get_or_create_online_payment_method(config.company_id.id, config.id)
|
||||
if config.self_ordering_mode == 'mobile' and config.self_ordering_service_mode == 'each' and config.self_order_online_payment_method_id and not config.self_order_online_payment_method_id._get_online_payment_providers(config.id, error_if_invalid=True):
|
||||
raise ValidationError(_("The online payment method used for self-order in a POS config must have at least one published payment provider supporting the currency of that POS config."))
|
||||
|
||||
def _get_self_ordering_data(self):
|
||||
res = super()._get_self_ordering_data()
|
||||
|
||||
@@ -95,5 +95,6 @@ class PosSession(models.Model):
|
||||
"note": "",
|
||||
"product_id": orderline.product_id.id,
|
||||
"quantity": orderline.qty,
|
||||
"attribute_value_ids": orderline.attribute_value_ids.ids,
|
||||
}
|
||||
order.write({'last_order_preparation_change': json.dumps(last_order_preparation_change)})
|
||||
|
||||
@@ -63,6 +63,7 @@
|
||||
'web/static/lib/bootstrap/js/dist/scrollspy.js',
|
||||
"pos_self_order/static/src/app/**/*",
|
||||
"point_of_sale/static/src/app/store/models/product_custom_attribute.js",
|
||||
"point_of_sale/static/src/utils.js",
|
||||
'web_editor/static/src/js/editor/odoo-editor/src/base_style.scss',
|
||||
'web_editor/static/src/scss/web_editor.common.scss',
|
||||
],
|
||||
|
||||
@@ -13,14 +13,10 @@ class PosSelfOrderController(http.Controller):
|
||||
is_take_away = order.get('take_away')
|
||||
pos_config, table = self._verify_authorization(access_token, table_identifier, is_take_away)
|
||||
pos_session = pos_config.current_session_id
|
||||
|
||||
date_string = fields.Date.today().isoformat()
|
||||
ir_sequence_session = pos_config.env['ir.sequence'].with_context(company_id=pos_config.company_id.id).next_by_code(f'pos.order_{pos_session.id}')
|
||||
ir_sequence_tracking = pos_config.env['ir.sequence'].with_context(company_id=pos_config.company_id.id).next_by_code(f'pos.order_{date_string}')
|
||||
|
||||
sequence_number = re.findall(r'\d+', ir_sequence_session)[0]
|
||||
order_reference = self._generate_unique_id(pos_session.id, pos_config.id, sequence_number, device_type)
|
||||
tracking_number = f"{'A' if device_type == 'kiosk' else 'B'}{ir_sequence_tracking}"
|
||||
|
||||
fiscal_position = (
|
||||
pos_config.self_ordering_alternative_fp_id
|
||||
@@ -49,7 +45,7 @@ class PosSelfOrderController(http.Controller):
|
||||
'amount_total': 0,
|
||||
'amount_paid': 0,
|
||||
'amount_return': 0,
|
||||
'tracking_number': tracking_number,
|
||||
'table_stand_number': order.get('table_stand_number'),
|
||||
},
|
||||
'to_invoice': False,
|
||||
'session_id': pos_session.id,
|
||||
@@ -143,6 +139,7 @@ class PosSelfOrderController(http.Controller):
|
||||
'amount_tax': amount_total - amount_untaxed,
|
||||
'amount_total': amount_total,
|
||||
'table_id': table if table else False,
|
||||
'table_stand_number': order.get('table_stand_number'),
|
||||
})
|
||||
|
||||
pos_order.send_table_count_notification(pos_order.table_id)
|
||||
|
||||
@@ -147,7 +147,7 @@ class PosConfig(models.Model):
|
||||
|
||||
def write(self, vals):
|
||||
for record in self:
|
||||
if vals.get('self_ordering_mode') == 'kiosk' or record.self_ordering_mode == 'kiosk':
|
||||
if vals.get('self_ordering_mode') == 'kiosk' or (vals.get('pos_self_ordering_mode') == 'mobile' and vals.get('pos_self_ordering_service_mode') == 'counter'):
|
||||
vals['self_ordering_pay_after'] = 'each'
|
||||
|
||||
if (not vals.get('module_pos_restaurant') and not record.module_pos_restaurant) and vals.get('self_ordering_mode') == 'mobile':
|
||||
@@ -170,6 +170,11 @@ class PosConfig(models.Model):
|
||||
|
||||
vals['self_ordering_image_home_ids'] = unlink_commands + vals['self_ordering_image_home_ids']
|
||||
|
||||
if vals.get('self_ordering_mode') == 'mobile' and vals.get('self_ordering_pay_after') == 'meal':
|
||||
vals['self_ordering_service_mode'] = 'table'
|
||||
|
||||
if (vals.get('self_ordering_service_mode') == 'counter' or record.self_ordering_service_mode == 'counter') and vals.get('self_ordering_mode') == 'mobile':
|
||||
vals['self_ordering_pay_after'] = 'each'
|
||||
return super().write(vals)
|
||||
|
||||
@api.depends("module_pos_restaurant")
|
||||
|
||||
@@ -42,7 +42,7 @@ class PosOrderLine(models.Model):
|
||||
class PosOrder(models.Model):
|
||||
_inherit = "pos.order"
|
||||
|
||||
tracking_number = fields.Char(string="Tracking Number")
|
||||
table_stand_number = fields.Char(string="Table Stand Number")
|
||||
take_away = fields.Boolean(string="Take Away", default=False)
|
||||
|
||||
@api.model
|
||||
@@ -66,8 +66,8 @@ class PosOrder(models.Model):
|
||||
def _order_fields(self, ui_order):
|
||||
fields = super()._order_fields(ui_order)
|
||||
fields.update({
|
||||
'tracking_number': ui_order.get('tracking_number'),
|
||||
'take_away': ui_order.get('take_away'),
|
||||
'table_stand_number': ui_order.get('table_stand_number'),
|
||||
})
|
||||
return fields
|
||||
|
||||
@@ -92,7 +92,7 @@ class PosOrder(models.Model):
|
||||
"take_away": self.take_away,
|
||||
"pos_reference": self.pos_reference,
|
||||
"access_token": self.access_token,
|
||||
"tracking_number": self.tracking_number,
|
||||
"table_stand_number": self.table_stand_number,
|
||||
"state": self.state,
|
||||
"date_order": str(self.date_order),
|
||||
"amount_total": self.amount_total,
|
||||
@@ -113,3 +113,7 @@ class PosOrder(models.Model):
|
||||
for line in self.lines
|
||||
],
|
||||
}
|
||||
|
||||
def _send_order(self):
|
||||
#This function is made to be overriden by pos_self_order_preparation_display
|
||||
pass
|
||||
|
||||
@@ -15,8 +15,6 @@ class PosSession(models.Model):
|
||||
|
||||
@api.model
|
||||
def _create_pos_self_sessions_sequence(self, sessions):
|
||||
date_string = fields.Date.today().isoformat()
|
||||
ir_sequence = self.env['ir.sequence'].sudo().search([('code', '=', f'pos.order_{date_string}')])
|
||||
company_id = self.env.company.id
|
||||
|
||||
for session in sessions:
|
||||
@@ -29,16 +27,6 @@ class PosSession(models.Model):
|
||||
'company_id': company_id,
|
||||
})
|
||||
|
||||
if not ir_sequence:
|
||||
self.env['ir.sequence'].sudo().create({
|
||||
'name': _("PoS Order"),
|
||||
'padding': 0,
|
||||
'code': f'pos.order_{date_string}',
|
||||
'number_next': 1,
|
||||
'number_increment': 1,
|
||||
'company_id': company_id,
|
||||
})
|
||||
|
||||
return sessions
|
||||
|
||||
def _loader_params_product_product(self):
|
||||
|
||||
@@ -5,6 +5,7 @@ import { useSelfOrder } from "@pos_self_order/app/self_order_service";
|
||||
import { useService, useForwardRefToParent } from "@web/core/utils/hooks";
|
||||
import { Line } from "@pos_self_order/app/models/line";
|
||||
import { ProductInfoPopup } from "@pos_self_order/app/components/product_info_popup/product_info_popup";
|
||||
import { constructFullProductName } from "@point_of_sale/utils";
|
||||
|
||||
export class ProductCard extends Component {
|
||||
static template = "pos_self_order.ProductCard";
|
||||
@@ -100,16 +101,18 @@ export class ProductCard extends Component {
|
||||
isProductInCart.qty++;
|
||||
} else {
|
||||
const lines = this.selfOrder.currentOrder.lines;
|
||||
|
||||
lines.push(
|
||||
new Line({
|
||||
id: null,
|
||||
uuid: null,
|
||||
qty: 1,
|
||||
product_id: product.id,
|
||||
full_product_name: product.name,
|
||||
})
|
||||
const line = new Line({
|
||||
id: null,
|
||||
uuid: null,
|
||||
qty: 1,
|
||||
product_id: product.id,
|
||||
});
|
||||
line.full_product_name = constructFullProductName(
|
||||
line,
|
||||
this.selfOrder.attributeValueById,
|
||||
product.name
|
||||
);
|
||||
lines.push(line);
|
||||
}
|
||||
await this.selfOrder.getPricesFromServer();
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ export class Line extends Reactive {
|
||||
// server data
|
||||
this.id = line.id || null;
|
||||
this.uuid = line.uuid || uuidv4();
|
||||
this.full_product_name = line.full_product_name;
|
||||
this.full_product_name = line.full_product_name || "";
|
||||
this.product_id = line.product_id;
|
||||
this.qty = line.qty ? line.qty : 0;
|
||||
this.customer_note = line.customer_note;
|
||||
|
||||
@@ -13,7 +13,6 @@ export class Order extends Reactive {
|
||||
date,
|
||||
amount_total,
|
||||
amount_tax,
|
||||
tracking_number,
|
||||
lastChangesSent,
|
||||
take_away,
|
||||
}) {
|
||||
@@ -32,7 +31,6 @@ export class Order extends Reactive {
|
||||
this.amount_total = order.amount_total || 0;
|
||||
this.amount_tax = order.amount_tax || 0;
|
||||
this.lines = order.lines || [];
|
||||
this.tracking_number = order.tracking_number || null;
|
||||
this.take_away = typeof order.take_away === "boolean" ? order.take_away : null;
|
||||
|
||||
// data
|
||||
@@ -53,6 +51,18 @@ export class Order extends Reactive {
|
||||
return this.isAlreadySent && this.hasNotAllLinesSent().length === 0;
|
||||
}
|
||||
|
||||
get trackingNumber() {
|
||||
if (this.pos_reference) {
|
||||
const reference = this.pos_reference;
|
||||
const arrRef = reference.split(" ")[1].split("-");
|
||||
const sessionID = parseInt(arrRef[0]).toString();
|
||||
const sequence = parseInt(arrRef[2]).toString();
|
||||
const trackingNumber = sessionID + sequence;
|
||||
return trackingNumber;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
initLines() {
|
||||
this.lines = this.lines.map((line) => new Line(line));
|
||||
}
|
||||
|
||||
@@ -63,6 +63,11 @@ export class CartPage extends Component {
|
||||
return;
|
||||
}
|
||||
|
||||
if (type === "mobile" && orderingMode === "table" && !takeAway && !this.selfOrder.table) {
|
||||
this.state.selectTable = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (mode === "meal" && !order.isSavedOnServer) {
|
||||
this.sendInProgress = true;
|
||||
await this.selfOrder.sendDraftOrderToServer();
|
||||
@@ -72,13 +77,9 @@ export class CartPage extends Component {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (orderingMode === "table" && !takeAway) {
|
||||
if (type === "kiosk") {
|
||||
this.router.navigate("stand_number");
|
||||
} else if (type === "mobile" && !this.selfOrder.table) {
|
||||
this.state.selectTable = true;
|
||||
return;
|
||||
} else {
|
||||
this.router.navigate("payment");
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<div class="product-info d-flex flex-column gap-2 flex-grow-1">
|
||||
<div>
|
||||
<span t-if="selfOrder.currentOrder.isSavedOnServer"><t t-esc="line.qty" />x </span>
|
||||
<strong t-esc="line.full_product_name"/>
|
||||
<strong t-esc="selfOrder.productByIds[line.product_id].name"/>
|
||||
</div>
|
||||
<div t-if="this.selfOrder.productByIds[line.product_id]?.attributes.length > 0 || childLines.length > 0" class="d-flex align-items-start gap-2 gap-md-3 my-2">
|
||||
<button
|
||||
@@ -37,7 +37,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div t-foreach="childLines" t-as="cline" t-key="cline.uuid" class="text-muted">
|
||||
- <span t-esc="cline.full_product_name" /> <span t-if="cline.price_subtotal_incl">(<t t-esc="selfOrder.formatMonetary(cline.price_subtotal_incl)"/>)</span>
|
||||
- <span t-esc="selfOrder.productByIds[cline.product_id].name" /> <span t-if="cline.price_subtotal_incl">(<t t-esc="selfOrder.formatMonetary(cline.price_subtotal_incl)"/>)</span>
|
||||
<div class="product-info d-flex flex-column flex-grow-1 ms-3">
|
||||
<div t-foreach="getSelectedAttributes(cline)" t-as="attribute" t-key="attribute.name">
|
||||
- <span t-esc="attribute.name" /> : <span t-esc="attribute.value" />
|
||||
|
||||
@@ -6,6 +6,7 @@ import { ComboSelection } from "@pos_self_order/app/components/combo_selection/c
|
||||
import { useService } from "@web/core/utils/hooks";
|
||||
import { Line } from "@pos_self_order/app/models/line";
|
||||
import { attributeFlatter, attributeFormatter } from "@pos_self_order/app/utils";
|
||||
import { constructFullProductName } from "@point_of_sale/utils";
|
||||
|
||||
export class ComboPage extends Component {
|
||||
static template = "pos_self_order.ComboPage";
|
||||
@@ -151,12 +152,16 @@ export class ComboPage extends Component {
|
||||
uuid: null,
|
||||
qty: this.state.qty,
|
||||
product_id: combo.product.id,
|
||||
full_product_name: combo.product.name,
|
||||
attribute_value_ids: attributeFlatter(combo.product.variants),
|
||||
custom_attribute_value_ids: Object.values(combo.product.customValues),
|
||||
combo_parent_uuid: parent_line.uuid,
|
||||
combo_id: combo.id,
|
||||
});
|
||||
child_line.full_product_name = constructFullProductName(
|
||||
child_line,
|
||||
this.selfOrder.attributeValueById,
|
||||
combo.product.name
|
||||
);
|
||||
lines.push(child_line);
|
||||
parent_line.child_lines.push(child_line);
|
||||
}
|
||||
|
||||
@@ -22,8 +22,6 @@ export class LandingPage extends Component {
|
||||
this.selfOrder.orders = [];
|
||||
this.selfOrder.editedOrder = null;
|
||||
}
|
||||
|
||||
this.tablePadNumber = null;
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
|
||||
+1
-1
@@ -55,7 +55,7 @@
|
||||
<t t-set="comboParent" t-value="line.combo_parent_uuid and order.lines.find(l => l.uuid === line.combo_parent_uuid)" />
|
||||
<div t-if="comboParent" class="info ms-2 combo-parent-name">
|
||||
<i class="fa fa-th-large me-2" role="img" aria-label="Combo" title="Combo"/>
|
||||
<t t-esc="comboParent.full_product_name" />
|
||||
<t t-esc="selfOrder.productByIds[comboParent.product_id].name" />
|
||||
</div>
|
||||
<div t-if="line.customer_note" class="d-inline-block m-0 text-muted small break-line">
|
||||
<i class="fa fa-pencil-square-o" aria-hidden="true" />
|
||||
|
||||
+3
-3
@@ -13,13 +13,13 @@
|
||||
<div class="d-inline-flex flex-column border rounded py-4 px-5 bg-view mb-3">
|
||||
<t t-if="selfOrder.currentOrder.take_away || selfOrder.config.self_ordering_service_mode !== 'table'">
|
||||
<span class="fs-2 text-muted">Your order number</span>
|
||||
<span class="number lh-1" t-esc="selfOrder.currentOrder.tracking_number" />
|
||||
<span class="number lh-1" t-esc="selfOrder.currentOrder.trackingNumber" />
|
||||
</t>
|
||||
<t t-else="">
|
||||
<span class="fs-2 text-muted">Your table number:</span>
|
||||
<span class="number lh-1 mb-4" t-esc="selfOrder.tablePadNumber" />
|
||||
<span class="number lh-1 mb-4" t-esc="selfOrder.currentOrder.table_stand_number" />
|
||||
<span class="fs-2 text-muted">Order number:</span>
|
||||
<span class="number lh-1" t-esc="selfOrder.currentOrder.tracking_number" />
|
||||
<span class="number lh-1" t-esc="selfOrder.currentOrder.trackingNumber" />
|
||||
</t>
|
||||
</div>
|
||||
<h2 class="m-0 text-muted">Get your ticket below</h2>
|
||||
|
||||
@@ -6,6 +6,7 @@ import { AttributeSelection } from "@pos_self_order/app/components/attribute_sel
|
||||
import { Line } from "@pos_self_order/app/models/line";
|
||||
import { useService } from "@web/core/utils/hooks";
|
||||
import { attributeFlatter } from "@pos_self_order/app/utils";
|
||||
import { constructFullProductName } from "@point_of_sale/utils";
|
||||
|
||||
export class ProductPage extends Component {
|
||||
static template = "pos_self_order.ProductPage";
|
||||
@@ -124,12 +125,17 @@ export class ProductPage extends Component {
|
||||
uuid: lineToMerge ? lineToMerge.uuid : null,
|
||||
qty: this.state.qty,
|
||||
product_id: this.product.id,
|
||||
full_product_name: this.product.name,
|
||||
customer_note: this.state.customer_note,
|
||||
custom_attribute_value_ids: Object.values(this.env.customValues),
|
||||
attribute_value_ids: attributeFlatter(this.env.selectedValues),
|
||||
});
|
||||
|
||||
mainLine.full_product_name = constructFullProductName(
|
||||
mainLine,
|
||||
this.selfOrder.attributeValueById,
|
||||
this.product.name
|
||||
);
|
||||
|
||||
lines.push(mainLine);
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ export class StandNumberPage extends Component {
|
||||
|
||||
confirm() {
|
||||
if (this.state.standNumber.length > 0) {
|
||||
this.selfOrder.tablePadNumber = this.state.standNumber;
|
||||
this.selfOrder.currentOrder.table_stand_number = this.state.standNumber;
|
||||
this.router.navigate("payment");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,6 @@ export class SelfOrder extends Reactive {
|
||||
this.lastEditedProductId = null;
|
||||
this.attributeValueById = {};
|
||||
this.eatingLocation = "in"; // (in, out) in by default because out can be disabled in the config
|
||||
this.tablePadNumber = null;
|
||||
this.currentProduct = 0;
|
||||
this.attributeById = {};
|
||||
this.priceLoading = false;
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
</div>
|
||||
<div id="self-payment-after" class="content-group row" invisible="not pos_self_ordering_mode in ['kiosk', 'mobile']">
|
||||
<label string="Pay after" for="pos_self_ordering_pay_after" class="col-lg-4"/>
|
||||
<field name="pos_self_ordering_pay_after" readonly="pos_self_ordering_mode == 'kiosk' or pos_self_ordering_service_mode == 'counter' and pos_self_ordering_mode == 'mobile'" widget="upgrade_selection"/>
|
||||
<field name="pos_self_ordering_pay_after" readonly="pos_self_ordering_mode == 'kiosk' or (pos_self_ordering_service_mode == 'counter' and pos_self_ordering_mode == 'mobile')" widget="upgrade_selection"/>
|
||||
</div>
|
||||
</setting>
|
||||
<setting string="Eat in / Take out" help="Adjust the tax rate based on whether customers are dining in or opting for takeout." invisible="not pos_self_ordering_mode in ['mobile', 'kiosk']">
|
||||
|
||||
@@ -4,7 +4,7 @@ from odoo import http, fields
|
||||
from odoo.http import request
|
||||
|
||||
|
||||
class PosSelfAdyenContoller(PosAdyenController):
|
||||
class PosSelfAdyenController(PosAdyenController):
|
||||
@http.route()
|
||||
def notification(self):
|
||||
super().notification()
|
||||
@@ -33,6 +33,7 @@ class PosSelfAdyenContoller(PosAdyenController):
|
||||
'pos_order_id': order_sudo.id
|
||||
})
|
||||
order_sudo.action_pos_order_paid()
|
||||
order_sudo._send_order()
|
||||
|
||||
if order_sudo.config_id.self_ordering_mode == 'kiosk':
|
||||
request.env['bus.bus']._sendone(f'pos_config-{order_sudo.config_id.access_token}', 'PAYMENT_STATUS', {
|
||||
|
||||
Reference in New Issue
Block a user