POS: venta de artículos de inventario (productos/consumibles)

- Toggle Servicios|Artículos en el catálogo del POS
- Líneas de venta con item_id (service_id opcional), stock descargado
  con movimiento 'venta' al cobrar, advertencias de sobreventa
- Campo precio de venta en artículos de inventario (backend Odoo)
This commit is contained in:
2026-08-14 01:52:01 +00:00
parent 07e05a643e
commit 84f34c542f
6 changed files with 193 additions and 36 deletions

View File

@@ -189,7 +189,8 @@ class SkeenVentaLine(models.Model):
_description = 'Línea de Venta SKEEN'
venta_id = fields.Many2one('skeen.venta', string='Venta', required=True, ondelete='cascade')
service_id = fields.Many2one('skeen.servicio', string='Servicio', required=True)
service_id = fields.Many2one('skeen.servicio', string='Servicio')
item_id = fields.Many2one('skeen.inventario.item', string='Artículo inventario')
description = fields.Char(string='Descripción')
quantity = fields.Float(string='Cantidad', default=1.0, required=True)
price_unit = fields.Float(string='Precio Unitario', required=True)
@@ -199,6 +200,17 @@ class SkeenVentaLine(models.Model):
help='Marcar si este artículo fue recetado por un médico (entra al cálculo de comisiones).')
prescribed_by_id = fields.Many2one('hr.employee', string='Recetado por')
_sql_constraints = [
('service_o_item', 'CHECK(service_id IS NOT NULL OR item_id IS NOT NULL)',
'La línea debe tener un servicio o un artículo de inventario.')
]
@api.constrains('service_id', 'item_id')
def _check_service_o_item(self):
for line in self:
if bool(line.service_id) == bool(line.item_id):
raise ValidationError(_('La línea debe tener un servicio O un artículo, no ambos.'))
@api.depends('quantity', 'price_unit')
def _compute_subtotal(self):
for line in self:
@@ -210,6 +222,12 @@ class SkeenVentaLine(models.Model):
self.price_unit = self.service_id.price
self.description = self.service_id.name
@api.onchange('item_id')
def _onchange_item(self):
if self.item_id:
self.price_unit = self.item_id.price
self.description = self.item_id.name
class SkeenCorteCaja(models.Model):
_name = 'skeen.corte.caja'