Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions stock_batch_picking_ux/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
#
##############################################################################
{
"name": "Stock Usability with Batch Picking and stock vouchers",
"version": "18.0.1.1.0",
"name": "Stock Usability with Batch Picking",
"version": "19.0.1.0.0",
"category": "Warehouse Management",
"sequence": 14,
"summary": "",
Expand All @@ -29,18 +29,16 @@
"images": [],
"depends": [
"stock_ux",
"stock_voucher",
"stock_picking_batch",
],
"data": [
"views/stock_batch_picking_views.xml",
"views/stock_move_line_views.xml",
"views/stock_picking_views.xml",
"reports/ir.actions.report.xml",
"reports/picking_templates.xml",
],
"demo": [],
"installable": False,
"installable": True,
"auto_install": True,
"application": False,
}
3 changes: 0 additions & 3 deletions stock_batch_picking_ux/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,3 @@
# directory
##############################################################################
from . import stock_batch_picking
from . import stock_move_line
from . import stock_picking_voucher
from . import stock_picking
93 changes: 35 additions & 58 deletions stock_batch_picking_ux/models/stock_batch_picking.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,34 +18,22 @@ class StockPickingBatch(models.Model):
# required=True,
help="If you choose a partner then only pickings of this partner will" "be sellectable",
)
voucher_number = fields.Char()
voucher_required = fields.Boolean(
# related='picking_type_id.voucher_required',
compute="_compute_picking_type_data",
)
restrict_number_package = fields.Boolean(
compute="_compute_picking_type_data",
)
number_of_packages = fields.Integer(
copy=False,
)

# restrict_number_package = fields.Boolean(
# compute="_compute_picking_type_data",
# )
# number_of_packages = fields.Integer(
# copy=False,
# )
Comment on lines +21 to +26
Copy link

Copilot AI Dec 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Se están eliminando campos almacenados (voucher_number y number_of_packages) del modelo stock.picking.batch sin proporcionar un script de migración.

Según las guías de migración, cuando se eliminan campos almacenados se debe crear un script de migración en migrations/19.0.1.0.0/pre-migration.py para eliminar las columnas de la base de datos de forma limpia:

def migrate(cr, version):
    # Eliminar campos obsoletos
    cr.execute("ALTER TABLE stock_picking_batch DROP COLUMN IF EXISTS voucher_number")
    cr.execute("ALTER TABLE stock_picking_batch DROP COLUMN IF EXISTS number_of_packages")
    cr.execute("ALTER TABLE stock_picking_batch DROP COLUMN IF EXISTS voucher_required")
    cr.execute("ALTER TABLE stock_picking_batch DROP COLUMN IF EXISTS restrict_number_package")

Esto evita warnings y problemas durante la actualización del módulo.

Copilot generated this review using guidance from repository custom instructions.
picking_type_id = fields.Many2one(required=True)

picking_type_ids = fields.Many2many(
"stock.picking.type",
# related='picking_type_id.voucher_required',
compute="_compute_picking_type_data",
)
vouchers = fields.Char(
related="picking_ids.vouchers",
)

picking_count = fields.Integer(
string="# Transferencias",
compute="_compute_picking_count",
)

notes = fields.Text(help="free form remarks")

def _compute_picking_count(self):
Expand All @@ -59,40 +47,43 @@ def _compute_picking_count(self):
for batch in self:
batch.picking_count = counts.get(batch.id, 0)

@api.depends("partner_id")
def _compute_allowed_picking_ids(self):
super()._compute_allowed_picking_ids()
for rec in self.filtered("partner_id"):
rec.allowed_picking_ids = rec.allowed_picking_ids.filtered(lambda p: p.partner_id == rec.partner_id)

def write(self, vals):
# Interceptamos las operaciones de picking_ids para evitar que se borren físicamente
# En lugar de comando 2 (delete), usamos comando 3 (unlink) que solo desvincula
if "picking_ids" in vals:
new_picking_ops = []
for operation in vals["picking_ids"]:
if operation[0] == 2: # Si es un delete (2), lo convertimos a unlink (3)
new_picking_ops.append((3, operation[1])) # Unlink en lugar de delete
else:
new_picking_ops.append(operation)
vals["picking_ids"] = new_picking_ops
return super().write(vals)

@api.depends("picking_ids")
def _compute_picking_type_data(self):
for rec in self:
types = rec.picking_ids.mapped("picking_type_id")
rec.picking_type_ids = types
rec.voucher_required = any(x.voucher_required for x in types)
rec.restrict_number_package = False
# rec.voucher_required = any(x.voucher_required for x in types)
# rec.restrict_number_package = False
# este viene exigido desde la cia pero seguramente lo movamos a
# exigir desde picking type
# solo es requerido para outgoings
if rec.picking_type_code == "outgoing":
rec.restrict_number_package = any(x.picking_type_id.restrict_number_package for x in rec.picking_ids)
# if rec.picking_type_code == "outgoing":
# rec.restrict_number_package = any(x.picking_type_id.restrict_number_package for x in rec.picking_ids)

@api.onchange("picking_type_code", "partner_id")
def changes_set_pickings(self):
# if we change type or partner reset pickings
self.picking_ids = False

@api.onchange("voucher_number", "picking_ids")
def format_voucher_number(self):
for rec in self:
if not rec.voucher_number:
continue
voucher_number = self.env["stock.picking.voucher"]._format_document_number(rec.voucher_number)
if voucher_number and voucher_number != rec.voucher_number:
rec.voucher_number = voucher_number

def write(self, vals):
if "voucher_number" in vals and vals.get("voucher_number"):
voucher_number = self.env["stock.picking.voucher"]._format_document_number(vals.get("voucher_number"))
if voucher_number and voucher_number != vals.get("voucher_number"):
vals["voucher_number"] = voucher_number
return super().write(vals)

def add_picking_operation(self):
self.ensure_one()
view_id = self.env.ref("stock_ux.view_move_line_tree").id
Expand All @@ -112,28 +103,14 @@ def action_done(self):
# al agregar la restriccion de que al menos una tenga que tener
# cantidad entonces nunca se manda el force_qty al picking
if all(operation.quantity == 0 for operation in rec.move_line_ids):
raise UserError(_("Debe definir Cantidad Realizada en al menos una " "operación."))
raise UserError(_("Debe definir Cantidad Realizada en al menos una operación."))

if rec.restrict_number_package and not rec.number_of_packages > 0:
raise UserError(_("The number of packages can not be 0"))
if rec.number_of_packages:
rec.picking_ids.write({"number_of_packages": rec.number_of_packages})
# if rec.restrict_number_package and not rec.number_of_packages > 0:
# raise UserError(_("The number of packages can not be 0"))
# if rec.number_of_packages:
# rec.picking_ids.write({"number_of_packages": rec.number_of_packages})

Comment on lines +108 to 112
Copy link

Copilot AI Dec 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment appears to contain commented-out code.

Suggested change
# if rec.restrict_number_package and not rec.number_of_packages > 0:
# raise UserError(_("The number of packages can not be 0"))
# if rec.number_of_packages:
# rec.picking_ids.write({"number_of_packages": rec.number_of_packages})
# Si se requiere la restricción de número de paquetes, validar aquí.

Copilot uses AI. Check for mistakes.
if rec.picking_type_code == "incoming" and rec.voucher_number:
for picking in rec.picking_ids:
# agregamos esto para que no se asigne a los pickings
# que no se van a recibir ya que todavia no se limpiaron
# y ademas, por lo de arriba, no se fuerza la cantidad
# si son todos cero, se terminan sacando
if all(operation.quantity == 0 for operation in picking.move_line_ids):
continue
rec.env["stock.picking.voucher"].create(
{
"picking_id": picking.id,
"name": rec.voucher_number,
}
)
return super(StockPickingBatch, self.with_context(do_not_assign_numbers=True)).action_done()
return super().action_done()

def action_view_stock_picking(self):
"""This function returns an action that display existing pickings of
Expand Down
15 changes: 0 additions & 15 deletions stock_batch_picking_ux/models/stock_move_line.py

This file was deleted.

58 changes: 0 additions & 58 deletions stock_batch_picking_ux/models/stock_picking.py

This file was deleted.

31 changes: 0 additions & 31 deletions stock_batch_picking_ux/models/stock_picking_voucher.py

This file was deleted.

26 changes: 6 additions & 20 deletions stock_batch_picking_ux/views/stock_batch_picking_views.xml
Original file line number Diff line number Diff line change
Expand Up @@ -52,26 +52,12 @@
</div>
</button>
</xpath>
<field name="user_id" position="before">
<field name="voucher_required" invisible="1"/>
<!-- <field name="picking_type_id"/> -->
<!-- al final lo sacamos porque ya lo estamos usando para otros tipos -->
<!-- como por ahora solo lo usamos para entrada lo restringimos -->
<field name="partner_id" context="{'res_partner_search_mode': picking_type_code == 'incoming' and 'supplier' or 'customer'}"/>
<!-- <field name="partner_id" context="{'search_default_supplier':1, 'default_supplier':1, 'default_customer':0}" domain="[('supplier','=',True)]"/> -->
<field name="voucher_number" invisible="picking_type_code != 'incoming'" required="voucher_required == True"/>
<field name="number_of_packages"/>
<!-- <field name="voucher_ids" attrs="{'invisible': [('picking_type_code','!=','incoming')]}" widget="many2many_tags" context="{'default_batch_picking': id}" domain="[('id', '=', False)]" options="{'create':True, 'create_edit':True}}"/> -->
</field>

<field name="picking_ids" position="attributes">
<attribute name="context">{'show_print_button': 1}</attribute>
<attribute name="domain">[('company_id', '=', company_id), ('state', 'in', ('confirmed', 'partially_available', 'assigned')), ('picking_type_id', '=', picking_type_id)] if not partner_id else [('company_id', '=', company_id), ('state', 'in', ('confirmed', 'partially_available', 'assigned')), ('picking_type_id', '=', picking_type_id), ('partner_id', '=', partner_id)]</attribute>
</field>

<field name="move_line_ids" position="attributes">
<attribute name="context">{'from_batch': True}</attribute>
</field>
<group id="batch_delivery_data" position="after">
<group id="column2">
<field name="partner_id" context="{'res_partner_search_mode': picking_type_code == 'incoming' and 'supplier' or 'customer'}"/>
<!-- <field name="number_of_packages"/> -->
</group>
</group>

<field name="move_ids" position="attributes">
<!-- usamos de vista tree la misma que se usan en los pickins y ademas mostramos el campo del picking -->
Expand Down
14 changes: 0 additions & 14 deletions stock_batch_picking_ux/views/stock_picking_views.xml

This file was deleted.

65 changes: 0 additions & 65 deletions stock_batch_picking_voucher/README.rst

This file was deleted.

Loading