Further work on sequences and wizard.

This commit is contained in:
Marc Durepos 2023-10-18 08:57:01 -04:00
parent a987afd5d3
commit 6e85c8655f
5 changed files with 62 additions and 23 deletions

View file

@ -5,11 +5,37 @@ from odoo.exceptions import ValidationError
class Document(models.Model):
_inherit = 'documents.document'
""" In order to implement named revisions, we hook into the already-existing version
tracking that documents.document records implement. The field previous_attachmen_ids
is already used to contain ir.attachment records that have been replaced after a
write call. What we are adding here is the concept of tying a revision number/name
to the current revision and keeping track of the same thing for previous revisions.
This is implemented in the documents.revision record.
"""
current_revision_id = fields.Many2one('documents.revision', 'Current Revision')
revision_ids = fields.One2many('documents.revision', 'document_id')
revision_sequence = fields.Many2one('ir.sequence',
'Revision Sequence', )
def write(self, vals):
# When a document already has an attachment and we are passed a new
# attachment_id in vals, we need to update the revision at least for the
# current revision and maybe for the one that was superseded.
recs_to_update = self.filtered(lambda r: r.attachment_id)
super().write(vals)
if 'attachment_id' in vals:
recs_to_update.update_revision()
def update_revision(self):
for rec in self:
if not rec.revision_sequence:
rec.set_up_revisions()
# TODO : finish writing this method
def set_up_revisions(self, initial_revision_name: str = None,
sequence_prefix: str = None,
sequence_suffix: str = None, sequence_padding: int = None):
@ -25,7 +51,8 @@ class Document(models.Model):
self.revision_sequence = self.revision_sequence or self._create_rev_sequence(
sequence_prefix, sequence_suffix, sequence_padding)
self.revision_ids = self.revision_ids or [Command.set(
[self._create_first_revision(initial_revision_name).id])]
[self._create_first_revision().id])]
def _create_rev_sequence(self, sequence_prefix: str = None,
sequence_suffix: str = None, sequence_padding: int = None):
@ -47,7 +74,8 @@ class Document(models.Model):
'implementation': 'standard',
})
def _create_first_revision(self, name: str = None):
def _create_first_revision(self):
"""
Creates a new documents.revision record to associate to this Document
@ -55,16 +83,17 @@ class Document(models.Model):
:return: a single, new documents.revision record
"""
self.ensure_one()
name = name or self.revision_sequence.get_next_char(0)
name = self.revision_sequence.next_by_id()
return self.env['documents.revision'].create({
'document_id': self.id,
'name': name,
'attachment_id': self.attachment_id.id,
})
def get_next_revision_name(self):
"""
:return str: The name of the next revision in the sequence or None if revision
tracking is not yet set up.
"""
return self.revision_sequence.get_next_char(self.revision_sequence._next())
return self.revision_sequence.predict_next_id()

View file

@ -11,8 +11,6 @@ class DocumentRevision(models.Model):
name = fields.Char()
document_id = fields.Many2one('documents.document', required=True)
attachment_id = fields.Many2one('ir.attachment', required=True)
previous_revision_id = fields.Many2one('documents.revision', 'Previous Revision')
next_revision_id = fields.One2many('documents.revision', 'previous_revision_id')
@api.model_create_multi
def create(self, vals_list):

View file

@ -1,6 +1,4 @@
from odoo import models, fields, api, _
from odoo.exceptions import UserError
class DocumentRevisionSequence(models.Model):
_inherit = 'ir.sequence'
@ -10,3 +8,13 @@ class DocumentRevisionSequence(models.Model):
document_id = fields.Many2one('documents.document', 'Document',
ondelete='cascade')
def predict_next_id(self, sequence_date=None):
self.check_access_rights('read')
return self._predict_next(sequence_date=sequence_date)
def _predict_next(self, sequence_date=None):
if not self.use_date_range:
return self.get_next_char(self.number_next_actual)
raise NotImplementedError(
_('_predict_next is not implemented for date sequences.'))

View file

@ -9,14 +9,14 @@ class DocumentRevisionWizard(models.TransientModel):
document_id = fields.Many2one('documents.document', 'Document')
document_name = fields.Char()
file = fields.Binary('File to upload')
revision_name = fields.Char(required=True)
revision_sequence_prefix = fields.Char(string='Sequence Prefix')
revision_sequence_suffix = fields.Char(string='Sequence Suffix')
revision_sequence_padding = fields.Integer(string='Sequence Padding',
help="Number of digits to show in the"
" sequence number. A value of 2 will"
" generate sequence numbers like 01,"
" 02, 03, etc.")
revision_name = fields.Char(required=True, readonly=True)
revision_sequence = fields.Many2one('ir.sequence', required=True)
revision_sequence_prefix = fields.Char(related='revision_sequence.prefix',
readonly=False)
revision_sequence_suffix = fields.Char(related='revision_sequence.suffix',
readonly=False)
revision_sequence_padding = fields.Integer(related='revision_sequence.padding',
readonly=False)
def default_get(self, fields_list):
ctx = self._context
@ -30,7 +30,7 @@ class DocumentRevisionWizard(models.TransientModel):
sequence = document.revision_sequence or self.env.ref(
'bemade_document_versions.document_revision_sequence_default')
if document.revision_sequence:
vals['revision_name'] = self.document_id.get_next_revision_name()
vals['revision_name'] = document.get_next_revision_name()
else:
vals['revision_name'] = sequence.get_next_char(0)
vals['revision_sequence_prefix'] = sequence.prefix
@ -38,12 +38,17 @@ class DocumentRevisionWizard(models.TransientModel):
vals['revision_sequence_padding'] = sequence.padding
return vals
@api.depends('document_id', 'document_id.revision_sequence',
'revision_sequence')
def action_upload_revision(self):
for wizard in self:
if not wizard.file:
raise UserError(_('You must upload a file.'))
if not wizard.revision_name:
raise UserError(_('Revision name cannot be empty.'))
wizard.revision_sequence.write({
'prefix': wizard.revision_sequence_prefix,
'suffix': wizard.revision_sequence_suffix,
'padding': wizard.revision_sequence_padding,
})
prev_attachment = wizard.document_id.attachment_id
attachment = self.env['ir.attachment'].with_context(
{'no_document': True}).create({
@ -55,14 +60,13 @@ class DocumentRevisionWizard(models.TransientModel):
'public': prev_attachment.public,
})
if not wizard.document_id.revision_sequence:
wizard.document_id.set_up_revisions(wizard.revision_name,
wizard.revision_sequence_prefix,
wizard.document_id.set_up_revisions(wizard.revision_sequence_prefix,
wizard.revision_sequence_suffix,
wizard.revision_sequence_padding)
else:
self.env['documents.revision'].create({
'document_id': wizard.document_id.id,
'attachment_id': attachment.id,
'name': wizard.revision_name,
'name': wizard.document_id.revision_sequence.next_by_id(),
'attachment_id': attachment.id,
})

View file

@ -14,4 +14,4 @@ class Document(models.Model):
""" Return the action used to display documents when returning from customer
portal."""
self.ensure_one()
return self.env.ref('documents.document_action')
return self.env.ref('documents.document_action')