From ad95870b647d3844cfa2e68312fc17678a5d34fe Mon Sep 17 00:00:00 2001 From: ahenriquez Date: Wed, 23 Oct 2019 12:18:43 +0200 Subject: [PATCH] [MIG]hr_timesheet_sheet_import_accounts to v12 --- .../__init__.py | 5 +- .../__manifest__.py | 36 +++--- hr_timesheet_sheet_import_accounts/hooks.py | 31 +++++ .../models/__init__.py | 4 - .../models/hr_employee.py | 13 +-- .../models/hr_timesheet_sheet.py | 93 ++++++++------- .../tests/__init__.py | 4 - ...test_hr_timesheet_sheet_import_accounts.py | 108 ++++++++++-------- .../views/hr_timesheet_sheet_view.xml | 12 +- 9 files changed, 170 insertions(+), 136 deletions(-) create mode 100644 hr_timesheet_sheet_import_accounts/hooks.py diff --git a/hr_timesheet_sheet_import_accounts/__init__.py b/hr_timesheet_sheet_import_accounts/__init__.py index d93dcaf62..6d58305f5 100644 --- a/hr_timesheet_sheet_import_accounts/__init__.py +++ b/hr_timesheet_sheet_import_accounts/__init__.py @@ -1,5 +1,2 @@ -# -*- coding: utf-8 -*- -# Copyright 2014-17 Eficent Business and IT Consulting Services, S.L. -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - from . import models +from .hooks import pre_init_hook diff --git a/hr_timesheet_sheet_import_accounts/__manifest__.py b/hr_timesheet_sheet_import_accounts/__manifest__.py index f08a7bcd6..a7d97bf60 100644 --- a/hr_timesheet_sheet_import_accounts/__manifest__.py +++ b/hr_timesheet_sheet_import_accounts/__manifest__.py @@ -1,24 +1,24 @@ -# -*- coding: utf-8 -*- # Copyright 2014-17 Eficent Business and IT Consulting Services, S.L. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - { - 'name': 'HR Timesheet Sheet Import Accounts', - 'version': '10.0.1.0.1', - 'author': 'Eficent, Odoo Community Association (OCA)', - 'category': 'Human Resources', - 'summary': "This module lets the user import the analytic accounts from " - "the previous timesheet, with a simple click.", - 'website': 'http://www.eficent.com', + "name": "HR Timesheet Sheet Import Accounts", + "version": "12.0.1.0.1", + "author": "Eficent, Odoo Community Association (OCA)", + "category": "Human Resources", + "summary": "This module lets the user import the analytic accounts from " + "the previous timesheet, with a simple click.", + "website": "http://www.eficent.com", "license": "LGPL-3", - 'depends': ['hr_timesheet_sheet', - 'hr_employee_product', - 'hr_timesheet_sheet_period', - ], - 'data': [ - 'views/hr_timesheet_sheet_view.xml', - 'views/hr_employee_view.xml', + "depends": [ + "hr_timesheet_sheet", + "hr_employee_product", + "hr_timesheet_sheet_period", ], - 'installable': True, - 'auto_install': False, + "data": [ + "views/hr_timesheet_sheet_view.xml", + "views/hr_employee_view.xml", + ], + "pre_init_hook": "pre_init_hook", + "installable": True, + "auto_install": False, } diff --git a/hr_timesheet_sheet_import_accounts/hooks.py b/hr_timesheet_sheet_import_accounts/hooks.py new file mode 100644 index 000000000..09a6a6b8a --- /dev/null +++ b/hr_timesheet_sheet_import_accounts/hooks.py @@ -0,0 +1,31 @@ +from odoo.api import Environment, SUPERUSER_ID +from openupgradelib.openupgrade_tools import column_exists +import logging + +logger = logging.getLogger(__name__) + + +def pre_init_hook(cr): + env = Environment(cr, SUPERUSER_ID, {}) + logger.info("Assigning product to employees") + if not column_exists(cr, "hr_employee", "product_id"): + cr.execute( + """ + ALTER TABLE hr_employee ADD COLUMN product_id integer; + """ + ) + cr.execute( + """ + SELECT id FROM hr_employee WHERE product_id is null; + """ + ) + employees = [x for x in cr.fetchall()] + product_id = env["product.product"].create( + {"name": "Employee", "is_employee": True} + ) + cr.execute( + """ + UPDATE hr_employee SET product_id=%s WHERE id in %s; + """, + (product_id.id, tuple(employees)), + ) diff --git a/hr_timesheet_sheet_import_accounts/models/__init__.py b/hr_timesheet_sheet_import_accounts/models/__init__.py index 73568f901..30d843c02 100644 --- a/hr_timesheet_sheet_import_accounts/models/__init__.py +++ b/hr_timesheet_sheet_import_accounts/models/__init__.py @@ -1,6 +1,2 @@ -# -*- coding: utf-8 -*- -# Copyright 2014-17 Eficent Business and IT Consulting Services, S.L. -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - from . import hr_timesheet_sheet from . import hr_employee diff --git a/hr_timesheet_sheet_import_accounts/models/hr_employee.py b/hr_timesheet_sheet_import_accounts/models/hr_employee.py index 9fca46e8d..5e632aa1a 100644 --- a/hr_timesheet_sheet_import_accounts/models/hr_employee.py +++ b/hr_timesheet_sheet_import_accounts/models/hr_employee.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -# Copyright 2014-17 Eficent Business and IT Consulting Services, S.L. -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from odoo import api, exceptions, fields, models, _ @@ -8,12 +5,14 @@ class HrEmployee(models.Model): _inherit = "hr.employee" product_id = fields.Many2one( - comodel_name='product.product', string='Product', required=True) + comodel_name="product.product", string="Product", required=True + ) @api.multi - @api.constrains('product_id') + @api.constrains("product_id") def _check_is_employee(self): for rec in self: if not rec.product_id.is_employee: - raise exceptions.ValidationError(_( - "The product is not marked as employee")) + raise exceptions.ValidationError( + _("The product is not marked as employee") + ) diff --git a/hr_timesheet_sheet_import_accounts/models/hr_timesheet_sheet.py b/hr_timesheet_sheet_import_accounts/models/hr_timesheet_sheet.py index 8e3fc0df8..7562e2971 100644 --- a/hr_timesheet_sheet_import_accounts/models/hr_timesheet_sheet.py +++ b/hr_timesheet_sheet_import_accounts/models/hr_timesheet_sheet.py @@ -1,77 +1,84 @@ -# -*- coding: utf-8 -*- -# Copyright 2014-17 Eficent Business and IT Consulting Services, S.L. -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - -from datetime import datetime from odoo import _, api, exceptions, models -from openerp.tools import DEFAULT_SERVER_DATE_FORMAT class HrTimesheetSheet(models.Model): - _inherit = "hr_timesheet_sheet.sheet" + _inherit = "hr_timesheet.sheet" @api.multi def prepare_timesheet(self, project_id, ga_id): for sheet in self: - aa = self.env['project.project'].browse( - project_id).analytic_account_id + aa = ( + self.env["project.project"] + .browse(project_id) + .analytic_account_id + ) vals = { - 'date': sheet.date_from, - 'account_id': aa.id, - 'project_id': project_id, - 'name': '/', - 'product_id': sheet.employee_id.product_id.id, - 'product_uom_id': - sheet.employee_id.product_id.uom_id.id, - 'general_account_id': ga_id, - 'amount': sheet.employee_id.product_id.standard_price, - 'user_id': sheet.user_id.id, - 'sheet_id': sheet.id, + "date": sheet.date_start, + "account_id": aa.id, + "project_id": project_id, + "name": "/", + "product_id": sheet.employee_id.product_id.id, + "product_uom_id": sheet.employee_id.product_id.uom_id.id, + "general_account_id": ga_id, + "amount": sheet.employee_id.product_id.standard_price, + "user_id": sheet.user_id.id, + "sheet_id": sheet.id, } return vals @api.model def get_accounts(self, anal_line_ids): - self.env.cr.execute("""SELECT DISTINCT L.project_id + self.env.cr.execute( + """SELECT DISTINCT L.project_id FROM account_analytic_line AS L WHERE L.id IN %s - GROUP BY L.project_id""", (tuple(anal_line_ids),)) + GROUP BY L.project_id""", + (tuple(anal_line_ids),), + ) return self.env.cr.dictfetchall() @api.model - def get_sheet_domain(self, date_from, emp_id, period_type): - return [('date_to', '<=', date_from), - ('employee_id', '=', emp_id), - ('hr_period_id.type_id', '=', period_type.id)] + def get_sheet_domain(self, date_start, emp_id, period_type): + return [ + ("date_end", "<=", date_start), + ("employee_id", "=", emp_id), + ("hr_period_id.type_id", "=", period_type.id), + ] @api.multi def set_previous_timesheet_ids(self): - sheet_obj = self.env['hr_timesheet_sheet.sheet'] + sheet_obj = self.env["hr_timesheet.sheet"] for sheet in self: - if sheet.state not in ('draft', 'new'): + if sheet.state not in ("draft", "new"): raise exceptions.ValidationError( - _('Timesheet draft or opened')) - date_from = datetime.strptime(sheet.date_from, - DEFAULT_SERVER_DATE_FORMAT) + _("Timesheet draft or opened") + ) + date_start = sheet.date_start emp_id = sheet.employee_id and sheet.employee_id.id or False if not emp_id: return False sheet_domain = self.get_sheet_domain( - date_from, emp_id, sheet.hr_period_id.type_id) + date_start, emp_id, sheet.hr_period_id.type_id + ) lw_sheet_ids = sheet_obj.search( - sheet_domain, limit=1, order='date_to desc') - a_line_ids = lw_sheet_ids.mapped('timesheet_ids').ids - ga_id = sheet.employee_id.product_id.\ - property_account_expense_id.id or \ - sheet.employee_id.product_id.\ - categ_id.property_account_expense_categ_id.id + sheet_domain, limit=1, order="date_end desc" + ) + a_line_ids = lw_sheet_ids.mapped("timesheet_ids").ids + ga_id = ( + sheet.employee_id.product_id.property_account_expense_id.id + or sheet.employee_id.product_id.categ_id. + property_account_expense_categ_id.id + ) if not ga_id: - raise exceptions.ValidationError(_( - 'Please set a general expense ' - 'account in your employee view')) + raise exceptions.ValidationError( + _( + "Please set a general expense " + "account in your employee view" + ) + ) if a_line_ids: projects = self.get_accounts(a_line_ids) - for project_id in [a['project_id'] for a in projects]: + for project_id in [a["project_id"] for a in projects]: vals = sheet.prepare_timesheet(project_id, ga_id) - self.env['account.analytic.line'].create(vals) + self.env["account.analytic.line"].create(vals) return True diff --git a/hr_timesheet_sheet_import_accounts/tests/__init__.py b/hr_timesheet_sheet_import_accounts/tests/__init__.py index df4a3b27b..24aebbbc0 100644 --- a/hr_timesheet_sheet_import_accounts/tests/__init__.py +++ b/hr_timesheet_sheet_import_accounts/tests/__init__.py @@ -1,5 +1 @@ -# -*- coding: utf-8 -*- -# Copyright 2014-17 Eficent Business and IT Consulting Services, S.L. -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - from . import test_hr_timesheet_sheet_import_accounts diff --git a/hr_timesheet_sheet_import_accounts/tests/test_hr_timesheet_sheet_import_accounts.py b/hr_timesheet_sheet_import_accounts/tests/test_hr_timesheet_sheet_import_accounts.py index ca5b3eeaa..efc1bb830 100644 --- a/hr_timesheet_sheet_import_accounts/tests/test_hr_timesheet_sheet_import_accounts.py +++ b/hr_timesheet_sheet_import_accounts/tests/test_hr_timesheet_sheet_import_accounts.py @@ -1,78 +1,86 @@ -# -*- coding: utf-8 -*- -# Copyright 2014-17 Eficent Business and IT Consulting Services, S.L. -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - from odoo.tests.common import TransactionCase import time class TestHRTimesheetSheetImportAccounts(TransactionCase): - def setUp(self): super(TestHRTimesheetSheetImportAccounts, self).setUp() - self.timesheet_sheet = self.env['hr_timesheet_sheet.sheet'] - self.analytic_line = self.env['account.analytic.line'] - self.project_2 = self.env.ref('project.project_project_2') - self.dept = self.env.ref('hr.dep_management') - self.dept_1 = self.env.ref('hr.dep_rd') - self.root = self.env.ref('hr.employee_root') - self.user = self.env.ref('base.user_root') - self.root.write({'user_id': self.user.id}) - self.dept.write({ - 'parent_id': self.dept_1.id, - 'manager_id': self.root.id - }) - self.product = self.env.ref('product.product_product_11') - self.product.write({'is_employee': True}) + self.timesheet_sheet = self.env["hr_timesheet.sheet"] + self.analytic_line = self.env["account.analytic.line"] + self.project_2 = self.env.ref("project.project_project_2") + self.dept = self.env.ref("hr.dep_management") + self.dept_1 = self.env.ref("hr.dep_rd") + self.root = self.env.ref("hr.employee_admin") + self.user = self.env.ref("base.user_admin") + self.root.write({"user_id": self.user.id}) + self.dept.write( + {"parent_id": self.dept_1.id, "manager_id": self.root.id} + ) + self.product = self.env.ref("product.product_product_11") + self.product.write({"is_employee": True}) # create user user_dict = { - 'name': 'User 1', - 'login': 'tua@example.com', - 'password': 'base-test-passwd', + "name": "User 1", + "login": "tua@example.com", + "password": "base-test-passwd", } - self.user_test = self.env['res.users'].create(user_dict) + self.user_test = self.env["res.users"].create(user_dict) # create Employee employee_dict = { - 'name': 'Employee 1', - 'user_id': self.user_test.id, - 'address_id': self.user_test.partner_id.id, - 'parent_id': self.root.id, - 'product_id': self.product.id + "name": "Employee 1", + "user_id": self.user_test.id, + "address_id": self.user_test.partner_id.id, + "parent_id": self.root.id, + "product_id": self.product.id, } - self.employee = self.env['hr.employee'].create(employee_dict) + self.employee = self.env["hr.employee"].create(employee_dict) self.timesheet_sheet_1 = self._create_timesheet_sheet( - time.strftime('%Y-%m-11'), time.strftime('%Y-%m-17'), qty=5) + time.strftime("%Y-%m-11"), time.strftime("%Y-%m-17"), qty=5 + ) self.timesheet_sheet_2 = self._create_timesheet_sheet( - time.strftime('%Y-%m-18'), time.strftime('%Y-%m-24'), qty=10) + time.strftime("%Y-%m-18"), time.strftime("%Y-%m-24"), qty=10 + ) - def _create_timesheet_sheet(self, date_from, date_to, qty): - timesheet_sheet = self.timesheet_sheet.create({ - 'date_from': date_from, - 'date_to': date_to, - 'name': 'Employee 1', - 'state': 'new', - 'user_id': self.user_test.id, - 'employee_id': self.employee.id, - 'department_id': self.dept.id, - }) + def _create_timesheet_sheet(self, date_start, date_end, qty): + timesheet_sheet = self.timesheet_sheet.create( + { + "date_start": date_start, + "date_end": date_end, + "name": "Employee 1", + "state": "new", + "user_id": self.user_test.id, + "employee_id": self.employee.id, + "department_id": self.dept.id, + } + ) # I add 5 hours of work timesheet - timesheet_sheet.write({'timesheet_ids': [(0, 0, { - 'project_id': self.project_2.id, - 'date': date_from, - 'name': 'Develop UT for hr module(1)', - 'user_id': self.user_test.id, - 'unit_amount': qty, - })]}) + timesheet_sheet.write( + { + "timesheet_ids": [ + ( + 0, + 0, + { + "project_id": self.project_2.id, + "date": date_start, + "name": "Develop UT for hr module(1)", + "user_id": self.user_test.id, + "unit_amount": qty, + }, + ) + ] + } + ) return timesheet_sheet def test_timesheet_methods(self): self.timesheet_sheet_1.action_timesheet_confirm() self.timesheet_sheet_2.set_previous_timesheet_ids() - analytic_1 = self.timesheet_sheet_1.timesheet_ids.mapped('account_id') - analytic_2 = self.timesheet_sheet_2.timesheet_ids.mapped('account_id') + analytic_1 = self.timesheet_sheet_1.timesheet_ids.mapped("account_id") + analytic_2 = self.timesheet_sheet_2.timesheet_ids.mapped("account_id") self.assertEqual(len(analytic_2), 1) self.assertEqual(analytic_1.id, analytic_2.id) diff --git a/hr_timesheet_sheet_import_accounts/views/hr_timesheet_sheet_view.xml b/hr_timesheet_sheet_import_accounts/views/hr_timesheet_sheet_view.xml index 6c87746e9..3e756b222 100644 --- a/hr_timesheet_sheet_import_accounts/views/hr_timesheet_sheet_view.xml +++ b/hr_timesheet_sheet_import_accounts/views/hr_timesheet_sheet_view.xml @@ -3,14 +3,14 @@ hr.timesheet.sheet.form - hr_timesheet_sheet.sheet + hr_timesheet.sheet - -