-
-
Notifications
You must be signed in to change notification settings - Fork 81
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by pedrobaeza
- Loading branch information
Showing
3 changed files
with
69 additions
and
163 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
from . import fleet_vehicle_cost, fleet_vehicle | ||
from . import fleet_vehicle_log_fuel | ||
from . import fleet_vehicle |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,177 +1,82 @@ | ||
# Copyright 2022 ForgeFlow S.L. <https://www.forgeflow.com> | ||
# Copyright 2024 Tecnativa - Pedro M. Baeza | ||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). | ||
from psycopg2 import sql | ||
|
||
from odoo import models, tools | ||
from odoo import fields, models, tools | ||
|
||
|
||
class FleetReport(models.Model): | ||
_inherit = "fleet.vehicle.cost.report" | ||
|
||
cost_type = fields.Selection(selection_add=[("fuel", "Fuel")]) | ||
|
||
def init(self): | ||
query = """ | ||
WITH service_costs AS ( | ||
SELECT | ||
ve.id AS vehicle_id, | ||
ve.company_id AS company_id, | ||
ve.name AS name, | ||
ve.driver_id AS driver_id, | ||
ve.fuel_type AS fuel_type, | ||
date(date_trunc('month', d)) AS date_start, | ||
COALESCE(sum(se.amount), 0) AS | ||
COST, | ||
'service' AS cost_type | ||
FROM | ||
fleet_vehicle ve | ||
CROSS JOIN generate_series( | ||
( | ||
SELECT min(date) | ||
FROM fleet_vehicle_log_services), | ||
CURRENT_DATE + '1 month'::interval, '1 month') d | ||
LEFT JOIN fleet_vehicle_log_services se ON se.vehicle_id = ve.id | ||
AND date_trunc('month', se.date) = date_trunc('month', d) | ||
WHERE | ||
ve.active AND se.active AND se.state != 'cancelled' | ||
GROUP BY | ||
ve.id, | ||
ve.company_id, | ||
ve.name, | ||
date_start, | ||
d | ||
ORDER BY | ||
ve.id, | ||
date_start | ||
), | ||
fuel_costs AS ( | ||
SELECT | ||
ve.id AS vehicle_id, | ||
ve.company_id AS company_id, | ||
ve.name AS name, | ||
ve.driver_id AS driver_id, | ||
ve.fuel_type AS fuel_type, | ||
date(date_trunc('month', d)) AS date_start, | ||
COALESCE(sum(se.amount), 0) AS | ||
COST, | ||
'fuel' AS cost_type | ||
FROM | ||
fleet_vehicle ve | ||
CROSS JOIN generate_series( | ||
( | ||
SELECT min(date) | ||
FROM fleet_vehicle_log_fuel), | ||
CURRENT_DATE + '1 month'::interval, '1 month') d | ||
LEFT JOIN fleet_vehicle_log_fuel se ON se.vehicle_id = ve.id | ||
AND date_trunc('month', se.date) = date_trunc('month', d) | ||
WHERE | ||
ve.active AND se.active AND se.state != 'cancelled' | ||
GROUP BY | ||
ve.id, | ||
ve.company_id, | ||
ve.name, | ||
date_start, | ||
d | ||
ORDER BY | ||
ve.id, | ||
date_start | ||
), | ||
contract_costs AS ( | ||
SELECT | ||
ve.id AS vehicle_id, | ||
ve.company_id AS company_id, | ||
ve.name AS name, | ||
ve.driver_id AS driver_id, | ||
ve.fuel_type AS fuel_type, | ||
date(date_trunc('month', d)) AS date_start, | ||
( | ||
COALESCE( | ||
sum(co.amount), 0 | ||
) + COALESCE( | ||
sum(cod.cost_generated * extract(day FROM | ||
least (date_trunc('month', d) + interval '1 month', cod.expiration_date | ||
) - greatest (date_trunc('month', d), cod.start_date) | ||
)), 0 | ||
) + COALESCE( | ||
sum(com.cost_generated), 0 | ||
) + COALESCE( | ||
sum(coy.cost_generated), 0 | ||
) | ||
) AS COST, | ||
'contract' AS cost_type | ||
FROM | ||
fleet_vehicle ve | ||
CROSS JOIN generate_series(( | ||
SELECT | ||
min(acquisition_date) | ||
FROM fleet_vehicle), CURRENT_DATE + '1 month'::interval, '1 month') d | ||
LEFT JOIN fleet_vehicle_log_contract co ON co.vehicle_id = ve.id | ||
AND date_trunc('month', co.date) = date_trunc('month', d) | ||
LEFT JOIN fleet_vehicle_log_contract cod ON cod.vehicle_id = ve.id | ||
AND date_trunc('month', cod.start_date) <= date_trunc('month', d) | ||
AND date_trunc('month', cod.expiration_date) >= date_trunc('month', d) | ||
AND cod.cost_frequency = 'daily' | ||
LEFT JOIN fleet_vehicle_log_contract com ON com.vehicle_id = ve.id | ||
AND date_trunc('month', com.start_date) <= date_trunc('month', d) | ||
AND date_trunc('month', com.expiration_date) >= date_trunc('month', d) | ||
AND com.cost_frequency = 'monthly' | ||
LEFT JOIN fleet_vehicle_log_contract coy ON coy.vehicle_id = ve.id | ||
AND date_trunc('month', coy.date) = date_trunc('month', d) | ||
AND date_trunc('month', coy.start_date) <= date_trunc('month', d) | ||
AND date_trunc('month', coy.expiration_date) >= date_trunc('month', d) | ||
AND coy.cost_frequency = 'yearly' | ||
WHERE | ||
ve.active | ||
GROUP BY | ||
ve.id, | ||
ve.company_id, | ||
ve.name, | ||
date_start, | ||
d | ||
ORDER BY | ||
ve.id, | ||
date_start | ||
) | ||
SELECT | ||
vehicle_id AS id, | ||
company_id, | ||
vehicle_id, | ||
name, | ||
driver_id, | ||
fuel_type, | ||
date_start, | ||
COST, | ||
'service' as cost_type | ||
FROM | ||
service_costs sc | ||
UNION ALL ( | ||
SELECT | ||
vehicle_id AS id, | ||
company_id, | ||
vehicle_id, | ||
name, | ||
driver_id, | ||
fuel_type, | ||
date_start, | ||
COST, | ||
'fuel' as cost_type | ||
FROM | ||
fuel_costs cc) | ||
UNION ALL ( | ||
SELECT | ||
vehicle_id AS id, | ||
company_id, | ||
vehicle_id, | ||
name, | ||
driver_id, | ||
fuel_type, | ||
date_start, | ||
COST, | ||
'contract' as cost_type | ||
FROM | ||
contract_costs cc) | ||
""" | ||
"""Inject parts in the query with this hack, fetching the query and | ||
recreating it. Query is returned all in upper case and with final ';'. | ||
""" | ||
super().init() | ||
self.env.cr.execute(f"SELECT pg_get_viewdef('{self._table}', true)") | ||
view_def = self.env.cr.fetchone()[0] | ||
if view_def[-1] == ";": # Remove trailing semicolon | ||
view_def = view_def[:-1] | ||
# Subquery | ||
view_def = view_def.replace( | ||
"contract_costs AS (", | ||
""" | ||
fuel_costs AS ( | ||
SELECT | ||
ve.id AS vehicle_id, | ||
ve.company_id AS company_id, | ||
ve.name AS name, | ||
ve.driver_id AS driver_id, | ||
ve.fuel_type AS fuel_type, | ||
date(date_trunc('month', d)) AS date_start, | ||
vem.vehicle_type as vehicle_type, | ||
COALESCE(sum(fvlf.amount), 0) AS cost, | ||
'fuel' AS cost_type | ||
FROM | ||
fleet_vehicle ve | ||
JOIN | ||
fleet_vehicle_model vem ON vem.id = ve.model_id | ||
CROSS JOIN generate_series( | ||
( | ||
SELECT min(date) | ||
FROM fleet_vehicle_log_fuel), | ||
CURRENT_DATE + '1 month'::interval, '1 month') d | ||
LEFT JOIN fleet_vehicle_log_fuel fvlf ON fvlf.vehicle_id = ve.id | ||
AND date_trunc('month', fvlf.date) = date_trunc('month', d) | ||
WHERE | ||
ve.active AND fvlf.active AND fvlf.state <> 'cancelled' | ||
GROUP BY ve.id, ve.company_id, ve.name, vem.vehicle_type, date_start, d | ||
ORDER BY ve.id, date_start | ||
), | ||
contract_costs AS (""", | ||
) | ||
# Union | ||
view_def = view_def.replace( | ||
"UNION ALL", | ||
""" | ||
UNION ALL | ||
SELECT | ||
fc.company_id, | ||
fc.vehicle_id, | ||
fc.name, | ||
fc.driver_id, | ||
fc.fuel_type, | ||
fc.date_start, | ||
fc.vehicle_type, | ||
fc.cost, | ||
'fuel' as cost_type | ||
FROM | ||
fuel_costs fc | ||
UNION ALL""", | ||
) | ||
# Re-create view | ||
tools.drop_view_if_exists(self.env.cr, self._table) | ||
self.env.cr.execute( | ||
sql.SQL("""CREATE or REPLACE VIEW {} as ({})""").format( | ||
sql.Identifier(self._table), sql.SQL(query) | ||
sql.Identifier(self._table), sql.SQL(view_def) | ||
) | ||
) | ||
return True |