From 02488e4aafa882d59d44deda26c31be85da8655b Mon Sep 17 00:00:00 2001 From: Remi <remi@le-filament.com> Date: Mon, 29 Apr 2019 13:16:30 +0200 Subject: [PATCH] Fix coding according to standards --- LICENSE | 27 -------- README.rst | 10 +-- __init__.py | 5 +- __manifest__.py | 53 +++++++++------- models/__init__.py | 15 ++--- models/product.py | 7 ++- models/project.py | 3 +- models/project_task.py | 17 +++-- models/project_task_type.py | 3 +- models/res_config.py | 12 +++- models/sale_config_settings.py | 11 ++-- models/sale_order.py | 87 +++++++++++++++++-------- security/ir.model.access.csv | 2 - views/product_views.xml | 4 +- views/project_task_views.xml | 2 + views/project_views.xml | 4 +- views/res_config_views.xml | 8 ++- views/sale_config_settings_views.xml | 27 ++++---- views/sale_views.xml | 12 ++-- wizard/__init__.py | 4 +- wizard/sale_views_wizard.py | 94 +++++++++++++++++----------- wizard/sale_views_wizard.xml | 16 +++-- 22 files changed, 238 insertions(+), 185 deletions(-) delete mode 100644 security/ir.model.access.csv diff --git a/LICENSE b/LICENSE index 7e5dad2..33aa54e 100644 --- a/LICENSE +++ b/LICENSE @@ -201,30 +201,3 @@ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY C If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS - -How to Apply These Terms to Your New Programs - -If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. - -To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. - - <one line to give the program's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <https://www.gnu.org/licenses/>. -Also add information on how to contact you by electronic and paper mail. - -If your software can interact with users remotely through a computer network, you should also make sure that it provides a way for users to get its source. For example, if your program is a web application, its interface could display a "Source" link that leads users to an archive of the code. There are many ways you could offer source, and different solutions will be better for different programs; see section 13 for the specific requirements. - -You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU AGPL, see <https://www.gnu.org/licenses/>. \ No newline at end of file diff --git a/README.rst b/README.rst index 4b6fe88..f1e1522 100644 --- a/README.rst +++ b/README.rst @@ -3,9 +3,9 @@ :alt: License: AGPL-3 -================= +================================ Le Filament Link Sale to Project -================= +================================ This module provides a new functionality to transform your sale order in projects and tasks (and to update those in case sale order is updated) @@ -15,7 +15,7 @@ This module depends upon *sale_service* and *lefilament_projets* modules. Configuration -===== +============= 1. In *Sales > Products* when creating a product of Service type, in *Invoicing > Invoicing policy* you can now use an extra *track service* named 'Create a project and link tasks'. @@ -69,8 +69,8 @@ Contributors Maintainer ------------ -.. image:: https://le-filament.com/images/logo-lefilament.png +.. image:: https://le-filament.com/img/logo-lefilament.png :alt: Le Filament :target: https://le-filament.com -This module is maintained by Le Filament \ No newline at end of file +This module is maintained by Le Filament diff --git a/__init__.py b/__init__.py index eb6cc70..55f67ff 100644 --- a/__init__.py +++ b/__init__.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -import models -import wizard \ No newline at end of file +from . import models +from . import wizard diff --git a/__manifest__.py b/__manifest__.py index e3c373b..55d8491 100644 --- a/__manifest__.py +++ b/__manifest__.py @@ -1,31 +1,36 @@ +# -*- coding: utf-8 -*- +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). { - 'name': 'Le Filament - Link Sales Order to Project', - 'version': '10.0.1.0', - 'license': 'AGPL-3', - 'description': """ - MODULE LINK SALE ORDER / PROJECT LE FILAMENT + 'name': 'Le Filament - Link Sales Order to Project', + 'version': '10.0.1.0.0', + 'license': 'AGPL-3', + 'description': """ + MODULE LINK SALE ORDER / PROJECT LE FILAMENT - This module depends upon *sale_service* and *lefilament_projets* modules. + This module depends upon *sale_service* and *lefilament_projets* modules. - - This module provides a new functionality to transform your sale order in projects and tasks (and to update those in case sale order is updated) - - Product template has been enhanced, invoicing policy section in order to set how each product should behave when transformed from sale order to project/task. - """, - 'author': 'LE FILAMENT', - 'category': 'LE FILAMENT', - 'depends': ['sale_timesheet', 'lefilament_projets'], - 'contributors': [ + - This module provides a new functionality to transform your sale order in + projects and tasks (and to update those in case sale order is updated) + - Product template has been enhanced, invoicing policy section in order to + set how each product should behave when transformed from sale order to + project/task. + """, + 'author': 'LE FILAMENT', + 'category': 'LE FILAMENT', + 'depends': ['sale_timesheet', 'lefilament_projets'], + 'contributors': [ 'Juliana Poudou <juliana@le-filament.com>', ], - 'website': 'http://www.le-filament.com', - 'data': [ - 'views/product_views.xml', - 'views/sale_config_settings_views.xml', - 'wizard/sale_views_wizard.xml', - 'views/sale_views.xml', - 'views/res_config_views.xml', - 'views/project_views.xml', - 'views/project_task_views.xml', - ], - 'qweb': [ + 'website': 'http://www.le-filament.com', + 'data': [ + 'views/product_views.xml', + 'views/sale_config_settings_views.xml', + 'wizard/sale_views_wizard.xml', + 'views/sale_views.xml', + 'views/res_config_views.xml', + 'views/project_views.xml', + 'views/project_task_views.xml', + ], + 'qweb': [ ], } diff --git a/models/__init__.py b/models/__init__.py index 6c5713e..b98ff0d 100644 --- a/models/__init__.py +++ b/models/__init__.py @@ -1,9 +1,10 @@ # -*- coding: utf-8 -*- +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -import product -import sale_config_settings -import res_config -import project_task_type -import project -import project_task -import sale_order \ No newline at end of file +from . import product +from . import sale_config_settings +from . import res_config +from . import project_task_type +from . import project +from . import project_task +from . import sale_order \ No newline at end of file diff --git a/models/product.py b/models/product.py index 31cfb4b..8e39c66 100644 --- a/models/product.py +++ b/models/product.py @@ -1,9 +1,10 @@ # -*- coding: utf-8 -*- -# © 2017 Le Filament (<http://www.le-filament.com>) +# © 2017 Le Filament (<https://le-filament.com>) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from odoo import api, fields, models +from odoo import fields, models + class LeFilamentProductTemplate(models.Model): _inherit = 'product.template' @@ -11,4 +12,4 @@ class LeFilamentProductTemplate(models.Model): project_task_type_id = fields.Many2one( 'project.task.type', 'Project task stage') track_service = fields.Selection(selection_add=[ - ('project', 'Create a project and link tasks')]) \ No newline at end of file + ('project', 'Create a project and link tasks')]) diff --git a/models/project.py b/models/project.py index c76d8fe..d376bfe 100644 --- a/models/project.py +++ b/models/project.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- -# © 2017 Le Filament (<http://www.le-filament.com>) + +# © 2017 Le Filament (<https://le-filament.com>) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from odoo import models, fields diff --git a/models/project_task.py b/models/project_task.py index 565ae6c..9965638 100644 --- a/models/project_task.py +++ b/models/project_task.py @@ -1,13 +1,20 @@ # -*- coding: utf-8 -*- -# © 2017 Le Filament (<http://www.le-filament.com>) + +# © 2017 Le Filament (<https://le-filament.com>) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from odoo import models, fields -from odoo.tools import float_is_zero, float_compare, DEFAULT_SERVER_DATETIME_FORMAT -import odoo.addons.decimal_precision as dp + class LeFilamentProjectTask(models.Model): _inherit = 'project.task' - price_subtotal = fields.Monetary(string='Subtotal initial', readonly=True, store='True') - currency_id = fields.Many2one(related='sale_line_id.currency_id', store=True, string='Currency', readonly=True) \ No newline at end of file + price_subtotal = fields.Monetary( + string='Subtotal initial', readonly=True, store='True' + ) + currency_id = fields.Many2one( + related='sale_line_id.currency_id', + store=True, + string='Currency', + readonly=True + ) diff --git a/models/project_task_type.py b/models/project_task_type.py index d1f8e8f..207d91a 100644 --- a/models/project_task_type.py +++ b/models/project_task_type.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- -# © 2017 Le Filament (<http://www.le-filament.com>) + +# © 2017 Le Filament (<https://le-filament.com>) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from odoo import models, fields diff --git a/models/res_config.py b/models/res_config.py index ee44d99..7b1bc4d 100644 --- a/models/res_config.py +++ b/models/res_config.py @@ -1,10 +1,11 @@ # -*- coding: utf-8 -*- -# © 2017 Le Filament (<http://www.le-filament.com>) +# © 2017 Le Filament (<https://le-filament.com>) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from odoo import api, fields, models + class ProjectLFConfiguration(models.TransientModel): _name = 'project.config.settings' _inherit = 'project.config.settings' @@ -16,7 +17,9 @@ class ProjectLFConfiguration(models.TransientModel): def set_default_generate_project_alias(self): Values = self.env['ir.values'].sudo() or self.env['ir.values'] for config in self: - Values.set_default('project.config.settings', 'generate_project_alias', config.generate_project_alias) + Values.set_default('project.config.settings', + 'generate_project_alias', + config.generate_project_alias) @api.multi def set_default_lf_tarif_jour(self): @@ -26,4 +29,7 @@ class ProjectLFConfiguration(models.TransientModel): @api.multi def set_default_alias_prefix(self): return self.env['ir.values'].sudo().set_default( - 'project.config.settings', 'lf_alias_prefix', self.lf_alias_prefix) \ No newline at end of file + 'project.config.settings', + 'lf_alias_prefix', + self.lf_alias_prefix + ) diff --git a/models/sale_config_settings.py b/models/sale_config_settings.py index b1c4d17..f41b27f 100644 --- a/models/sale_config_settings.py +++ b/models/sale_config_settings.py @@ -1,14 +1,10 @@ # -*- coding: utf-8 -*- -# © 2017 Le Filament (<http://www.le-filament.com>) +# © 2017 Le Filament (<https://le-filament.com>) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -import logging - from odoo import api, fields, models -_logger = logging.getLogger(__name__) - class LeFilamentSaleConfiguration(models.TransientModel): _inherit = 'sale.config.settings' @@ -19,4 +15,7 @@ class LeFilamentSaleConfiguration(models.TransientModel): @api.multi def set_project_task_type(self): return self.env['ir.values'].sudo().set_default( - 'sale.config.settings', 'project_task_type_id', self.project_task_type_id.id) \ No newline at end of file + 'sale.config.settings', + 'project_task_type_id', + self.project_task_type_id.id + ) diff --git a/models/sale_order.py b/models/sale_order.py index 764fa67..a0fbc69 100644 --- a/models/sale_order.py +++ b/models/sale_order.py @@ -1,11 +1,11 @@ # -*- coding: utf-8 -*- -# © 2017 Le Filament (<http://www.le-filament.com>) + +# © 2017 Le Filament (<https://le-filament.com>) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from odoo import api, fields, models, _ from datetime import datetime +from odoo import api, models from dateutil.relativedelta import relativedelta -from odoo.exceptions import ValidationError class SaleOrder(models.Model): @@ -14,28 +14,39 @@ class SaleOrder(models.Model): @api.multi def lefilament_update_tasks(self): for order in self: - stage_id_new = self.env['ir.values'].get_default('sale.config.settings', 'project_task_type_id') + stage_id_new = self.env['ir.values'].get_default( + 'sale.config.settings', 'project_task_type_id') stage_new = self.env['project.task.type'].browse(stage_id_new) - lf_tarif_jour = self.env['ir.values'].get_default('project.config.settings', 'lf_tarif_jour') - lf_heures_jour = self.env['ir.values'].get_default('project.config.settings', 'lf_heures_jour') + lf_tarif_jour = self.env['ir.values'].get_default( + 'project.config.settings', 'lf_tarif_jour') + lf_heures_jour = self.env['ir.values'].get_default( + 'project.config.settings', 'lf_heures_jour') sale_project_id = order.project_project_id - sale_task_ids = order.tasks_ids project_id = sale_project_id.id project_total_budget = 0 for line in order.order_line: - task_id_refer = self.env['project.task'].search([('sale_line_id', '=', line.id)]) + task_id_refer = self.env['project.task'].search( + [('sale_line_id', '=', line.id)]) if task_id_refer: if not line.product_id.project_id: - project_total_budget = project_total_budget + line.price_subtotal - planned_hours = (line.price_subtotal / lf_tarif_jour) * lf_heures_jour + project_total_budget = (project_total_budget + + line.price_subtotal) + planned_hours = ((line.price_subtotal / lf_tarif_jour) + * lf_heures_jour) task_id_refer.planned_hours = planned_hours else: if line.price_subtotal != task_id_refer.price_subtotal: project = line.product_id.project_id project_id_maint = project.id - project_update = self.env['project.project'].browse(project_id_maint) - project_update.lf_total_budget = ( project_update.lf_total_budget - task_id_refer.price_subtotal ) + line.price_subtotal - planned_hours = (line.price_subtotal / lf_tarif_jour) * lf_heures_jour + project_update = self.env[ + 'project.project'].browse(project_id_maint) + project_update.lf_total_budget = ( + (project_update.lf_total_budget + - task_id_refer.price_subtotal) + + line.price_subtotal) + planned_hours = ( + (line.price_subtotal / lf_tarif_jour) + * lf_heures_jour) task_id_refer.planned_hours = planned_hours task_id_refer.price_subtotal = line.price_subtotal else: @@ -43,32 +54,42 @@ class SaleOrder(models.Model): if line.product_id.project_id: project = line.product_id.project_id project_id = project.id - date_plan = datetime.strptime(order.confirmation_date,'%Y-%m-%d %H:%M:%S') - date_deadline = (date_plan.date() + relativedelta(years=int(line.product_uom_qty))).strftime('%Y-%m-%d') + date_plan = datetime.strptime( + order.confirmation_date, '%Y-%m-%d %H:%M:%S') + date_deadline = ( + date_plan.date() + + relativedelta( + years=int(line.product_uom_qty))).strftime( + '%Y-%m-%d') stage = line.product_id.project_task_type_id - if order.partner_id.is_company == True: - name_task = order.partner_id.name + " - " + stage.name + if order.partner_id.is_company is True: + name_task = (order.partner_id.name + " - " + + stage.name) else: - name_task = order.partner_id.parent_id.name + " - " + stage.name + name_task = (order.partner_id.parent_id.name + + " - " + stage.name) else: stage = stage_new project_id = sale_project_id.id date_deadline = False name_task = line.name.split('\n', 1)[0] - project_total_budget = project_total_budget + line.price_subtotal - planned_hours = (line.price_subtotal / lf_tarif_jour) * lf_heures_jour + project_total_budget = (project_total_budget + + line.price_subtotal) + planned_hours = ((line.price_subtotal / lf_tarif_jour) + * lf_heures_jour) description_line = "<p>" for line_name in line.name: if line_name == '\n': description_line = description_line + "</p><p>" else: description_line = description_line + line_name - task = self.env['project.task'].create({ + self.env['project.task'].create({ 'name': name_task, 'date_deadline': date_deadline, 'planned_hours': planned_hours, 'remaining_hours': planned_hours, - 'partner_id': order.partner_id.id or self.partner_dest_id.id, + 'partner_id': (order.partner_id.id + or self.partner_dest_id.id), 'user_id': self.env.uid, # 'procurement_id': line.procurement_ids.id, 'description': description_line + '</p><br/>', @@ -80,9 +101,11 @@ class SaleOrder(models.Model): project_date = self.env['project.project'].browse(project_id) project_date.lf_tarif_jour = lf_tarif_jour project_date.lf_total_budget = project_total_budget - order.tasks_ids = self.env['project.task'].search([('sale_line_id', 'in', order.order_line.ids)]) + order.tasks_ids = self.env['project.task'].search( + [('sale_line_id', 'in', order.order_line.ids)]) order.tasks_count = len(order.tasks_ids) + class LeFilamentSaleOrderLine(models.Model): _inherit = "sale.order.line" @@ -90,8 +113,18 @@ class LeFilamentSaleOrderLine(models.Model): def _compute_analytic(self, domain=None): if not domain and self.ids: # To filter on analyic lines linked to an expense - expense_type_id = self.env.ref('account.data_account_type_expenses', raise_if_not_found=False) + expense_type_id = self.env.ref( + 'account.data_account_type_expenses', + raise_if_not_found=False + ) expense_type_id = expense_type_id and expense_type_id.id - prod_list = self.env['product.template'].search([('track_service','in', ['task','timesheet'])]) - domain = [('product_id', 'in', prod_list.ids), ('so_line', 'in', self.ids), '|', ('amount', '<=', 0.0), ('project_id', '!=', False)] - return super(LeFilamentSaleOrderLine, self)._compute_analytic(domain=domain) \ No newline at end of file + prod_list = self.env['product.template'].search( + [('track_service', 'in', ['task', 'timesheet'])] + ) + domain = [ + ('product_id', 'in', prod_list.ids), + ('so_line', 'in', self.ids), + '|', ('amount', '<=', 0.0), ('project_id', '!=', False) + ] + return super(LeFilamentSaleOrderLine, self)._compute_analytic( + domain=domain) diff --git a/security/ir.model.access.csv b/security/ir.model.access.csv deleted file mode 100644 index 77ff07c..0000000 --- a/security/ir.model.access.csv +++ /dev/null @@ -1,2 +0,0 @@ -id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_project_config_settings_group_user,project.config.settings,model_project_config_settings,base.group_user,1,1,1,1 \ No newline at end of file diff --git a/views/product_views.xml b/views/product_views.xml index 4443b8e..0e936eb 100644 --- a/views/product_views.xml +++ b/views/product_views.xml @@ -1,4 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2017 Le Filament (<https://le-filament.com>) + License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). --> <odoo> <record id="lefilament_view_product_timesheet_form" model="ir.ui.view"> <field name="name">lefilament.product.template.timesheet.form</field> @@ -13,4 +15,4 @@ </field> </field> </record> -</odoo> \ No newline at end of file +</odoo> diff --git a/views/project_task_views.xml b/views/project_task_views.xml index 73c5518..f9e1023 100644 --- a/views/project_task_views.xml +++ b/views/project_task_views.xml @@ -1,4 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2017 Le Filament (<https://le-filament.com>) + License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). --> <odoo> <record id="lefilament_view_sale_service_inherit_form2" model="ir.ui.view"> <field name="name">lefilament.sale.service.form.view.inherit</field> diff --git a/views/project_views.xml b/views/project_views.xml index 771eb9f..c28863c 100644 --- a/views/project_views.xml +++ b/views/project_views.xml @@ -1,6 +1,7 @@ <?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2017 Le Filament (<https://le-filament.com>) + License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). --> <odoo> - <record id="lefilament_task_type_edit" model="ir.ui.view"> <field name="name">lefilament.task.type.form</field> <field name="model">project.task.type</field> @@ -37,5 +38,4 @@ </xpath> </field> </record> - </odoo> diff --git a/views/res_config_views.xml b/views/res_config_views.xml index d808fb5..6c33c6f 100644 --- a/views/res_config_views.xml +++ b/views/res_config_views.xml @@ -1,14 +1,16 @@ <?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2017 Le Filament (<https://le-filament.com>) + License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). --> <odoo> - <record id="view_lefilament_project_config_settings" model="ir.ui.view"> + <record id="view_lefilament_project_config_settings" model="ir.ui.view"> <field name="name">project.lefilament.settings</field> <field name="model">project.config.settings</field> <field name="inherit_id" ref="project.view_config_settings"/> <field name="arch" type="xml"> <xpath expr="//field[@name='module_rating_project']" position="after"> <field name="lf_tarif_jour" class="oe_inline oe_text_right" /> - <field name="lf_alias_prefix" class="oe_inline" /> + <field name="lf_alias_prefix" class="oe_inline" /> </xpath> </field> </record> -</odoo> \ No newline at end of file +</odoo> diff --git a/views/sale_config_settings_views.xml b/views/sale_config_settings_views.xml index f12e47a..94987bd 100644 --- a/views/sale_config_settings_views.xml +++ b/views/sale_config_settings_views.xml @@ -1,16 +1,17 @@ <?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2017 Le Filament (<https://le-filament.com>) + License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). --> <odoo> - <record id="lefilament_view_sales_config" model="ir.ui.view"> - <field name="name">lefilament.sale.settings</field> - <field name="model">sale.config.settings</field> - <field name="inherit_id" ref="sale.view_sales_config"/> - <field name="arch" type="xml"> - <div id="main" position="inside"> - <group string="Task"> - <field name="project_task_type_id" class="oe_inline"/> - </group> - </div> - </field> - </record> - + <record id="lefilament_view_sales_config" model="ir.ui.view"> + <field name="name">lefilament.sale.settings</field> + <field name="model">sale.config.settings</field> + <field name="inherit_id" ref="sale.view_sales_config"/> + <field name="arch" type="xml"> + <div id="main" position="inside"> + <group string="Task"> + <field name="project_task_type_id" class="oe_inline"/> + </group> + </div> + </field> + </record> </odoo> diff --git a/views/sale_views.xml b/views/sale_views.xml index 1857e77..5babd05 100644 --- a/views/sale_views.xml +++ b/views/sale_views.xml @@ -1,9 +1,10 @@ <?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2017 Le Filament (<https://le-filament.com>) + License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). --> <odoo> - <data> - - <record id="lefilament_view_order_form" model="ir.ui.view"> + <data> + <record id="lefilament_view_order_form" model="ir.ui.view"> <field name="name">lefilament.sale.order.form</field> <field name="model">sale.order</field> <field name="inherit_id" ref="sale.view_order_form"/> @@ -14,6 +15,5 @@ </header> </field> </record> - - </data> -</odoo> \ No newline at end of file + </data> +</odoo> diff --git a/wizard/__init__.py b/wizard/__init__.py index 5a71743..a38a692 100644 --- a/wizard/__init__.py +++ b/wizard/__init__.py @@ -1,4 +1,4 @@ # -*- coding: utf-8 -*- -# Part of Odoo. See LICENSE file for full copyright and licensing details. +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -import sale_views_wizard \ No newline at end of file +from . import sale_views_wizard diff --git a/wizard/sale_views_wizard.py b/wizard/sale_views_wizard.py index 3a132e7..1e4ea7b 100644 --- a/wizard/sale_views_wizard.py +++ b/wizard/sale_views_wizard.py @@ -1,40 +1,46 @@ -# -*- coding: utf-8 -*- +# -*- coding: utf-8 -*- -# © 2017 Le Filament (<http://www.le-filament.com>) +# © 2017 Le Filament (<https://le-filament.com>) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from odoo import models, fields, api from datetime import datetime +from odoo import models, fields, api from dateutil.relativedelta import relativedelta - -class LeFilamentSaleWizard(models.TransientModel): - _name = 'lefilament.sale.views.wizard' + + +class LeFilamentSaleWizard(models.TransientModel): + _name = 'lefilament.sale.views.wizard' _description = 'Sale Project Assignment' @api.model def _default_sale_id(self): - return self.env['sale.order'].browse(self.env.context.get('active_id')) + return self.env['sale.order'].browse(self.env.context.get('active_id')) @api.model def _default_project_project_id(self): - return self._default_sale_id().project_project_id + return self._default_sale_id().project_project_id @api.model def _default_related_project_id(self): - return self._default_sale_id().related_project_id + return self._default_sale_id().related_project_id @api.model def _default_project_name(self): - if self._default_sale_id().partner_id.is_company == True: + if self._default_sale_id().partner_id.is_company is True: return self._default_sale_id().partner_id.name - else: - return self._default_sale_id().partner_id.parent_id.name - sale_id = fields.Many2one('sale.order', string='Sale', default=_default_sale_id) - project_id = fields.Many2one('project.project', string='Existing project', default=_default_project_project_id) + return self._default_sale_id().partner_id.parent_id.name + + sale_id = fields.Many2one('sale.order', string='Sale', + default=_default_sale_id) + project_id = fields.Many2one('project.project', string='Existing project', + default=_default_project_project_id) project_name = fields.Char('New project', default=_default_project_name) - related_project_id = fields.Many2one('account.analytic.account', string='Analytical account related', default=_default_related_project_id) - related_project_name = fields.Char('New Analytical Account', default=_default_project_name) + related_project_id = fields.Many2one('account.analytic.account', + string='Analytical account related', + default=_default_related_project_id) + related_project_name = fields.Char('New Analytical Account', + default=_default_project_name) @api.onchange('project_id') def onchange_project_id(self): @@ -42,36 +48,49 @@ class LeFilamentSaleWizard(models.TransientModel): @api.multi def close_dialog(self): - sale_id = self.env['sale.order'].browse(self.env.context.get('active_id')) + sale_id = self.env['sale.order'].browse( + self.env.context.get('active_id')) if self.project_id: sale_id.project_id = self.project_id.analytic_account_id sale_id.project_project_id = self.project_id project_id_new = self.project_id.id else: sale_id._create_analytic_account(prefix=None) - project_id_new = sale_id.project_id.project_create({'name': self.project_name, 'use_tasks': True}) - stage_id_new = self.env['ir.values'].get_default('sale.config.settings', 'project_task_type_id') + project_id_new = sale_id.project_id.project_create( + {'name': self.project_name, 'use_tasks': True}) + stage_id_new = self.env['ir.values'].get_default( + 'sale.config.settings', 'project_task_type_id') stage_new = self.env['project.task.type'].browse(stage_id_new) - lf_tarif_jour = self.env['ir.values'].get_default('project.config.settings', 'lf_tarif_jour') - lf_heures_jour = self.env['ir.values'].get_default('project.config.settings', 'lf_heures_jour') - lf_alias_prefix = self.env['ir.values'].get_default('project.config.settings', 'lf_alias_prefix') - ir_values = self.env['ir.values'].get_default('project.config.settings', 'generate_project_alias') + lf_tarif_jour = self.env['ir.values'].get_default( + 'project.config.settings', 'lf_tarif_jour') + lf_heures_jour = self.env['ir.values'].get_default( + 'project.config.settings', 'lf_heures_jour') + lf_alias_prefix = self.env['ir.values'].get_default( + 'project.config.settings', 'lf_alias_prefix') + ir_values = self.env['ir.values'].get_default( + 'project.config.settings', 'generate_project_alias') for line in sale_id.order_line: if line.product_id.track_service == 'project': if line.product_id.project_id: project = line.product_id.project_id project_id = project.id - date_plan = datetime.strptime(sale_id.confirmation_date,'%Y-%m-%d %H:%M:%S') - date_deadline = (date_plan.date() + relativedelta(years=int(line.product_uom_qty))).strftime('%Y-%m-%d') + date_plan = datetime.strptime(sale_id.confirmation_date, + '%Y-%m-%d %H:%M:%S') + date_deadline = (date_plan.date() + + relativedelta(years=int( + line.product_uom_qty))).strftime( + '%Y-%m-%d') stage = line.product_id.project_task_type_id - if sale_id.partner_id.is_company == True: + if sale_id.partner_id.is_company is True: if stage.name: - name_task = sale_id.partner_id.name + " - " + stage.name + name_task = (sale_id.partner_id.name + + " - " + stage.name) else: name_task = sale_id.partner_id.name else: if stage.name: - name_task = sale_id.partner_id.parent_id.name + " - " + stage.name + name_task = (sale_id.partner_id.parent_id.name + + " - " + stage.name) else: name_task = sale_id.partner_id.parent_id.name else: @@ -80,26 +99,28 @@ class LeFilamentSaleWizard(models.TransientModel): date_deadline = False name_task = line.name.split('\n', 1)[0] project_date = self.env['project.project'].browse(project_id) - project_date.lf_total_budget = project_date.lf_total_budget + line.price_subtotal + project_date.lf_total_budget = (project_date.lf_total_budget + + line.price_subtotal) project_date.lf_tarif_jour = lf_tarif_jour - if not line.product_id.project_id: + if not line.product_id.project_id: if ir_values and lf_alias_prefix: lf_alias_name = lf_alias_prefix + project_date.name project_date.alias_name = lf_alias_name - planned_hours = (line.price_subtotal / lf_tarif_jour) * lf_heures_jour + planned_hours = ((line.price_subtotal / lf_tarif_jour) + * lf_heures_jour) description_line = "<p>" - i = 1 for line_name in line.name: if line_name == '\n': description_line = description_line + "</p><p>" else: description_line = description_line + line_name - task = self.env['project.task'].create({ + self.env['project.task'].create({ 'name': name_task, 'date_deadline': date_deadline, 'planned_hours': planned_hours, 'remaining_hours': planned_hours, - 'partner_id': sale_id.partner_id.id or self.partner_dest_id.id, + 'partner_id': (sale_id.partner_id.id + or self.partner_dest_id.id), 'user_id': self.env.uid, # 'procurement_id': line.procurement_ids.id, 'description': description_line + '</p><br/>', @@ -110,6 +131,7 @@ class LeFilamentSaleWizard(models.TransientModel): 'price_subtotal': line.price_subtotal, 'currency_id': line.currency_id.id }) - sale_id.tasks_ids = self.env['project.task'].search([('sale_line_id', 'in', sale_id.order_line.ids)]) + sale_id.tasks_ids = self.env['project.task'].search( + [('sale_line_id', 'in', sale_id.order_line.ids)]) sale_id.tasks_count = len(sale_id.tasks_ids) - return {'type': 'ir.actions.act_window_close'} \ No newline at end of file + return {'type': 'ir.actions.act_window_close'} diff --git a/wizard/sale_views_wizard.xml b/wizard/sale_views_wizard.xml index 329e516..8f12996 100644 --- a/wizard/sale_views_wizard.xml +++ b/wizard/sale_views_wizard.xml @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="utf-8"?> - +<!-- Copyright 2017 Le Filament (<https://le-filament.com>) + License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). --> <odoo> - <data> - - <record id="lefilament_project_view_form_create" model="ir.ui.view"> + <data> + <record id="lefilament_project_view_form_create" model="ir.ui.view"> <field name="name">lefilament.project.view.form.create</field> <field name="model">lefilament.sale.views.wizard</field> <field name="arch" type="xml"> @@ -24,19 +24,17 @@ <button string="Create" name="close_dialog" type="object" class="btn-primary"/> <button string="Discard" class="btn-default" special="cancel"/> </footer> - </sheet> </form> </field> </record> - <record id="lefilament_open_create_project" model="ir.actions.act_window"> + <record id="lefilament_open_create_project" model="ir.actions.act_window"> <field name="name">Create project</field> <field name="res_model">lefilament.sale.views.wizard</field> <field name="view_type">form</field> <field name="view_mode">form</field> <field name="target">new</field> </record> - - </data> -</odoo> \ No newline at end of file + </data> +</odoo> -- GitLab