Browse Source

Jun 23: [FIX] Bug Fixed 'project_task_sequence_number'

pull/313/merge
Cybrosys Technologies 3 months ago
parent
commit
3591fe96ef
  1. 4
      project_task_sequence_number/__manifest__.py
  2. 5
      project_task_sequence_number/doc/RELEASE_NOTES.md
  3. 103
      project_task_sequence_number/models/project_task.py
  4. BIN
      project_task_sequence_number/static/description/assets/screenshots/img.png
  5. BIN
      project_task_sequence_number/static/description/assets/screenshots/task7.png
  6. 20
      project_task_sequence_number/static/description/index.html

4
project_task_sequence_number/__manifest__.py

@ -21,7 +21,7 @@
############################################################################### ###############################################################################
{ {
'name': 'Project & Project Task Sequence Number', 'name': 'Project & Project Task Sequence Number',
'version': '17.0.1.0.0', 'version': '17.0.1.0.1',
'category': 'Project', 'category': 'Project',
'summary': 'Add dynamic sequence number for project and task.', 'summary': 'Add dynamic sequence number for project and task.',
'description': 'This helps to give unique sequence number to project and ' 'description': 'This helps to give unique sequence number to project and '
@ -35,7 +35,7 @@
'data': [ 'data': [
'data/ir_sequence_data.xml', 'data/ir_sequence_data.xml',
'views/project_project_views.xml', 'views/project_project_views.xml',
'views/project_task_views.xml' 'views/project_task_views.xml',
], ],
'images': ['static/description/banner.jpg'], 'images': ['static/description/banner.jpg'],
'license': 'AGPL-3', 'license': 'AGPL-3',

5
project_task_sequence_number/doc/RELEASE_NOTES.md

@ -3,3 +3,8 @@
#### Version 17.0.1.0.0 #### Version 17.0.1.0.0
#### ADD #### ADD
- Initial commit for Project & Project Task Sequence Number - Initial commit for Project & Project Task Sequence Number
#### 18.06.2025
#### Version 17.0.1.0.1
#### BUG FIX
- Added a sequence for sub-tasks also.

103
project_task_sequence_number/models/project_task.py

@ -19,62 +19,67 @@
# If not, see <http://www.gnu.org/licenses/>. # If not, see <http://www.gnu.org/licenses/>.
# #
############################################################################### ###############################################################################
from odoo import api, fields, models
from odoo import api, fields, models
#
#
class ProjectTask(models.Model): class ProjectTask(models.Model):
"""In ProjectTask class, which will add a new field for task sequence.
When we create the record, the sequence will be based on the
task_sequence."""
_inherit = 'project.task' _inherit = 'project.task'
task_sequence = fields.Char(string='Task Sequence', readonly=True, task_sequence = fields.Char(string='Task Sequence', readonly=True, copy=False, default='New',
copy=False, default='New', help='Hierarchical sequence number of the task.')
help='Unique sequence number of the task.')
@api.model_create_multi @api.model_create_multi
def create(self, vals): def create(self, vals_list):
"""Overwrite the function create to calculate the sequence value based tasks = super(ProjectTask, self).create(vals_list)
on the given prefix""" for task in tasks:
for records in vals: task.with_context(bypass_sequence=True)._compute_custom_sequence()
if not records['project_id']: return tasks
if records.get('task_sequence', 'New') == 'New':
records['task_sequence'] = self.env['ir.sequence']. \
next_by_code(
'project.task') or 'New'
else:
project = self.env['project.project'].browse(
records['project_id'])
if project.task_sequence_id.prefix:
records['task_sequence'] = '%s/%s/%s' % \
(project.project_sequence,
project.task_sequence_id.prefix,
self.env['ir.sequence'].
next_by_code('project.task') or
'New')
else:
records['task_sequence'] = '%s/%s' % \
(project.project_sequence,
self.env['ir.sequence'].
next_by_code(
'project.task') or
'New')
return super(ProjectTask, self).create(records)
def write(self, vals): def write(self, vals):
"""Overwrite the function to update the sequence """ result = super(ProjectTask, self).write(vals)
if vals.get('project_id'): if not self.env.context.get('bypass_sequence'):
project = self.env['project.project'].browse(vals.get( for task in self:
'project_id')) task.with_context(bypass_sequence=True)._compute_custom_sequence()
if project.task_sequence_id.prefix: return result
vals['task_sequence'] = '%s/%s/%s' % \
(project.project_sequence, def _compute_custom_sequence(self):
project.task_sequence_id.prefix, for task in self:
self.env['ir.sequence'].next_by_code( task_seq = self.env['ir.sequence'].next_by_code('project.task') or 'New'
'project.task') or 'New')
if not task.project_id or not task.project_id.project_sequence:
continue # Skip if missing project data
if task.parent_id:
parent_seq = task.parent_id.task_sequence or task.parent_id.name
subtask_number = task._get_sibling_count(task.parent_id)
# Use sub-task name if provided
# subtask_name = (task.name or '').split(',')[0].strip()
# if subtask_name:
# sequence = f"{parent_seq}/{subtask_name}"
# else:
sequence = f"{parent_seq}/Sub Task {subtask_number}"
else: else:
vals['task_sequence'] = '%s/%s' % \ task_number = task._get_task_count(task.project_id)
(project.project_sequence, formatted_task_number = str(task_number).zfill(4)
self.env['ir.sequence'].
next_by_code('project.task') or 'New') sequence = self.env['ir.sequence'].search([('code', '=', 'project.task')], limit=1)
return super(ProjectTask, self).write(vals) task_prefix = sequence.prefix if sequence else ''
sequence = f"{task.project_id.project_sequence}-{task_prefix}{formatted_task_number}"
# Avoid recursion
task.sudo().write({'task_sequence': sequence})
def _get_task_count(self, project):
return self.search_count([
('project_id', '=', project.id),
('parent_id', '=', False)
])
def _get_sibling_count(self, parent_task):
return self.search_count([
('parent_id', '=', parent_task.id),
('id', '!=', self.id)
]) + 1

BIN
project_task_sequence_number/static/description/assets/screenshots/img.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

BIN
project_task_sequence_number/static/description/assets/screenshots/task7.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

20
project_task_sequence_number/static/description/index.html

@ -212,7 +212,8 @@
We can specify 'Prefix' of the task.</h4> We can specify 'Prefix' of the task.</h4>
</div> </div>
</div> </div>
</div><div class="col-lg-12 py-2" </div>
<div class="col-lg-12 py-2"
style="padding: 1rem 4rem !important;"> style="padding: 1rem 4rem !important;">
<div <div
style="border: 1px solid #d8d6d6; border-radius: 4px; background: #fff; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);"> style="border: 1px solid #d8d6d6; border-radius: 4px; background: #fff; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);">
@ -229,6 +230,23 @@
</div> </div>
</div> </div>
</div> </div>
<div class="col-lg-12 py-2"
style="padding: 1rem 4rem !important;">
<div
style="border: 1px solid #d8d6d6; border-radius: 4px; background: #fff; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);">
<div class="row justify-content-center p-3 w-100 m-0">
<img src="assets/screenshots/task7.png"
class="img-responsive" width="100%"
height="auto">
</div>
<div class="px-3">
<h4 class="mt-2"
style=" font-weight:600 !important; color:#282F33 !important; font-size:1.3rem !important">
When a sub-task is created, the sequence should be</h4>
</div>
</div>
</div>
</div> </div>
<div id="tab2" class="tab-pane fade"> <div id="tab2" class="tab-pane fade">
<div class="col-mg-12" style="padding: 1rem 4rem;"> <div class="col-mg-12" style="padding: 1rem 4rem;">

Loading…
Cancel
Save