19.0 vanilla

This commit is contained in:
Ernad Husremovic 2026-03-09 09:29:53 +01:00
parent 6e54c1af6c
commit 3ca647e428
1087 changed files with 132065 additions and 108499 deletions

View file

@ -1,55 +1,100 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models, _
from odoo import api, fields, models, _, Command
from odoo.exceptions import UserError
class RestaurantFloor(models.Model):
_name = 'restaurant.floor'
_description = 'Restaurant Floor'
_order = "sequence, name"
_inherit = ['pos.load.mixin']
name = fields.Char('Floor Name', required=True)
pos_config_id = fields.Many2one('pos.config', string='Point of Sale')
pos_config_ids = fields.Many2many('pos.config', string='Point of Sales', domain="[('module_pos_restaurant', '=', True)]")
background_image = fields.Binary('Background Image')
background_color = fields.Char('Background Color', help='The background color of the floor in a html-compatible format', default='rgb(210, 210, 210)')
background_color = fields.Char('Background Color', help='The background color of the floor in a html-compatible format')
table_ids = fields.One2many('restaurant.table', 'floor_id', string='Tables')
sequence = fields.Integer('Sequence', default=1)
active = fields.Boolean(default=True)
floor_background_image = fields.Image(string='Floor Background Image')
@api.model
def _load_pos_data_domain(self, data, config):
return [('pos_config_ids', '=', config.id)]
@api.model
def _load_pos_data_fields(self, config):
return ['name', 'background_color', 'table_ids', 'sequence', 'pos_config_ids', 'floor_background_image', 'active']
@api.ondelete(at_uninstall=False)
def _unlink_except_active_pos_session(self):
confs = self.mapped('pos_config_id').filtered(lambda c: c.is_table_management == True)
confs = self.mapped('pos_config_ids').filtered(lambda c: c.module_pos_restaurant)
opened_session = self.env['pos.session'].search([('config_id', 'in', confs.ids), ('state', '!=', 'closed')])
if opened_session:
if opened_session and confs:
error_msg = _("You cannot remove a floor that is used in a PoS session, close the session(s) first: \n")
for floor in self:
for session in opened_session:
if floor in session.config_id.floor_ids:
error_msg += _("Floor: %s - PoS Config: %s \n") % (floor.name, session.config_id.name)
if confs:
raise UserError(error_msg)
error_msg += _("Floor: %(floor)s - PoS Config: %(config)s \n", floor=floor.name, config=session.config_id.name)
raise UserError(error_msg)
def write(self, vals):
for floor in self:
if floor.pos_config_id.has_active_session and (vals.get('pos_config_id') or vals.get('active')) :
raise UserError(
'Please close and validate the following open PoS Session before modifying this floor.\n'
'Open session: %s' % (' '.join(floor.pos_config_id.mapped('name')),))
if vals.get('pos_config_id') and floor.pos_config_id.id and vals.get('pos_config_id') != floor.pos_config_id.id:
raise UserError(_('The %s is already used in another Pos Config.', floor.name))
return super(RestaurantFloor, self).write(vals)
for config in floor.pos_config_ids:
if config.has_active_session and (vals.get('pos_config_ids') or vals.get('active')):
raise UserError(
self.env._(
"Please close and validate the following open PoS Session before modifying this floor.\n"
"Open session: %(session_names)s",
session_names=" ".join(config.mapped("name")),
)
)
return super().write(vals)
def rename_floor(self, new_name):
for floor in self:
floor.name = new_name
@api.model
def sync_from_ui(self, name, background_color, config_id):
floor_fields = {
"name": name,
"background_color": background_color,
}
pos_floor = self.create(floor_fields)
pos_floor.pos_config_ids = [Command.link(config_id)]
return {
'id': pos_floor.id,
'name': pos_floor.name,
'background_color': pos_floor.background_color,
'table_ids': [],
'sequence': pos_floor.sequence,
'tables': [],
}
def deactivate_floor(self, session_id):
draft_orders = self.env['pos.order'].search([('session_id', '=', session_id), ('state', '=', 'draft'), ('table_id.floor_id', '=', self.id)])
if draft_orders:
raise UserError(_("You cannot delete a floor when orders are still in draft for this floor."))
for table in self.table_ids:
table.active = False
self.active = False
return True
class RestaurantTable(models.Model):
_name = 'restaurant.table'
_description = 'Restaurant Table'
name = fields.Char('Table Name', required=True, help='An internal identification of a table')
floor_id = fields.Many2one('restaurant.floor', string='Floor')
_description = 'Restaurant Table'
_inherit = ['pos.load.mixin']
floor_id = fields.Many2one('restaurant.floor', string='Floor', index='btree_not_null')
table_number = fields.Integer('Table Number', required=True, help='The number of the table as displayed on the floor plan', default=0)
shape = fields.Selection([('square', 'Square'), ('round', 'Round')], string='Shape', required=True, default='square')
position_h = fields.Float('Horizontal Position', default=10,
help="The table's horizontal position from the left side to the table's center, in pixels")
@ -59,43 +104,35 @@ class RestaurantTable(models.Model):
height = fields.Float('Height', default=50, help="The table's height in pixels")
seats = fields.Integer('Seats', default=1, help="The default number of customer served at this table.")
color = fields.Char('Color', help="The table's color, expressed as a valid 'background' CSS property value")
parent_id = fields.Many2one('restaurant.table', string='Parent Table', help="The parent table if this table is part of a group of tables")
active = fields.Boolean('Active', default=True, help='If false, the table is deactivated and will not be available in the point of sale')
@api.model
def create_from_ui(self, table):
""" create or modify a table from the point of sale UI.
table contains the table's fields. If it contains an
id, it will modify the existing table. It then
returns the id of the table.
"""
if table.get('floor_id'):
table['floor_id'] = table['floor_id'][0]
@api.depends('table_number', 'floor_id')
def _compute_display_name(self):
for table in self:
table.display_name = f"{table.floor_id.name}, {table.table_number}"
sanitized_table = dict([(key, val) for key, val in table.items() if key in self._fields and val is not None])
table_id = sanitized_table.pop('id', False)
if table_id:
self.browse(table_id).write(sanitized_table)
else:
table_id = self.create(sanitized_table).id
return table_id
@api.model
def _load_pos_data_domain(self, data, config):
return [('active', '=', True), ('floor_id', 'in', config.floor_ids.ids)]
@api.model
def _load_pos_data_fields(self, config):
return ['table_number', 'width', 'height', 'position_h', 'position_v', 'parent_id', 'shape', 'floor_id', 'color', 'seats', 'active']
def are_orders_still_in_draft(self):
draft_orders_count = self.env['pos.order'].search_count([('table_id', 'in', self.ids), ('state', '=', 'draft')])
if draft_orders_count > 0:
raise UserError(_("You cannot delete a table when orders are still in draft for this table."))
return True
@api.ondelete(at_uninstall=False)
def _unlink_except_active_pos_session(self):
confs = self.mapped('floor_id').mapped('pos_config_id').filtered(lambda c: c.is_table_management == True)
confs = self.mapped('floor_id.pos_config_ids').filtered(lambda c: c.module_pos_restaurant)
opened_session = self.env['pos.session'].search([('config_id', 'in', confs.ids), ('state', '!=', 'closed')])
if opened_session:
error_msg = _("You cannot remove a table that is used in a PoS session, close the session(s) first.")
if confs:
raise UserError(error_msg)
class RestaurantPrinter(models.Model):
_name = 'restaurant.printer'
_description = 'Restaurant Printer'
name = fields.Char('Printer Name', required=True, default='Printer', help='An internal identification of the printer')
printer_type = fields.Selection(string='Printer Type', default='iot',
selection=[('iot', ' Use a printer connected to the IoT Box')])
proxy_ip = fields.Char('Proxy IP Address', help="The IP Address or hostname of the Printer's hardware proxy")
product_categories_ids = fields.Many2many('pos.category', 'printer_category_rel', 'printer_id', 'category_id', string='Printed Product Categories')