@ -0,0 +1,47 @@ |
|||||
|
.. image:: https://img.shields.io/badge/license-LGPL--3-green.svg |
||||
|
:target: https://www.gnu.org/licenses/lgpl-3.0-standalone.html |
||||
|
:alt: License: LGPL-3 |
||||
|
|
||||
|
Advanced project management system |
||||
|
================================== |
||||
|
All additional features of project module are in single module |
||||
|
|
||||
|
Configuration |
||||
|
============= |
||||
|
- No additional configuration required |
||||
|
|
||||
|
License |
||||
|
------- |
||||
|
General Public License, Version 3 (LGPL v3). |
||||
|
(https://www.gnu.org/licenses/lgpl-3.0-standalone.html) |
||||
|
|
||||
|
Company |
||||
|
------- |
||||
|
* `Cybrosys Techno Solutions <https://cybrosys.com/>`__ |
||||
|
|
||||
|
Credits |
||||
|
------- |
||||
|
Developer: (V16) Sreeshanth V S, Jumana Jabin MP, Contact: odoo@cybrosys.com |
||||
|
|
||||
|
Contacts |
||||
|
-------- |
||||
|
* Mail Contact : odoo@cybrosys.com |
||||
|
* Website : https://cybrosys.com |
||||
|
|
||||
|
Bug Tracker |
||||
|
----------- |
||||
|
Bugs are tracked on GitHub Issues. In case of trouble, please check there if |
||||
|
your issue has already been reported. |
||||
|
|
||||
|
Maintainer |
||||
|
========== |
||||
|
.. image:: https://cybrosys.com/images/logo.png |
||||
|
:target: https://cybrosys.com |
||||
|
|
||||
|
This module is maintained by Cybrosys Technologies. |
||||
|
|
||||
|
For support and more information, please visit `Our Website <https://cybrosys.com/>`__ |
||||
|
|
||||
|
Further information |
||||
|
=================== |
||||
|
HTML Description: `<static/description/index.html>`__ |
@ -0,0 +1,24 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################# |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU LESSER |
||||
|
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE |
||||
|
# (LGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################# |
||||
|
from . import models |
||||
|
from . import report |
||||
|
from . import wizard |
@ -0,0 +1,81 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################# |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU LESSER |
||||
|
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE |
||||
|
# (LGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################# |
||||
|
{ |
||||
|
'name': "Advanced Project Management System", |
||||
|
"version": "16.0.1.0.0", |
||||
|
"category": "Project", |
||||
|
"summary": "Advanced Project Management System for Odoo16", |
||||
|
"description": "AAdvanced Project Management System", |
||||
|
'author': 'Cybrosys Techno Solutions', |
||||
|
'company': 'Cybrosys Techno Solutions', |
||||
|
'maintainer': 'Cybrosys Techno Solutions', |
||||
|
'website': "https://www.cybrosys.com", |
||||
|
'depends': ['project', 'hr_timesheet'], |
||||
|
'data': [ |
||||
|
'security/ir_attachment_security.xml', |
||||
|
'security/ir.model.access.csv', |
||||
|
'data/ir_cron_data.xml', |
||||
|
'data/mail_template_data.xml', |
||||
|
'data/ir_actions_server_data.xml', |
||||
|
'data/ir_sequence_data.xml', |
||||
|
'views/project_milestone_views.xml', |
||||
|
'views/res_config_settings_views.xml', |
||||
|
'views/project_checklist_views.xml', |
||||
|
'views/project_task_checklist_views.xml', |
||||
|
'views/project_task_views.xml', |
||||
|
'views/project_task_checklist_template_views.xml', |
||||
|
'views/project_checklist_template_views.xml', |
||||
|
'views/project_category_views.xml', |
||||
|
'views/project_project_views.xml', |
||||
|
'views/ir_attachment_views.xml', |
||||
|
'views/project_issue_views.xml', |
||||
|
'report/project_project_template.xml', |
||||
|
'report/project_task_template.xml', |
||||
|
'report/ir_action_report.xml', |
||||
|
'report/project_task_burnup_chart_report_views.xml', |
||||
|
'report/project_task_velocity_chart_report_views.xml', |
||||
|
'wizard/project_task_checklist_import_views.xml', |
||||
|
'wizard/project_stage_update_views.xml', |
||||
|
'wizard/project_task_mass_update_views.xml', |
||||
|
'wizard/project_shortcut_views.xml' |
||||
|
], |
||||
|
'assets': { |
||||
|
'web.assets_backend': { |
||||
|
'/advanced_project_management_system/static/src/js/burnup_chart_search_model.js', |
||||
|
'/advanced_project_management_system/static/src/js/burnup_chart_model.js', |
||||
|
'/advanced_project_management_system/static/src/js/burnup_chart_view.js', |
||||
|
'/advanced_project_management_system/static/src/xml/burnup_chart_view.xml', |
||||
|
'/advanced_project_management_system/static/src/xml/chatter_topbar_templates.xml', |
||||
|
'/advanced_project_management_system/static/src/js/chatter_topbar.js', |
||||
|
'/advanced_project_management_system/static/src/js/chatter_time.js', |
||||
|
'/advanced_project_management_system/static/src/js/velocity_chart_model.js', |
||||
|
'/advanced_project_management_system/static/src/js/velocity_chart_search_model.js', |
||||
|
'/advanced_project_management_system/static/src/js/velocity_chart_view.js', |
||||
|
'/advanced_project_management_system/static/src/xml/velocity_chart_view.xml', |
||||
|
}, |
||||
|
}, |
||||
|
'images': ['static/description/banner.jpg'], |
||||
|
'license': 'LGPL-3', |
||||
|
'installable': True, |
||||
|
'auto_install': False, |
||||
|
'application': False, |
||||
|
} |
@ -0,0 +1,25 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<odoo> |
||||
|
<data noupdate="1"> |
||||
|
<!-- server action for updating project stage --> |
||||
|
<record id="project_stage_multi_update" model="ir.actions.server"> |
||||
|
<field name="name">Mass Stage Update</field> |
||||
|
<field name="model_id" ref="model_project_project"/> |
||||
|
<field name="binding_model_id" ref="model_project_project"/> |
||||
|
<field name="state">code</field> |
||||
|
<field name="code"> |
||||
|
action = record.project_multi_stage_update() |
||||
|
</field> |
||||
|
</record> |
||||
|
<!-- server action for mass task details update --> |
||||
|
<record id="task_mass_update" model="ir.actions.server"> |
||||
|
<field name="name">Mass Update</field> |
||||
|
<field name="model_id" ref="model_project_task"/> |
||||
|
<field name="binding_model_id" ref="model_project_task"/> |
||||
|
<field name="state">code</field> |
||||
|
<field name="code"> |
||||
|
action = record.task_mass_update() |
||||
|
</field> |
||||
|
</record> |
||||
|
</data> |
||||
|
</odoo> |
@ -0,0 +1,25 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<odoo> |
||||
|
<data noupdate="1"> |
||||
|
<!-- schedule action for document expiry notification --> |
||||
|
<record id="document_expire_schedule_action" model="ir.cron"> |
||||
|
<field name="name">Document Expire</field> |
||||
|
<field name="model_id" ref="model_ir_attachment"/> |
||||
|
<field name="state">code</field> |
||||
|
<field name="code">model.document_expire_notification()</field> |
||||
|
<field name="interval_number">1</field> |
||||
|
<field name="interval_type">days</field> |
||||
|
<field name="numbercall">-1</field> |
||||
|
</record> |
||||
|
<!-- schedule action for task overdue notification --> |
||||
|
<record id="task_overdue_notification_schedule_action" model="ir.cron"> |
||||
|
<field name="name">Task overdue notification</field> |
||||
|
<field name="model_id" ref="model_project_task"/> |
||||
|
<field name="state">code</field> |
||||
|
<field name="code">model.task_overdue_notification()</field> |
||||
|
<field name="interval_number">1</field> |
||||
|
<field name="interval_type">days</field> |
||||
|
<field name="numbercall">-1</field> |
||||
|
</record> |
||||
|
</data> |
||||
|
</odoo> |
@ -0,0 +1,12 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<odoo> |
||||
|
<data noupdate="1"> |
||||
|
<!-- Generate sequence for the project issue --> |
||||
|
<record id="seq_project_issue" model="ir.sequence"> |
||||
|
<field name="name">Sequence</field> |
||||
|
<field name="code">project.issue</field> |
||||
|
<field name="prefix">PI</field> |
||||
|
<field name="padding">3</field> |
||||
|
</record> |
||||
|
</data> |
||||
|
</odoo> |
@ -0,0 +1,116 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<odoo> |
||||
|
<data noupdate="1"> |
||||
|
<!-- document expiry notification template for customers --> |
||||
|
<record id="document_expire_notification_to_customer" |
||||
|
model="mail.template"> |
||||
|
<field name="name">Document Expire Notification</field> |
||||
|
<field name="model_id" |
||||
|
ref="advanced_project_management_system.model_ir_attachment"/> |
||||
|
<field name="auto_delete" eval="True"/> |
||||
|
<field name="email_from">{{object.company_id.email}}</field> |
||||
|
<field name="email_to">{{object.partner_id.email}}</field> |
||||
|
<field name="subject">Document Expiry Notification for |
||||
|
{{object.name}} |
||||
|
</field> |
||||
|
<field name="body_html" type="html"> |
||||
|
<p> |
||||
|
Dear Mr/Ms<t t-out="object.partner_id.name"/>, |
||||
|
<br/> |
||||
|
Your document |
||||
|
<strong> |
||||
|
<t t-out="object.name"/> |
||||
|
</strong> |
||||
|
is expiring on |
||||
|
<strong> |
||||
|
<t t-out="object.expiry_date"/> |
||||
|
</strong> |
||||
|
<div style="margin: 16px 0px 16px 0px;"> |
||||
|
<a t-attf-href="{{ object.get_base_url() }}/web#id={{object.id}}&cids=1&model=ir.attachment&view_type=form" |
||||
|
style="background-color: #875A7B; padding: 8px 16px 8px 16px; text-decoration: none; color: #fff; border-radius: 5px; font-size:13px;"> |
||||
|
View Document |
||||
|
</a> |
||||
|
</div> |
||||
|
Thank you |
||||
|
</p> |
||||
|
</field> |
||||
|
</record> |
||||
|
<!-- document expiry notification email template to team--> |
||||
|
<record id="document_expire_notification_mail_template" |
||||
|
model="mail.template"> |
||||
|
<field name="name">Document Expire Notification</field> |
||||
|
<field name="model_id" |
||||
|
ref="advanced_project_management_system.model_ir_attachment"/> |
||||
|
<field name="auto_delete" eval="True"/> |
||||
|
<field name="email_from">{{object.company_id.email}}</field> |
||||
|
<field name="email_to">{{object.document_email_to}}</field> |
||||
|
<field name="subject">Document Expiry Notification for |
||||
|
{{object.name}} |
||||
|
</field> |
||||
|
<field name="body_html" type="html"> |
||||
|
<p> |
||||
|
Hi Team, |
||||
|
<br/> |
||||
|
The document |
||||
|
<strong> |
||||
|
<t t-out="object.name"/> |
||||
|
</strong> |
||||
|
is expiring on |
||||
|
<strong> |
||||
|
<t t-out="object.expiry_date"/> |
||||
|
</strong> |
||||
|
|
||||
|
<div style="margin: 16px 0px 16px 0px;"> |
||||
|
<a t-attf-href="{{ object.get_base_url() }}/web#id={{object.id}}&cids=1&model=ir.attachment&view_type=form" |
||||
|
style="background-color: #875A7B; padding: 8px 16px 8px 16px; text-decoration: none; color: #fff; border-radius: 5px; font-size:13px;"> |
||||
|
View Document |
||||
|
</a> |
||||
|
</div> |
||||
|
Thank you |
||||
|
</p> |
||||
|
</field> |
||||
|
</record> |
||||
|
<!-- Task due email notification template --> |
||||
|
<record id="task_due_email_notification" |
||||
|
model="mail.template"> |
||||
|
<field name="name">Task due Notification</field> |
||||
|
<field name="model_id" |
||||
|
ref="advanced_project_management_system.model_project_task"/> |
||||
|
<field name="auto_delete" eval="True"/> |
||||
|
<field name="email_from">{{object.company_id.email}}</field> |
||||
|
<field name="email_to">{{object._get_user_emails()}}</field> |
||||
|
<field name="subject">Task Overdue notification |
||||
|
</field> |
||||
|
<field name="body_html" type="html"> |
||||
|
<p> |
||||
|
Dear Employee |
||||
|
<br/> |
||||
|
Your overdue tasklist are |
||||
|
<table class="table"> |
||||
|
<thead> |
||||
|
<tr> |
||||
|
<th>Project</th> |
||||
|
<th>Task</th> |
||||
|
<th>Deadline Date</th> |
||||
|
</tr> |
||||
|
</thead> |
||||
|
<tbody> |
||||
|
<tr> |
||||
|
<td> |
||||
|
<t t-out="object.project_id.name"/> |
||||
|
</td> |
||||
|
<td> |
||||
|
<t t-out="object.name"/> |
||||
|
</td> |
||||
|
<td> |
||||
|
<t t-out="object.date_deadline"/> |
||||
|
</td> |
||||
|
</tr> |
||||
|
</tbody> |
||||
|
</table> |
||||
|
Thank you |
||||
|
</p> |
||||
|
</field> |
||||
|
</record> |
||||
|
</data> |
||||
|
</odoo> |
@ -0,0 +1,6 @@ |
|||||
|
## Module <advanced_project_management_system> |
||||
|
|
||||
|
#### 14.03.2024 |
||||
|
#### Version 16.0.1.0.0 |
||||
|
#### ADD |
||||
|
- Initial commit for Advanced project management system |
@ -0,0 +1,34 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################# |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU LESSER |
||||
|
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE |
||||
|
# (LGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################# |
||||
|
from . import ir_attachment |
||||
|
from . import project_project |
||||
|
from . import project_category |
||||
|
from . import project_checklist |
||||
|
from . import project_checklist_info |
||||
|
from . import project_checklist_template |
||||
|
from . import project_issue |
||||
|
from . import project_task |
||||
|
from . import project_task_checklist |
||||
|
from . import project_task_checklist_info |
||||
|
from . import project_task_checklist_template |
||||
|
from . import project_task_type |
||||
|
from . import res_config_settings |
@ -0,0 +1,71 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################# |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU LESSER |
||||
|
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE |
||||
|
# (LGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################# |
||||
|
from odoo import api, fields, models |
||||
|
|
||||
|
|
||||
|
class IrAttachment(models.Model): |
||||
|
""" Added document expiry information""" |
||||
|
_inherit = 'ir.attachment' |
||||
|
|
||||
|
expiry_date = fields.Date(string='Expiry Date', |
||||
|
help="for setting expiry date for the document") |
||||
|
expiry_notification = fields.Boolean(string='Expiry Date Notification', |
||||
|
help="For sending expiry notification") |
||||
|
partner_id = fields.Many2one('res.partner', string="partner", |
||||
|
help="For adding the partner ") |
||||
|
document_email_to = fields.Char( |
||||
|
default=lambda self: self.env['ir.config_parameter'].sudo().get_param( |
||||
|
'res.config.settings.email'), string="Email to", |
||||
|
help="For getting owner email") |
||||
|
document_mai_customer = fields.Boolean( |
||||
|
default=lambda self: self.env['ir.config_parameter'].sudo().get_param( |
||||
|
'res.config.settings.notify_customer'), string="Email to customer", |
||||
|
help="Notify email to customer ") |
||||
|
|
||||
|
def document_expire_notification(self): |
||||
|
""" Automatically sent email when the |
||||
|
document expiration date is over""" |
||||
|
if self.env['ir.config_parameter'].sudo().get_param( |
||||
|
'res.config.settings.notify_customer'): |
||||
|
attachments = self.search([('expiry_date', '!=', None)]) |
||||
|
for attachment in attachments: |
||||
|
if attachment.expiry_date < fields.Date.today(): |
||||
|
mail_template = attachment.env.ref( |
||||
|
'advanced_project_management_system.document_expire_notification_to_customer') |
||||
|
mail_template.send_mail(attachment.id, force_send=True) |
||||
|
attachments = self.search([('expiry_date', '!=', None)]) |
||||
|
for attachment in attachments: |
||||
|
if attachment.expiry_notification: |
||||
|
if attachment.expiry_date < fields.Date.today(): |
||||
|
mail_template = attachment.env.ref( |
||||
|
'advanced_project_management_system.document_expire_notification_mail_template') |
||||
|
mail_template.send_mail(attachment.id, force_send=True) |
||||
|
|
||||
|
@api.onchange('res_id') |
||||
|
def _onchange_res_id(self): |
||||
|
""" Compute customer name and add to attachment from projects""" |
||||
|
attachments = self.search([('res_model', '=', 'project.project')]) |
||||
|
for attachment in attachments: |
||||
|
projects = self.env['project.project'].search( |
||||
|
[('id', '=', attachment.res_id)]) |
||||
|
if projects.partner_id: |
||||
|
attachment.partner_id = projects.partner_id.id |
@ -0,0 +1,33 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################# |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU LESSER |
||||
|
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE |
||||
|
# (LGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################# |
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
class ProjectCategory(models.Model): |
||||
|
""" Setting up the project category""" |
||||
|
_name = "project.category" |
||||
|
_description = "Project categories" |
||||
|
|
||||
|
name = fields.Char(string='Project Category', tracking=True, |
||||
|
help="Name of the category") |
||||
|
is_active = fields.Boolean(string='Active', |
||||
|
help="Check is it active or not ") |
@ -0,0 +1,36 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################# |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU LESSER |
||||
|
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE |
||||
|
# (LGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################# |
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
class ProjectChecklist(models.Model): |
||||
|
""" Project checklist information""" |
||||
|
_name = "project.checklist" |
||||
|
_description = "Project checklist" |
||||
|
|
||||
|
name = fields.Char(string='Name', required=True, |
||||
|
name="name of the checklist") |
||||
|
description = fields.Char(string='Description', required=True, |
||||
|
help="Description about the checklist ") |
||||
|
company_id = fields.Many2one('res.company', string='Company', |
||||
|
required=True, help="Company information", |
||||
|
default=lambda self: self.env.company.id) |
@ -0,0 +1,58 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################# |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU LESSER |
||||
|
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE |
||||
|
# (LGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################# |
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
class ProjectChecklistInfo(models.Model): |
||||
|
""" Project checklist details""" |
||||
|
_name = "project.checklist.info" |
||||
|
_description = "Project checklist information" |
||||
|
|
||||
|
checklist_id = fields.Many2one('project.checklist', |
||||
|
string='Name', |
||||
|
help="Project checklist details") |
||||
|
description = fields.Char(string='Description', |
||||
|
related='checklist_id.description', |
||||
|
help="description about the checklist") |
||||
|
project_id = fields.Many2one('project.project', string="Project", |
||||
|
help="details of the project") |
||||
|
date = fields.Date(string='Date', default=fields.Date.today(), |
||||
|
help="get the date ") |
||||
|
state = fields.Selection( |
||||
|
selection=[('new', 'New'), ('progres', 'In Progress'), |
||||
|
('done', 'Done'), ('cancel', 'Cancel')], default='new', |
||||
|
readonly=False, string="Status", |
||||
|
help="Get information about the state") |
||||
|
|
||||
|
def action_set_checklist_complete(self): |
||||
|
""" Mark the checklist progress and completion""" |
||||
|
if self.state in ['new', 'progres']: |
||||
|
self.state = 'done' |
||||
|
checklist_template_id = self.env[ |
||||
|
'project.checklist.template'].search( |
||||
|
[('id', 'in', self.project_id.checklist_template_ids.ids)]) |
||||
|
self.project_id.checklist_progress += 100 / float( |
||||
|
len(checklist_template_id.checklist_ids.ids)) |
||||
|
|
||||
|
def action_set_checklist_close(self): |
||||
|
""" Checklist cancel details""" |
||||
|
self.state = 'cancel' |
@ -0,0 +1,33 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################# |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU LESSER |
||||
|
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE |
||||
|
# (LGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################# |
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
class ProjectChecklistTemplate(models.Model): |
||||
|
""" Project checklist template""" |
||||
|
_name = "project.checklist.template" |
||||
|
_description = "Project checklist template" |
||||
|
|
||||
|
name = fields.Char(string='Name', help="name of the template") |
||||
|
checklist_ids = fields.Many2many('project.checklist', |
||||
|
string='Checklist', |
||||
|
help="checklist information") |
@ -0,0 +1,67 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################# |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU LESSER |
||||
|
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE |
||||
|
# (LGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################# |
||||
|
from odoo import api, fields, models |
||||
|
|
||||
|
|
||||
|
class ProjectIssue(models.Model): |
||||
|
""" For managing project issues""" |
||||
|
_name = "project.issue" |
||||
|
_description = 'Project and task issue' |
||||
|
|
||||
|
user_id = fields.Many2one("res.users", string="Assigned to", |
||||
|
help="The person who is responsible to solve " |
||||
|
"the issue") |
||||
|
summary = fields.Text(string='Issue summary', help="Adding project issue") |
||||
|
email = fields.Char(string="Email", help="Email address") |
||||
|
project_id = fields.Many2one('project.project', string="project", |
||||
|
help="To know issue noticed in which project") |
||||
|
task_id = fields.Many2one('project.task', string="Task", |
||||
|
help="To know issue noticed in which task", |
||||
|
domain=[('project_id', '=', project_id)]) |
||||
|
priority = fields.Selection([('0', 'Low'), ('1', 'High')], default='0', |
||||
|
string="Priority") |
||||
|
tag_ids = fields.Many2many('project.tags', string='Tags', |
||||
|
help='Set the tags') |
||||
|
partner_id = fields.Many2one('res.partner', string="Contact", |
||||
|
help="Know about the contact details") |
||||
|
name = fields.Char(string='Number', default='new', |
||||
|
help='To track the issue reference') |
||||
|
description = fields.Text(string='Description', |
||||
|
help="To add the issue in detail") |
||||
|
extra_info = fields.Text(string="Extra Info", |
||||
|
help="To add some extra information") |
||||
|
state = fields.Selection([('new', 'New'), ('progress', 'In Progress'), |
||||
|
('done', 'Done'), ('cancel', 'Cancel')], |
||||
|
default='new', string='State', |
||||
|
help='Project issue pipeline stages') |
||||
|
create_date = fields.Datetime(string="Create Date", |
||||
|
help='For tracking the record creation date', |
||||
|
default=fields.Datetime.now()) |
||||
|
|
||||
|
@api.model |
||||
|
def create(self, vals): |
||||
|
""" Added reference number""" |
||||
|
if vals.get('name', 'New'): |
||||
|
vals['name'] = self.env['ir.sequence'].next_by_code( |
||||
|
'project.issue') |
||||
|
res = super(ProjectIssue, self).create(vals) |
||||
|
return res |
@ -0,0 +1,219 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################# |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU LESSER |
||||
|
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE |
||||
|
# (LGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################# |
||||
|
import json |
||||
|
from odoo import api, fields, models, _ |
||||
|
|
||||
|
|
||||
|
class ProjectProject(models.Model): |
||||
|
""" Added project documents,checklist,stage updates""" |
||||
|
_inherit = 'project.project' |
||||
|
|
||||
|
project_category_id = fields.Many2one('project.category', |
||||
|
string='Project Category', |
||||
|
help="For adding project category ") |
||||
|
document_count = fields.Integer(string='Documents', |
||||
|
compute='_compute_document_count', |
||||
|
help="For getting the document count") |
||||
|
project_stage_id = fields.Many2one('project.project.stage', |
||||
|
tracking=True, string='Stage', |
||||
|
help="Project stages") |
||||
|
project_checklist_info_ids = fields.One2many('project.checklist.info', |
||||
|
'project_id', |
||||
|
help="Project checklist details", |
||||
|
string='Checklist') |
||||
|
checklist_progress = fields.Integer(string="Progress", |
||||
|
help="For checklist progress bar ") |
||||
|
checklist_template_ids = fields.Many2many('project.checklist.template', |
||||
|
string='checklist template', |
||||
|
help="For getting checklist " |
||||
|
"template") |
||||
|
issue_count = fields.Integer(string="Project issue", |
||||
|
help="For getting project issue ", |
||||
|
compute="_compute_issue_count") |
||||
|
shortcut_ids = fields.One2many('project.shortcut', 'project_id', |
||||
|
string='Shortcuts') |
||||
|
url_shortcut = fields.Char(string="URL Shortcut", |
||||
|
compute="_compute_url_shortcut", |
||||
|
help="Enter the URL shortcut.") |
||||
|
is_active = fields.Boolean(string="Is Active", store=True, |
||||
|
help="Check this box if the URL is active.") |
||||
|
url_link = fields.Char(string="URL Link", help="Enter the URL link.") |
||||
|
url_name = fields.Char(string="URL Name", |
||||
|
help="Enter the name associated with the URL.") |
||||
|
|
||||
|
def open_project_creation_wizard(self): |
||||
|
""" Open the project creation wizard """ |
||||
|
return { |
||||
|
'type': 'ir.actions.act_window', |
||||
|
'res_model': 'project.project', |
||||
|
'view_mode': 'form', |
||||
|
'view_id': self.env.ref( |
||||
|
'advanced_project_management_system.project.project.view.form.' |
||||
|
'simplified').id, |
||||
|
'target': 'current', |
||||
|
} |
||||
|
|
||||
|
@api.depends('url_link', 'url_name') |
||||
|
def _compute_url_shortcut(self): |
||||
|
""" Compute the URL shortcut and its activation status """ |
||||
|
for project in self: |
||||
|
if project.url_link: |
||||
|
project.is_active = True |
||||
|
project.url_shortcut = project.url_link |
||||
|
else: |
||||
|
project.url_shortcut = "Add Link" |
||||
|
project.is_active = False |
||||
|
|
||||
|
def open_url_shortcut(self): |
||||
|
""" Open the URL shortcut """ |
||||
|
for project in self: |
||||
|
if project.url_shortcut: |
||||
|
return { |
||||
|
'name': self.url_name, |
||||
|
'type': 'ir.actions.act_url', |
||||
|
'url': project.url_shortcut, |
||||
|
'target': 'self', |
||||
|
} |
||||
|
|
||||
|
def button_document(self): |
||||
|
""" Return document kanban for the project""" |
||||
|
return { |
||||
|
'name': 'Documents', |
||||
|
'type': 'ir.actions.act_window', |
||||
|
'res_model': 'ir.attachment', |
||||
|
'view_mode': 'kanban,form', |
||||
|
'res_id': self._origin.id, |
||||
|
'domain': [ |
||||
|
('res_id', '=', self._origin.id), |
||||
|
('res_model', '=', 'project.project') |
||||
|
], |
||||
|
} |
||||
|
|
||||
|
def _compute_document_count(self): |
||||
|
""" Compute document count and return """ |
||||
|
for rec in self: |
||||
|
attachment_ids = self.env['ir.attachment'].search( |
||||
|
[('res_model', '=', 'project.project'), |
||||
|
('res_id', '=', rec.id)]) |
||||
|
rec.document_count = len(attachment_ids) |
||||
|
|
||||
|
def project_multi_stage_update(self): |
||||
|
""" Return wizard to update the project stage""" |
||||
|
return { |
||||
|
'type': 'ir.actions.act_window', |
||||
|
'name': 'Mass Update', |
||||
|
'view_mode': 'form', |
||||
|
'target': 'new', |
||||
|
'res_model': 'project.stage.update', |
||||
|
} |
||||
|
|
||||
|
@api.onchange('checklist_template_ids') |
||||
|
def _onchange_checklist_template_ids(self): |
||||
|
""" Updating checklist""" |
||||
|
check_list_id = self.env['project.checklist.template'].browse( |
||||
|
self.checklist_template_ids.ids) |
||||
|
if check_list_id: |
||||
|
for checklist_id in check_list_id.checklist_ids.ids: |
||||
|
self.update({ |
||||
|
'project_checklist_info_ids': |
||||
|
[(0, 0, { |
||||
|
'checklist_id': checklist_id |
||||
|
})] |
||||
|
}) |
||||
|
|
||||
|
def _compute_issue_count(self): |
||||
|
""" For getting project issue count""" |
||||
|
for rec in self: |
||||
|
issue_id = self.env['project.issue'].search( |
||||
|
[('project_id', '=', rec.id)]) |
||||
|
rec.issue_count = len(issue_id) |
||||
|
|
||||
|
def button_issue(self): |
||||
|
"""Return project issues""" |
||||
|
return { |
||||
|
'type': 'ir.actions.act_window', |
||||
|
'name': 'Project Issues', |
||||
|
'view_mode': 'tree,form', |
||||
|
'res_model': 'project.issue', |
||||
|
'domain': [('project_id', '=', self.id)] |
||||
|
} |
||||
|
|
||||
|
def _get_stat_buttons(self): |
||||
|
""" Get statistical buttons for the project """ |
||||
|
self.ensure_one() |
||||
|
buttons = super(ProjectProject, self)._get_stat_buttons() |
||||
|
if self.user_has_groups('project.group_project_user'): |
||||
|
buttons.append({ |
||||
|
'icon': 'area-chart', |
||||
|
'text': _('Burnup Chart'), |
||||
|
'action_type': 'action', |
||||
|
'action': 'advanced_project_management_system.action_project_task_burnup_chart_report', |
||||
|
'additional_context': json.dumps({ |
||||
|
'active_id': self.id, |
||||
|
}), |
||||
|
'show': True, |
||||
|
'sequence': 60, |
||||
|
}) |
||||
|
if self.user_has_groups('project.group_project_user'): |
||||
|
buttons.append({ |
||||
|
'icon': 'line-chart', |
||||
|
'text': _('Velocity Chart'), |
||||
|
'action_type': 'action', |
||||
|
'action': 'advanced_project_management_system.action_project_velocity_chart_report', |
||||
|
'additional_context': json.dumps({ |
||||
|
'active_id': self.id, |
||||
|
}), |
||||
|
'show': True, |
||||
|
'sequence': 60, |
||||
|
}) |
||||
|
return buttons |
||||
|
|
||||
|
def action_project_task_burnup_chart_report(self): |
||||
|
""" Open the Burnup Chart report for the project """ |
||||
|
action = self.env['ir.actions.act_window']._for_xml_id( |
||||
|
'advanced_project_management_system' |
||||
|
'.action_project_task_burnup_chart_report') |
||||
|
action['display_name'] = _("%(name)s's Burnup Chart", name=self.name) |
||||
|
return action |
||||
|
|
||||
|
def action_project_velocity_chart_report(self): |
||||
|
""" Open the Velocity Chart report for the project """ |
||||
|
action = self.env['ir.actions.act_window']._for_xml_id( |
||||
|
'advanced_project_management_system' |
||||
|
'.action_project_velocity_chart_report') |
||||
|
action['display_name'] = _("%(name)s's Velocity Chart", |
||||
|
name=self.name) |
||||
|
return action |
||||
|
|
||||
|
def action_open_shortcut(self): |
||||
|
""" Open the shortcut creation form """ |
||||
|
view_id = self.env.ref( |
||||
|
'advanced_project_management_system.project_shortcut_view_form').id |
||||
|
return { |
||||
|
'name': 'Add Custom Project Shortcut', |
||||
|
'view_type': 'form', |
||||
|
'view_mode': 'form', |
||||
|
'res_model': 'project.shortcut', |
||||
|
'views': [(view_id, 'form')], |
||||
|
'type': 'ir.actions.act_window', |
||||
|
'target': 'new', |
||||
|
} |
@ -0,0 +1,122 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################# |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU LESSER |
||||
|
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE |
||||
|
# (LGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################# |
||||
|
from odoo import api, fields, models |
||||
|
from datetime import datetime |
||||
|
|
||||
|
|
||||
|
class ProjectTask(models.Model): |
||||
|
""" Added checklist and document details""" |
||||
|
_inherit = 'project.task' |
||||
|
|
||||
|
document_count = fields.Integer(string='Documents', |
||||
|
compute='_compute_document_count', |
||||
|
help="For getting document count") |
||||
|
checklist_template_ids = fields.Many2many( |
||||
|
'project.task.checklist.template', |
||||
|
string='Checklist', help="For adding project checklist template") |
||||
|
checklist_info_ids = fields.One2many('project.task.checklist.info', |
||||
|
'task_id', string="checklist info", |
||||
|
help="for getting project checklist " |
||||
|
"details") |
||||
|
checklist_progress = fields.Float(string='Checklist Completed', |
||||
|
colors="red,orange,yellow,green", |
||||
|
help="For tracking checklist progress", |
||||
|
max_value=1, min_value=0) |
||||
|
task_type = fields.Selection([ |
||||
|
('task', 'Task'), |
||||
|
('subtask', 'Subtask'), |
||||
|
('bug', 'Bug'), |
||||
|
], string='Task Type', default="task") |
||||
|
|
||||
|
def task_overdue_notification(self): |
||||
|
""" Scheduled action for email notification to |
||||
|
employee about task due """ |
||||
|
if self.env['ir.config_parameter'].sudo().get_param( |
||||
|
'res.config.settings.is_overdue_notification'): |
||||
|
task_ids = self.search([]) |
||||
|
for task in task_ids: |
||||
|
if task.stage_id.name not in ( |
||||
|
'Done', |
||||
|
'Canceled') and task.date_deadline and task.date_deadline < fields.Date.today(): |
||||
|
mail_template = task.env.ref( |
||||
|
'advanced_project_management_system.task_due_email_notification') |
||||
|
mail_template.send_mail(task.id, force_send=True) |
||||
|
|
||||
|
def _get_user_emails(self): |
||||
|
""" Return email ids of the employee""" |
||||
|
emails = [] |
||||
|
task_ids = self.search([('date_deadline', '<', fields.Date.today())]) |
||||
|
for task in task_ids: |
||||
|
if task.stage_id.name not in ('Done', 'Canceled'): |
||||
|
for user in task.user_ids: |
||||
|
emails.append(user.login) |
||||
|
return emails |
||||
|
|
||||
|
def _compute_document_count(self): |
||||
|
""" Compute document count and return """ |
||||
|
for rec in self: |
||||
|
attachment_ids = self.env['ir.attachment'].search( |
||||
|
[('res_model', '=', 'project.task'), ('res_id', '=', rec.id)]) |
||||
|
rec.document_count = len(attachment_ids) |
||||
|
|
||||
|
def button_task_document(self): |
||||
|
""" Return document kanban for the task""" |
||||
|
return { |
||||
|
'name': 'Documents', |
||||
|
'type': 'ir.actions.act_window', |
||||
|
'res_model': 'ir.attachment', |
||||
|
'view_mode': 'kanban,form', |
||||
|
'res_id': self._origin.id, |
||||
|
'domain': [ |
||||
|
('res_id', '=', self._origin.id), |
||||
|
('res_model', '=', 'project.task')], |
||||
|
} |
||||
|
|
||||
|
def task_mass_update(self): |
||||
|
""" Return wizard for updating task details""" |
||||
|
return { |
||||
|
'name': 'Documents', |
||||
|
'type': 'ir.actions.act_window', |
||||
|
'res_model': 'project.task.mass.update', |
||||
|
'target': 'new', |
||||
|
'view_mode': 'form', |
||||
|
} |
||||
|
|
||||
|
@api.onchange('stage_id') |
||||
|
def _onchange_stage_id(self): |
||||
|
""" While changing task stage task will automatically assign to |
||||
|
users from task stage""" |
||||
|
if self.stage_id.user_ids: |
||||
|
self.user_ids = self.stage_id.user_ids |
||||
|
|
||||
|
@api.onchange('checklist_template_ids') |
||||
|
def _onchange_checklist_template_ids(self): |
||||
|
check_list_id = self.env['project.task.checklist.template'].browse( |
||||
|
self.checklist_template_ids.ids) |
||||
|
if check_list_id: |
||||
|
for checklist_id in check_list_id.checklist_ids.ids: |
||||
|
self.update({ |
||||
|
'checklist_info_ids': |
||||
|
[(0, 0, { |
||||
|
'checklist_id': checklist_id |
||||
|
})] |
||||
|
}) |
@ -0,0 +1,37 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################# |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU LESSER |
||||
|
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE |
||||
|
# (LGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################# |
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
class ProjectChecklist(models.Model): |
||||
|
"""Task checklist details""" |
||||
|
_name = "project.task.checklist" |
||||
|
_description = "Task Custom Checklist" |
||||
|
|
||||
|
name = fields.Char(string='Name', required=True, |
||||
|
help="name of the checklist") |
||||
|
description = fields.Char(string='Description', required=True, |
||||
|
help="Description of the checklist") |
||||
|
company_id = fields.Many2one('res.company', string='Company', |
||||
|
required=True, |
||||
|
default=lambda self: self.env.company.id, |
||||
|
help="For getting company details") |
@ -0,0 +1,63 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################# |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU LESSER |
||||
|
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE |
||||
|
# (LGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################# |
||||
|
from odoo import fields, models, _ |
||||
|
from odoo.exceptions import ValidationError |
||||
|
|
||||
|
|
||||
|
class ProjectTaskChecklistInfo(models.Model): |
||||
|
""" Task checklist details""" |
||||
|
_name = "project.task.checklist.info" |
||||
|
_description = "Task checklist information" |
||||
|
|
||||
|
checklist_id = fields.Many2one('project.task.checklist', |
||||
|
string='Name', help="checklist") |
||||
|
description = fields.Char(string='Description', |
||||
|
related='checklist_id.description', |
||||
|
help="Description of the checklist info ") |
||||
|
task_id = fields.Many2one('project.task', string="Task", |
||||
|
help="Task details") |
||||
|
checklist_progress = fields.Integer(string="progress", |
||||
|
help="For tracking the checklist " |
||||
|
"progress and completion") |
||||
|
date = fields.Date(string='Date', default=fields.Date.today(), |
||||
|
help="Get the date information") |
||||
|
state = fields.Selection( |
||||
|
selection=[('new', 'New'), ('progres', 'In Progress'), |
||||
|
('done', 'Done'), ('cancel', 'Cancel')], default='new', |
||||
|
string="Status", help="get the status of the checklist ") |
||||
|
|
||||
|
def action_set_checklist_complete(self): |
||||
|
""" Managing the checklist progress and completion""" |
||||
|
if self.state in ['new', 'progres']: |
||||
|
checklist_template_id = self.env[ |
||||
|
'project.task.checklist.template'].search( |
||||
|
[('id', 'in', self.task_id.checklist_template_ids.ids)]) |
||||
|
if len(checklist_template_id.checklist_ids.ids) > 0: |
||||
|
self.task_id.checklist_progress += 100 / float( |
||||
|
len(checklist_template_id.checklist_ids.ids)) |
||||
|
self.state = 'done' |
||||
|
else: |
||||
|
raise ValidationError(_("Please add checklist")) |
||||
|
|
||||
|
def action_set_checklist_close(self): |
||||
|
""" Checklist cancel info """ |
||||
|
self.state = 'cancel' |
@ -0,0 +1,33 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################# |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU LESSER |
||||
|
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE |
||||
|
# (LGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################# |
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
class ProjectTaskChecklistTemplate(models.Model): |
||||
|
"""Task checklist template""" |
||||
|
_name = "project.task.checklist.template" |
||||
|
_description = "Task checklist template" |
||||
|
|
||||
|
name = fields.Char(string='Name', help="name of the template") |
||||
|
checklist_ids = fields.Many2many('project.task.checklist', |
||||
|
string='Checklist', |
||||
|
help="To get the checklist details") |
@ -0,0 +1,30 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################# |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU LESSER |
||||
|
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE |
||||
|
# (LGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################# |
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
class ProjectTaskType(models.Model): |
||||
|
""" Added user information""" |
||||
|
_inherit = 'project.task.type' |
||||
|
|
||||
|
user_ids = fields.Many2many('res.users', string='Assign Multiple Users', |
||||
|
help="We can assign multiple users ") |
@ -0,0 +1,67 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################# |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU LESSER |
||||
|
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE |
||||
|
# (LGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################# |
||||
|
from odoo import api, fields, models |
||||
|
|
||||
|
|
||||
|
class ResConfigSettings(models.TransientModel): |
||||
|
""" Added document expiry notification expiry mail details """ |
||||
|
_inherit = "res.config.settings" |
||||
|
|
||||
|
is_project_category = fields.Boolean( |
||||
|
string='Enable Project Category', |
||||
|
help="Enabling project category", |
||||
|
config_parameter='advanced_project_management_system.is_project_category') |
||||
|
document_expiry_notification = fields.Boolean( |
||||
|
string='Document Expiry Notification', |
||||
|
help="For sending document expiry notification", |
||||
|
config_parameter='advanced_project_management_system.document_expiry_notification') |
||||
|
notify_customer = fields.Boolean( |
||||
|
string='Notify Customer', |
||||
|
help="For notifying the customer", |
||||
|
config_parameter='advanced_project_management_system.notify_customer') |
||||
|
on_expiry_notification = fields.Boolean( |
||||
|
string='On Expiry Date Notification', help="Sent expiry notification", |
||||
|
config_parameter='advanced_project_management_system.on_expiry_notification') |
||||
|
email = fields.Char( |
||||
|
string='Notify Email to', help="Get email id", |
||||
|
config_parameter='advanced_project_management_system.email') |
||||
|
notify_days = fields.Integer( |
||||
|
string='Notify After Expiry Date', |
||||
|
help="Notification sent before these days", |
||||
|
config_parameter='advanced_project_management_system.notify_days') |
||||
|
is_overdue_notification = fields.Boolean( |
||||
|
string='Overdue Notification?', |
||||
|
help="For sending overdue notification", |
||||
|
config_parameter='advanced_project_management_system.is_overdue_notification') |
||||
|
notification_before = fields.Integer( |
||||
|
string='Notification Days', |
||||
|
help="Sent notification before these days", |
||||
|
config_parameter='advanced_project_management_system.notification_before') |
||||
|
|
||||
|
@api.onchange('is_project_category') |
||||
|
def _onchange_is_project_category(self): |
||||
|
groups = self.env.ref( |
||||
|
'advanced_project_management_system.group_project_category') |
||||
|
if self.is_project_category: |
||||
|
groups.write({'users': [(4, self.env.user.id)]}) |
||||
|
else: |
||||
|
groups.write({'users': [(3, self.env.user.id)]}) |
@ -0,0 +1,23 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################# |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU LESSER |
||||
|
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE |
||||
|
# (LGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################# |
||||
|
from . import project_task_burnup_chart_report |
||||
|
from . import project_task_velocity_chart_report |
@ -0,0 +1,28 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<odoo> |
||||
|
<!-- project report action --> |
||||
|
<record id="action_print_project_details" model="ir.actions.report"> |
||||
|
<field name="name">Print Project</field> |
||||
|
<field name="model">project.project</field> |
||||
|
<field name="report_type">qweb-pdf</field> |
||||
|
<field name="report_name">advanced_project_management_system.project_details_report |
||||
|
</field> |
||||
|
<field name="report_file">project_report</field> |
||||
|
<field name="print_report_name">'Project Details' |
||||
|
</field> |
||||
|
<field name="binding_model_id" ref="model_project_project"/> |
||||
|
<field name="binding_type">report</field> |
||||
|
</record> |
||||
|
<!-- task report action--> |
||||
|
<record id="action_print_project_task_details" model="ir.actions.report"> |
||||
|
<field name="name">Print Task</field> |
||||
|
<field name="model">project.task</field> |
||||
|
<field name="report_type">qweb-pdf</field> |
||||
|
<field name="report_name">advanced_project_management_system.task_details_report</field> |
||||
|
<field name="report_file">task_report</field> |
||||
|
<field name="print_report_name">'Task Details' |
||||
|
</field> |
||||
|
<field name="binding_model_id" ref="model_project_task"/> |
||||
|
<field name="binding_type">report</field> |
||||
|
</record> |
||||
|
</odoo> |
@ -0,0 +1,125 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<odoo> |
||||
|
<!-- PDF report template for project --> |
||||
|
<template id="project_details_report"> |
||||
|
<t t-call="web.html_container"> |
||||
|
<div class="article"> |
||||
|
<div class="header"> |
||||
|
<div class="row text-left" |
||||
|
style="border-top: 1px solid black;"> |
||||
|
<div class="col-xs-3 col-xs-offset-9 text-right"> |
||||
|
<ul class="list-inline" |
||||
|
style="margin-top:10px;"> |
||||
|
<li> |
||||
|
<span class="page"/> |
||||
|
/ |
||||
|
<span class="topage"/> |
||||
|
</li> |
||||
|
</ul> |
||||
|
<br/> |
||||
|
<div> |
||||
|
<t t-set="docs" t-value="docs"/> |
||||
|
<span class="text-left" |
||||
|
style="color:black;" |
||||
|
t-esc="docs.company_id.name"/> |
||||
|
<br/> |
||||
|
<span class="text-left" |
||||
|
style="color:black;" |
||||
|
t-esc="docs.company_id.street"/> |
||||
|
<br/> |
||||
|
<span class="text-left" |
||||
|
style="color:black;" |
||||
|
t-esc="docs.company_id.state_id.name"/> |
||||
|
, |
||||
|
<span class="text-left" |
||||
|
style="color:black;" |
||||
|
t-esc="docs.company_id.country_id.name"/> |
||||
|
<br/> |
||||
|
<span class="text-left" |
||||
|
style="color:black;" |
||||
|
t-esc="docs.company_id.email"/> |
||||
|
<br/> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<h3> |
||||
|
<strong> |
||||
|
<center> |
||||
|
<t t-set="docs" t-value="docs"/> |
||||
|
<span class="text-left" style="color:black;" |
||||
|
t-esc="docs.name"/> |
||||
|
</center> |
||||
|
</strong> |
||||
|
</h3> |
||||
|
<strong>Project Manager :</strong> |
||||
|
<span class="text-left" style="color:black;" |
||||
|
t-esc="docs.user_id.name"/> |
||||
|
<br/> |
||||
|
<strong>Customer :</strong> |
||||
|
<span class="text-left" style="color:black;" |
||||
|
t-esc="docs.partner_id.name"/> |
||||
|
<table class="table"> |
||||
|
<thead> |
||||
|
<tr> |
||||
|
<th>Task Name</th> |
||||
|
<th>Planned Hours</th> |
||||
|
<th>Spend Hours</th> |
||||
|
<th>Remaining Hours</th> |
||||
|
<th>Assigned To</th> |
||||
|
<th>Assign Date</th> |
||||
|
<th>Deadline</th> |
||||
|
<th>Stage</th> |
||||
|
</tr> |
||||
|
</thead> |
||||
|
<tbody> |
||||
|
<t t-foreach="docs.task_ids" t-as="task"> |
||||
|
<tr> |
||||
|
<td> |
||||
|
<span class="text-left" |
||||
|
style="color:black;" |
||||
|
t-esc="task.name"/> |
||||
|
</td> |
||||
|
<td> |
||||
|
<span class="text-left" |
||||
|
style="color:black;" |
||||
|
t-esc="task.planned_hours"/> |
||||
|
</td> |
||||
|
<td> |
||||
|
<span class="text-left" |
||||
|
style="color:black;" |
||||
|
t-esc="task.effective_hours"/> |
||||
|
</td> |
||||
|
<td> |
||||
|
<span class="text-left" |
||||
|
style="color:black;" |
||||
|
t-esc="task.remaining_hours"/> |
||||
|
</td> |
||||
|
<td> |
||||
|
<span class="text-left" |
||||
|
style="color:black;" |
||||
|
t-esc="task.user_ids.name"/> |
||||
|
</td> |
||||
|
<td> |
||||
|
<span class="text-left" |
||||
|
style="color:black;" |
||||
|
t-esc="task.date_assign"/> |
||||
|
</td> |
||||
|
<td> |
||||
|
<span class="text-left" |
||||
|
style="color:black;" |
||||
|
t-esc="task.date_deadline"/> |
||||
|
</td> |
||||
|
<td> |
||||
|
<span class="text-left" |
||||
|
style="color:black;" |
||||
|
t-esc="task.stage_id.name"/> |
||||
|
</td> |
||||
|
</tr> |
||||
|
</t> |
||||
|
</tbody> |
||||
|
</table> |
||||
|
</div> |
||||
|
</t> |
||||
|
</template> |
||||
|
</odoo> |
@ -0,0 +1,68 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################# |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU LESSER |
||||
|
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE |
||||
|
# (LGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################# |
||||
|
from collections import defaultdict |
||||
|
from odoo import api, fields, models, _ |
||||
|
|
||||
|
|
||||
|
class ProjectTaskBurnupChartReport(models.AbstractModel): |
||||
|
"""This model defines the Burnup Chart report for project tasks. """ |
||||
|
_name = 'project.task.burnup.chart.report' |
||||
|
_description = 'Burnup Chart' |
||||
|
|
||||
|
date = fields.Datetime(string='Date', readonly=True, |
||||
|
help='The date of data entry') |
||||
|
completed_count = fields.Integer(string='Completed Tasks', readonly=True, |
||||
|
help='The number of completed tasks') |
||||
|
total_count = fields.Integer(string='Total Tasks', readonly=True, |
||||
|
help='The total number of tasks') |
||||
|
@api.model |
||||
|
def _read_group_raw(self, domain, fields, groupby, offset=0, |
||||
|
limit=None, orderby=False, lazy=True): |
||||
|
"""Generate raw data for the Burnup Chart report.""" |
||||
|
data = [] |
||||
|
project_id = self._context.get('active_id') |
||||
|
if groupby: |
||||
|
tasks = self.env['project.task'].search([ |
||||
|
('project_id', '=', project_id), |
||||
|
('stage_id.name', '=', 'Done') |
||||
|
]) |
||||
|
task_counts = defaultdict(lambda: defaultdict(int)) |
||||
|
task_names = defaultdict(list) |
||||
|
for task in tasks: |
||||
|
completion_date = task.date_deadline or task.create_date.date() |
||||
|
start_date = task.create_date.date() |
||||
|
if task.stage_id.name == 'Done': |
||||
|
month_year = completion_date.strftime('%B %Y') |
||||
|
task_counts[month_year]['Total'] += 1 |
||||
|
if start_date != completion_date: |
||||
|
task_counts[month_year]['Start'] += 1 |
||||
|
task_names[month_year].append(task.name) |
||||
|
for month_year, counts in task_counts.items(): |
||||
|
data.append({ |
||||
|
'date:month': [0, month_year], |
||||
|
'stage_id': True, |
||||
|
'completed_count': "\n".join(task_names[month_year]), |
||||
|
'__count': counts['Total'], |
||||
|
'date_start': counts['Start'], |
||||
|
'__domain': domain |
||||
|
}) |
||||
|
return data |
@ -0,0 +1,48 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<odoo> |
||||
|
<!-- Define a view for the search functionality of the Burnup Chart report --> |
||||
|
<record id="project_task_burnup_chart_report_view_search" |
||||
|
model="ir.ui.view"> |
||||
|
<field name="name">project.task.burnup.chart.report.view.search</field> |
||||
|
<field name="model">project.task.burnup.chart.report</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<search string="Burnup Chart"> |
||||
|
<separator/> |
||||
|
</search> |
||||
|
</field> |
||||
|
</record> |
||||
|
<!-- Define a view for displaying the Burnup Chart --> |
||||
|
<record id="project_task_burnup_chart_report_view_graph" |
||||
|
model="ir.ui.view"> |
||||
|
<field name="name">project.task.burnup.chart.report.view.graph</field> |
||||
|
<field name="model">project.task.burnup.chart.report</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<graph string="Burnup Chart" type="line" sample="1" |
||||
|
disable_linking="1" js_class="burnup_chart"> |
||||
|
<field name="date" string="Date" interval="month"/> |
||||
|
<field name="completed_count" string="Completed Tasks"/> |
||||
|
</graph> |
||||
|
</field> |
||||
|
</record> |
||||
|
<!-- Define an action for opening the Burnup Chart report --> |
||||
|
<record id="action_project_task_burnup_chart_report" |
||||
|
model="ir.actions.act_window"> |
||||
|
<field name="name">Burnup Chart</field> |
||||
|
<field name="res_model">project.task.burnup.chart.report</field> |
||||
|
<field name="view_mode">graph</field> |
||||
|
<field name="search_view_id" |
||||
|
ref="project_task_burnup_chart_report_view_search"/> |
||||
|
<field name="context">{'search_default_project_id': active_id, |
||||
|
'search_default_date': 1, 'search_default_stage': 1} |
||||
|
</field> |
||||
|
<field name="domain">[('display_project_id', '!=', False)]</field> |
||||
|
<field name="help" type="html"> |
||||
|
<p class="o_view_nocontent_empty_folder"> |
||||
|
No data yet! |
||||
|
</p> |
||||
|
<p>Analyze the growth of your project's scope and track progress |
||||
|
over time with the Burnup Chart. |
||||
|
</p> |
||||
|
</field> |
||||
|
</record> |
||||
|
</odoo> |
@ -0,0 +1,112 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<odoo> |
||||
|
<!-- PDF report template for task details --> |
||||
|
<template id="task_details_report"> |
||||
|
<t t-call="web.html_container"> |
||||
|
<div class="article"> |
||||
|
<div class="header"> |
||||
|
<div class="row text-left" |
||||
|
style="border-top: 1px solid black;"> |
||||
|
<div class="col-xs-3 col-xs-offset-9 text-right"> |
||||
|
<ul class="list-inline" |
||||
|
style="margin-top:10px;"> |
||||
|
<li> |
||||
|
<span class="page"/> |
||||
|
/ |
||||
|
<span class="topage"/> |
||||
|
</li> |
||||
|
</ul> |
||||
|
<br/> |
||||
|
<div> |
||||
|
<t t-set="docs" t-value="docs"/> |
||||
|
<span class="text-left" |
||||
|
style="color:black;" |
||||
|
t-esc="docs.company_id.name"/> |
||||
|
<br/> |
||||
|
<span class="text-left" |
||||
|
style="color:black;" |
||||
|
t-esc="docs.company_id.street"/> |
||||
|
<br/> |
||||
|
<span class="text-left" |
||||
|
style="color:black;" |
||||
|
t-esc="docs.company_id.state_id.name"/> |
||||
|
<span class="text-left" |
||||
|
style="color:black;" |
||||
|
t-esc="docs.company_id.country_id.name"/> |
||||
|
<br/> |
||||
|
<span class="text-left" |
||||
|
style="color:black;" |
||||
|
t-esc="docs.company_id.email"/> |
||||
|
<br/> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div style="border:1px solid black;"> |
||||
|
<h3> |
||||
|
<strong> |
||||
|
<center> |
||||
|
<t t-set="docs" t-value="docs"/> |
||||
|
<span class="text-left" |
||||
|
style="color:black;" |
||||
|
t-esc="docs.name"/> |
||||
|
</center> |
||||
|
</strong> |
||||
|
</h3> |
||||
|
</div> |
||||
|
<div style="border:1px solid black;"> |
||||
|
<strong>Project Name:</strong> |
||||
|
<span class="text-left" |
||||
|
style="color:black;" |
||||
|
t-esc="docs.project_id.name"/> |
||||
|
<br/> |
||||
|
<br/> |
||||
|
<strong>Customer Name:</strong> |
||||
|
<span class="text-left" |
||||
|
style="color:black;" |
||||
|
t-esc="docs.partner_id.name"/> |
||||
|
<br/> |
||||
|
<br/> |
||||
|
<strong>Customer Email:</strong> |
||||
|
<span class="text-left" |
||||
|
style="color:black;" |
||||
|
t-esc="docs.partner_id.email"/> |
||||
|
<br/> |
||||
|
<br/> |
||||
|
<strong>Responsible User:</strong> |
||||
|
<span class="text-left" |
||||
|
style="color:black;" |
||||
|
t-esc="docs.user_ids.name"/> |
||||
|
<br/> |
||||
|
<br/> |
||||
|
<strong>Assign To:</strong> |
||||
|
<span class="text-left" |
||||
|
style="color:black;" |
||||
|
t-esc="docs.user_ids.name"/> |
||||
|
<br/> |
||||
|
<br/> |
||||
|
<strong>Assign Date:</strong> |
||||
|
<span class="text-left" |
||||
|
style="color:black;" |
||||
|
t-esc="docs.date_assign"/> |
||||
|
<br/> |
||||
|
<br/> |
||||
|
<strong>Deadline Date:</strong> |
||||
|
<span class="text-left" |
||||
|
style="color:black;" |
||||
|
t-esc="docs.date_deadline"/> |
||||
|
<br/> |
||||
|
<br/> |
||||
|
<div align="center"> |
||||
|
<strong>Description</strong> |
||||
|
<span class="text-left" |
||||
|
style="color:black;" |
||||
|
t-esc="docs.description"/> |
||||
|
</div> |
||||
|
<br/> |
||||
|
<br/> |
||||
|
</div> |
||||
|
</div> |
||||
|
</t> |
||||
|
</template> |
||||
|
</odoo> |
@ -0,0 +1,78 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################# |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# You can modify it under the terms of the GNU LESSER |
||||
|
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE |
||||
|
# (LGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################# |
||||
|
from collections import defaultdict |
||||
|
from odoo import api, fields, models, _ |
||||
|
|
||||
|
|
||||
|
class ProjectVelocityChartReport(models.AbstractModel): |
||||
|
""" |
||||
|
Abstract model for the Velocity Chart report. |
||||
|
This model is used to calculate and display the Velocity Chart report |
||||
|
for a specific project and task. |
||||
|
""" |
||||
|
_name = 'project.velocity.chart.report' |
||||
|
_description = 'Velocity Chart' |
||||
|
|
||||
|
date = fields.Date(string='Sprint Start Date', readonly=True, |
||||
|
help="The start date of the sprint.") |
||||
|
completed_story_points = fields.Float(string='Completed Story Points', |
||||
|
readonly=True, |
||||
|
help="The total story points" |
||||
|
" completed in the sprint.") |
||||
|
|
||||
|
|
||||
|
|
||||
|
@api.model |
||||
|
def _read_group_raw(self, domain, fields, groupby, offset=0, limit=None, |
||||
|
orderby=False, lazy=True): |
||||
|
"""Compute grouped data for the Velocity Chart report.""" |
||||
|
data = [] |
||||
|
project_id = self._context.get('active_id') |
||||
|
if groupby: |
||||
|
tasks = self.env['project.task'].search([ |
||||
|
('project_id', '=', project_id), |
||||
|
('stage_id.name', '=', 'Done') |
||||
|
]) |
||||
|
completed_within_deadline_count = defaultdict( |
||||
|
lambda: defaultdict(int)) |
||||
|
completed_names = defaultdict(list) |
||||
|
for task in tasks: |
||||
|
sprint_start_date = task.create_date.date() |
||||
|
completion_date = task.date_deadline or task.create_date.date() |
||||
|
if task.stage_id.name == 'Done': |
||||
|
month_year = completion_date.strftime('%B %Y') |
||||
|
completed_within_deadline_count[month_year]['Total'] += 1 |
||||
|
if sprint_start_date != completion_date: |
||||
|
completed_within_deadline_count[month_year][ |
||||
|
'Start'] += 1 |
||||
|
completed_names[month_year].append(task.name) |
||||
|
for month_year, counts in completed_within_deadline_count.items(): |
||||
|
data.append({ |
||||
|
'date:month': [0, month_year], |
||||
|
'stage_id': True, |
||||
|
'completed_count': "\n".join( |
||||
|
completed_names[month_year]), |
||||
|
'__count': counts['Total'], |
||||
|
'date_start': counts['Start'], |
||||
|
'__domain': domain |
||||
|
}) |
||||
|
return data |
@ -0,0 +1,50 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8" ?> |
||||
|
<odoo> |
||||
|
<!-- Define a view for searching Velocity Chart records --> |
||||
|
<record id="project_velocity_chart_report_view_search" |
||||
|
model="ir.ui.view"> |
||||
|
<field name="name">project.velocity.chart.report.view.search</field> |
||||
|
<field name="model">project.velocity.chart.report</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<search string="Velocity Chart"> |
||||
|
<separator/> |
||||
|
</search> |
||||
|
</field> |
||||
|
</record> |
||||
|
<!-- Define a view for displaying the Velocity Chart as a graph --> |
||||
|
<record id="project_velocity_chart_report_view_graph" |
||||
|
model="ir.ui.view"> |
||||
|
<field name="name">project.velocity.chart.report.view.graph</field> |
||||
|
<field name="model">project.velocity.chart.report</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<graph string="Velocity Chart" type="line" sample="1" |
||||
|
disable_linking="1" js_class="velocity_chart"> |
||||
|
<field name="date" string="Sprint Start Date" |
||||
|
interval="month"/> |
||||
|
<field name="completed_story_points" |
||||
|
string="Completed Story Points"/> |
||||
|
</graph> |
||||
|
</field> |
||||
|
</record> |
||||
|
<!-- Define an action for opening the Velocity Chart --> |
||||
|
<record id="action_project_velocity_chart_report" |
||||
|
model="ir.actions.act_window"> |
||||
|
<field name="name">Velocity Chart</field> |
||||
|
<field name="res_model">project.velocity.chart.report</field> |
||||
|
<field name="view_mode">graph</field> |
||||
|
<field name="search_view_id" |
||||
|
ref="project_velocity_chart_report_view_search"/> |
||||
|
<field name="context">{'search_default_project_id': active_id, |
||||
|
'search_default_date': 1} |
||||
|
</field> |
||||
|
<field name="domain">[('project_id', '!=', False)]</field> |
||||
|
<field name="help" type="html"> |
||||
|
<p class="o_view_nocontent_empty_folder"> |
||||
|
No data yet! |
||||
|
</p> |
||||
|
<p>Analyze your project's velocity over time with the Velocity |
||||
|
Chart. |
||||
|
</p> |
||||
|
</field> |
||||
|
</record> |
||||
|
</odoo> |
|
@ -0,0 +1,12 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<odoo> |
||||
|
<!-- security groups --> |
||||
|
<record id="ir_attachment_group_user" model="res.groups"> |
||||
|
<field name="name">Access Project Document</field> |
||||
|
<field name="category_id" ref="base.module_category_usability"/> |
||||
|
</record> |
||||
|
<record id="group_project_category" model="res.groups"> |
||||
|
<field name="name">access project category menu</field> |
||||
|
<field name="category_id" ref="base.module_category_usability"/> |
||||
|
</record> |
||||
|
</odoo> |
|
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 310 B |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 576 B |
After Width: | Height: | Size: 733 B |
After Width: | Height: | Size: 911 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 673 B |
After Width: | Height: | Size: 878 B |
After Width: | Height: | Size: 653 B |
After Width: | Height: | Size: 905 B |
After Width: | Height: | Size: 839 B |
After Width: | Height: | Size: 427 B |
After Width: | Height: | Size: 627 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 988 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 4.4 KiB |
After Width: | Height: | Size: 589 B |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 967 B |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 5.0 KiB |
After Width: | Height: | Size: 84 KiB |
After Width: | Height: | Size: 80 KiB |
After Width: | Height: | Size: 45 KiB |
After Width: | Height: | Size: 91 KiB |
After Width: | Height: | Size: 90 KiB |
After Width: | Height: | Size: 85 KiB |
After Width: | Height: | Size: 642 KiB |
After Width: | Height: | Size: 118 KiB |
After Width: | Height: | Size: 73 KiB |
After Width: | Height: | Size: 79 KiB |
After Width: | Height: | Size: 82 KiB |
After Width: | Height: | Size: 104 KiB |
After Width: | Height: | Size: 115 KiB |
After Width: | Height: | Size: 77 KiB |
After Width: | Height: | Size: 159 KiB |
After Width: | Height: | Size: 118 KiB |
After Width: | Height: | Size: 74 KiB |
After Width: | Height: | Size: 147 KiB |
After Width: | Height: | Size: 226 KiB |
After Width: | Height: | Size: 211 KiB |
After Width: | Height: | Size: 117 KiB |
After Width: | Height: | Size: 81 KiB |
After Width: | Height: | Size: 154 KiB |
After Width: | Height: | Size: 117 KiB |
After Width: | Height: | Size: 80 KiB |
After Width: | Height: | Size: 81 KiB |
After Width: | Height: | Size: 150 KiB |
After Width: | Height: | Size: 134 KiB |
After Width: | Height: | Size: 79 KiB |
After Width: | Height: | Size: 116 KiB |
After Width: | Height: | Size: 88 KiB |
After Width: | Height: | Size: 122 KiB |
After Width: | Height: | Size: 86 KiB |
After Width: | Height: | Size: 198 KiB |