1
0
forked from Mapan/odoo17e
odoo17e-kedaikipas58/addons/pos_blackbox_be/models/pos_config.py
2024-12-10 09:04:09 +07:00

230 lines
9.8 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import models, fields, api
from odoo.exceptions import UserError
from odoo.exceptions import ValidationError
from odoo.tools.translate import _
from odoo.osv.expression import OR
from odoo.service.common import exp_version
class PosConfig(models.Model):
_inherit = "pos.config"
iface_fiscal_data_module = fields.Many2one(
"iot.device",
domain="[('type', '=', 'fiscal_data_module'), '|', ('company_id', '=', False), ('company_id', '=', company_id)]",
)
certified_blackbox_identifier = fields.Char(
"Blackbox Identifier",
store=True,
compute="_compute_certified_pos",
readonly=True,
)
pos_version = fields.Char('Odoo Version', compute='_compute_odoo_version')
def _compute_odoo_version(self):
self.pos_version = exp_version()['server_serie']
@api.depends("iface_fiscal_data_module")
def _compute_certified_pos(self):
if self.iface_fiscal_data_module:
self.certified_blackbox_identifier = self.iface_fiscal_data_module.name[
-14:
]
self.env["pos_blackbox_be.log"].sudo().create([{
"action": "create",
"model_name": self._name,
"record_name": self.name,
"description": "Session started with: %s" % self.certified_blackbox_identifier,
}])
if not self.env['ir.sequence'].search([('code', '=', f'pos_blackbox_be.NS_blackbox_{self.certified_blackbox_identifier}')]):
self.env['ir.sequence'].sudo().create({
'name': _("NS Order by blackbox"),
'padding': 4,
'code': f'pos_blackbox_be.NS_blackbox_{self.certified_blackbox_identifier}',
'company_id': self.company_id.id,
})
self.env['ir.sequence'].sudo().create({
'name': _("PS Order by blackbox"),
'padding': 4,
'code': f'pos_blackbox_be.PS_blackbox_{self.certified_blackbox_identifier}',
'company_id': self.company_id.id,
})
def _check_is_certified_pos(self):
if self.certified_blackbox_identifier and not self.iface_fiscal_data_module:
raise UserError(
_("Forbidden to start a certified Point of sale without blackbox")
)
@api.depends("iface_fiscal_data_module")
def _compute_iot_device_ids(self):
super(PosConfig, self)._compute_iot_device_ids()
for config in self:
if config.is_posbox:
config.iot_device_ids += config.iface_fiscal_data_module
def _check_before_creating_new_session(self):
self._check_is_certified_pos()
if self.iface_fiscal_data_module:
self._check_self_order()
self._check_loyalty()
self._check_insz_user()
self._check_company_address()
self._check_work_product_taxes()
self._check_employee_insz_or_bis_number()
self._check_pos_category()
self._check_cash_rounding()
self._check_printer_connected()
self._check_floor_plan_ids()
self._check_is_table()
return super(PosConfig, self)._check_before_creating_new_session()
def _check_self_order(self):
for config in self:
if (
self.env['ir.module.module'].search([('name', '=', 'pos_self_order'), ('state', '=', 'installed')]) and config.self_ordering_mode not in ['nothing', 'consultation']
):
raise UserError(
_(
'Certified blackbox are not compatible with the self-ordering mode ("QR menu + Ordering" and "Kiosk") for the moment. Please disable it.'
)
)
def _check_loyalty(self):
for config in self:
if (
self.env['ir.module.module'].search([('name', '=', 'pos_loyalty'), ('state', '=', 'installed')]) and config._get_program_ids()
):
raise UserError(
_(
"Loyalty programs and gift card cannot be used on a PoS associated with a blackbox."
)
)
def _check_work_product_taxes(self):
work_in = self.env.ref("pos_blackbox_be.product_product_work_in")
work_out = self.env.ref("pos_blackbox_be.product_product_work_out")
if (
not work_in.taxes_id
or work_in.taxes_id.amount != 0
or not work_out.taxes_id
or work_out.taxes_id.amount != 0
):
raise ValidationError(
_("The WORK IN/OUT products must have a taxes with 0%.")
)
def _check_insz_user(self):
if not self.env.user.insz_or_bis_number:
raise ValidationError(_("The user must have a INSZ or BIS number."))
def _check_company_address(self):
if not self.company_id.street:
raise ValidationError(_("The address of the company must be filled."))
if not self.company_id.company_registry:
raise ValidationError(_("The VAT number of the company must be filled."))
def _check_pos_category(self):
if self.limit_categories:
if (
self.env.ref("pos_blackbox_be.pos_category_fdm").id
not in self.iface_available_categ_ids.ids
):
raise ValidationError(
_(
"You have to add the fiscal category to the limited category in order to use the fiscal data module"
)
)
def _check_is_table(self):
if self.iface_fiscal_data_module and self.module_pos_restaurant:
if not self.floor_ids:
raise ValidationError(_("You must link at least 1 floor to the configuration in order to use the fiscal data module."))
for floor in self.floor_ids:
if floor.table_ids:
return
raise ValidationError(_("You must link at least 1 table to the configuration in order to use the fiscal data module."))
@api.constrains("iface_fiscal_data_module", "fiscal_position_ids")
def _check_posbox_fp_tax_code(self):
invalid_tax_lines = [
(fp.name, tax_line.tax_dest_id.name)
for config in self
for fp in config.fiscal_position_ids
for tax_line in fp.tax_ids
if (
tax_line.tax_src_id.identification_letter
and not tax_line.tax_dest_id.identification_letter
)
]
if invalid_tax_lines:
raise ValidationError(
"Fiscal Position %s (tax %s) has an invalid tax amount. Only 21%%, 12%%, 6%% and 0%% are allowed." %
invalid_tax_lines[0]
)
@api.constrains('iface_fiscal_data_module', 'floor_ids')
def _check_floor_plan_ids(self):
if self.iface_fiscal_data_module and self.floor_ids:
for floor in self.floor_ids:
if len(floor.pos_config_ids) > 1:
raise ValidationError("Floor plans cannot be shared in different POS configurations when using the Blackbox module.")
def _check_employee_insz_or_bis_number(self):
for config in self:
if config.module_pos_hr:
all_employee_ids = self.env['hr.employee'].search(self._employee_domain(self.env.uid))
emp_names = [emp.name for emp in all_employee_ids if not emp.sudo().insz_or_bis_number] + ([self.env.user.name] if not self.env.user.employee_id.insz_or_bis_number else [])
if len(emp_names) > 0:
raise ValidationError(
_("%s must have an INSZ or BIS number.", ", ".join(emp_names))
)
def _check_cash_rounding(self):
if not self.cash_rounding:
raise ValidationError(_("Cash rounding must be enabled"))
if (
self.rounding_method.rounding != 0.05
or self.rounding_method.rounding_method != "HALF-UP"
):
raise ValidationError(
_("The rounding method must be set to 0.5 and HALF-UP")
)
def _check_printer_connected(self):
epson_printer = False
if hasattr(self, "epson_printer_ip"):
epson_printer = self.epson_printer_ip
if not self.iface_printer_id and not epson_printer:
raise ValidationError(_("A printer must be connected"))
if not self.iface_print_auto:
raise ValidationError(_("Automatic Receipt Printing must be activated"))
if not self.iface_print_skip_screen:
raise ValidationError(_("Skip Preview Screen must be activated"))
def _get_work_products(self):
empty_product = self.env['product.product']
work_in_product = self.env.ref('pos_blackbox_be.product_product_work_in', raise_if_not_found=False) or empty_product
work_out_product = self.env.ref('pos_blackbox_be.product_product_work_out', raise_if_not_found=False) or empty_product
return work_in_product | work_out_product
def _get_special_products(self):
return super()._get_special_products() | self._get_work_products()
def _get_available_product_domain(self):
domain = super()._get_available_product_domain()
if work_products := self._get_work_products():
return OR([domain, [('id', 'in', work_products.ids)]])
return domain
def get_NS_sequence_next(self):
return self.env['ir.sequence'].next_by_code(f'pos_blackbox_be.NS_blackbox_{self.certified_blackbox_identifier}')
def get_PS_sequence_next(self):
return self.env['ir.sequence'].next_by_code(f'pos_blackbox_be.PS_blackbox_{self.certified_blackbox_identifier}')