167 lines
5.7 KiB
Python
167 lines
5.7 KiB
Python
# -*- coding: utf-8 -*-
|
|
from odoo import models, fields, api, Command, _
|
|
from odoo.exceptions import ValidationError
|
|
|
|
|
|
class StockPickingBatch(models.Model):
|
|
_inherit = "stock.picking.batch"
|
|
|
|
purchase_order_ids = fields.Many2many(
|
|
"purchase.order",
|
|
string="Bons de commande",
|
|
compute="_compute_purchase_orders",
|
|
compute_sudo=True,
|
|
)
|
|
|
|
partner_ids = fields.Many2many(
|
|
"res.partner",
|
|
string="Fournisseur",
|
|
compute="_compute_partner",
|
|
compute_sudo=True,
|
|
)
|
|
|
|
@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",
|
|
default=True,
|
|
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",
|
|
compute_sudo=True,
|
|
)
|
|
invoice_count = fields.Integer(
|
|
string="Nombre de factures",
|
|
compute="_compute_invoice_count",
|
|
compute_sudo=True,
|
|
)
|
|
|
|
# Field computation methods
|
|
|
|
@api.depends("picking_ids.move_ids.purchase_line_id.order_id")
|
|
def _compute_purchase_orders(self):
|
|
for batch in self:
|
|
batch.purchase_order_ids = (
|
|
batch.picking_ids.move_ids.purchase_line_id.order_id
|
|
)
|
|
|
|
@api.depends("purchase_order_ids")
|
|
def _compute_partner(self):
|
|
for wizard in self:
|
|
wizard.partner_ids = wizard.purchase_order_ids.mapped("partner_id")
|
|
|
|
def _prepare_move_line_vals(self, **kwargs):
|
|
vals = super()._prepare_move_line_vals(**kwargs)
|
|
if self.zero_quantity_default:
|
|
vals["quantity"] = 0.0
|
|
return vals
|
|
|
|
@api.depends("move_line_ids.move_id.purchase_line_id.order_id.invoice_ids")
|
|
def _compute_invoice_ids(self):
|
|
for batch in self:
|
|
batch.invoice_ids = (
|
|
batch.move_line_ids.move_id.purchase_line_id.invoice_lines.move_id
|
|
)
|
|
|
|
@api.depends("invoice_ids")
|
|
def _compute_invoice_count(self):
|
|
for batch in self:
|
|
batch.invoice_count = len(batch.invoice_ids)
|
|
|
|
# Actions
|
|
|
|
def action_view_invoices(self):
|
|
self.ensure_one()
|
|
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
|
|
else:
|
|
action["domain"] = [("id", "in", self.invoice_ids.ids)]
|
|
return action
|
|
|
|
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
|
|
|
|
def action_create_bill(self):
|
|
self.ensure_one()
|
|
if not self.purchase_order_ids:
|
|
raise ValidationError(_("No purchase orders found in this batch."))
|
|
|
|
if len(self.partner_ids) > 1:
|
|
raise ValidationError(_("The batch must have only one supplier."))
|
|
|
|
bill = self.env["account.move"].create(self._get_bill_values())
|
|
return self._get_view_bill_action(bill)
|
|
|
|
# Helpers
|
|
|
|
def _get_view_bill_action(self, bill):
|
|
action = self.env["ir.actions.act_window"]._for_xml_id(
|
|
"account.action_move_in_invoice_type"
|
|
)
|
|
action["views"] = [(False, "form")]
|
|
action["res_id"] = bill.id
|
|
return action
|
|
|
|
def _get_currency_id(self):
|
|
currency_id = self.purchase_order_ids.mapped("currency_id")
|
|
if len(currency_id) > 1:
|
|
raise UserError(_("The selected receipts do not have the same currency."))
|
|
return currency_id.id
|
|
|
|
def _get_bill_values(self):
|
|
"""Build a dictionary of the values for the vendor bill to create."""
|
|
|
|
company_id = self.company_id.id
|
|
partner_id = self.partner_ids.id
|
|
invoice_date = self.scheduled_date
|
|
invoice_origin = ", ".join(self.purchase_order_ids.mapped("name"))
|
|
move_line_ids = self._get_line_values()
|
|
currency_id = self._get_currency_id()
|
|
return {
|
|
"company_id": company_id,
|
|
"partner_id": partner_id,
|
|
"move_type": "in_invoice",
|
|
"invoice_date": invoice_date,
|
|
"invoice_origin": invoice_origin,
|
|
"currency_id": currency_id,
|
|
"line_ids": move_line_ids,
|
|
}
|
|
|
|
def _get_line_values(self):
|
|
"""For each of the stock.move.line in the batch, build a dictionary of values for the invoice line to match."""
|
|
line_vals = []
|
|
for move_line in self.move_line_ids:
|
|
purchase_line_id = move_line.move_id.purchase_line_id
|
|
line_vals.append(
|
|
Command.create(
|
|
{
|
|
"product_id": move_line.product_id.id,
|
|
"quantity": move_line.quantity,
|
|
"price_unit": purchase_line_id.price_unit,
|
|
"discount": purchase_line_id.discount,
|
|
"purchase_line_id": purchase_line_id.id,
|
|
}
|
|
)
|
|
)
|
|
return line_vals
|