mirror of
https://github.com/bringout/oca-technical.git
synced 2026-04-19 17:52:05 +02:00
Initial commit: OCA Technical packages (595 packages)
This commit is contained in:
commit
2cc02aac6e
24950 changed files with 2318079 additions and 0 deletions
|
|
@ -0,0 +1,201 @@
|
|||
# Copyright 2019-20 ForgeFlow S.L. (http://www.forgeflow.com)
|
||||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
|
||||
|
||||
from odoo import _, api, fields, models
|
||||
from odoo.exceptions import UserError, ValidationError
|
||||
from odoo.tools import float_compare
|
||||
|
||||
|
||||
class MakeProcurementBuffer(models.TransientModel):
|
||||
_name = "make.procurement.buffer"
|
||||
_description = "Make Procurements from Stock Buffers"
|
||||
|
||||
partner_id = fields.Many2one(
|
||||
comodel_name="res.partner",
|
||||
string="Vendor",
|
||||
help="If set, will be used as preferred vendor for purchase routes.",
|
||||
)
|
||||
item_ids = fields.One2many(
|
||||
comodel_name="make.procurement.buffer.item",
|
||||
inverse_name="wiz_id",
|
||||
string="Items",
|
||||
)
|
||||
|
||||
@api.model
|
||||
def _prepare_item(self, buffer, qty_override=None):
|
||||
qty = (
|
||||
qty_override if qty_override is not None else buffer.procure_recommended_qty
|
||||
)
|
||||
return {
|
||||
"recommended_qty": buffer.procure_recommended_qty,
|
||||
"qty": qty,
|
||||
"uom_id": buffer.procure_uom_id.id or buffer.product_uom.id,
|
||||
"date_planned": buffer._get_date_planned(),
|
||||
"buffer_id": buffer.id,
|
||||
"product_id": buffer.product_id.id,
|
||||
"warehouse_id": buffer.warehouse_id.id,
|
||||
"location_id": buffer.location_id.id,
|
||||
}
|
||||
|
||||
@api.model
|
||||
def default_get(self, fields):
|
||||
res = super().default_get(fields)
|
||||
buffer_obj = self.env["stock.buffer"]
|
||||
buffer_ids = self.env.context["active_ids"] or []
|
||||
active_model = self.env.context["active_model"]
|
||||
|
||||
if not buffer_ids:
|
||||
return res
|
||||
assert active_model == "stock.buffer", "Bad context propagation"
|
||||
|
||||
items = []
|
||||
for line in buffer_obj.browse(buffer_ids):
|
||||
max_order = line.procure_max_qty
|
||||
qty_to_order = line._procure_qty_to_order()
|
||||
|
||||
if max_order and max_order < qty_to_order:
|
||||
# split the procurement in batches:
|
||||
while qty_to_order > 0.0:
|
||||
if qty_to_order > max_order:
|
||||
qty = max_order
|
||||
else:
|
||||
rounding = (
|
||||
line.procure_uom_id.rounding or line.product_uom.rounding
|
||||
)
|
||||
profile = line.buffer_profile_id
|
||||
limit_to_free_qty = (
|
||||
line.item_type == "distributed"
|
||||
and profile.replenish_distributed_limit_to_free_qty
|
||||
)
|
||||
if limit_to_free_qty:
|
||||
if (
|
||||
float_compare(
|
||||
qty_to_order,
|
||||
line.procure_min_qty,
|
||||
precision_rounding=rounding,
|
||||
)
|
||||
< 0
|
||||
):
|
||||
# not enough in stock to have a batch
|
||||
# respecting the min qty!
|
||||
break
|
||||
# not more that what we have in stock!
|
||||
qty = qty_to_order
|
||||
else:
|
||||
# FIXME it will apply a second time the unit conversion
|
||||
qty = line._adjust_procure_qty(qty_to_order)
|
||||
items.append([0, 0, self._prepare_item(line, qty)])
|
||||
qty_to_order -= qty
|
||||
else:
|
||||
items.append([0, 0, self._prepare_item(line, qty_to_order)])
|
||||
res["item_ids"] = items
|
||||
return res
|
||||
|
||||
def _get_procurement_location(self, item):
|
||||
return item.buffer_id.location_id
|
||||
|
||||
def _get_procurement_name(self, item):
|
||||
return item.buffer_id.name
|
||||
|
||||
def _get_procurement_origin(self, item):
|
||||
return item.buffer_id.name
|
||||
|
||||
def make_procurement(self):
|
||||
self.ensure_one()
|
||||
errors = []
|
||||
pg_obj = self.env["procurement.group"]
|
||||
procurements = []
|
||||
for item in self.item_ids:
|
||||
# As procurement is processed with SUPERUSER_ID (see _run_buy and
|
||||
# _run_manufacture), ensure the current user has write access on
|
||||
# the buffer to make a procurement. Otherwise, any user can request
|
||||
# a procurement on any buffer
|
||||
item.buffer_id.check_access_rights("write")
|
||||
item.buffer_id.check_access_rule("write")
|
||||
if item.qty <= 0.0:
|
||||
raise ValidationError(_("Quantity must be positive."))
|
||||
if not item.buffer_id:
|
||||
raise ValidationError(_("No stock buffer found."))
|
||||
values = item._prepare_values_make_procurement()
|
||||
proc_location = self._get_procurement_location(item)
|
||||
proc_name = self._get_procurement_name(item)
|
||||
proc_origin = self._get_procurement_origin(item)
|
||||
procurements.append(
|
||||
pg_obj.Procurement(
|
||||
item.buffer_id.product_id,
|
||||
item.qty,
|
||||
item.uom_id,
|
||||
proc_location,
|
||||
proc_name,
|
||||
proc_origin,
|
||||
item.buffer_id.company_id,
|
||||
values,
|
||||
)
|
||||
)
|
||||
# Run procurements
|
||||
try:
|
||||
pg_obj.run(procurements)
|
||||
except UserError as error:
|
||||
errors.append(error.name)
|
||||
if errors:
|
||||
raise UserError("\n".join(errors))
|
||||
# Update buffer computed fields:
|
||||
buffers = self.mapped("item_ids.buffer_id")
|
||||
buffers.invalidate_recordset()
|
||||
self.env.add_to_compute(buffers._fields["procure_recommended_qty"], buffers)
|
||||
buffers.flush_recordset()
|
||||
return {"type": "ir.actions.act_window_close"}
|
||||
|
||||
|
||||
class MakeProcurementBufferItem(models.TransientModel):
|
||||
_name = "make.procurement.buffer.item"
|
||||
_description = "Make Procurements from Stock Buffer Item"
|
||||
|
||||
wiz_id = fields.Many2one(
|
||||
comodel_name="make.procurement.buffer",
|
||||
string="Wizard",
|
||||
required=True,
|
||||
ondelete="cascade",
|
||||
readonly=True,
|
||||
)
|
||||
recommended_qty = fields.Float(readonly=True)
|
||||
qty = fields.Float()
|
||||
uom_id = fields.Many2one(
|
||||
string="Unit of Measure",
|
||||
comodel_name="uom.uom",
|
||||
)
|
||||
date_planned = fields.Datetime(string="Planned Date", required=False)
|
||||
buffer_id = fields.Many2one(
|
||||
string="Stock Buffer",
|
||||
comodel_name="stock.buffer",
|
||||
readonly=False,
|
||||
)
|
||||
product_id = fields.Many2one(
|
||||
string="Product",
|
||||
comodel_name="product.product",
|
||||
readonly=True,
|
||||
)
|
||||
warehouse_id = fields.Many2one(
|
||||
string="Warehouse",
|
||||
comodel_name="stock.warehouse",
|
||||
readonly=True,
|
||||
)
|
||||
location_id = fields.Many2one(
|
||||
string="Location",
|
||||
comodel_name="stock.location",
|
||||
readonly=True,
|
||||
)
|
||||
|
||||
@api.onchange("uom_id")
|
||||
def onchange_uom_id(self):
|
||||
for rec in self:
|
||||
rec.qty = rec.buffer_id.product_uom._compute_quantity(
|
||||
rec.buffer_id.procure_recommended_qty, rec.uom_id
|
||||
)
|
||||
|
||||
def _prepare_values_make_procurement(self):
|
||||
values = self.buffer_id._prepare_procurement_values(self.qty)
|
||||
values.update(
|
||||
{"date_planned": self.date_planned, "supplier_id": self.wiz_id.partner_id}
|
||||
)
|
||||
return values
|
||||
Loading…
Add table
Add a link
Reference in a new issue