-
Notifications
You must be signed in to change notification settings - Fork 76
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
[ADD][BR1228][T24770]Extra time application #210
base: 10.0
Are you sure you want to change the base?
Changes from all commits
aba0ace
126fc0f
1135ecb
4ba428e
c908843
97ded94
6adecce
7bd17b5
c64767c
b7f03f6
2a88b15
223aceb
05012ca
4896596
794b7b8
e18439d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
.. 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 | ||
====================== | ||
Extra Time Application | ||
====================== | ||
This module adds functionality to the application time and | ||
will not allow to add new items if the task time is less than 0 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. item -> timesheets There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add perido |
||
|
||
Bug Tracker | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add runbot |
||
=========== | ||
|
||
Bugs are tracked on `GitHub Issues | ||
<https://github.com/Elico-Corp/odoo-addons/issues>`_. In case of trouble, please | ||
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 | ||
======= | ||
|
||
Images | ||
------ | ||
|
||
* Elico Corp: `Icon <https://elico-corp.com/logo.png>`_. | ||
|
||
Contributors | ||
------------ | ||
|
||
* Miya Xing <[email protected]> | ||
* Eric Caudal <[email protected]> | ||
* Sébastien Maillard <[email protected]> | ||
* Hulk Liu <[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]>`__ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# -*-coding: utf-8 -*- | ||
|
||
from . import models | ||
from . import wizard | ||
from . import tests |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# -*- coding: utf-8 -*- | ||
# © 2017 Elico Corp (https://www.elico-corp.com) | ||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). | ||
|
||
{ | ||
'name': 'Extra Time Application', | ||
'version': '10.0.1.0.0', | ||
'author': "Elico Corp", | ||
'website': 'https://www.elico-corp.com', | ||
'license': 'AGPL-3', | ||
'support': 'https://[email protected]', | ||
'depends': [ | ||
'project', | ||
], | ||
'data': [ | ||
'wizard/time_prompt_view.xml', | ||
'views/extra_time_approve_view.xml', | ||
'views/project_task_form_inherit.xml', | ||
'security/extra_time_application_security.xml', | ||
'security/ir.model.access.csv', | ||
], | ||
'installable': True | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# -*- coding:utf-8 -*- | ||
|
||
from . import task_timesheet | ||
from . import project_task_inherit | ||
from . import project_project_inherit |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# -*- coding: utf-8 -*- | ||
# © 2017 Elico Corp (www.elico-corp.com). | ||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). | ||
from openerp import fields, models | ||
|
||
|
||
class ProjectProjectInherit(models.Model): | ||
_inherit = 'project.project' | ||
|
||
is_modified = fields.Boolean( | ||
string='Is modified', | ||
help='If this field is true,everyone can create the corresponding ' | ||
'task,and if it is false, only the person in the manager group ' | ||
'can create the corresponding task') |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
# -*- coding: utf-8 -*- | ||
# © 2017 Elico Corp (www.elico-corp.com). | ||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). | ||
from openerp import api, fields, models, _ | ||
from odoo.exceptions import UserError | ||
from lxml import etree | ||
|
||
|
||
class ProjectTaskInherit(models.Model): | ||
_inherit = 'project.task' | ||
|
||
sub_extra_time = fields.Float( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. better |
||
'Extra Time', help='the sum of the extra time', | ||
default='0', | ||
) | ||
|
||
@api.multi | ||
def write(self, vals): | ||
for log in self: | ||
current_user = log.env.user | ||
remaining = log.remaining_hours | ||
spending_hours = 0 | ||
if not log.env.context.get('flag') and \ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. flag? |
||
not log.env.context.get('flag_remaine'): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. flag_remaine? |
||
for record in vals.get('timesheet_ids', []): | ||
if record[0] == 0: | ||
remaining -= record[2]['unit_amount'] | ||
spending_hours += record[2]['unit_amount'] | ||
elif record[0] == 2: | ||
item = log.timesheet_ids.search([ | ||
('id', '=', record[1]) | ||
]) | ||
remaining += item['unit_amount'] | ||
spending_hours -= item['unit_amount'] | ||
if vals.get('remaining_hours') and \ | ||
(vals.get('remaining_hours') != remaining): | ||
log.env['extra.time.application'].create({ | ||
'submit_user_id': current_user.id, | ||
'task_id': log.id, | ||
'reason': 'Automatically create From PM or Reviewer', | ||
'apply_hours': | ||
vals.get('remaining_hours') - | ||
log.remaining_hours + spending_hours, | ||
'state': 'approve', | ||
}) | ||
log.sub_extra_time += \ | ||
(vals.get('remaining_hours') - | ||
log.remaining_hours + spending_hours) | ||
if remaining < 0: | ||
raise UserError( | ||
_( | ||
'The task has no enough time left, ' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no ->not |
||
'please apply for more extra time.' | ||
)) | ||
res = super(ProjectTaskInherit, self).write(vals) | ||
return res | ||
|
||
@api.model | ||
def create(self, vals): | ||
current_user = self.env.user | ||
is_exist = current_user.has_group( | ||
'extra_time_application.group_project_task_manager') | ||
if not vals.get('project_id.is_modified'): | ||
if not is_exist and self.project_id.user_id != current_user: | ||
raise UserError( | ||
_('You do not have permission to ' | ||
'create task belong to this project.')) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. belong to -> in |
||
return super(ProjectTaskInherit, self).create(vals) | ||
|
||
@api.multi | ||
def open_extra_time_line(self): | ||
for record in self: | ||
domain = [('task_id', '=', record.name)] | ||
return { | ||
'name': _('Extra Time Approval'), | ||
'type': 'ir.actions.act_window', | ||
'view_type': 'form', | ||
'view_mode': 'tree,form', | ||
'res_model': 'extra.time.application', | ||
'target': 'current', | ||
'domain': domain, | ||
} | ||
|
||
@api.model | ||
def fields_view_get(self, view_id=None, view_type='form', | ||
toolbar=False, submenu=False): | ||
res = super(ProjectTaskInherit, self).fields_view_get( | ||
view_id=view_id, view_type=view_type, toolbar=toolbar, | ||
submenu=submenu) | ||
dom = etree.XML(res['arch']) | ||
if view_type == 'form': | ||
current_user = self.env.user | ||
is_exist = current_user.has_group( | ||
'extra_time_application.group_project_task_manager') | ||
if is_exist or self.project_id.is_modified: | ||
for node in dom.xpath("//field[@name='remaining_hours']"): | ||
node.set("modifiers", '{"readonly": false}') | ||
res['arch'] = etree.tostring(dom) | ||
return res |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
# -*- coding: utf-8 -*- | ||
# © 2017 Elico Corp (www.elico-corp.com). | ||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). | ||
from openerp import api, fields, models, _ | ||
from odoo.exceptions import UserError | ||
|
||
|
||
class TaskTimeSheet(models.Model): | ||
_name = 'extra.time.application' | ||
_inherit = ['mail.thread', 'ir.needaction_mixin'] | ||
|
||
submit_user_id = fields.Many2one( | ||
'res.users', 'Applicant', help='Applicant', | ||
) | ||
task_id = fields.Many2one('project.task', 'Task No', help='Task No') | ||
reason = fields.Text('Reason', help='the reason of apply') | ||
apply_hours = fields.Float('Apply Hours', help='the length of apply time') | ||
state = fields.Selection([ | ||
('to_approve', 'To Approve'), | ||
('approve', 'Approved'), | ||
('refused', 'Refused'), | ||
], track_visibility='onchange', defaule='to_approve') | ||
|
||
@api.one | ||
def approve_function(self): | ||
task_id = self.task_id | ||
task_manager = task_id.project_id.user_id | ||
if (self.env.user in self.env.ref( | ||
'extra_time_application.group_extra_time_manager').users) or ( | ||
self.env.user == task_manager.user_id) or \ | ||
task_id.project_id.is_modified: | ||
self.with_context(flag='True'). \ | ||
task_id.remaining_hours += self.apply_hours | ||
self.task_id.sub_extra_time += self.apply_hours | ||
self.state = 'approve' | ||
self.message_post( | ||
body=_(" <em>%s</em> <b>Approved</b>.") % (self.env.user.name)) | ||
else: | ||
raise UserError( | ||
_( | ||
'You do not have permission to approve it.' | ||
)) | ||
|
||
@api.one | ||
def refuse_function(self): | ||
task_id = self.task_id | ||
task_manager = task_id.project_id.user_id | ||
if (self.env.user in self.env.ref( | ||
'extra_time_application.group_extra_time_manager').users) or ( | ||
self.env.user == task_manager.user_id) or \ | ||
task_id.project_id.is_modified: | ||
self.state = 'refused' | ||
self.message_post( | ||
body=_(" <em>%s</em> <b>Refused</b>.") % (self.env.user.name)) | ||
else: | ||
raise UserError( | ||
_( | ||
'You do not have permission to refuse it.' | ||
)) | ||
|
||
@api.model | ||
def create(self, vals): | ||
msg_followers = [] | ||
for user in self.env.ref( | ||
'extra_time_application.group_extra_time_manager').users: | ||
if user != self.env['project.task'].browse( | ||
vals.get('task_id')).user_id: | ||
msg_vals = { | ||
'partner_id': user.partner_id.id, | ||
'res_model': self._name, | ||
} | ||
msg_followers.append((0, 0, msg_vals)) | ||
task_id = self.env['project.task']. \ | ||
browse(vals.get('task_id')) | ||
task_manager = task_id.project_id.user_id | ||
if (task_manager not in self.env.ref( | ||
'extra_time_application.group_extra_time_manager').users) and ( | ||
task_manager != task_id.user_id): | ||
msg_vals = { | ||
'partner_id': task_manager.partner_id.id, | ||
'res_model': self._name, | ||
} | ||
msg_followers.append((0, 0, msg_vals)) | ||
if msg_followers: | ||
vals['message_follower_ids'] = msg_followers | ||
return super(TaskTimeSheet, self).create(vals) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<odoo> | ||
<record id="group_project_task_manager" model="res.groups"> | ||
<field name="name">Time Application Manager</field> | ||
<field name="users" eval="[(4, ref('base.user_root'))]"/> | ||
</record> | ||
<record id="group_project_task_user" model="res.groups"> | ||
<field name="name">Time Application User</field> | ||
</record> | ||
<record id="group_extra_time_manager" model="res.groups"> | ||
<field name="name">Extra Time Manager</field> | ||
<field name="users" eval="[(4, ref('base.user_root'))]"/> | ||
</record> | ||
<record id="extra_time_applacation_rule" model="ir.rule"> | ||
<field name="name">extra time rule</field> | ||
<field name="model_id" ref="model_extra_time_application"/> | ||
<field name="domain_force">[('submit_user_id','=',user.id)]</field> | ||
</record> | ||
</odoo> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink" | ||
access_project_task_manager,project_task_manager,project.model_project_task,extra_time_application.group_project_task_manager,1,1,1,1 | ||
access_project_task_user,project_task_user,project.model_project_task,extra_time_application.group_project_task_user,1,1,0,0 | ||
access_extra_time_manager,extra_time_manager,extra_time_application.model_extra_time_application,extra_time_application.group_extra_time_manager,1,1,1,1 | ||
access_extra_time_user,extra_time_user,extra_time_application.model_extra_time_application,base.group_user,1,1,1,1 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# -*- coding:utf-8 -*- | ||
|
||
from . import test_extra_time | ||
from . import test_project_task_save | ||
from . import test_extra_time_wizard |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# -*- 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 TestExtraTime(common.TransactionCase): | ||
|
||
def setUp(self): | ||
super(TestExtraTime, self).setUp() | ||
self.submit_user_id = self.env.ref("base.user_demo") | ||
self.task_id = self.env.ref('project.project_task_9') | ||
|
||
self.extra_time_record = self.env['extra.time.application'].create({ | ||
'submit_user_id': self.submit_user_id.id, | ||
'task_id': self.task_id.id, | ||
'reason': 'Automatically created From PM or Reviewer', | ||
'apply_hours': 2, | ||
'state': 'to_approve' | ||
}) | ||
|
||
def test_approve_function(self): | ||
try: | ||
self.extra_time_record.approve_function() | ||
except UserError: | ||
pass | ||
|
||
def test_refuse_function(self): | ||
try: | ||
self.extra_time_record.refuse_function() | ||
except UserError: | ||
pass |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
# -*- 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 | ||
|
||
|
||
class TestExtraTimeWizard(common.TransactionCase): | ||
|
||
def setUp(self): | ||
super(TestExtraTimeWizard, self).setUp() | ||
self.task_id = self.env.ref('project.project_task_9') | ||
self.submit_user_id = self.env.ref('base.user_demo') | ||
self.extra_time_1 = self.env['extra.time.application.wizard'].create({ | ||
'submit_user_id': self.submit_user_id.id, | ||
'task_id': self.task_id.id, | ||
'reason': 'system test', | ||
'apply_hours': 3 | ||
}) | ||
self.extra_time_2 = self.env['extra.time.application.wizard'].create({ | ||
'submit_user_id': self.submit_user_id.id, | ||
'task_id': self.task_id.id, | ||
'reason': 'system test', | ||
'apply_hours': 3 | ||
}) | ||
|
||
def test_subscribe(self): | ||
self.extra_time_1.subscribe() | ||
self.extra_time_2.subscribe() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This module adds functionality of time application to extend the remaining time in tasks and