Further work on sequences and wizard.
This commit is contained in:
parent
a987afd5d3
commit
6e85c8655f
5 changed files with 62 additions and 23 deletions
|
|
@ -5,11 +5,37 @@ from odoo.exceptions import ValidationError
|
||||||
class Document(models.Model):
|
class Document(models.Model):
|
||||||
_inherit = 'documents.document'
|
_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')
|
current_revision_id = fields.Many2one('documents.revision', 'Current Revision')
|
||||||
revision_ids = fields.One2many('documents.revision', 'document_id')
|
revision_ids = fields.One2many('documents.revision', 'document_id')
|
||||||
revision_sequence = fields.Many2one('ir.sequence',
|
revision_sequence = fields.Many2one('ir.sequence',
|
||||||
'Revision 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,
|
def set_up_revisions(self, initial_revision_name: str = None,
|
||||||
sequence_prefix: str = None,
|
sequence_prefix: str = None,
|
||||||
sequence_suffix: str = None, sequence_padding: int = 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(
|
self.revision_sequence = self.revision_sequence or self._create_rev_sequence(
|
||||||
sequence_prefix, sequence_suffix, sequence_padding)
|
sequence_prefix, sequence_suffix, sequence_padding)
|
||||||
self.revision_ids = self.revision_ids or [Command.set(
|
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,
|
def _create_rev_sequence(self, sequence_prefix: str = None,
|
||||||
sequence_suffix: str = None, sequence_padding: int = None):
|
sequence_suffix: str = None, sequence_padding: int = None):
|
||||||
|
|
@ -47,7 +74,8 @@ class Document(models.Model):
|
||||||
'implementation': 'standard',
|
'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
|
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
|
:return: a single, new documents.revision record
|
||||||
"""
|
"""
|
||||||
self.ensure_one()
|
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({
|
return self.env['documents.revision'].create({
|
||||||
'document_id': self.id,
|
'document_id': self.id,
|
||||||
'name': name,
|
'name': name,
|
||||||
'attachment_id': self.attachment_id.id,
|
'attachment_id': self.attachment_id.id,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
def get_next_revision_name(self):
|
def get_next_revision_name(self):
|
||||||
"""
|
"""
|
||||||
:return str: The name of the next revision in the sequence or None if revision
|
:return str: The name of the next revision in the sequence or None if revision
|
||||||
tracking is not yet set up.
|
tracking is not yet set up.
|
||||||
"""
|
"""
|
||||||
return self.revision_sequence.get_next_char(self.revision_sequence._next())
|
return self.revision_sequence.predict_next_id()
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,6 @@ class DocumentRevision(models.Model):
|
||||||
name = fields.Char()
|
name = fields.Char()
|
||||||
document_id = fields.Many2one('documents.document', required=True)
|
document_id = fields.Many2one('documents.document', required=True)
|
||||||
attachment_id = fields.Many2one('ir.attachment', 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
|
@api.model_create_multi
|
||||||
def create(self, vals_list):
|
def create(self, vals_list):
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,4 @@
|
||||||
from odoo import models, fields, api, _
|
from odoo import models, fields, api, _
|
||||||
from odoo.exceptions import UserError
|
|
||||||
|
|
||||||
|
|
||||||
class DocumentRevisionSequence(models.Model):
|
class DocumentRevisionSequence(models.Model):
|
||||||
_inherit = 'ir.sequence'
|
_inherit = 'ir.sequence'
|
||||||
|
|
@ -10,3 +8,13 @@ class DocumentRevisionSequence(models.Model):
|
||||||
|
|
||||||
document_id = fields.Many2one('documents.document', 'Document',
|
document_id = fields.Many2one('documents.document', 'Document',
|
||||||
ondelete='cascade')
|
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.'))
|
||||||
|
|
|
||||||
|
|
@ -9,14 +9,14 @@ class DocumentRevisionWizard(models.TransientModel):
|
||||||
document_id = fields.Many2one('documents.document', 'Document')
|
document_id = fields.Many2one('documents.document', 'Document')
|
||||||
document_name = fields.Char()
|
document_name = fields.Char()
|
||||||
file = fields.Binary('File to upload')
|
file = fields.Binary('File to upload')
|
||||||
revision_name = fields.Char(required=True)
|
revision_name = fields.Char(required=True, readonly=True)
|
||||||
revision_sequence_prefix = fields.Char(string='Sequence Prefix')
|
revision_sequence = fields.Many2one('ir.sequence', required=True)
|
||||||
revision_sequence_suffix = fields.Char(string='Sequence Suffix')
|
revision_sequence_prefix = fields.Char(related='revision_sequence.prefix',
|
||||||
revision_sequence_padding = fields.Integer(string='Sequence Padding',
|
readonly=False)
|
||||||
help="Number of digits to show in the"
|
revision_sequence_suffix = fields.Char(related='revision_sequence.suffix',
|
||||||
" sequence number. A value of 2 will"
|
readonly=False)
|
||||||
" generate sequence numbers like 01,"
|
revision_sequence_padding = fields.Integer(related='revision_sequence.padding',
|
||||||
" 02, 03, etc.")
|
readonly=False)
|
||||||
|
|
||||||
def default_get(self, fields_list):
|
def default_get(self, fields_list):
|
||||||
ctx = self._context
|
ctx = self._context
|
||||||
|
|
@ -30,7 +30,7 @@ class DocumentRevisionWizard(models.TransientModel):
|
||||||
sequence = document.revision_sequence or self.env.ref(
|
sequence = document.revision_sequence or self.env.ref(
|
||||||
'bemade_document_versions.document_revision_sequence_default')
|
'bemade_document_versions.document_revision_sequence_default')
|
||||||
if document.revision_sequence:
|
if document.revision_sequence:
|
||||||
vals['revision_name'] = self.document_id.get_next_revision_name()
|
vals['revision_name'] = document.get_next_revision_name()
|
||||||
else:
|
else:
|
||||||
vals['revision_name'] = sequence.get_next_char(0)
|
vals['revision_name'] = sequence.get_next_char(0)
|
||||||
vals['revision_sequence_prefix'] = sequence.prefix
|
vals['revision_sequence_prefix'] = sequence.prefix
|
||||||
|
|
@ -38,12 +38,17 @@ class DocumentRevisionWizard(models.TransientModel):
|
||||||
vals['revision_sequence_padding'] = sequence.padding
|
vals['revision_sequence_padding'] = sequence.padding
|
||||||
return vals
|
return vals
|
||||||
|
|
||||||
|
@api.depends('document_id', 'document_id.revision_sequence',
|
||||||
|
'revision_sequence')
|
||||||
def action_upload_revision(self):
|
def action_upload_revision(self):
|
||||||
for wizard in self:
|
for wizard in self:
|
||||||
if not wizard.file:
|
if not wizard.file:
|
||||||
raise UserError(_('You must upload a file.'))
|
raise UserError(_('You must upload a file.'))
|
||||||
if not wizard.revision_name:
|
wizard.revision_sequence.write({
|
||||||
raise UserError(_('Revision name cannot be empty.'))
|
'prefix': wizard.revision_sequence_prefix,
|
||||||
|
'suffix': wizard.revision_sequence_suffix,
|
||||||
|
'padding': wizard.revision_sequence_padding,
|
||||||
|
})
|
||||||
prev_attachment = wizard.document_id.attachment_id
|
prev_attachment = wizard.document_id.attachment_id
|
||||||
attachment = self.env['ir.attachment'].with_context(
|
attachment = self.env['ir.attachment'].with_context(
|
||||||
{'no_document': True}).create({
|
{'no_document': True}).create({
|
||||||
|
|
@ -55,14 +60,13 @@ class DocumentRevisionWizard(models.TransientModel):
|
||||||
'public': prev_attachment.public,
|
'public': prev_attachment.public,
|
||||||
})
|
})
|
||||||
if not wizard.document_id.revision_sequence:
|
if not wizard.document_id.revision_sequence:
|
||||||
wizard.document_id.set_up_revisions(wizard.revision_name,
|
wizard.document_id.set_up_revisions(wizard.revision_sequence_prefix,
|
||||||
wizard.revision_sequence_prefix,
|
|
||||||
wizard.revision_sequence_suffix,
|
wizard.revision_sequence_suffix,
|
||||||
wizard.revision_sequence_padding)
|
wizard.revision_sequence_padding)
|
||||||
else:
|
else:
|
||||||
self.env['documents.revision'].create({
|
self.env['documents.revision'].create({
|
||||||
'document_id': wizard.document_id.id,
|
'document_id': wizard.document_id.id,
|
||||||
'attachment_id': attachment.id,
|
'attachment_id': attachment.id,
|
||||||
'name': wizard.revision_name,
|
'name': wizard.document_id.revision_sequence.next_by_id(),
|
||||||
'attachment_id': attachment.id,
|
'attachment_id': attachment.id,
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -14,4 +14,4 @@ class Document(models.Model):
|
||||||
""" Return the action used to display documents when returning from customer
|
""" Return the action used to display documents when returning from customer
|
||||||
portal."""
|
portal."""
|
||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
return self.env.ref('documents.document_action')
|
return self.env.ref('documents.document_action')
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue