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
18 changes: 13 additions & 5 deletions project_task_stock/models/stock_move.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# 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
from odoo.tools import float_is_zero

Expand Down Expand Up @@ -90,32 +91,39 @@ 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.account_id
project_id = task.project_id
analytic_account = task.stock_analytic_account_id or project_id.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()
is_return = bool(
self.origin_returned_move_id
and self.location_id == project_id.location_dest_id
and self.location_dest_id == project_id.location_id
)
quantity_done = self.quantity * (-1 if is_return else 1)
res = {
"date": (
task.stock_analytic_date
or task.project_id.stock_analytic_date
or project_id.stock_analytic_date
or fields.date.today()
),
"name": task.name + ": " + product.name,
"unit_amount": self.quantity,
"unit_amount": quantity_done,
"account_id": analytic_account.id,
"user_id": self.env.user.id,
"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,
"partner_id": task.partner_id.id or project_id.partner_id.id or False,
"stock_move_id": self.id,
"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 or 0.0
amount = amount_unit * 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
Expand Down
39 changes: 39 additions & 0 deletions project_task_stock/tests/test_project_task_stock.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,45 @@ def test_project_task_analytic_lines_with_tag_2(self):
fields.first(self.task.stock_analytic_line_ids).date, fields.date.today()
)

def test_project_task_analytic_lines_with_returned_picking(self):
# Create initial moves
self.task = self.env["project.task"].browse(self.task.id)
self.task.action_assign()
picking = self.task.move_ids.picking_id
for move in picking.move_ids:
move.quantity = move.product_uom_qty
picking.button_validate()
self.assertEqual(picking.state, "done")
# Return the initial moves
stock_return_picking_form = Form(
self.env["stock.return.picking"].with_context(
active_ids=picking.ids,
active_id=picking.id,
active_model="stock.picking",
)
)
stock_return_picking = stock_return_picking_form.save()
for return_line in stock_return_picking.product_return_moves:
return_line.quantity = return_line.move_id.product_uom_qty
stock_return_picking_action = stock_return_picking.action_create_returns()
return_pick = self.env["stock.picking"].browse(
stock_return_picking_action["res_id"]
)
return_pick.action_assign()
for return_line in return_pick.move_ids:
return_line.quantity = return_line.origin_returned_move_id.quantity
return_pick.button_validate()
self.assertEqual(return_pick.state, "done")
# Check that the resulting analytic lines sum is 0
stock_analytic_lines = self.task.sudo().stock_analytic_line_ids
self.assertEqual(len(stock_analytic_lines), 4)
self.assertEqual(sum(stock_analytic_lines.mapped("unit_amount")), 0)
self.assertEqual(sum(stock_analytic_lines.mapped("amount")), 0)
self.assertIn(
self.analytic_account,
stock_analytic_lines.mapped("account_id"),
)

@users("manager-user")
def test_project_task_analytic_lines_with_tag_2_manager_user(self):
self.task.stock_analytic_distribution = {
Expand Down