Skip to content

Commit

Permalink
IMP: make the check-in function control the layout update status
Browse files Browse the repository at this point in the history
  • Loading branch information
mboscolo committed Oct 16, 2023
1 parent e1911c1 commit 138b868
Show file tree
Hide file tree
Showing 9 changed files with 180 additions and 24 deletions.
2 changes: 1 addition & 1 deletion activity_validation/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
##############################################################################
{
"name": "Activity Validation",
"version": "16.0.1",
"version": "16.0.2",
"author": "OmniaSolutions",
"website": "https://github.com/OmniaGit/odooplm",
"category": "Custom",
Expand Down
3 changes: 2 additions & 1 deletion activity_validation/models/product_product.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ def search_read(self, domain=None, fields=None, offset=0, limit=None, order=None
def get_user_activities(self, ids_to_read=[]):
activity = self.env['mail.activity']
act_filter = [
('activity_type_id', '=', self.env.ref('plm.mail_activity_plm_activity').id),
('activity_type_id', 'in', [self.env.ref('plm.mail_activity_plm_activity').id,
self.env.ref('plm.mail_activity_check_out_request').id]),
('user_id', '=', self.env.uid),
('plm_state', 'not in', [False, 'done', 'cancel'])
]
Expand Down
4 changes: 3 additions & 1 deletion plm/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
##############################################################################
{
"name": "Product Lifecycle Management",
"version": "16.0.21",
"version": "16.0.22",
"author": "OmniaSolutions",
"website": "https://odooplm.omniasolutions.website",
"category": "Manufacturing/Product Lifecycle Management (PLM)",
Expand All @@ -31,6 +31,8 @@
"images": ["static/img/odoo_plm.png"],
"depends": ["base", "board", "product", "mrp"],
"data": [
# data
"data/data.xml",
# security
"security/base_plm_security.xml",
# views
Expand Down
14 changes: 14 additions & 0 deletions plm/data/data.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<record id="mail_activity_check_out_request" model="mail.activity.type">
<field name="name">Check-Out Request</field>
<field name="icon">fa-mail-reply</field>
<field name="sequence">3</field>
<field name="res_model">ir.attachment</field>
<field name="sequence">200</field>
<field name="change_activity_type">request</field>
</record>

</data>
</odoo>
117 changes: 106 additions & 11 deletions plm/models/ir_attachment.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,19 @@ class IrAttachment(models.Model):
default=False)
library_path = fields.Char("File library path")

must_update_from_cad = fields.Boolean("Must Update form CAD",
compute="_compute_must_update_from_cad",
help="""When this flag is enabled the 2d document must be updated in order to guaranteey the update betwin 2d and 3d document""")

def _compute_must_update_from_cad(self):
ir_attachment_relation = self.env['ir.attachment.relation']
for ir_attachment in self:
ir_attachment.must_update_from_cad=False
if ir_attachment.document_type =='2d':
ir_attachment.must_update_from_cad=ir_attachment_relation.is_2d_ok(ir_attachment)
if ir_attachment.document_type =='pr':
ir_attachment.must_update_from_cad=ir_attachment_relation.is_pr_ok(ir_attachment)

def _getPrintoutName(self):
for ir_attachment_id in self:
ir_attachment_id.printout_name=f"{ir_attachment_id.engineering_code}_{ir_attachment_id.engineering_revision}.pdf"
Expand Down Expand Up @@ -967,7 +980,7 @@ def _check_unique_document(self, vals):
if self.env.context.get('odooPLM'):
if 'name' in vals and 'engineering_code' in vals:
if self.search_count([('engineering_code','=', vals['engineering_code']),
('name','!=',vals['name'])]):
('name','not ilike',vals['name'])]):
raise Exception(_(f"You are trying to create a new attachment [{vals['name']}] with the some engineering code [{vals['engineering_code']}]"))

@api.model_create_multi
Expand Down Expand Up @@ -1603,7 +1616,15 @@ def getCheckedOut(self, oid, default=None):
self.getUserSign(checkOutBrws.userid.id),
checkOutBrws.hostname)
return ('', False, '', '')


def _getCheckOutUser(self):
for ir_attachment_id in self:
checkoutType = self.env['plm.checkout']
checkoutBrwsList = checkoutType.search([('documentid', '=', ir_attachment_id.id)])
for checkOutBrws in checkoutBrwsList:
return checkOutBrws.userid
return self.env['res.users']

@api.model
def _file_delete(self, fname):
"""
Expand Down Expand Up @@ -1940,9 +1961,28 @@ def checkout(self, hostName, hostPws, showError=True, user_id=False):
break
return plm_checkout_id, msg

@api.model
def clientCanCheckOut(self, doc_attrs):
for attachment_id in self.getDocumentBrws(doc_attrs):
return attachment_id.canCheckOut1()
return False, 'not_found', f'File Not found from attributes {doc_attrs}'

def canCheckOut(self, showError=False):
def canCheckOut1(self):
for docBrws in self:
if docBrws.isCheckedOutByMe():
msg = _(f"Unable to check-Out a document that is already checked Out By {docBrws.checkout_user}")
return docBrws.id, 'check_out_by_me', msg
if docBrws.is_checkout:
msg = _(f"Unable to check-Out a document that is already checked IN by user {docBrws.checkout_user}")
return docBrws.id, 'check_out_by_user', msg
if docBrws.engineering_state not in [START_STATUS, False]:
msg = _(f"Unable to check-Out a document that is in state {docBrws.engineering_state}")
return docBrws.id, 'check_out_released', msg
return docBrws.id, 'check_in', ''
raise Exception()

def canCheckOut(self, showError=False):
for docBrws in self:
if docBrws.is_checkout:
msg = _("Unable to check-Out a document that is already checked IN by user %r" % docBrws.checkout_user)
if showError:
Expand Down Expand Up @@ -2029,14 +2069,34 @@ def cleanDocumentRelations(self):
for docBrws in self:
for linkedBrws in linkedDocEnv.search([('child_id', '=', docBrws.id), ('parent_id', '=', docBrws.id)]):
linkedBrws.unlink()

@api.model
def getIdFromAttrs(self, attrs):
for ir_attachment in self.getDocumentBrws(json.loads(attrs)):
return ir_attachment.id
return False

def getDocumentBrws(self, docVals):
docName = docVals.get('engineering_code', '')
docRev = docVals.get('engineering_revision', None)
if not docName or docRev is None:
return self.browse()
return self.search([('engineering_code', '=', docName),
('engineering_revision', '=', docRev)])
"""
function to convert dict client info into attachment browse record
:docVals could be dictionaty or list of dictionaty
es1. {'engineering_code': '102030', 'engineering_revision': 0}
es2. [{'engineering_code': '102030', 'engineering_revision': 0},{ },..]
:return: browse_record(ir_attachment)
"""
if not isinstance(docVals, list):
docVals=[docVals]
out = self.env[self._name]
for doc_dict in docVals:
docName = doc_dict.get('engineering_code', '')
docRev = doc_dict.get('engineering_revision', None)
if not docName or docRev is None:
continue
for ir_attachment_id in self.search([('engineering_code', '=', docName),
('engineering_revision', '=', docRev)]):
out+=ir_attachment_id
break
return out

def checkStructureDocument(self, docAttrs):
docName = docAttrs.get('engineering_code', '')
Expand Down Expand Up @@ -2616,6 +2676,7 @@ def getDefaulValueDict(self, docBrws, PLM_DT_DELTA, is_root):
tmp_dict['is_latest_rev'] = docBrws.isLatestRevision()
tmp_dict['PLM_DT_DELTA'] = PLM_DT_DELTA
tmp_dict['is_root'] = is_root
tmp_dict['must_update_from_cad'] = docBrws.must_update_from_cad
tmp_dict['msg'] = ''
return tmp_dict

Expand Down Expand Up @@ -2666,7 +2727,7 @@ def _preCheckInRecursive_all(self,
doc_2d_ids=self.env[self._name]
doc_3d_ids=self.env[self._name]
#
for doc_id in self.browse(list(set(self.getRelatedLyTree(root_id.id)+self.getRelatedPrTree(root_id.id,recursion=True)))):
for doc_id in self.browse(list(set(self.getRelatedLyTree(root_id.id) + self.getRelatedPrTree(root_id.id,recursion=True)))):
if doc_id.is3D():
doc_3d_ids+=doc_id
else:
Expand Down Expand Up @@ -2700,7 +2761,6 @@ def _preCheckInRecursive_all(self,
out['to_check_3d'].append(data_info)
else:
out['info'].append(data_info)

return out

@api.model
Expand Down Expand Up @@ -3050,4 +3110,39 @@ def getDocBom(self,
'children': children_list}
break
return vals

@api.model
def sent_check_out_requests(self, document_id):
"""
create an activity on document asking to check-out the document
"""
for ir_attachment_id in self.browse([document_id]):
_id, action, _message = ir_attachment_id.canCheckOut1()
if action=='check_out_by_user':
res_user_id = ir_attachment_id._getCheckOutUser()
message = _(f"User {self.env.user.display_name} request this document for make some modification")
todos = {'res_id': ir_attachment_id.id,
'res_model_id': self.env['ir.model'].search([('model', '=', self._name)]).id,
'user_id': res_user_id.id,
'summary': _("Check-In request"),
'note': message,
'activity_type_id': self.env.ref("plm.mail_activity_check_out_request").id,
'date_deadline': datetime.today().date(),
}
self.env['mail.activity'].create(todos)
return True

def related_not_update(self):
for attachment_id in self:
relation_ids = self.env['ir.attachment.relation'].search(["|",('parent_id','=',attachment_id.id),
('child_id','=',attachment_id.id),
('link_kind', '=', 'LyTree')])
return {'name': _('Attachment Relations.'),
'res_model': 'ir.attachment.relation',
'view_type': 'form',
'view_mode': 'kanban,tree,form',
'type': 'ir.actions.act_window',
'domain': [('id', 'in', relation_ids.ids)],
'context': {}}

# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
27 changes: 27 additions & 0 deletions plm/models/ir_attachment_relations.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,4 +177,31 @@ def removeChildRelation(self, parent_ir_attachment_id, linkType='HiTree'):
self.search([('parent_id', '=', parent_ir_attachment_id),
('link_kind', '=', linkType)]).unlink()

def is_2d_ok(self, from_ir_attachment_id):
for relation_id in self.search(["|",('parent_id','=',from_ir_attachment_id.id),
('child_id','=',from_ir_attachment_id.id),
('link_kind', '=', 'LyTree')
]):
if relation_id.parent_id.document_type=='2d' and relation_id.child_id.document_type in ['3d','pr']:
if relation_id.parent_id.write_date < relation_id.child_id.write_date:
return False
if relation_id.child_id.document_type=='2d' and relation_id.parent_id.document_type in ['3d','pr'] :
if relation_id.child_id.write_date<relation_id.parent_id.write_date:
return False
return True

def is_pr_ok(self, from_ir_attachment_id):
for relation_id in self.search(["|",('parent_id','=',from_ir_attachment_id.id),
('child_id','=',from_ir_attachment_id.id),
('link_kind', '=', 'LyTree')
]):
if relation_id.parent_id.document_type=='pr' and relation_id.child_id.document_type in ['2d','3d']:
if relation_id.parent_id.write_date < relation_id.child_id.write_date:
return False
if relation_id.child_id.document_type=='pr' and relation_id.parent_id.document_type==['2d','3d']:
if relation_id.child_id.write_date < relation_id.parent_id.write_date:
return False
return True


# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
1 change: 1 addition & 0 deletions plm/models/product_product.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ def action_show_reference(self):
'name': _('Document'),
'view_type': 'form',
'view_mode': 'form',
'view_id': self.env.ref("plm.view_attachment_form_plm_hinerit").id,
'res_model': 'ir.attachment',
'target': 'new',
'res_id': ir_attachment_id,
Expand Down
25 changes: 22 additions & 3 deletions plm/views/ir_attachment_view.xml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
readonly="1"/>
</header>
<sheet>

<div class="oe_button_box" name="button_box">
<button class="oe_stat_button" icon="fa-sitemap" type="object" name="action_view_rel_doc">
<field name="document_rel_count" string="Documents" widget="statinfo"/>
Expand Down Expand Up @@ -103,12 +104,21 @@
<button name="check_out_user" icon="fa-user" attrs="{'invisible': ['|',('checkout_user', '=', 'False'),('checkout_user', '=', '')]}">
<field name="checkout_user"/>
</button>
<field name="must_update_from_cad" invisible="1"></field>
<button name="related_not_update"
icon="fa-warning"
type="object"
attrs="{'invisible': [('must_update_from_cad', '=', False)]}">
<div class="o_field_widget o_stat_info o_readonly_modifier">
<span style="color:orange">Not.Update</span>
</div>
</button>
</div>
<group>
<group string= "PLM Infos:" name="main_doc_info">
<field string="Eng. Document Name" name="engineering_code" attrs="{'readonly':[('engineering_state','in',['released','obsoleted'])]}"/>
<field string="Eng. Document Name" name="engineering_code" attrs="{'readonly':[('id','>',0)]}"/>
<field string="Enineering revision" name="engineering_revision" readonly="True"/>
<field string="Is a Plm Document" name="is_plm" visible="0" widget="boolean_toggle"/>
<field string="Is a Plm Document" name="is_plm" visible="0" widget="boolean_toggle" readonly="True"/>
</group>
<group name="doc_preview">
<field name="preview"
Expand Down Expand Up @@ -189,6 +199,7 @@
<div class="oe_chatter">
<field name="message_follower_ids" widget="mail_followers" modifiers="{}"/>
<field name="message_ids" widget="mail_thread" modifiers="{}"/>
<field name="activity_ids"/>
</div>
</form>
</field>
Expand Down Expand Up @@ -311,8 +322,11 @@
<field name="engineering_code"/>
<field name="engineering_revision"/>
<field name="description"/>
<field name="datas"/>
<field name="name"/>
<field name="engineering_state"/>
<field name="document_type"/>
<field name="must_update_from_cad" invisible="True"/>
<field name="is_checkout" invisible="True"/>
<field name="is_linkedcomponents" invisible="True"/>
<templates>
Expand Down Expand Up @@ -340,6 +354,10 @@
</strong>
</td>
<td name="Component" style="text-align: right; width: 100%; padding:1px;">
<div class="fa fa-warning fa-2x"
style="color: orange"
attrs="{'invisible': [('must_update_from_cad', '=', False)]}"
/>
<div class="fa fa-lock fa-2x"
string="."
style="color:red;display: inline;"
Expand Down Expand Up @@ -378,8 +396,9 @@
</tr>
<tr>
<td>
<field name="datas" filename="name" widget="binary"/>
<t><strong>Name:</strong></t>
<field name="engineering_code"/>
<field name="engineering_code" attrs="{'readonly': [('id', 'not in', [False, [], 0])]}"/>
<field name="display_name" attrs="{'invisible': [('id', 'not in', [False, []])]}"/>
</td>
</tr>
Expand Down
11 changes: 4 additions & 7 deletions plm_box/models/ir_attachment.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,11 @@ def create(self, vals):
name = self.getNewSequencedName(vals)
vals['name'] = name
return super(Plm_box_document, self).create(vals)

def getCheckOutUser(self):
for docBrws in self:
checkOutObj = self.env.get('plm.checkout')
checkOutBrwsList = checkOutObj.search([('documentid', '=', docBrws.id)])
for checkOutBrws in checkOutBrwsList:
if checkOutBrws:
return self.getUserNameFromId(checkOutBrws.write_uid)
for checkOutBrws in self._getCheckOutUser():
if checkOutBrws:
return checkOutBrws.name
return ''

@api.model
Expand Down

0 comments on commit 138b868

Please sign in to comment.