[FIX] sale_timesheet: fix amount computed for other_revenue
How to reproduce the problem: - Install sale_timesheet. - Create 2 service products: one with "Create a task in sales order's project" (e.g. Product X), and the other with "Don't create task" (e.g. Product Y), in the Service Tracking field. Both with "Milestones" as Service Invoicing Policy. - Create a Sale Order with these 2 products (with e.g. quantity of 10 for both). Confirm the SO. - Edit the SO. Put 5 in the "Delivered" column of the Product Y. Create Invoice and confirm it. - Go to the Project app -> Overview (of the newly created project). - The "Other Revenues" is missing/not correctly filled Cause of the problem : the query to fetch the value would not take the invoiced Product Y into account, it should now work correctly. opw-2540624 closes odoo/odoo#74191 X-original-commit: 59b5667665124e8db51caa94039e33b5f718718d Signed-off-by: LTU-Odoo <IT-Ideas@users.noreply.github.com>
This commit is contained in:
@@ -178,16 +178,18 @@ class ProfitabilityAnalysis(models.Model):
|
||||
0.0 AS amount_untaxed_invoiced,
|
||||
AAL.date AS line_date
|
||||
FROM project_project P
|
||||
LEFT JOIN account_analytic_account AA ON P.analytic_account_id = AA.id
|
||||
LEFT JOIN account_analytic_line AAL ON AAL.account_id = AA.id
|
||||
WHERE AAL.amount > 0.0 AND AAL.project_id IS NULL AND P.active = 't' AND P.allow_timesheets = 't'
|
||||
AND NOT EXISTS (
|
||||
SELECT SOL.id
|
||||
FROM sale_order_line SOL
|
||||
JOIN sale_order_line_invoice_rel SOINV ON SOINV.order_line_id = SOL.id AND SOINV.invoice_line_id = AAL.move_id -- AAL.move_id is an account.move.line id
|
||||
WHERE SOL.qty_delivered_method IN ('timesheet', 'manual')
|
||||
OR (SOL.qty_delivered_method = 'analytic' AND SOL.invoice_status != 'no')
|
||||
)
|
||||
JOIN account_analytic_account AA ON P.analytic_account_id = AA.id
|
||||
JOIN account_analytic_line AAL ON AAL.account_id = AA.id
|
||||
JOIN product_product PP ON PP.id = AAL.product_id
|
||||
JOIN product_template PT ON PT.id = PP.product_tmpl_id
|
||||
LEFT JOIN sale_order_line_invoice_rel SOINV ON SOINV.invoice_line_id = AAL.move_id
|
||||
LEFT JOIN sale_order_line SOL ON SOINV.order_line_id = SOL.id
|
||||
WHERE AAL.amount > 0.0 AND AAL.project_id IS NULL AND P.active = 't'
|
||||
AND P.allow_timesheets = 't'
|
||||
AND PT.service_type = 'manual' -- default value or Milestone service for services products
|
||||
AND PT.service_tracking = 'no' -- default value or not a tracking service for services products
|
||||
AND (SOL.id IS NULL
|
||||
OR (SOL.is_expense IS NOT TRUE AND SOL.is_downpayment IS NOT TRUE))
|
||||
|
||||
UNION ALL
|
||||
|
||||
|
||||
@@ -20,6 +20,16 @@ class TestSaleProject(TestReporting):
|
||||
'price_unit': self.product_delivery_timesheet2.list_price,
|
||||
'order_id': self.sale_order_2.id,
|
||||
})
|
||||
so_line_deliver_no_task = self.env['sale.order.line'].create({
|
||||
'name': self.product_delivery_manual1.name,
|
||||
'product_id': self.product_delivery_manual1.id,
|
||||
'product_uom_qty': 50,
|
||||
'product_uom': self.product_delivery_manual1.uom_id.id,
|
||||
'price_unit': self.product_delivery_manual1.list_price,
|
||||
'order_id': self.sale_order_2.id,
|
||||
})
|
||||
so_line_deliver_no_task.write({'qty_delivered': 1.0})
|
||||
|
||||
self.sale_order_2.action_confirm()
|
||||
project_so = self.so_line_order_project.project_id
|
||||
# log timesheet for billable time
|
||||
@@ -87,6 +97,7 @@ class TestSaleProject(TestReporting):
|
||||
'product_id': self.product_expense.id,
|
||||
'product_uom_id': self.product_expense.uom_id.id,
|
||||
})
|
||||
|
||||
view_id = self.env.ref('sale_timesheet.project_timesheet_action_client_timesheet_plan').id
|
||||
vals = self.env['project.project']._qweb_prepare_qcontext(view_id, [['id', '=', project_so.id]])
|
||||
|
||||
@@ -99,6 +110,7 @@ class TestSaleProject(TestReporting):
|
||||
project_rate_total = project_rate_non_billable + project_rate_non_billable_project + project_rate_billable_time + project_rate_billable_fixed
|
||||
project_invoiced = self.so_line_order_project.price_unit * self.so_line_order_project.product_uom_qty * timesheet1.unit_amount
|
||||
project_timesheet_cost = timesheet2.amount + timesheet3.amount + timesheet4.amount + timesheet5.amount + timesheet1.amount
|
||||
project_other_revenues = invoice.invoice_line_ids.search([('product_id', '=', self.product_delivery_manual1.id)])
|
||||
|
||||
self.assertEqual(float_compare(vals['dashboard']['time']['non_billable'], timesheet5.unit_amount, precision_rounding=rounding), 0, "The hours non-billable should be the one from the SO2 line, as we are in ordered quantity")
|
||||
self.assertEqual(float_compare(vals['dashboard']['time']['non_billable_project'], timesheet2.unit_amount, precision_rounding=rounding), 0, "The hours non-billable-project should be the one from the SO2 line, as we are in ordered quantity")
|
||||
@@ -113,6 +125,6 @@ class TestSaleProject(TestReporting):
|
||||
self.assertEqual(float_compare(vals['dashboard']['profit']['invoiced'], project_invoiced, precision_rounding=rounding), 0, "The amount invoiced should be the one from the SO2 line, as we are in ordered quantity")
|
||||
self.assertEqual(float_compare(vals['dashboard']['profit']['cost'], project_timesheet_cost, precision_rounding=rounding), 0, "The amount cost should be the one from the SO2 line, as we are in ordered quantity")
|
||||
self.assertEqual(float_compare(vals['dashboard']['profit']['expense_cost'], expense.amount, precision_rounding=rounding), 0, "The amount expense-cost should be the one from the SO2 line, as we are in ordered quantity")
|
||||
self.assertEqual(float_compare(vals['dashboard']['profit']['other_revenues'], other_revenues.amount, precision_rounding=rounding), 0, "The amount of the other revenues should be equal to the created other_revenues account analytic line")
|
||||
self.assertEqual(float_compare(vals['dashboard']['profit']['total'], project_invoiced + project_timesheet_cost + expense.amount + other_revenues.amount, precision_rounding=rounding), 0, "The total amount should be the sum of the SO2 line and the created other_revenues account analytic line")
|
||||
self.assertEqual(float_compare(vals['dashboard']['profit']['other_revenues'], other_revenues.amount + project_other_revenues.price_total, precision_rounding=rounding), 0, "The amount of the other revenues should be equal to the corresponding account move line and the one from the SO line")
|
||||
self.assertEqual(float_compare(vals['dashboard']['profit']['total'], project_invoiced + project_timesheet_cost + expense.amount + other_revenues.amount + project_other_revenues.price_total, precision_rounding=rounding), 0, "The total amount should be the sum of the SO2 line and the created other_revenues account analytic line")
|
||||
self.assertEqual(float_compare(vals['repartition_employee_max'], 11.0, precision_rounding=rounding), 0, "The amount of repartition-employee-max should be the one from SO2 line")
|
||||
|
||||
Reference in New Issue
Block a user