started on module bemade_document_versions.
This commit is contained in:
parent
1379fe609d
commit
f0f92cf483
12 changed files with 207 additions and 12 deletions
2
bemade_document_versions/__init__.py
Normal file
2
bemade_document_versions/__init__.py
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
from . import models
|
||||
|
||||
31
bemade_document_versions/__manifest__.py
Normal file
31
bemade_document_versions/__manifest__.py
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
#
|
||||
# Bemade Inc.
|
||||
#
|
||||
# Copyright (C) September 2023 Bemade Inc. (<https://www.bemade.org>).
|
||||
# Author: Marc Durepos (Contact : marc@bemade.org)
|
||||
#
|
||||
# This program is under the terms of the Odoo Proprietary License v1.0 (OPL-1)
|
||||
# It is forbidden to publish, distribute, sublicense, or sell copies of the Software
|
||||
# or modified copies of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
{
|
||||
'name': 'Document Versions',
|
||||
'version': '15.0.1.0.0',
|
||||
'summary': 'Adds document revisions alongside Documents',
|
||||
'category': 'Document Management',
|
||||
'author': 'Bemade Inc.',
|
||||
'website': 'https://www.bemade.org',
|
||||
'license': 'OPL-1',
|
||||
'depends': ['documents', 'mail'],
|
||||
'data': [],
|
||||
'installable': True,
|
||||
'auto_install': False,
|
||||
}
|
||||
12
bemade_document_versions/data/document_revision_data.xml
Normal file
12
bemade_document_versions/data/document_revision_data.xml
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<odoo>
|
||||
<data>
|
||||
<record model="documents.revision.sequence" id="document_revision_sequence_default">
|
||||
<field name="name">Default Document Revision Sequence</field>
|
||||
<field name="code">document.revision</field>
|
||||
<field name="implementation">standard</field>
|
||||
<field name="prefix">DOC/</field>
|
||||
<field name="padding">2</field>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
3
bemade_document_versions/models/__init__.py
Normal file
3
bemade_document_versions/models/__init__.py
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
from . import document_revision
|
||||
from . import document
|
||||
from . import document_sequence
|
||||
70
bemade_document_versions/models/document.py
Normal file
70
bemade_document_versions/models/document.py
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
from odoo import models, fields, _, api, Command
|
||||
from odoo.exceptions import ValidationError
|
||||
|
||||
|
||||
class Document(models.Model):
|
||||
_inherit = ['documents.document']
|
||||
|
||||
current_revision_id = fields.Many2one('documents.revision', 'Current Revision')
|
||||
revision_ids = fields.One2many('documents.revision', 'document_id')
|
||||
revision_sequence = fields.Many2one('documents.revision.sequence', 'document_id',
|
||||
'Revision Sequence', )
|
||||
track_revisions = fields.Boolean(default=False)
|
||||
# set copy=False for number_next
|
||||
number_next = fields.Integer(string='Next Number', required=True, default=1,
|
||||
copy=False, help="Next number of this sequence")
|
||||
|
||||
@api.constrains('revision_ids', 'revision_sequence', 'track_revisions')
|
||||
def constrain_revisions(self):
|
||||
for rec in self:
|
||||
revision_fields = [rec.revision_ids, rec.revision_sequence,
|
||||
rec.track_revisions]
|
||||
if any(revision_fields) and not all(revision_fields):
|
||||
raise ValidationError(_('A revision sequence must be selected to track'
|
||||
' revisions.'))
|
||||
|
||||
def write(self, vals):
|
||||
super().write(vals)
|
||||
if self.track_revisions and 'track_revisions' in vals \
|
||||
and not vals['track_revisions']:
|
||||
raise ValidationError(_('Revision tracking cannot be disabled after it has'
|
||||
'been turned on for a document.'))
|
||||
self._check_revision_fields()
|
||||
|
||||
@api.model_create_multi
|
||||
def create(self, vals):
|
||||
res = super().create(vals)
|
||||
for rec in res:
|
||||
rec._check_revision_fields()
|
||||
return res
|
||||
|
||||
def _check_revision_fields(self):
|
||||
""" Helper method to check that all three fields `track_revisions`,
|
||||
`revisions_sequence` and `revision_ids` are properly set if any one of them is set.
|
||||
:return: None
|
||||
"""
|
||||
self.ensure_one()
|
||||
revision_fields = [self.revision_ids, self.revision_sequence,
|
||||
self.track_revisions]
|
||||
if any(revision_fields) and not all(revision_fields):
|
||||
self._set_up_revisions()
|
||||
|
||||
def _set_up_revisions(self):
|
||||
"""
|
||||
Helper method to set up revisions, no matter how we got into tracking them.
|
||||
:return: None
|
||||
"""
|
||||
self.ensure_one()
|
||||
self.track_revisions = True # may already be true, but no matter
|
||||
self.revision_sequence = self.revision_sequence or self.env.ref(
|
||||
'bemade_document_versions.document_revision_sequence_default')
|
||||
self.revision_ids = self.revision_ids or Command.set(
|
||||
[self._create_first_revision()])
|
||||
|
||||
def _create_first_revision(self):
|
||||
"""
|
||||
Creates a new documents.revision record to associate to this Document
|
||||
:return: a single, new documents.revision record
|
||||
"""
|
||||
self.ensure_one()
|
||||
return self.env['documents.revision'].create({'document_id': self.id, })
|
||||
23
bemade_document_versions/models/document_revision.py
Normal file
23
bemade_document_versions/models/document_revision.py
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
from odoo import models, fields, _, api
|
||||
|
||||
|
||||
class DocumentRevision(models.Model):
|
||||
_name = "documents.revision"
|
||||
_description = "Document Revision"
|
||||
|
||||
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):
|
||||
res = super().create(vals_list)
|
||||
for rec in res:
|
||||
# When we create a new revision, we need to replace the attachment linked
|
||||
# to the document to keep it on the latest version.
|
||||
rec.document_id.attachment_id = rec.attachment_id
|
||||
# Then we update the current revision to this new revision and link
|
||||
# back to the previous revisions
|
||||
rec.previous_revision_id = rec.document_id.current_revision_id
|
||||
rec.document_id.current_revision_id = rec
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
from odoo import models, fields, api, _
|
||||
|
||||
|
||||
class DocumentRevisionSequence(models.Model):
|
||||
""" Creates an independent sequence for each Document when the document is set to
|
||||
track
|
||||
"""
|
||||
_name = 'documents.revision.sequence'
|
||||
_inherit = 'ir.sequence'
|
||||
|
||||
document_id = fields.Many2one('documents.document', 'Document', ondelete='cascade')
|
||||
19
bemade_document_versions/wizard/document_revision_wizard.py
Normal file
19
bemade_document_versions/wizard/document_revision_wizard.py
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
from odoo import models, fields, _
|
||||
from odoo.exceptions import UserError
|
||||
|
||||
|
||||
class DocumentRevisionWizard(models.TransientModel):
|
||||
_name = 'documents.revision.wizard'
|
||||
_description = 'Allows the creation of new document revisions'
|
||||
|
||||
document_id = fields.Many2one('documents.document', 'Document')
|
||||
file = fields.Binary('File to upload')
|
||||
revision_name = fields.Char()
|
||||
|
||||
def default_get(self, fields_list):
|
||||
ctx = self._context
|
||||
if 'active_ids' in ctx and len(ctx.get('active_ids')) > 1:
|
||||
raise UserError(_('You can only create revisions for one document at a time.'))
|
||||
if 'active_id' not in ctx:
|
||||
raise UserError(_('You must select a document for which you are creating a revision.'))
|
||||
self.document_id = self.env['documents.document'].browse(ctx.get('active_id'))
|
||||
11
bemade_project_documents/data/mail_templates.xml
Normal file
11
bemade_project_documents/data/mail_templates.xml
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<odoo>
|
||||
<data>
|
||||
<record id="mail_template_document_approval_request" model="mail.template">
|
||||
<field name="name">Document Approval Request</field>
|
||||
<field name="model_id" ref="model_documents_document"/>
|
||||
<field name="subject">Document Approval Request {{ object.name != False and ': ' + object.name or '' }} </field>
|
||||
<field name="email_to">{{ }}</field>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
|
|
@ -5,3 +5,4 @@ class Document(models.Model):
|
|||
_inherit = 'documents.document'
|
||||
|
||||
external_approver_ids = fields.Many2many('res.partner')
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,24 @@
|
|||
from odoo import models, fields, api
|
||||
from odoo import models, fields, api, _
|
||||
from odoo.exceptions import ValidationError
|
||||
|
||||
|
||||
class RequestDocumentApprovalsWizard(models.TransientModel):
|
||||
_name = 'project_documents.approval.wizard'
|
||||
|
||||
document_ids = fields.Many2many('documents.document', string='Documents')
|
||||
partner_ids = fields.Many2many('res.partner')
|
||||
partner_ids = fields.Many2many('res.partner', string="Recipients",
|
||||
help="""Contacts who will receive a request to
|
||||
approve the document.""")
|
||||
request_template = fields.Many2one('mail.template')
|
||||
|
||||
def default_get(self, fields_list):
|
||||
if 'request_template' not in fields_list:
|
||||
self.request_template = self.env.ref()
|
||||
|
||||
def request_approvals(self):
|
||||
pass
|
||||
self._validate_partners_have_emails()
|
||||
|
||||
def _validate_partners_have_emails(self):
|
||||
for wizard in self:
|
||||
if any([not p.email for p in wizard.partner_ids]):
|
||||
raise ValidationError(_('Each partner must have an email address.'))
|
||||
|
|
|
|||
|
|
@ -15,21 +15,17 @@
|
|||
<field name="model">project_documents.approval.wizard</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<!-- TODO: Add field labels -->
|
||||
<sheet>
|
||||
<field name="partner_ids" domain="[('is_company', '=', True)]">
|
||||
<label for="partner_ids"/>
|
||||
<field name="partner_ids" domain="[('is_company', '=', False)]">
|
||||
<tree editable="bottom">
|
||||
<field name="name" colspan="3"/>
|
||||
<field name="email"/>
|
||||
<field name="title"/>
|
||||
</tree>
|
||||
</field>
|
||||
<field name="document_ids">
|
||||
<!-- TODO: Add a domain to restrict to context domain -->
|
||||
<tree>
|
||||
<field name="name"/>
|
||||
</tree>
|
||||
</field>
|
||||
<label for="document_ids"/>
|
||||
<field name="document_ids" readonly="True"/>
|
||||
<footer>
|
||||
<button name="request_approvals" type="object"
|
||||
string="Request" class="btn btn-primary"/>
|
||||
|
|
@ -45,7 +41,10 @@
|
|||
<field name="res_model">project_documents.approval.wizard</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="context">{
|
||||
'form_view_ref': 'bemade_project_documents.documents_request_approval_form_view'}</field>
|
||||
'form_view_ref': 'bemade_project_documents.documents_request_approval_form_view',
|
||||
'default_res_model': context.get('default_res_model', False),
|
||||
'default_res_id': context.get('default_res_id', False)
|
||||
}</field>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
</data>
|
||||
|
|
|
|||
Loading…
Reference in a new issue