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

[ADD][BR1228][T24770]Extra time application #210

Open
wants to merge 16 commits into
base: 10.0
Choose a base branch
from
Open
60 changes: 60 additions & 0 deletions extra_time_application/README.rst
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
Copy link
Contributor

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

will not allow to add new items if the task time is less than 0
Copy link
Contributor

Choose a reason for hiding this comment

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

item -> timesheets

Copy link
Contributor

Choose a reason for hiding this comment

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

add perido


Bug Tracker
Copy link
Contributor

Choose a reason for hiding this comment

The 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]>`__
5 changes: 5 additions & 0 deletions extra_time_application/__init__.py
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
23 changes: 23 additions & 0 deletions extra_time_application/__manifest__.py
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
}
5 changes: 5 additions & 0 deletions extra_time_application/models/__init__.py
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
14 changes: 14 additions & 0 deletions extra_time_application/models/project_project_inherit.py
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')
99 changes: 99 additions & 0 deletions extra_time_application/models/project_task_inherit.py
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(
Copy link
Contributor

Choose a reason for hiding this comment

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

better total_extra_time?

'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 \
Copy link
Contributor

Choose a reason for hiding this comment

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

flag?

not log.env.context.get('flag_remaine'):
Copy link
Contributor

Choose a reason for hiding this comment

The 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, '
Copy link
Contributor

Choose a reason for hiding this comment

The 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.'))
Copy link
Contributor

Choose a reason for hiding this comment

The 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
86 changes: 86 additions & 0 deletions extra_time_application/models/task_timesheet.py
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>
5 changes: 5 additions & 0 deletions extra_time_application/security/ir.model.access.csv
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
5 changes: 5 additions & 0 deletions extra_time_application/tests/__init__.py
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
33 changes: 33 additions & 0 deletions extra_time_application/tests/test_extra_time.py
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
28 changes: 28 additions & 0 deletions extra_time_application/tests/test_extra_time_wizard.py
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()
Loading