-
Notifications
You must be signed in to change notification settings - Fork 78
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[MIG]hr_timesheet_sheet_import_accounts to v12
- Loading branch information
1 parent
8fa2358
commit ad95870
Showing
9 changed files
with
170 additions
and
136 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,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 |
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,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, | ||
} |
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 |
---|---|---|
@@ -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)), | ||
) |
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,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 |
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,19 +1,18 @@ | ||
# -*- 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, _ | ||
|
||
|
||
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") | ||
) |
93 changes: 50 additions & 43 deletions
93
hr_timesheet_sheet_import_accounts/models/hr_timesheet_sheet.py
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,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 |
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,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 |
108 changes: 58 additions & 50 deletions
108
hr_timesheet_sheet_import_accounts/tests/test_hr_timesheet_sheet_import_accounts.py
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,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) |
Oops, something went wrong.