Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FIX] point_of_sale : get the order_number from the same sequence as SO #162119

Draft
wants to merge 1 commit into
base: 17.0
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
29 changes: 29 additions & 0 deletions addons/point_of_sale/controllers/main.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# -*- coding: utf-8 -*-
import logging
import re

from werkzeug.exceptions import Unauthorized

from odoo import http, _
from odoo.http import request
Expand Down Expand Up @@ -257,3 +260,29 @@ def _get_invoice(self, partner_values, invoice_values, pos_order, additional_inv
# Allowing default values for moves is important for some localizations that would need specific fields to be set on the invoice, such as Mexico.
pos_order.with_context(with_context).action_pos_order_invoice()
return request.redirect('/my/invoices/%s?access_token=%s' % (pos_order.account_move.id, pos_order.account_move._portal_ensure_token()))

@http.route('/pos/get-sequence', auth='public', type='json', website=True)
def get_sequence_number(self, access_token, delete_empty_record=False):
pos_config = request.env['pos.config'].sudo().search([('access_token', '=', access_token)], limit=1)
if not pos_config.has_active_session:
raise Unauthorized("Invalid access token")
company = pos_config.company_id
user = pos_config.current_session_id.user_id or pos_config.self_ordering_default_user_id
pos_config = pos_config.sudo(False).with_company(company).with_user(user).with_context(
allowed_company_ids=company.ids)

pos_session = pos_config.current_session_id

if pos_config.module_pos_restaurant and not delete_empty_record:
seq_id = pos_config.env['ir.sequence'].search([('code', '=', f'pos.order_{pos_session.id}'),
('company_id', '=', pos_config.company_id.id)])

order = request.env['pos.order'].sudo().search([('sequence_number', '=', seq_id.number_next_actual - 1),
('session_id', '=', pos_session.id)], limit=1)
if not order:
return seq_id.number_next_actual - 1

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}')
sequence_number = re.findall(r'\d+', ir_sequence_session)[0]
return sequence_number
7 changes: 5 additions & 2 deletions addons/point_of_sale/models/pos_config.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.

from datetime import datetime
from uuid import uuid4
import pytz
Expand Down Expand Up @@ -568,7 +567,11 @@ def _force_http(self):
# Methods to open the POS
def _action_to_open_ui(self):
if not self.current_session_id:
self.env['pos.session'].create({'user_id': self.env.uid, 'config_id': self.id})
session = self.env['pos.session'].create({'user_id': self.env.uid, 'config_id': self.id})
# Start the sequence to avoid duplicating the sequence number
# in the first order
self.env['ir.sequence'].with_context(
company_id=self.company_id.id).next_by_code(f'pos.order_{session.id}')
path = '/pos/web' if self._force_http() else '/pos/ui'
return {
'type': 'ir.actions.act_url',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,15 @@ export class ReceiptScreen extends Component {
get ticketScreen() {
return { name: "TicketScreen" };
}
orderDone() {
async orderDone() {
this.pos.removeOrder(this.currentOrder);
if (!this.pos.config.module_pos_restaurant) {
this.pos.pos_session.sequence_number = await this.env.services.rpc("/pos/get-sequence", {
access_token: this.pos.config.access_token,
});
}
this._addNewOrder();
const { name, props } = this.nextScreen;
const {name, props} = this.nextScreen;
this.pos.showScreen(name, props);
}
resumeOrder() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,10 @@ export class TicketScreen extends Component {
}
}
}
onCreateNewOrder() {
async onCreateNewOrder() {
this.pos.pos_session.sequence_number = await this.env.services.rpc("/pos/get-sequence", {
access_token: this.pos.config.access_token,
});
this.pos.add_new_order();
this.pos.showScreen("ProductScreen");
}
Expand Down
4 changes: 2 additions & 2 deletions addons/point_of_sale/static/src/app/store/models.js
Original file line number Diff line number Diff line change
Expand Up @@ -1386,7 +1386,7 @@ export class Order extends PosModel {
}
} else {
this.set_pricelist(this.pos.default_pricelist);
this.sequence_number = this.pos.pos_session.sequence_number++;
this.sequence_number = this.pos.pos_session.sequence_number;
this.access_token = uuidv4(); // unique uuid used to identify the authenticity of the request from the QR code.
this.ticketCode = this._generateTicketCode(); // 5-digits alphanum code shown on the receipt
this.uid = this.generate_unique_id();
Expand Down Expand Up @@ -1428,7 +1428,7 @@ export class Order extends PosModel {
this.sequence_number = json.sequence_number;
this.pos_session_id = json.pos_session_id;
} else if (json.pos_session_id !== this.pos.pos_session.id) {
this.sequence_number = this.pos.pos_session.sequence_number++;
this.sequence_number = this.pos.pos_session.sequence_number;
} else {
this.sequence_number = json.sequence_number;
this.pos.pos_session.sequence_number = Math.max(
Expand Down
6 changes: 6 additions & 0 deletions addons/point_of_sale/static/src/app/store/pos_store.js
Original file line number Diff line number Diff line change
Expand Up @@ -1835,7 +1835,13 @@ export class PosStore extends Reactive {

addOrderIfEmpty() {
if (!this.get_order()) {
this.pos_session.sequence_number++;
this.add_new_order();
// Just a dummy call to update the sequence number
// to avoid duplicating the sequence number with future orders
this.env.services.rpc("/pos/get-sequence", {
access_token: this.config.access_token,
});
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ registry.category("web_tour.tours").add("EWalletProgramTour2", {
// - Refund order.
ProductScreen.clickRefund(),
TicketScreen.filterIs("Paid"),
TicketScreen.selectOrder("-0004"),
TicketScreen.selectOrder("-0006"),
TicketScreen.partnerIs("BBBBBBB"),
TicketScreen.confirmRefund(),
ProductScreen.isShown(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { Component, useState } from "@odoo/owl";
import { Orderline } from "@point_of_sale/app/generic_components/orderline/orderline";
import { OrderWidget } from "@point_of_sale/app/generic_components/order_widget/order_widget";
import { groupBy } from "@web/core/utils/arrays";
import { _t } from "@web/core/l10n/translation";

export class SplitBillScreen extends Component {
static template = "pos_restaurant.SplitBillScreen";
Expand Down Expand Up @@ -61,7 +62,7 @@ export class SplitBillScreen extends Component {
if (!this._isFullPayOrder()) {
this._setQuantityOnCurrentOrder();

this.newOrder.set_screen_data({ name: "PaymentScreen" });
this.newOrder.set_screen_data({name: "PaymentScreen"});

// for the kitchen printer we assume that everything
// has already been sent to the kitchen before splitting
Expand All @@ -76,13 +77,28 @@ export class SplitBillScreen extends Component {

this.newOrder.setCustomerCount(1);
this.newOrder.originalSplittedOrder = this.currentOrder;
this.newOrder.sequence_number = this.newOrder.pos.pos_session.sequence_number;
if (this.newOrder.sequence_number === this.currentOrder.sequence_number){
this.newOrder.sequence_number++;
}
this.newOrder.uid = this.newOrder.generate_unique_id()
this.newOrder.name = _t("Order %s", this.newOrder.uid)
this.newOrder.trackingNumber = (
(this.newOrder.pos_session_id % 10) * 100 +
(this.newOrder.sequence_number % 100)
).toString();
const newCustomerCount = this.currentOrder.getCustomerCount() - 1;
this.currentOrder.setCustomerCount(newCustomerCount || 1);
this.currentOrder.set_screen_data({ name: "ProductScreen" });
this.currentOrder.set_screen_data({name: "ProductScreen"});

const reactiveNewOrder = this.pos.makeOrderReactive(this.newOrder);
this.pos.orders.add(reactiveNewOrder);
this.pos.selectedOrder = reactiveNewOrder;
// Just a dummy call to update the sequence number
// to avoid duplicating the sequence number with future orders
this.env.services.rpc("/pos/get-sequence", {
access_token: this.newOrder.pos.config.access_token,
});
}
this.pos.showScreen("PaymentScreen");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ patch(TicketScreen.prototype, {
},
async onDeleteOrder(order) {
const confirmed = await super.onDeleteOrder(...arguments);
if (confirmed && order.orderlines.length === 0) {
this.pos.pos_session.sequence_number = await this.env.services.rpc("/pos/get-sequence", {
access_token: this.pos.config.access_token,
delete_empty_record: true
});
}
if (
confirmed &&
this.pos.config.module_pos_restaurant &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,9 @@ patch(PosStore.prototype, {
if (currentOrder) {
this.set_order(currentOrder);
} else {
this.pos_session.sequence_number = await this.env.services.rpc("/pos/get-sequence", {
access_token: this.config.access_token,
});
this.add_new_order();
}
}
Expand Down