[REF] point_of_sale, pos_*: only use export_for_ui for serializing
*:pos_hr,pos_hr_restaurant,pos_loyalty,pos_restaurant Before when serializing a pos.order from the server, we are using several methods for different use cases. - table syncing: get_table_draft_orders - order sharing: get_draft_share_order_ids - ticket screen: export_for_ui All of these methods had their own logic. Now, to improve the maintainability of point_of_sale, order serialization is only performed via export_for_ui. Enterprise PR: https://github.com/odoo/enterprise/pull/45151 closes odoo/odoo#130695 Taskid: 3449870 Related: odoo/enterprise#45151 Signed-off-by: Joseph Caburnay (jcb) <jcb@odoo.com>
This commit is contained in:
@@ -1039,169 +1039,9 @@ class PosOrder(models.Model):
|
||||
mail = self.env['mail.mail'].sudo().create(self._prepare_mail_values(name, client, ticket))
|
||||
mail.send()
|
||||
|
||||
def _get_order_lines(self, orders):
|
||||
"""Add pos_order_lines to the orders.
|
||||
|
||||
The function doesn't return anything but adds the results directly to the orders.
|
||||
|
||||
:param orders: orders for which the order_lines are to be requested.
|
||||
:type orders: pos.order.
|
||||
"""
|
||||
order_lines = self.env['pos.order.line'].search_read(
|
||||
domain=[('order_id', 'in', [to['id'] for to in orders])],
|
||||
fields=self._get_fields_for_order_line())
|
||||
|
||||
if order_lines != []:
|
||||
self._get_pack_lot_lines(order_lines)
|
||||
|
||||
extended_order_lines = []
|
||||
for order_line in order_lines:
|
||||
extended_order_lines.append([0, 0, self._prepare_order_line(order_line)])
|
||||
|
||||
for order_id, order_lines in groupby(extended_order_lines, key=lambda x: x[2]['order_id']):
|
||||
next(order for order in orders if order['id'] == order_id[0])['lines'] = list(order_lines)
|
||||
|
||||
def _get_pack_lot_lines(self, order_lines):
|
||||
"""Add pack_lot_lines to the order_lines.
|
||||
|
||||
The function doesn't return anything but adds the results directly to the order_lines.
|
||||
|
||||
:param order_lines: order_lines for which the pack_lot_lines are to be requested.
|
||||
:type order_lines: pos.order.line.
|
||||
"""
|
||||
pack_lots = self.env['pos.pack.operation.lot'].search_read(
|
||||
domain=[('pos_order_line_id', 'in', [order_line['id'] for order_line in order_lines])],
|
||||
fields=[
|
||||
'id',
|
||||
'lot_name',
|
||||
'pos_order_line_id'
|
||||
])
|
||||
for pack_lot in pack_lots:
|
||||
pack_lot['order_line'] = pack_lot['pos_order_line_id'][0]
|
||||
pack_lot['server_id'] = pack_lot['id']
|
||||
|
||||
del pack_lot['pos_order_line_id']
|
||||
del pack_lot['id']
|
||||
|
||||
for order_line_id, pack_lot_ids in groupby(pack_lots, key=lambda x: x['order_line']):
|
||||
next(order_line for order_line in order_lines if order_line['id'] == order_line_id)['pack_lot_ids'] = list(pack_lot_ids)
|
||||
|
||||
def _prepare_order_line(self, order_line):
|
||||
"""Method that will allow the cleaning of values to send the correct information.
|
||||
:param order_line: order_line that will be cleaned.
|
||||
:type order_line: pos.order.line.
|
||||
:returns: dict -- dict representing the order line's values.
|
||||
"""
|
||||
order_line["product_id"] = order_line["product_id"][0]
|
||||
order_line["server_id"] = order_line["id"]
|
||||
|
||||
del order_line["id"]
|
||||
if not "pack_lot_ids" in order_line:
|
||||
order_line["pack_lot_ids"] = []
|
||||
else:
|
||||
order_line["pack_lot_ids"] = [[0, 0, lot] for lot in order_line["pack_lot_ids"]]
|
||||
return order_line
|
||||
|
||||
def _get_fields_for_payment_lines(self):
|
||||
return [
|
||||
'id',
|
||||
'amount',
|
||||
'pos_order_id',
|
||||
'payment_method_id',
|
||||
'card_type',
|
||||
'cardholder_name',
|
||||
'transaction_id',
|
||||
'payment_status'
|
||||
]
|
||||
|
||||
def _get_payments_lines_list(self, orders):
|
||||
payment_lines = self.env['pos.payment'].search_read(
|
||||
domain=[('pos_order_id', 'in', [po['id'] for po in orders])],
|
||||
fields=self._get_fields_for_payment_lines())
|
||||
|
||||
extended_payment_lines = []
|
||||
for payment_line in payment_lines:
|
||||
payment_line['server_id'] = payment_line['id']
|
||||
payment_line['payment_method_id'] = payment_line['payment_method_id'][0]
|
||||
|
||||
del payment_line['id']
|
||||
extended_payment_lines.append([0, 0, payment_line])
|
||||
return extended_payment_lines
|
||||
|
||||
def _get_payment_lines(self, orders):
|
||||
"""Add account_bank_statement_lines to the orders.
|
||||
|
||||
The function doesn't return anything but adds the results directly to the orders.
|
||||
|
||||
:param orders: orders for which the payment_lines are to be requested.
|
||||
:type orders: pos.order.
|
||||
"""
|
||||
extended_payment_lines = self._get_payments_lines_list(orders)
|
||||
for order_id, payment_lines in groupby(extended_payment_lines, key=lambda x: x[2]['pos_order_id']):
|
||||
next(order for order in orders if order['id'] == order_id[0])['statement_ids'] = list(payment_lines)
|
||||
|
||||
def _get_fields_for_draft_order(self):
|
||||
return [
|
||||
'id',
|
||||
'pricelist_id',
|
||||
'partner_id',
|
||||
'sequence_number',
|
||||
'session_id',
|
||||
'pos_reference',
|
||||
'create_uid',
|
||||
'create_date',
|
||||
'fiscal_position_id',
|
||||
'last_order_preparation_change',
|
||||
'to_invoice',
|
||||
'access_token',
|
||||
'ticket_code',
|
||||
]
|
||||
|
||||
@api.model
|
||||
def get_draft_share_order_ids(self, config_id):
|
||||
"""Search for 'draft' orders that satisfy the given domain."""
|
||||
config = self.env['pos.config'].browse(config_id)
|
||||
default_domain = ['&', ('state', '=', 'draft'), '|', ('config_id', '=', config_id), ('config_id', 'in', config.trusted_config_ids.ids)]
|
||||
orders = self.search_read(
|
||||
domain=default_domain,
|
||||
fields=self._get_fields_for_draft_order())
|
||||
|
||||
self._get_order_lines(orders)
|
||||
self._get_payment_lines(orders)
|
||||
|
||||
self._prepare_order(orders)
|
||||
|
||||
return orders
|
||||
|
||||
def is_already_paid(self):
|
||||
return self.state == "paid"
|
||||
|
||||
@api.model
|
||||
def _prepare_order(self, orders):
|
||||
timezone = pytz.timezone(self._context.get('tz') or self.env.user.tz or 'UTC')
|
||||
for order in orders:
|
||||
order['pos_session_id'] = order['session_id'][0]
|
||||
order['uid'] = re.search(r"\d{5,}-\d{3,}-\d{4,}", order['pos_reference']).group(0)
|
||||
order['name'] = order['pos_reference']
|
||||
order['creation_date'] = order['create_date'].astimezone(timezone)
|
||||
order['server_id'] = order['id']
|
||||
if order['fiscal_position_id']:
|
||||
order['fiscal_position_id'] = order['fiscal_position_id'][0]
|
||||
if order['pricelist_id']:
|
||||
order['pricelist_id'] = order['pricelist_id'][0]
|
||||
if order['partner_id']:
|
||||
order['partner_id'] = order['partner_id'][0]
|
||||
|
||||
if not 'lines' in order:
|
||||
order['lines'] = []
|
||||
if not 'statement_ids' in order:
|
||||
order['statement_ids'] = []
|
||||
|
||||
del order['id']
|
||||
del order['session_id']
|
||||
del order['pos_reference']
|
||||
del order['create_date']
|
||||
|
||||
@api.model
|
||||
def remove_from_ui(self, server_ids):
|
||||
""" Remove orders from the frontend PoS application
|
||||
@@ -1275,24 +1115,14 @@ class PosOrder(models.Model):
|
||||
'tip_amount': order.tip_amount,
|
||||
'access_token': order.access_token,
|
||||
'ticket_code': order.ticket_code,
|
||||
'last_order_preparation_change': order.last_order_preparation_change,
|
||||
}
|
||||
|
||||
def _get_fields_for_order_line(self):
|
||||
"""This function is here to be overriden"""
|
||||
fields = [
|
||||
'id',
|
||||
'uuid',
|
||||
'discount',
|
||||
'skip_change',
|
||||
'product_id',
|
||||
'price_unit',
|
||||
'order_id',
|
||||
'qty',
|
||||
'full_product_name',
|
||||
'customer_note',
|
||||
'price_extra',
|
||||
]
|
||||
return fields
|
||||
@api.model
|
||||
def export_for_ui_shared_order(self, config_id):
|
||||
config = self.env['pos.config'].browse(config_id)
|
||||
orders = self.env['pos.order'].search(['&', ('state', '=', 'draft'), '|', ('config_id', '=', config_id), ('config_id', 'in', config.trusted_config_ids.ids)])
|
||||
return orders.export_for_ui()
|
||||
|
||||
def export_for_ui(self):
|
||||
""" Returns a list of dict with each item having similar signature as the return of
|
||||
@@ -1473,7 +1303,7 @@ class PosOrderLine(models.Model):
|
||||
'refunded_qty': orderline.refunded_qty,
|
||||
'price_extra': orderline.price_extra,
|
||||
'full_product_name': orderline.full_product_name,
|
||||
'refunded_orderline_id': orderline.refunded_orderline_id,
|
||||
'refunded_orderline_id': orderline.refunded_orderline_id.id,
|
||||
}
|
||||
|
||||
def export_for_ui(self):
|
||||
@@ -1602,6 +1432,7 @@ class PosOrderLineLot(models.Model):
|
||||
def _export_for_ui(self, lot):
|
||||
return {
|
||||
'lot_name': lot.lot_name,
|
||||
'order_line': lot.pos_order_line_id.id,
|
||||
}
|
||||
|
||||
def export_for_ui(self):
|
||||
|
||||
@@ -51,6 +51,7 @@ class PosPayment(models.Model):
|
||||
return {
|
||||
'payment_method_id': payment.payment_method_id.id,
|
||||
'amount': payment.amount,
|
||||
'pos_order_id': payment.pos_order_id.id,
|
||||
'payment_status': payment.payment_status,
|
||||
'card_type': payment.card_type,
|
||||
'cardholder_name': payment.cardholder_name,
|
||||
|
||||
@@ -1317,7 +1317,7 @@ export class Order extends PosModel {
|
||||
this.name = sprintf(_t("Order %s"), this.uid);
|
||||
}
|
||||
this.validation_date = json.creation_date;
|
||||
this.server_id = json.server_id ? json.server_id : false;
|
||||
this.server_id = json.server_id || json.id || false;
|
||||
this.user_id = json.user_id;
|
||||
this.firstDraft = false;
|
||||
|
||||
|
||||
@@ -749,7 +749,7 @@ export class PosStore extends Reactive {
|
||||
return message;
|
||||
}
|
||||
async _getOrdersJson() {
|
||||
return await this.orm.call("pos.order", "get_draft_share_order_ids", [], {
|
||||
return await this.orm.call("pos.order", "export_for_ui_shared_order", [], {
|
||||
config_id: this.config.id,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -28,17 +28,3 @@ class PosOrder(models.Model):
|
||||
'employee_id': order.employee_id.id,
|
||||
})
|
||||
return result
|
||||
|
||||
def _get_fields_for_draft_order(self):
|
||||
fields = super(PosOrder, self)._get_fields_for_draft_order()
|
||||
fields.append('employee_id')
|
||||
return fields
|
||||
|
||||
@api.model
|
||||
def get_draft_share_order_ids(self, config_id):
|
||||
orders = super(PosOrder, self).get_draft_share_order_ids(config_id)
|
||||
for order in orders:
|
||||
if order['employee_id']:
|
||||
order['employee_id'] = order['employee_id'][0]
|
||||
|
||||
return orders
|
||||
|
||||
@@ -1,4 +1,2 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import models
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import pos_order
|
||||
@@ -1,17 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import models, api
|
||||
|
||||
|
||||
class PosOrder(models.Model):
|
||||
_inherit = "pos.order"
|
||||
|
||||
@api.model
|
||||
def get_table_draft_orders(self, table_ids):
|
||||
table_orders = super().get_table_draft_orders(table_ids)
|
||||
for order in table_orders:
|
||||
if order['employee_id']:
|
||||
order['employee_id'] = order['employee_id'][0]
|
||||
|
||||
return table_orders
|
||||
@@ -145,21 +145,6 @@ class PosOrder(models.Model):
|
||||
'coupon_report': coupon_per_report,
|
||||
}
|
||||
|
||||
def _prepare_order_line(self, order_line):
|
||||
order_line = super(PosOrder, self)._prepare_order_line(order_line)
|
||||
|
||||
if order_line.get("reward_id"):
|
||||
order_line["reward_id"] = order_line["reward_id"][0]
|
||||
if order_line.get("coupon_id"):
|
||||
order_line["coupon_id"] = order_line["coupon_id"][0]
|
||||
|
||||
return order_line
|
||||
|
||||
def _get_fields_for_order_line(self):
|
||||
fields = super(PosOrder, self)._get_fields_for_order_line()
|
||||
fields.extend(['is_reward_line', 'reward_id', 'coupon_id', 'reward_identifier_code', 'points_cost'])
|
||||
return fields
|
||||
|
||||
def _add_mail_attachment(self, name, ticket):
|
||||
attachment = super()._add_mail_attachment(name, ticket)
|
||||
gift_card_programs = self.config_id._get_program_ids().filtered(lambda p: p.program_type == 'gift_card' and
|
||||
|
||||
@@ -33,4 +33,7 @@ class PosOrderLine(models.Model):
|
||||
result = super()._export_for_ui(orderline)
|
||||
result['is_reward_line'] = orderline.is_reward_line
|
||||
result['reward_id'] = orderline.reward_id.id
|
||||
result['coupon_id'] = orderline.coupon_id.id
|
||||
result['reward_identifier_code'] = orderline.reward_identifier_code
|
||||
result['points_cost'] = orderline.points_cost
|
||||
return result
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
from odoo.tools import groupby
|
||||
from re import search
|
||||
from functools import partial
|
||||
|
||||
import pytz
|
||||
|
||||
from odoo import api, fields, models
|
||||
|
||||
|
||||
@@ -21,39 +17,6 @@ class PosOrder(models.Model):
|
||||
table_id = fields.Many2one('restaurant.table', string='Table', help='The table where this order was served', index='btree_not_null', readonly=True)
|
||||
customer_count = fields.Integer(string='Guests', help='The amount of customers that have been served by this order.', readonly=True)
|
||||
|
||||
def _get_fields_for_order_line(self):
|
||||
fields = super(PosOrder, self)._get_fields_for_order_line()
|
||||
fields.extend([
|
||||
'note',
|
||||
'full_product_name',
|
||||
'customer_note',
|
||||
'price_extra',
|
||||
'refunded_orderline_id',
|
||||
])
|
||||
return fields
|
||||
|
||||
def _prepare_order_line(self, order_line):
|
||||
order_line = super(PosOrder, self)._prepare_order_line(order_line)
|
||||
order_line["refunded_orderline_id"] = order_line["refunded_orderline_id"] and \
|
||||
order_line["refunded_orderline_id"][0]
|
||||
return order_line
|
||||
|
||||
def _get_fields_for_draft_order(self):
|
||||
fields = super()._get_fields_for_draft_order()
|
||||
fields.extend([
|
||||
'table_id',
|
||||
'customer_count',
|
||||
])
|
||||
return fields
|
||||
|
||||
def _get_domain_for_draft_orders(self, table_ids):
|
||||
""" Get the domain to search for draft orders on a table.
|
||||
:param table_ids: Ids of the selected tables.
|
||||
:type table_ids: list of int.
|
||||
"returns: list -- list of tuples that represents a domain.
|
||||
"""
|
||||
return [('state', '=', 'draft'), ('table_id', 'in', table_ids)]
|
||||
|
||||
@api.model
|
||||
def remove_from_ui(self, server_ids):
|
||||
tables = self.env['pos.order'].search([('id', 'in', server_ids)]).table_id
|
||||
@@ -75,35 +38,6 @@ class PosOrder(models.Model):
|
||||
messages.append((config_cur_session._get_bus_channel_name(), 'TABLE_ORDER_COUNT', order_count))
|
||||
self.env['bus.bus']._sendmany(messages)
|
||||
|
||||
@api.model
|
||||
def get_table_draft_orders(self, table_ids):
|
||||
"""Generate an object of all draft orders for the given table.
|
||||
|
||||
Generate and return an JSON object with all draft orders for the given table, to send to the
|
||||
front end application.
|
||||
|
||||
:param table_ids: Ids of the selected tables.
|
||||
:type table_ids: list of int.
|
||||
:returns: list -- list of dict representing the table orders
|
||||
"""
|
||||
table_orders = self.search_read(
|
||||
domain=self._get_domain_for_draft_orders(table_ids),
|
||||
fields=self._get_fields_for_draft_order())
|
||||
|
||||
self._get_order_lines(table_orders)
|
||||
self._get_payment_lines(table_orders)
|
||||
|
||||
self._prepare_order(table_orders)
|
||||
|
||||
return table_orders
|
||||
|
||||
@api.model
|
||||
def _prepare_order(self, orders):
|
||||
super(PosOrder, self)._prepare_order(orders)
|
||||
for order in orders:
|
||||
if order['table_id']:
|
||||
order['table_id'] = order['table_id'][0]
|
||||
|
||||
def set_tip(self, tip_line_vals):
|
||||
"""Set tip to `self` based on values in `tip_line_vals`."""
|
||||
|
||||
@@ -152,4 +86,10 @@ class PosOrder(models.Model):
|
||||
def _export_for_ui(self, order):
|
||||
result = super(PosOrder, self)._export_for_ui(order)
|
||||
result['table_id'] = order.table_id.id
|
||||
result['customer_count'] = order.customer_count
|
||||
return result
|
||||
|
||||
@api.model
|
||||
def export_for_ui_table_draft(self, table_ids):
|
||||
orders = self.env['pos.order'].search([('state', '=', 'draft'), ('table_id', 'in', table_ids)])
|
||||
return orders.export_for_ui()
|
||||
|
||||
@@ -141,7 +141,7 @@ patch(PosStore.prototype, {
|
||||
// FIXME POSREF timeout
|
||||
const orders = await this.env.services.orm.silent.call(
|
||||
"pos.order",
|
||||
"get_table_draft_orders",
|
||||
"export_for_ui_table_draft",
|
||||
[tableIds]
|
||||
);
|
||||
this.set_synch("connected");
|
||||
|
||||
@@ -198,11 +198,11 @@ class TestFrontend(odoo.tests.HttpCase):
|
||||
self.pos_config.with_user(self.env.ref('base.user_demo')).open_ui()
|
||||
self.start_tour("/pos/ui?config_id=%d" % self.pos_config.id, 'PosResTipScreenTour', login="demo")
|
||||
|
||||
order1 = self.env['pos.order'].search([('pos_reference', 'ilike', '%-0001')])
|
||||
order2 = self.env['pos.order'].search([('pos_reference', 'ilike', '%-0002')])
|
||||
order3 = self.env['pos.order'].search([('pos_reference', 'ilike', '%-0003')])
|
||||
order4 = self.env['pos.order'].search([('pos_reference', 'ilike', '%-0004')])
|
||||
order5 = self.env['pos.order'].search([('pos_reference', 'ilike', '%-0005')])
|
||||
order1 = self.env['pos.order'].search([('pos_reference', 'ilike', '%-0001')], limit=1, order='id desc')
|
||||
order2 = self.env['pos.order'].search([('pos_reference', 'ilike', '%-0002')], limit=1, order='id desc')
|
||||
order3 = self.env['pos.order'].search([('pos_reference', 'ilike', '%-0003')], limit=1, order='id desc')
|
||||
order4 = self.env['pos.order'].search([('pos_reference', 'ilike', '%-0004')], limit=1, order='id desc')
|
||||
order5 = self.env['pos.order'].search([('pos_reference', 'ilike', '%-0005')], limit=1, order='id desc')
|
||||
|
||||
self.assertTrue(order1.is_tipped and order1.tip_amount == 0.40)
|
||||
self.assertTrue(order2.is_tipped and order2.tip_amount == 1.00)
|
||||
|
||||
Reference in New Issue
Block a user