Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BR1230][T25029][ADD]project_timesheet_detail #212

Open
wants to merge 4 commits into
base: 10.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions project_timesheet_detailed/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
.. 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

========================
Project TimeSheet Detail
========================

This module extends the function of project timesheet,allows the manager to
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

space after the ','

review, approve or reject the timesheet by every single record.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

by every single record -> one by one


Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add the runbot

Installation
============

To install this module, you need to:

#. have basic module installed (project_issue_sheet)

Bug Tracker
===========

Bugs are tracked on `GitHub Issues
<https://github.com/Elico-Corp/elico_odoo/issues>`_. In case of trouble, please
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

update the url

check there if your issue has already been reported. If you spotted it first,
help us smash it by providing detailed and welcomed feedback.

Credits
=======

Contributors
------------

Miya Xing <[email protected]>
Joseph Wang <[email protected]>

Maintainer
----------

.. image:: https://www.elico-corp.com/logo.png
:alt: Elico Corp
:target: https://www.elico-corp.com

This module is maintained by Elico Corporation.

Elico Corp is an innovative actor in China, Hong-Kong and Singapore servicing
well known international companies and as well as local mid-sized businesses.
Since 2010, our seasoned Sino-European consultants have been providing full
range Odoo services:

* Business consultancy for Gap analysis, BPM, operational work-flows review.
* Ready-to-use ERP packages aimed at starting businesses.
* Odoo implementation for manufacturing, international trading, service industry
and e-commerce.
* Connectors and integration with 3rd party software (Magento, Taobao, Coswin,
Joomla, Prestashop, Tradevine etc...).
* Odoo Support services such as developments, training, maintenance and hosting.

Our headquarters are located in Shanghai with branch in Singapore servicing
customers from all over Asia Pacific.

Contact information: `Sales <[email protected]>`__
3 changes: 3 additions & 0 deletions project_timesheet_detailed/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-

from . import models
25 changes: 25 additions & 0 deletions project_timesheet_detailed/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
# © 2017 Elico Corp (www.elico-corp.com).
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
{
'name': "project_timesheet_detailed",
'summary': """This module extends the function of project timesheet,
allows the manager to review, approve or reject the timesheet by every
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

update

single record.""",
'author': "Elico Corp",
"support": "[email protected]",
"license": "AGPL-3",
'website': "https://www.elico-corp.com",
'category': 'Project Management',
'version': '10.0.0.1.0',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

10.0.1.0.0

'depends': ['project_issue_sheet'],
'data': [
'security/project_timesheet_detail.xml',
'security/ir.model.access.csv',
'views/project_inherit_view.xml',
'views/project_timesheet_detail_view.xml',
'views/function_views.xml',
],
'installable': True,
'application': False,
}
4 changes: 4 additions & 0 deletions project_timesheet_detailed/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-

from . import models
from . import project_inherit
133 changes: 133 additions & 0 deletions project_timesheet_detailed/models/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
# -*- coding: utf-8 -*-
# © 2017 Elico Corp (www.elico-corp.com).
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

from odoo import models, fields, api
from odoo.exceptions import UserError


class AccountAnalyticLine(models.Model):

_inherit = 'account.analytic.line'

stage = fields.Selection(
selection=[
('fixed', 'Fixed'),
('to review', 'To review'),
('approved', 'Approved'),
('rejected', 'Rejected'),
],
default='to review',

)
estimated_time = fields.Float(
'Estimated time', compute='_compute_estimated_time')
approved_time = fields.Float(
'Approved time', compute='_compute_approved_time')

@api.multi
@api.depends('task_id')
def _compute_estimated_time(self):
for rec in self:
if rec.task_id:
rec.estimated_time = rec.task_id.planned_hours

@api.multi
@api.depends('task_id')
def _compute_approved_time(self):
for rec in self:
if rec.task_id:
approved_tms = rec.env['account.analytic.line'].search(
[('task_id', '=', rec.task_id.id)]).filtered(
lambda rec: rec.stage == 'approved')
rec.approved_time = \
sum([tms.unit_amount for tms in approved_tms])

@api.multi
def set_approved(self):
current_user = self.env.user
for rec in self:
if (current_user == rec.project_id.user_id) or (
current_user ==
rec.user_id.employee_ids.parent_id.user_id):
rec.stage = 'approved'
else:
raise UserError(
'Sorry,you do not have permission to approve it')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove 'Sorry,' (everywhere)


@api.multi
def set_rejected(self):
current_user = self.env.user
for rec in self:
if (current_user == rec.project_id.user_id) or (
current_user ==
rec.user_id.employee_ids.parent_id.user_id):
rec.stage = 'rejected'
mail = self.env['mail.mail'].create({
'body_html': 'Your TMS %s was turn down' % (rec.name),
'email_to': rec.user_id.login,
'subject': 'Reject TMS',
})
mail.send()
else:
raise UserError(
'Sorry,you do not have permission to reject it')

@api.multi
def set_review(self):
current_user = self.env.user
for rec in self:
if (current_user == rec.project_id.user_id) or (
current_user ==
rec.user_id.employee_ids.parent_id.user_id):
rec.stage = 'to review'
else:
raise UserError(
'Sorry,you do not have permission to change the state')

@api.onchange('project_id')
def onchange_project_id(self):
eml = self.task_id
res = super(AccountAnalyticLine, self).onchange_project_id()
self.task_id = eml
return res

@api.onchange('task_id')
def task_id_on_change(self):
if self.task_id:
self.project_id = self.task_id.project_id.id

@api.onchange('issue_id')
def issue_id_on_change(self):
if self.issue_id:
self.project_id = self.issue_id.project_id.id

@api.multi
def write(self, vals):
for rec in self:
if rec.stage == 'rejected' and vals:
vals['stage'] = 'fixed'
if vals.get('task_id'):
vals.update({
'project_id':
self.env['project.task'].search([
('id', '=', vals.get('task_id'))]).project_id.id})
if vals.get('issue_id'):
vals.update(
{'project_id': self.env['project.issue'].search(
[('id', '=', vals.get('issue_id'))]).project_id.id})
return super(AccountAnalyticLine, self).write(vals)

@api.multi
def unlink(self):
for rec in self:
if rec.stage != 'to review':
raise UserError('Only records in to review can be deleted!')
return super(AccountAnalyticLine, self).unlink()

@api.multi
@api.constrains('task_id', 'issue_id')
def _check_task_and_issue(self):
if self.task_id and self.issue_id:
raise ValueError(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How would that happen?

'It is not allowed to have task and issue at the same time.')
15 changes: 15 additions & 0 deletions project_timesheet_detailed/models/project_inherit.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# -*- coding: utf-8 -*-
# © 2017 Elico Corp (www.elico-corp.com).
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import models, fields


class ProjectInherit(models.Model):
_inherit = 'project.project'

check_timesheet = fields.Boolean(
string="Check TMS",
default=True,
help='If true, the TMS will be assigned to the manager of the'
' employee,if false, the TMS will be assigned to the manager '
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

always ',' then a space

'of the project.')
4 changes: 4 additions & 0 deletions project_timesheet_detailed/security/ir.model.access.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
access_check_timesheet_manager,check_timesheet_manager,model_account_analytic_line,group_timesheet_manager,1,1,1,1
access_timesheet_project_manager,timesheet_project_manager,model_account_analytic_line,group_timesheet_project_manager,1,1,1,1
access_group_timesheet_employee,group_timesheet_employee,model_account_analytic_line,base.group_user,1,1,1,0
10 changes: 10 additions & 0 deletions project_timesheet_detailed/security/project_timesheet_detail.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="group_timesheet_manager" model="res.groups">
<field name="name">Timesheet Manager</field>
<field name="users" eval="[(4, ref('base.user_root'))]"/>
</record>
<record id="group_timesheet_project_manager" model="res.groups">
<field name="name">Timesheet Project Manager</field>
</record>
</odoo>
3 changes: 3 additions & 0 deletions project_timesheet_detailed/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# -*- coding:utf-8 -*-

from . import test_models
98 changes: 98 additions & 0 deletions project_timesheet_detailed/tests/test_models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# -*- coding:utf-8 -*-
# © 2017 Elico Corp (www.elico-corp.com).
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo.tests import common
from odoo.exceptions import UserError


class TestTimesheetDetail(common.TransactionCase):

def setUp(self):
super(TestTimesheetDetail, self).setUp()
self.account = self.env.ref('analytic.analytic_millennium_industries')
self.task_1 = self.env.ref('project.project_task_1')
self.task_2 = self.env.ref('project.project_task_20')
self.issue_1 = self.env.ref(
'project_issue.crm_case_buginaccountsmodule0')
self.issue_2 = self.env.ref(
'project_issue.crm_case_programnotgivingproperoutput0')
self.timesheet_1 = self.env['account.analytic.line'].create({
'name': 'test timesheet',
'task_id': self.task_1.id,
'date': '2018-1-10',
'unit_amount': 2,
'stage': 'to review',
'account_id': self.account.id
})
self.timesheet_2 = self.env['account.analytic.line'].create({
'name': 'test test timesheet',
'task_id': self.task_2.id,
'date': '2018-1-10',
'unit_amount': 2,
'stage': 'to review',
'account_id': self.account.id
})
self.timesheet_3 = self.env['account.analytic.line'].create({
'name': 'test timesheet',
'issue_id': self.issue_1.id,
'date': '2018-1-10',
'unit_amount': 2,
'stage': 'approved',
'account_id': self.account.id
})
try:
self.env['account.analytic.line'].create({
'name': 'test timesheet',
'issue_id': self.issue_1.id,
'task_id': self.task_1.id,
'date': '2018-1-10',
'unit_amount': 2,
'stage': 'to review',
'account_id': self.account.id
})
except ValueError:
pass

def test_set_approved(self):
try:
self.timesheet_1.set_approved()
self.timesheet_2.set_approved()
except UserError as e:
self.assertEquals(e.name,
'Sorry,you do not have permission to approve it')

def test_set_rejected(self):
try:
self.timesheet_1.set_rejected()
self.timesheet_2.set_rejected()
except UserError as e:
self.assertEquals(e.name,
'Sorry,you do not have permission to reject it')

def test_set_review(self):
try:
self.timesheet_1.set_review()
self.timesheet_2.set_review()
except UserError as e:
self.assertEquals(
e.name, 'Sorry,you do not have permission to change the state')

def test_onchange_project_id(self):
self.timesheet_1.task_id = self.task_2.id
self.assertEquals(self.timesheet_1.project_id, self.task_2.project_id)

def test_issue_id_on_change(self):
self.timesheet_3.issue_id = self.issue_2.id
self.assertEquals(self.timesheet_3.project_id, self.issue_2.project_id)

def test_write(self):
vals_1 = {'task_id': self.task_2.id}
self.timesheet_1.write(vals_1)
self.assertEquals(self.timesheet_1.project_id, self.task_2.project_id)

def test_unlink(self):
try:
self.timesheet_3.unlink()
except UserError as e:
self.assertEquals(e.name,
'Only records in to review can be deleted!')
Loading