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
7 changes: 3 additions & 4 deletions stock_batch_picking_ux/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,13 @@ This module add the following features:
#. While creating a batch picking:
- Add the partner in the batch transfer, and then filter the transfers able to be selected according to it.
- Add the number of packages in the batch transfer
- For receipts, it add the supplier's shipping number.
- When pickings are selected while creating a new batch, we allow them to check availability.
#. While proccesing the batch picking:
- Add the possibility of processing stock.move.line from a list view.
- In the transfer lines it add information of the vouchers, from & to and source document, among others.
- Allow to unreserve everything from the batch
- A smart button is added to go to the list view of associated transfers.
- When you click on a transfer (from the transfer tab) you see all the possible actions that would be seen by entering it directly, such as the possibility of printing the voucher.
#. Batch Delivery Slip report:
- A **Delivery Slip** report for batch transfers is included, analogous to the one available for individual pickings.
- The **Print** button in the batch form view follows the same logic as native pickings: when the batch is ``in_progress`` it prints the *Batch Transfer* report; once the batch is ``done`` it prints the *Delivery Slip* instead.

Installation
============
Expand Down
9 changes: 4 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,17 @@
"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",
"reports/report_batch_deliveryslip.xml",
],
"demo": [],
"installable": False,
"installable": True,
"auto_install": True,
"application": False,
}
2 changes: 0 additions & 2 deletions stock_batch_picking_ux/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,4 @@
# directory
##############################################################################
from . import stock_batch_picking
from . import stock_move_line
from . import stock_picking_voucher
from . import stock_picking
106 changes: 27 additions & 79 deletions stock_batch_picking_ux/models/stock_batch_picking.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
# For copyright and license notices, see __manifest__.py file in module root
# directory
##############################################################################
from odoo import _, api, fields, models
from odoo.exceptions import UserError
from odoo import api, fields, models


class StockPickingBatch(models.Model):
Expand All @@ -18,34 +17,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",
)
# restrict_number_package = fields.Boolean(
# compute="_compute_picking_type_data",
# )
number_of_packages = fields.Integer(
copy=False,
)

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,82 +46,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
search_view_id = self.env.ref("stock_ux.stock_move_line_view_search").id
return {
"type": "ir.actions.act_window",
"res_model": "stock.move.line",
"search_view_id": search_view_id,
"views": [[view_id, "list"], [False, "form"]],
"domain": [["id", "in", self.move_line_ids.ids]],
"context": {"create": False, "from_batch": True},
}

def action_done(self):
# agregamos los numeros de remito
for rec in 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."))

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.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()

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

This file was deleted.

62 changes: 9 additions & 53 deletions stock_batch_picking_ux/models/stock_picking.py
Original file line number Diff line number Diff line change
@@ -1,58 +1,14 @@
# @2016 Cyril Gaudin, Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from odoo import models
from odoo.tools import float_is_zero
from odoo import _, api, models
from odoo.exceptions import ValidationError


class StockPicking(models.Model):
_inherit = "stock.picking"

# sobreescribimos esta funcion por el FIX, deberia ir a la oca una vez
# depurado
def force_transfer(self, force_qty=True):
"""Do the picking transfer (by calling do_transfer)

If *force_qty* is True, force the transfer for all product_qty
when quantity is 0.

Otherwise, process only pack operation with quantity.
If a picking has no quantity filled, we released it from his batch
"""
for pick in self:
if pick.state != "assigned":
pick.action_assign()
# FIX
# fix porque si el picking esta parcialmente disponible
# no lo termina procesando
# if pick.state != 'assigned':
if pick.state not in ["assigned", "partially_available"]:
continue
# END FIX

if force_qty:
for pack in pick.move_line_ids:
pack.quantity = pack.quantity
else:
if all(
float_is_zero(pack.quantity, precision_rounding=pack.product_uom_id.rounding)
for pack in pick.move_line_ids
):
# No qties to process, release out of the batch
pick.batch_id = False
continue
else:
for pack in pick.move_line_ids:
if not pack.quantity:
pack.unlink()

pick._action_done()

def _action_generate_backorder_wizard(self, show_transfers=False):
if self._context.get("picking_batches", False):
wiz = self.env["stock.backorder.confirmation"].create({"pick_ids": [(4, p.id) for p in self]})
wiz.process()
self._context.get("picking_batches").write({"state": "done"})
return True
else:
return super(StockPicking, self)._action_generate_backorder_wizard(show_transfers=show_transfers)
@api.constrains("picking_type_id", "batch_id")
def _check_picking_type_batch(self):
for rec in self.filtered("batch_id"):
if rec.batch_id.picking_type_id and rec.picking_type_id != rec.batch_id.picking_type_id:
raise ValidationError(
_("You cannot change the operation type of a picking if it is already assigned to a batch.")
)
31 changes: 0 additions & 31 deletions stock_batch_picking_ux/models/stock_picking_voucher.py

This file was deleted.

10 changes: 10 additions & 0 deletions stock_batch_picking_ux/reports/ir.actions.report.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,14 @@
<field name="binding_type">report</field>
<field name="paperformat_id" ref="stock_batch_picking_ux.label_10x15_batch"/>
</record>

<record id="action_report_batch_deliveryslip" model="ir.actions.report">
<field name="name">Delivery Slip</field>
<field name="model">stock.picking.batch</field>
<field name="binding_model_id" ref="stock_picking_batch.model_stock_picking_batch"/>
<field name="report_type">qweb-pdf</field>
<field name="report_name">stock_batch_picking_ux.report_batch_deliveryslip</field>
<field name="report_file">stock_batch_picking_ux.report_batch_deliveryslip</field>
<field name="binding_type">report</field>
</record>
</odoo>
Loading
Loading