mirror of
https://github.com/bringout/oca-workflow-process.git
synced 2026-04-20 09:12:00 +02:00
148 lines
5.6 KiB
Python
148 lines
5.6 KiB
Python
# Copyright 2022-2025 Tecnativa - Víctor Martínez
|
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
|
|
from odoo import api, fields, models
|
|
|
|
|
|
class StockMove(models.Model):
|
|
_inherit = "stock.move"
|
|
|
|
task_id = fields.Many2one(
|
|
comodel_name="project.task",
|
|
string="Related Task",
|
|
check_company=True,
|
|
)
|
|
raw_material_task_id = fields.Many2one(
|
|
comodel_name="project.task", string="Task for material", check_company=True
|
|
)
|
|
|
|
@api.onchange("product_id")
|
|
def _onchange_product_id(self):
|
|
"""It is necessary to overwrite the name to prevent set product name
|
|
from being auto-defined."""
|
|
res = super()._onchange_product_id()
|
|
if self.raw_material_task_id:
|
|
self.name = self.raw_material_task_id.name
|
|
return res
|
|
|
|
def _prepare_analytic_line_from_task(self):
|
|
product = self.product_id
|
|
company_id = self.env.company
|
|
task = self.task_id or self.raw_material_task_id
|
|
analytic_account = (
|
|
task.stock_analytic_account_id or task.project_id.analytic_account_id
|
|
)
|
|
if not analytic_account:
|
|
return False
|
|
# Apply sudo() in case there is any rule that does not allow access to
|
|
# the analytic account, for example with analytic_hr_department_restriction
|
|
analytic_account = analytic_account.sudo()
|
|
res = {
|
|
"date": (
|
|
task.stock_analytic_date
|
|
or task.project_id.stock_analytic_date
|
|
or fields.date.today()
|
|
),
|
|
"name": task.name + ": " + product.name,
|
|
"unit_amount": self.quantity_done,
|
|
"account_id": analytic_account.id,
|
|
"user_id": self._uid,
|
|
"product_uom_id": self.product_uom.id,
|
|
"company_id": analytic_account.company_id.id or self.env.company.id,
|
|
"partner_id": task.partner_id.id or task.project_id.partner_id.id or False,
|
|
"stock_task_id": task.id,
|
|
}
|
|
amount_unit = product.with_context(uom=self.product_uom.id).price_compute(
|
|
"standard_price"
|
|
)[product.id]
|
|
amount = amount_unit * self.quantity_done or 0.0
|
|
result = round(amount, company_id.currency_id.decimal_places) * -1
|
|
vals = {"amount": result}
|
|
analytic_line_fields = self.env["account.analytic.line"]._fields
|
|
# Extra fields added in account addon
|
|
if "ref" in analytic_line_fields:
|
|
vals["ref"] = task.name
|
|
if "product_id" in analytic_line_fields:
|
|
vals["product_id"] = product.id
|
|
# Prevent incoherence when hr_timesheet addon is installed.
|
|
if "project_id" in analytic_line_fields:
|
|
vals["project_id"] = False
|
|
# distributions
|
|
if task.stock_analytic_distribution:
|
|
new_amount = 0
|
|
for distribution in task.stock_analytic_distribution.values():
|
|
new_amount -= (amount / 100) * distribution
|
|
vals["amount"] = new_amount
|
|
res.update(vals)
|
|
return res
|
|
|
|
@api.model
|
|
def default_get(self, fields_list):
|
|
defaults = super().default_get(fields_list)
|
|
if self.env.context.get("default_raw_material_task_id"):
|
|
task = self.env["project.task"].browse(
|
|
self.env.context.get("default_raw_material_task_id")
|
|
)
|
|
if not task.group_id:
|
|
task.group_id = self.env["procurement.group"].create(
|
|
task._prepare_procurement_group_vals()
|
|
)
|
|
defaults.update(
|
|
{
|
|
"group_id": task.group_id.id,
|
|
"location_id": (
|
|
task.location_id.id or task.project_id.location_id.id
|
|
),
|
|
"location_dest_id": (
|
|
task.location_dest_id.id or task.project_id.location_dest_id.id
|
|
),
|
|
"picking_type_id": (
|
|
task.picking_type_id.id or task.project_id.picking_type_id.id
|
|
),
|
|
}
|
|
)
|
|
return defaults
|
|
|
|
def _action_done(self, cancel_backorder=False):
|
|
"""Create the analytical notes for stock movements linked to tasks."""
|
|
moves_todo = super()._action_done(cancel_backorder)
|
|
# Use sudo to avoid error for users with no access to analytic
|
|
analytic_line_model = self.env["account.analytic.line"].sudo()
|
|
for move in moves_todo.filtered(lambda x: x.raw_material_task_id):
|
|
vals = move._prepare_analytic_line_from_task()
|
|
if vals:
|
|
analytic_line_model.create(vals)
|
|
return moves_todo
|
|
|
|
def action_task_product_forecast_report(self):
|
|
self.ensure_one()
|
|
action = self.product_id.action_product_forecast_report()
|
|
action["context"] = {
|
|
"active_id": self.product_id.id,
|
|
"active_model": "product.product",
|
|
"move_to_match_ids": self.ids,
|
|
}
|
|
warehouse = self.warehouse_id
|
|
if warehouse:
|
|
action["context"]["warehouse"] = warehouse.id
|
|
return action
|
|
|
|
|
|
class StockMoveLine(models.Model):
|
|
_inherit = "stock.move.line"
|
|
|
|
task_id = fields.Many2one(
|
|
comodel_name="project.task",
|
|
string="Task",
|
|
compute="_compute_task_id",
|
|
store=True,
|
|
)
|
|
|
|
@api.depends("move_id.raw_material_task_id", "move_id.task_id")
|
|
def _compute_task_id(self):
|
|
for item in self:
|
|
task = (
|
|
item.move_id.raw_material_task_id
|
|
if item.move_id.raw_material_task_id
|
|
else item.move_id.task_id
|
|
)
|
|
item.task_id = task if task else False
|