diff --git a/sale_service_fleet/README.rst b/sale_service_fleet/README.rst new file mode 100644 index 00000000000..39ff78d1fa4 --- /dev/null +++ b/sale_service_fleet/README.rst @@ -0,0 +1,64 @@ +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 + +================== +Sale Service Fleet +================== + +This module was written to extends the functionality of sale service project +and allow you to assign a vehicle to a sale order, so when the project is +created the vehicle is assigned to it. + +Usage +===== + +To use this module, you need to: + +1. Create a vehicle in fleet menu and assign it to a sale order. + +.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas + :alt: Try me on Runbot + :target: https://runbot.odoo-community.org/runbot/140/8.0 + +For further information, please visit: + +* https://www.odoo.com/forum/help-1 + +Known issues / Roadmap +====================== + + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed feedback +`here `_. + +Credits +======= + +Contributors +------------ + +* Rafael Blasco +* Pedro M. Baeza +* Carlos Dauden +* Sergio Teruel + +Maintainer +---------- + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +This module is maintained by the OCA. + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +To contribute to this module, please visit http://odoo-community.org. diff --git a/sale_service_fleet/__init__.py b/sale_service_fleet/__init__.py new file mode 100644 index 00000000000..38e796ced1b --- /dev/null +++ b/sale_service_fleet/__init__.py @@ -0,0 +1,7 @@ +# -*- coding: utf-8 -*- +# (c) 2015 Antiun Ingeniería S.L. - Sergio Teruel +# (c) 2015 Antiun Ingeniería S.L. - Carlos Dauden +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html + +from . import models +from . import report diff --git a/sale_service_fleet/__openerp__.py b/sale_service_fleet/__openerp__.py new file mode 100644 index 00000000000..37c546fa188 --- /dev/null +++ b/sale_service_fleet/__openerp__.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +# (c) 2015 Antiun Ingeniería S.L. - Sergio Teruel +# (c) 2015 Antiun Ingeniería S.L. - Carlos Dauden +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html + +{ + 'name': "Sale Service Fleet", + 'category': 'Sales', + 'version': '8.0.1.0.0', + 'depends': [ + 'sale_service_project', + 'fleet', + ], + 'data': [ + 'views/sale_view.xml', + 'views/project_view.xml', + 'views/report_saleorder.xml', + 'views/report_invoice.xml', + 'report/project_report_view.xml', + ], + 'author': 'Incaser Informatica S.L., ' + 'Antiun Ingeniería S.L., ' + 'Odoo Community Association (OCA)', + 'website': 'http://www.incaser.es', + 'license': 'AGPL-3', + 'installable': True, + 'autoinstall': True, +} diff --git a/sale_service_fleet/i18n/es.po b/sale_service_fleet/i18n/es.po new file mode 100644 index 00000000000..711ca9429e4 --- /dev/null +++ b/sale_service_fleet/i18n/es.po @@ -0,0 +1,68 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * sale_service_fleet +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 8.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-12-22 12:56+0000\n" +"PO-Revision-Date: 2015-12-22 13:57+0100\n" +"Last-Translator: Sergio Teruel \n" +"Language-Team: \n" +"Language: es-ES\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.5.4\n" + +#. module: sale_service_fleet +#: model:ir.model,name:sale_service_fleet.model_fleet_vehicle +msgid "Information on a vehicle" +msgstr "Información de un vehículo" + +#. module: sale_service_fleet +#: model:ir.model,name:sale_service_fleet.model_procurement_order +msgid "Procurement" +msgstr "Abastecimiento" + +#. module: sale_service_fleet +#: model:ir.model,name:sale_service_fleet.model_project_project +msgid "Project" +msgstr "Proyecto" + +#. module: sale_service_fleet +#: field:fleet.vehicle,project_ids:0 field:fleet.vehicle,task_ids:0 +msgid "Projects" +msgstr "Proyectos" + +#. module: sale_service_fleet +#: model:ir.model,name:sale_service_fleet.model_sale_order +msgid "Sales Order" +msgstr "Pedido de venta" + +#. module: sale_service_fleet +#: model:ir.model,name:sale_service_fleet.model_project_task +msgid "Task" +msgstr "Tarea" + +#. module: sale_service_fleet +#: model:ir.model,name:sale_service_fleet.model_report_project_task_user +msgid "Tasks by user and project" +msgstr "Tareas por usuario y proyecto" + +#. module: sale_service_fleet +#: view:project.project:sale_service_fleet.view_sale_service_fleet_edit_project_form_inherit +#: field:project.project,vehicle_id:0 +#: view:project.task:sale_service_fleet.view_sale_service_fleet_inherit_form2 +#: view:project.task:sale_service_fleet.view_sale_service_fleet_task_search +#: field:project.task,vehicle_id:0 +#: view:report.project.task.user:sale_service_fleet.view_task_project_user_search +#: field:report.project.task.user,vehicle_id:0 field:sale.order,vehicle_id:0 +msgid "Vehicle" +msgstr "Vehículo" + +#. module: sale_service_fleet +#: view:website:sale.report_saleorder_document +msgid "Vehicle:" +msgstr "Vehículo" diff --git a/sale_service_fleet/i18n/sale_service_fleet.pot b/sale_service_fleet/i18n/sale_service_fleet.pot new file mode 100644 index 00000000000..af77e351057 --- /dev/null +++ b/sale_service_fleet/i18n/sale_service_fleet.pot @@ -0,0 +1,70 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * sale_service_fleet +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 8.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-12-22 12:56+0000\n" +"PO-Revision-Date: 2015-12-22 12:56+0000\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: sale_service_fleet +#: model:ir.model,name:sale_service_fleet.model_fleet_vehicle +msgid "Information on a vehicle" +msgstr "" + +#. module: sale_service_fleet +#: model:ir.model,name:sale_service_fleet.model_procurement_order +msgid "Procurement" +msgstr "" + +#. module: sale_service_fleet +#: model:ir.model,name:sale_service_fleet.model_project_project +msgid "Project" +msgstr "" + +#. module: sale_service_fleet +#: field:fleet.vehicle,project_ids:0 +#: field:fleet.vehicle,task_ids:0 +msgid "Projects" +msgstr "" + +#. module: sale_service_fleet +#: model:ir.model,name:sale_service_fleet.model_sale_order +msgid "Sales Order" +msgstr "" + +#. module: sale_service_fleet +#: model:ir.model,name:sale_service_fleet.model_project_task +msgid "Task" +msgstr "" + +#. module: sale_service_fleet +#: model:ir.model,name:sale_service_fleet.model_report_project_task_user +msgid "Tasks by user and project" +msgstr "" + +#. module: sale_service_fleet +#: view:project.project:sale_service_fleet.view_sale_service_fleet_edit_project_form_inherit +#: field:project.project,vehicle_id:0 +#: view:project.task:sale_service_fleet.view_sale_service_fleet_inherit_form2 +#: view:project.task:sale_service_fleet.view_sale_service_fleet_task_search +#: field:project.task,vehicle_id:0 +#: view:report.project.task.user:sale_service_fleet.view_task_project_user_search +#: field:report.project.task.user,vehicle_id:0 +#: field:sale.order,vehicle_id:0 +msgid "Vehicle" +msgstr "" + +#. module: sale_service_fleet +#: view:website:sale.report_saleorder_document +msgid "Vehicle:" +msgstr "" + diff --git a/sale_service_fleet/models/__init__.py b/sale_service_fleet/models/__init__.py new file mode 100644 index 00000000000..7cceaa3d3b8 --- /dev/null +++ b/sale_service_fleet/models/__init__.py @@ -0,0 +1,9 @@ +# -*- coding: utf-8 -*- +# (c) 2015 Antiun Ingeniería S.L. - Sergio Teruel +# (c) 2015 Antiun Ingeniería S.L. - Carlos Dauden +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html + +from . import fleet +from . import sale +from . import sale_service +from . import project diff --git a/sale_service_fleet/models/fleet.py b/sale_service_fleet/models/fleet.py new file mode 100644 index 00000000000..d5df54c2e61 --- /dev/null +++ b/sale_service_fleet/models/fleet.py @@ -0,0 +1,17 @@ +# -*- coding: utf-8 -*- +# (c) 2015 Antiun Ingeniería S.L. - Sergio Teruel +# (c) 2015 Antiun Ingeniería S.L. - Carlos Dauden +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html + +from openerp import models, fields + + +class FleetVehicle(models.Model): + _inherit = "fleet.vehicle" + + project_ids = fields.One2many( + comodel_name='project.project', inverse_name='vehicle_id', + string='Projects') + task_ids = fields.One2many( + comodel_name='project.task', inverse_name='vehicle_id', + string='Projects') diff --git a/sale_service_fleet/models/project.py b/sale_service_fleet/models/project.py new file mode 100644 index 00000000000..7ae2441c548 --- /dev/null +++ b/sale_service_fleet/models/project.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# (c) 2015 Antiun Ingeniería S.L. - Sergio Teruel +# (c) 2015 Antiun Ingeniería S.L. - Carlos Dauden +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html + +from openerp import models, fields + + +class ProjectProject(models.Model): + _inherit = 'project.project' + + vehicle_id = fields.Many2one( + comodel_name='fleet.vehicle', string='Vehicle') + + +class ProjectTask(models.Model): + _inherit = 'project.task' + + vehicle_id = fields.Many2one( + comodel_name='fleet.vehicle', string='Vehicle') diff --git a/sale_service_fleet/models/sale.py b/sale_service_fleet/models/sale.py new file mode 100644 index 00000000000..a2effe0ce73 --- /dev/null +++ b/sale_service_fleet/models/sale.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +# (c) 2015 Antiun Ingeniería S.L. - Sergio Teruel +# (c) 2015 Antiun Ingeniería S.L. - Carlos Dauden +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html + +from openerp import models, fields, api + + +class SaleOrder(models.Model): + _inherit = 'sale.order' + + vehicle_id = fields.Many2one( + comodel_name='fleet.vehicle', string='Vehicle') + + @api.onchange('project_id') + def _onchange_project(self): + project = self.env['project.project'].search( + [('analytic_account_id', '=', self.project_id.id)]) + self.vehicle_id = project.vehicle_id diff --git a/sale_service_fleet/models/sale_service.py b/sale_service_fleet/models/sale_service.py new file mode 100644 index 00000000000..19486454041 --- /dev/null +++ b/sale_service_fleet/models/sale_service.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +# (c) 2015 Antiun Ingeniería S.L. - Sergio Teruel +# (c) 2015 Antiun Ingeniería S.L. - Carlos Dauden +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html + +from openerp import models, api + + +class ProcurementOrder(models.Model): + _inherit = "procurement.order" + + @api.model + def _prepare_project(self, procurement): + res = super(ProcurementOrder, self)._prepare_project(procurement) + sale_order = procurement.sale_line_id.order_id + if sale_order.vehicle_id: + vehicle = {'vehicle_id': sale_order.vehicle_id.id} + res.update(vehicle) + return res + + @api.model + def _prepare_task(self, procurement): + res = super(ProcurementOrder, self)._prepare_task(procurement) + sale_order = procurement.sale_line_id.order_id + if sale_order.vehicle_id: + vehicle = {'vehicle_id': sale_order.vehicle_id.id} + res.update(vehicle) + return res diff --git a/sale_service_fleet/report/__init__.py b/sale_service_fleet/report/__init__.py new file mode 100644 index 00000000000..6cbb1de1158 --- /dev/null +++ b/sale_service_fleet/report/__init__.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# (c) 2015 Antiun Ingeniería S.L. - Sergio Teruel +# (c) 2015 Antiun Ingeniería S.L. - Carlos Dauden +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.h + +from . import project_report diff --git a/sale_service_fleet/report/project_report.py b/sale_service_fleet/report/project_report.py new file mode 100644 index 00000000000..670408601ea --- /dev/null +++ b/sale_service_fleet/report/project_report.py @@ -0,0 +1,76 @@ +# -*- coding: utf-8 -*- +# (c) 2015 Antiun Ingeniería S.L. - Sergio Teruel +# (c) 2015 Antiun Ingeniería S.L. - Carlos Dauden +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html + +from openerp import models, fields +from openerp import tools + + +class ReportProjectTaskUser(models.Model): + _inherit = 'report.project.task.user' + + vehicle_id = fields.Many2one( + comodel_name='fleet.vehicle', string='Vehicle', readonly=True) + + def init(self, cr): + tools.sql.drop_view_if_exists(cr, 'report_project_task_user') + cr.execute(""" + CREATE view report_project_task_user as + SELECT + (select 1 ) AS nbr, + t.id as id, + t.date_start as date_start, + t.date_end as date_end, + t.date_last_stage_update as date_last_stage_update, + t.date_deadline as date_deadline, + abs((extract('epoch' from + (t.write_date-t.date_start)))/(3600*24)) as no_of_days, + t.user_id, + t.reviewer_id, + progress as progress, + t.project_id, + t.effective_hours as hours_effective, + t.priority, + t.name as name, + t.company_id, + t.partner_id, + t.stage_id as stage_id, + t.kanban_state as state, + remaining_hours as remaining_hours, + total_hours as total_hours, + t.delay_hours as hours_delay, + planned_hours as hours_planned, + (extract('epoch' from (t.write_date-t.create_date)))/ + (3600*24) as closing_days, + (extract('epoch' from (t.date_start-t.create_date)))/ + (3600*24) as opening_days, + (extract('epoch' from (t.date_deadline-(now() at time + zone 'UTC'))))/(3600*24) as delay_endings_days, + t.vehicle_id + FROM project_task t + WHERE t.active = 'true' + GROUP BY + t.id, + remaining_hours, + t.effective_hours, + progress, + total_hours, + planned_hours, + hours_delay, + create_date, + write_date, + date_start, + date_end, + date_deadline, + date_last_stage_update, + t.user_id, + t.reviewer_id, + t.project_id, + t.priority, + name, + t.company_id, + t.partner_id, + stage_id, + t.vehicle_id + """) diff --git a/sale_service_fleet/report/project_report_view.xml b/sale_service_fleet/report/project_report_view.xml new file mode 100644 index 00000000000..0b3b006c355 --- /dev/null +++ b/sale_service_fleet/report/project_report_view.xml @@ -0,0 +1,18 @@ + + + + + + report.project.task.user.search.fleet + report.project.task.user + + + + + + + + + + diff --git a/sale_service_fleet/static/description/icon.png b/sale_service_fleet/static/description/icon.png new file mode 100644 index 00000000000..3a0328b516c Binary files /dev/null and b/sale_service_fleet/static/description/icon.png differ diff --git a/sale_service_fleet/tests/__init__.py b/sale_service_fleet/tests/__init__.py new file mode 100644 index 00000000000..ea28afc79e5 --- /dev/null +++ b/sale_service_fleet/tests/__init__.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# (c) 2015 Antiun Ingeniería S.L. - Sergio Teruel +# (c) 2015 Antiun Ingeniería S.L. - Carlos Dauden +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html + +from . import test_sale_service_fleet diff --git a/sale_service_fleet/tests/test_sale_service_fleet.py b/sale_service_fleet/tests/test_sale_service_fleet.py new file mode 100644 index 00000000000..4187f47ce3a --- /dev/null +++ b/sale_service_fleet/tests/test_sale_service_fleet.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# (c) 2015 Antiun Ingeniería S.L. - Sergio Teruel +# (c) 2015 Antiun Ingeniería S.L. - Carlos Dauden +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html + +from openerp.tests.common import TransactionCase + + +class TestSaleServiceFleet(TransactionCase): + # Use case : Prepare some data for current test case + def setUp(self): + super(TestSaleServiceFleet, self).setUp() + + self.product_template_revision = self.env.ref( + 'sale_service_project.product_template_revision_1') + self.product_revision = self.env['product.product'].search( + [('product_tmpl_id', '=', self.product_template_revision.id)]) + self.product_stock = self.env.ref('product.product_product_4') + self.vehicle = self.env.ref('fleet.vehicle_1') + self.product_cost_service = self.env.ref( + 'product.product_product_consultant') + self.sale_order_model = self.env['sale.order'] + self.sale_order_line = self.env['sale.order.line'] + self.partner = self.env.ref('base.res_partner_2') + + self.price_list = self.env.ref('product.list0') + + self.sale_order_manual = self.sale_order_model.create({ + 'partner_id': self.partner.id, + 'order_policy': 'manual', + 'pricelist_id': self.price_list.id, + 'vehicle_id': self.vehicle.id + }) + self.sale_order_line.create( + {'product_id': self.product_revision.id, + 'product_uos_qty': 1, + 'price_unit': self.product_revision.list_price, + 'order_id': self.sale_order_manual.id, + 'name': self.product_revision.name}) + + def test_sale_order_fleet(self): + # Confirm the sale order + self.sale_order_manual.action_button_confirm() + + # Search task generate by sale order + task = self.env['project.task'].search( + [('sale_line_id', '=', self.sale_order_manual.order_line[0].id)]) + self.assertTrue(task) + self.assertEqual(task.vehicle_id.id, self.vehicle.id) + self.assertEqual(task.project_id.vehicle_id.id, self.vehicle.id) diff --git a/sale_service_fleet/views/project_view.xml b/sale_service_fleet/views/project_view.xml new file mode 100644 index 00000000000..4a2f6afaf69 --- /dev/null +++ b/sale_service_fleet/views/project_view.xml @@ -0,0 +1,55 @@ + + + + + + sale.service.fleet.form.view.inherit + project.task + + + + + + + + + + sale.service.fleet.project.form.inherit + project.project + + + + + + + + + + + sale.service.fleet.task.filter.inherit + project.task + + + + + + + + + + + + + sale.service.fleet.project.filter.inherit + project.project + + + + + + + + + + diff --git a/sale_service_fleet/views/report_invoice.xml b/sale_service_fleet/views/report_invoice.xml new file mode 100644 index 00000000000..c0a323046ec --- /dev/null +++ b/sale_service_fleet/views/report_invoice.xml @@ -0,0 +1,23 @@ + + + + + + + + diff --git a/sale_service_fleet/views/report_saleorder.xml b/sale_service_fleet/views/report_saleorder.xml new file mode 100644 index 00000000000..2c2ba286e3e --- /dev/null +++ b/sale_service_fleet/views/report_saleorder.xml @@ -0,0 +1,15 @@ + + + + + + + + diff --git a/sale_service_fleet/views/sale_view.xml b/sale_service_fleet/views/sale_view.xml new file mode 100644 index 00000000000..7a402b3c57e --- /dev/null +++ b/sale_service_fleet/views/sale_view.xml @@ -0,0 +1,28 @@ + + + + + + sale.order.fleet.form.inherit + sale.order + + + + + + + + + + sale.order.fleet.filter.inherit + sale.order + + + + + + + + + +