diff --git a/batch_picking_create_one_bill/__init__.py b/batch_picking_create_one_bill/__init__.py
index 862180d..408a600 100644
--- a/batch_picking_create_one_bill/__init__.py
+++ b/batch_picking_create_one_bill/__init__.py
@@ -1,3 +1,3 @@
# -*- coding: utf-8 -*-
from . import models
-from . import wizards
+from . import wizard
diff --git a/batch_picking_create_one_bill/__manifest__.py b/batch_picking_create_one_bill/__manifest__.py
index 44e921a..43c0f29 100644
--- a/batch_picking_create_one_bill/__manifest__.py
+++ b/batch_picking_create_one_bill/__manifest__.py
@@ -1,10 +1,10 @@
# -*- coding: utf-8 -*-
{
- 'name': 'Batch Picking - Create One Bill',
- 'version': '18.0.1.0.0',
- 'category': 'Inventory/Purchase',
- 'summary': 'Créer une seule facture fournisseur pour tous les bons de commande d\'un batch picking',
- 'description': """
+ "name": "Batch Picking - Create One Bill",
+ "version": "18.0.1.0.0",
+ "category": "Inventory/Purchase",
+ "summary": "Créer une seule facture fournisseur pour tous les bons de commande d'un batch picking",
+ "description": """
Ce module permet de générer une seule facture fournisseur pour tous les bons de commande
associés à un batch picking.
@@ -14,23 +14,24 @@
- Validation que tous les bons de commande proviennent du même fournisseur
- Suivi des factures créées directement depuis le batch
""",
- 'author': 'Pneumac',
- 'website': 'https://www.pneumac.ca',
- 'depends': [
- 'stock_picking_batch',
- 'purchase',
- 'purchase_stock',
- 'account',
- 'account_reports',
+ "author": "Pneumac",
+ "website": "https://www.pneumac.ca",
+ "depends": [
+ "stock_picking_batch",
+ "purchase",
+ "purchase_stock",
+ "account",
+ "account_reports",
],
- 'data': [
- 'security/ir.model.access.csv',
- 'wizards/create_bill_wizard_views.xml',
- 'wizards/merge_bill_wizard_views.xml',
- 'views/stock_picking_batch_views.xml',
+ "data": [
+ "security/ir.model.access.csv",
+ "wizard/create_bill_wizard_views.xml",
+ "wizard/merge_bill_wizard_views.xml",
+ "wizard/stock_picking_to_batch_views.xml",
+ "views/stock_picking_batch_views.xml",
],
- 'installable': True,
- 'application': False,
- 'auto_install': False,
- 'license': 'LGPL-3',
+ "installable": True,
+ "application": False,
+ "auto_install": False,
+ "license": "LGPL-3",
}
diff --git a/batch_picking_create_one_bill/models/stock_picking_batch.py b/batch_picking_create_one_bill/models/stock_picking_batch.py
index eb46d5a..829da5d 100644
--- a/batch_picking_create_one_bill/models/stock_picking_batch.py
+++ b/batch_picking_create_one_bill/models/stock_picking_batch.py
@@ -2,61 +2,81 @@
from odoo import models, fields, api
from odoo.exceptions import ValidationError
+
class StockPickingBatch(models.Model):
- _inherit = 'stock.picking.batch'
+ _inherit = "stock.picking.batch"
+
+ @api.model_create_multi
+ def create(self, vals_list):
+ # Handle zero_quantity_default from context if not explicitly set in vals
+ for vals in vals_list:
+ if (
+ "zero_quantity_default" not in vals
+ and self.env.context.get("default_zero_quantity_default") is not None
+ ):
+ vals["zero_quantity_default"] = self.env.context.get(
+ "default_zero_quantity_default"
+ )
+ return super().create(vals_list)
zero_quantity_default = fields.Boolean(
- string='Quantités à zéro par défaut',
+ string="Quantités à zéro par défaut",
default=True,
- help='Initialiser les quantités à zéro lors de la création du batch'
+ help="Initialiser les quantités à zéro lors de la création du batch",
)
invoice_ids = fields.Many2many(
- 'account.move',
- string='Factures associées',
- compute='_compute_invoice_ids',
- store=True
+ "account.move",
+ string="Factures associées",
+ compute="_compute_invoice_ids",
+ store=True,
)
invoice_count = fields.Integer(
- string='Nombre de factures',
- compute='_compute_invoice_count',
+ string="Nombre de factures",
+ compute="_compute_invoice_count",
store=True,
- compute_sudo=True
+ compute_sudo=True,
)
def _prepare_move_line_vals(self, **kwargs):
vals = super()._prepare_move_line_vals(**kwargs)
if self.zero_quantity_default:
- vals['quantity'] = 0.0
+ vals["quantity"] = 0.0
return vals
- @api.depends('picking_ids.move_ids.purchase_line_id.order_id.invoice_ids')
+ @api.depends("picking_ids.move_ids.purchase_line_id.order_id.invoice_ids")
def _compute_invoice_ids(self):
for batch in self:
purchase_orders = batch.picking_ids.move_ids.purchase_line_id.order_id
batch.invoice_ids = purchase_orders.invoice_ids
- @api.depends('invoice_ids')
+ @api.depends("invoice_ids")
def _compute_invoice_count(self):
for batch in self:
batch.invoice_count = len(batch.invoice_ids)
def action_view_invoices(self):
self.ensure_one()
- action = self.env['ir.actions.act_window']._for_xml_id(
- 'account.action_move_in_invoice_type'
+ action = self.env["ir.actions.act_window"]._for_xml_id(
+ "account.action_move_in_invoice_type"
)
if self.invoice_count == 1:
- action['views'] = [(False, 'form')]
- action['res_id'] = self.invoice_ids.id
+ action["views"] = [(False, "form")]
+ action["res_id"] = self.invoice_ids.id
else:
- action['domain'] = [('id', 'in', self.invoice_ids.ids)]
+ action["domain"] = [("id", "in", self.invoice_ids.ids)]
return action
- @api.constrains('picking_ids')
+ @api.constrains("picking_ids")
def _check_purchase_orders(self):
for batch in self:
partners = batch.picking_ids.purchase_id.partner_id
if len(partners) > 1:
raise ValidationError(
- 'Tous les bons de commande du batch doivent provenir du même fournisseur.'
+ "Tous les bons de commande du batch doivent provenir du même fournisseur."
)
+
+ def action_confirm(self):
+ """Override to set zero quantity on move lines at confirmation of the batch"""
+ res = super().action_confirm()
+ self.filtered("zero_quantity_default").move_line_ids.write({"quantity": 0})
+ return res
diff --git a/batch_picking_create_one_bill/tests/test_batch_picking_bill.py b/batch_picking_create_one_bill/tests/test_batch_picking_bill.py
index 2e5c6cc..1627f7b 100644
--- a/batch_picking_create_one_bill/tests/test_batch_picking_bill.py
+++ b/batch_picking_create_one_bill/tests/test_batch_picking_bill.py
@@ -251,3 +251,68 @@ class TestBatchPickingBill(TransactionCase):
],
}
)
+
+ def test_zero_quantity_default_from_wizard(self):
+ """Test that zero_quantity_default is properly set when creating a batch from wizard"""
+ # Switch to warehouse user like in the parent test
+ self.env = self.env(user=self.warehouse_user)
+
+ pickings = (self.po1 + self.po2).picking_ids
+ self.assertTrue(pickings, "Purchase orders should have created pickings")
+
+ # Create batch through wizard
+ wizard = (
+ self.env["stock.picking.to.batch"]
+ .with_context(active_ids=pickings.ids, active_model="stock.picking")
+ .create(
+ {
+ "mode": "new",
+ "zero_quantity_default": True,
+ }
+ )
+ )
+
+ result = wizard.attach_pickings()
+ batch = self.env["stock.picking.batch"].browse(result["res_id"])
+
+ # Check that zero_quantity_default was properly set on the batch
+ self.assertTrue(
+ batch.zero_quantity_default,
+ "zero_quantity_default should be True on the created batch",
+ )
+
+ # Check that all move lines have quantity 0
+ for move_line in batch.move_line_ids:
+ self.assertEqual(
+ move_line.quantity,
+ 0.0,
+ f"Move line for {move_line.product_id.name} should have quantity 0",
+ )
+
+ def test_zero_quantity_default_from_picking(self):
+ """Test that zero_quantity_default works when adding picking to existing batch"""
+ # Switch to warehouse user like in the parent test
+ self.env = self.env(user=self.warehouse_user)
+
+ pickings = (self.po1 + self.po2).picking_ids
+
+ # Create batch directly
+ batch = self.env["stock.picking.batch"].create(
+ {
+ "zero_quantity_default": True,
+ }
+ )
+
+ # Add pickings to batch
+ pickings.write({"batch_id": batch.id})
+
+ # Confirm the batch to get the move lines set up
+ batch.action_confirm()
+
+ # Check that all move lines have quantity 0
+ for move_line in batch.move_line_ids:
+ self.assertEqual(
+ move_line.quantity,
+ 0.0,
+ f"Move line for {move_line.product_id.name} should have quantity 0",
+ )
diff --git a/batch_picking_create_one_bill/views/stock_picking_batch_views.xml b/batch_picking_create_one_bill/views/stock_picking_batch_views.xml
index bea2f0c..c1953aa 100644
--- a/batch_picking_create_one_bill/views/stock_picking_batch_views.xml
+++ b/batch_picking_create_one_bill/views/stock_picking_batch_views.xml
@@ -7,18 +7,10 @@
-
+
-
@@ -27,4 +19,19 @@
+
+
+
+ stock.move.line.tree.picked.inherit
+ stock.move.line
+
+
+
+
+
+
+ picked
+
+
+
diff --git a/batch_picking_create_one_bill/wizards/__init__.py b/batch_picking_create_one_bill/wizard/__init__.py
similarity index 70%
rename from batch_picking_create_one_bill/wizards/__init__.py
rename to batch_picking_create_one_bill/wizard/__init__.py
index 7306402..cb92c49 100644
--- a/batch_picking_create_one_bill/wizards/__init__.py
+++ b/batch_picking_create_one_bill/wizard/__init__.py
@@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
from . import create_bill_wizard
from . import merge_bill_wizard
+from . import stock_picking_to_batch
diff --git a/batch_picking_create_one_bill/wizards/create_bill_wizard.py b/batch_picking_create_one_bill/wizard/create_bill_wizard.py
similarity index 100%
rename from batch_picking_create_one_bill/wizards/create_bill_wizard.py
rename to batch_picking_create_one_bill/wizard/create_bill_wizard.py
diff --git a/batch_picking_create_one_bill/wizards/create_bill_wizard_views.xml b/batch_picking_create_one_bill/wizard/create_bill_wizard_views.xml
similarity index 100%
rename from batch_picking_create_one_bill/wizards/create_bill_wizard_views.xml
rename to batch_picking_create_one_bill/wizard/create_bill_wizard_views.xml
diff --git a/batch_picking_create_one_bill/wizards/merge_bill_wizard.py b/batch_picking_create_one_bill/wizard/merge_bill_wizard.py
similarity index 100%
rename from batch_picking_create_one_bill/wizards/merge_bill_wizard.py
rename to batch_picking_create_one_bill/wizard/merge_bill_wizard.py
diff --git a/batch_picking_create_one_bill/wizards/merge_bill_wizard_views.xml b/batch_picking_create_one_bill/wizard/merge_bill_wizard_views.xml
similarity index 100%
rename from batch_picking_create_one_bill/wizards/merge_bill_wizard_views.xml
rename to batch_picking_create_one_bill/wizard/merge_bill_wizard_views.xml
diff --git a/batch_picking_create_one_bill/wizard/stock_picking_to_batch.py b/batch_picking_create_one_bill/wizard/stock_picking_to_batch.py
new file mode 100644
index 0000000..9dae773
--- /dev/null
+++ b/batch_picking_create_one_bill/wizard/stock_picking_to_batch.py
@@ -0,0 +1,20 @@
+from odoo import _, fields, models
+from odoo.exceptions import UserError
+
+
+class StockPickingToBatch(models.TransientModel):
+ _inherit = "stock.picking.to.batch"
+
+ zero_quantity_default = fields.Boolean(
+ string="Zero Quantity by Default",
+ default=False,
+ help="If checked, the default quantity for new move lines will be 0 instead of the computed quantity.",
+ )
+
+ def attach_pickings(self):
+ self.ensure_one()
+ # Pass zero_quantity_default through context to be handled in batch create
+ return super(
+ StockPickingToBatch,
+ self.with_context(default_zero_quantity_default=self.zero_quantity_default),
+ ).attach_pickings()
diff --git a/batch_picking_create_one_bill/wizard/stock_picking_to_batch_views.xml b/batch_picking_create_one_bill/wizard/stock_picking_to_batch_views.xml
new file mode 100644
index 0000000..ac145a7
--- /dev/null
+++ b/batch_picking_create_one_bill/wizard/stock_picking_to_batch_views.xml
@@ -0,0 +1,13 @@
+
+
+
+ stock.picking.to.batch.form.inherit
+ stock.picking.to.batch
+
+
+
+
+
+
+
+