-
-
-
+
+
+
+ invisible="plm_state not in ['in_progress']"/>
+ invisible="change_activity_type not in ['request', 'plm_activity'] or plm_state not in ['eco', 'in_progress']"/>
+ invisible="change_activity_type not in ['request', 'plm_activity'] or plm_state not in ['exception', 'draft', 'eco', 'in_progress']"/>
+ invisible="change_activity_type not in ['request', 'plm_activity'] or plm_state not in ['exception', 'eco', 'in_progress']"/>
@@ -53,8 +164,13 @@
-
-
+
+
@@ -63,9 +179,12 @@
-
-
+
+
@@ -81,15 +200,15 @@
- {'invisible': [('change_activity_type', 'in', ['request', 'plm_activity'])]}
+ change_activity_type in ['request', 'plm_activity']
- {'invisible': [('change_activity_type', 'in', ['request', 'plm_activity'])]}
+ change_activity_type in ['request', 'plm_activity']
- {'invisible': [('change_activity_type', 'in', ['request', 'plm_activity'])]}
+ change_activity_type in ['request', 'plm_activity']
diff --git a/activity_validation/views/mail_activity_children_rel.xml b/activity_validation/views/mail_activity_children_rel.xml
index 005f9056..1a09b1a3 100755
--- a/activity_validation/views/mail_activity_children_rel.xml
+++ b/activity_validation/views/mail_activity_children_rel.xml
@@ -10,8 +10,8 @@
-
-
+
+
diff --git a/plm/__manifest__.py b/plm/__manifest__.py
index cb9095fa..b6ec1edc 100644
--- a/plm/__manifest__.py
+++ b/plm/__manifest__.py
@@ -20,7 +20,7 @@
##############################################################################
{
"name": "Product Lifecycle Management",
- "version": "16.0.27",
+ "version": "17.0.0.3",
"author": "OmniaSolutions",
"website": "https://odooplm.omniasolutions.website",
"category": "Manufacturing/Product Lifecycle Management (PLM)",
diff --git a/plm/models/base.py b/plm/models/base.py
index 178109ea..05acdfe1 100644
--- a/plm/models/base.py
+++ b/plm/models/base.py
@@ -23,7 +23,10 @@
@author: mboscolo
'''
+import json
import logging
+from lxml import etree
+
from odoo import models
from odoo import fields
from odoo import api
@@ -33,7 +36,6 @@
from datetime import date
from datetime import datetime
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT
-import json
def json_serial(obj):
"""JSON serializer for objects not serializable by default json code"""
@@ -49,18 +51,33 @@ class Base(models.AbstractModel):
def fields_view_get(self, view_id=None, view_type='form', toolbar=False, submenu=False):
if self.env.context.get('odooPLM'):
return self.koo_fields_view_get(view_id, view_type, toolbar, submenu)
- else:
- return super(Base, self).fields_view_get(view_id=view_id, view_type=view_type, toolbar=toolbar, submenu=submenu)
+ raise NotImplemented("Function not available")
@api.model
def koo_fields_view_get(self, view_id=None, view_type='form', toolbar=False, submenu=False):
def sanitize(dict_from):
return json.loads(json.dumps(dict_from, default=json_serial).replace("null", "false"))
- f = super(Base, self).fields_view_get(view_id=view_id, view_type=view_type, toolbar=toolbar, submenu=submenu)
- for key in ['field_parent', 'name', 'type', 'view_id', 'base_model', 'fields', 'toolbar']:
- if key in f:
- f[key] = sanitize(f.get(key))
- return f
+ result = self.get_views([(view_id, view_type)], {'toolbar': toolbar, 'submenu': submenu})['views'][view_type]
+ node = etree.fromstring(result['arch'])
+ view_fields = set(el.get('name') for el in node.xpath('.//field[not(ancestor::field)]'))
+ result['fields'] = self.fields_get(view_fields)
+ result.pop('models', None)
+ if 'id' in result:
+ view = self.env['ir.ui.view'].sudo().browse(result.pop('id'))
+ result['name'] = view.name
+ result['type'] = view.type
+ result['view_id'] = view.id
+ #result['field_parent'] = view.field_parent
+ result['base_model'] = view.model
+ else:
+ result['type'] = view_type
+ result['name'] = 'default'
+ #result['field_parent'] = False
+
+ for key in ['arch', 'id', 'model', 'models', 'fields']:
+ if key in result:
+ result[key] = sanitize(result.get(key))
+ return result
diff --git a/plm/models/ir_attachment.py b/plm/models/ir_attachment.py
index 3fbe278a..b4c97775 100755
--- a/plm/models/ir_attachment.py
+++ b/plm/models/ir_attachment.py
@@ -2293,61 +2293,6 @@ def getCheckedOutAttrs(self, vals):
break
outDict[file_path] = outLocalDict
return outDict
-
- @api.model
- def _search(self, args, offset=0, limit=None, order=None, count=False, access_rights_uid=None):
- # add res_field=False in domain if not present; the arg[0] trick below
- # works for domain items and '&'/'|'/'!' operators too
- if not any(arg[0] in ('id', 'res_field') for arg in args):
- args.insert(0, ('res_field', '=', False))
-
- ids = super(models.Model, self)._search(args, offset=offset, limit=limit, order=order,
- count=False, access_rights_uid=access_rights_uid)
-
- if self.env.user and (self.env.user._is_admin() or self.env.user._is_superuser()):
- # rules do not apply for the superuser
- return len(ids) if count else ids
-
- if not ids:
- return 0 if count else []
-
- # Work with a set, as list.remove() is prohibitive for large lists of documents
- # (takes 20+ seconds on a db with 100k docs during search_count()!)
- orig_ids = ids
- ids = set(ids)
-
- # For attachments, the permissions of the document they are attached to
- # apply, so we must remove attachments for which the user cannot access
- # the linked document.
- # Use pure SQL rather than read() as it is about 50% faster for large dbs (100k+ docs),
- # and the permissions are checked in super() and below anyway.
- model_attachments = defaultdict(lambda: defaultdict(set)) # {res_model: {res_id: set(ids)}}
- self._cr.execute("""SELECT id, res_model, res_id, public FROM ir_attachment WHERE id IN %s""", [tuple(ids)])
- for row in self._cr.dictfetchall():
- if not row['res_model'] or row['public']:
- continue
- # model_attachments = {res_model: {res_id: set(ids)}}
- model_attachments[row['res_model']][row['res_id']].add(row['id'])
-
- # To avoid multiple queries for each attachment found, checks are
- # performed in batch as much as possible.
- for res_model, targets in model_attachments.items():
- if res_model not in self.env:
- continue
- if not self.env[res_model].check_access_rights('read', False):
- # remove all corresponding attachment ids
- ids.difference_update(itertools.chain(*targets.values()))
- continue
- # filter ids according to what access rules permit
- target_ids = list(targets)
- allowed = self.env[res_model].with_context(active_test=False).search([('id', 'in', target_ids)])
- for res_id in set(target_ids).difference(allowed.ids):
- ids.difference_update(targets[res_id])
-
- # sort result according to the original sort ordering
- result = [id for id in orig_ids if id in ids]
- return len(result) if count else list(result)
-
def open_related_document_revisions(self):
ir_attachment_ids = self.search([('engineering_code', '=', self.engineering_code)])
diff --git a/plm/models/ir_ui_view.py b/plm/models/ir_ui_view.py
index c9822ad4..49ae3dfb 100755
--- a/plm/models/ir_ui_view.py
+++ b/plm/models/ir_ui_view.py
@@ -37,7 +37,8 @@ class IrUiView(models.Model):
_inherit = 'ir.ui.view'
@api.model
- def search(self, args, offset=0, limit=None, order=None, count=False):
+ @api.returns('self')
+ def search(self, args, offset=0, limit=None, order=None):
if self.env.context.get('odooPLM'):
self = self.sudo()
- return super(IrUiView, self).search(args, offset, limit, order, count)
+ return super(IrUiView, self).search(args, offset, limit, order)
diff --git a/plm/models/plm_mixin.py b/plm/models/plm_mixin.py
index 3d78f201..d2ed5256 100644
--- a/plm/models/plm_mixin.py
+++ b/plm/models/plm_mixin.py
@@ -413,6 +413,9 @@ def get_all_revision(self):
def write(self, vals):
if 'engineering_code' in vals and vals['engineering_code'] not in [False, '-','']:
vals['engineering_code_editable']=False
+ else:
+ if self.engineering_code and self.engineering_code_editable==True:
+ vals['engineering_code_editable']=False
return super(RevisionBaseMixin, self).write(vals)
def create(self, vals):
diff --git a/plm/models/product_product.py b/plm/models/product_product.py
index a0a41a1b..c1eb1048 100755
--- a/plm/models/product_product.py
+++ b/plm/models/product_product.py
@@ -40,6 +40,7 @@
from odoo.exceptions import AccessError
from odoo.exceptions import UserError
import odoo.tools as tools
+from odoo.osv import expression
_logger = logging.getLogger(__name__)
@@ -229,7 +230,7 @@ def on_change_stdvalue(self):
self.std_value1,
self.std_value2,
self.std_value3)
-
+
@api.onchange('tmp_material')
def on_change_tmpmater(self):
if self.tmp_material:
@@ -912,7 +913,7 @@ def _commonWFAction(obj,
return _commonWFAction(self, status, include_statuses, recursive,check_in_check=check_in_check)
# ######################################################################################################################################33
- def plm_sanitize(self, vals):
+ def plm_sanitize(self, vals):
all_keys = self._fields
if isinstance(vals, dict):
valsKey = list(vals.keys())
@@ -1052,13 +1053,21 @@ def write(self, vals):
def read(self, fields=[], load='_classic_read'):
try:
- customFields = [field.replace('plm_m2o_', '') for field in fields if field.startswith('plm_m2o_')]
- fields.extend(customFields)
- fields = list(set(fields))
- fields = self.plm_sanitize(fields)
- res = super(ProductProduct, self).read(fields=fields, load=load)
- res = self.readMany2oneFields(res, fields)
- return res
+ if self.env.context.get('odooPLM'):
+ if not fields:
+ fields = list(self._fields.keys())
+ cleaned_up_fields = []
+ for field_name, field_attrs in self.fields_get(fields).items():
+ if field_attrs['type']=='properties':
+ continue
+ cleaned_up_fields.append(field_name)
+ customFields = [field.replace('plm_m2o_', '') for field in cleaned_up_fields if field.startswith('plm_m2o_')]
+ fields.extend(customFields)
+ fields = list(set(cleaned_up_fields))
+ fields = self.plm_sanitize(fields)
+ res = super(ProductProduct, self).read(fields=fields, load=load)
+ return self.readMany2oneFields(res, fields)
+ return super(ProductProduct, self).read(fields=fields, load=load)
except Exception as ex:
if isinstance(ex, AccessError) and 'sale.report' in ex.name:
return """
@@ -1790,11 +1799,17 @@ def name_get(self):
return result
@api.model
- def _name_search(self, name, args=None, operator='ilike', limit=100, name_get_uid=None):
- if not args:
- args = []
- product_ids = list(self._search([('engineering_code', operator, name)] + args, limit=limit, access_rights_uid=name_get_uid))
- product_ids += list(super(ProductProduct, self)._name_search(name, args, operator, limit, name_get_uid))
+ def _name_search(self, name, domain=None, operator='ilike', limit=None, order=None):
+ if not domain:
+ domain=[('engineering_code', 'ilike', name)]
+ else:
+ domain = expression.OR([domain,
+ [('engineering_code', 'ilike', name)]])
+ product_ids = list(super(ProductProduct, self)._name_search(name,
+ domain,
+ operator,
+ limit,
+ order=None))
return list(set(product_ids))
@api.model
@@ -1868,6 +1883,29 @@ def populate(product_id):
populate(self)
return out
+
+ @api.model
+ def get_all_document_source_path(self, attributes, *k, **kw):
+ out_src = []
+ #
+ def fillUpSrvPath(p_p_id):
+ for ir_attachment_id in p_p_id.linkeddocuments.filtered(lambda x:x.document_type=='3d'):
+ is_brake=False
+ for sub_ir_attachment_id in ir_attachment_id.GetRelatedDocs(getBrowse=True):
+ if sub_ir_attachment_id.document_type=='2d':
+ is_brake=True
+ break
+ if is_brake:
+ continue
+ out_src.append((ir_attachment_id.first_source_path,
+ ir_attachment_id.id))
+ #
+ product_product_id = attributes.get('_id')
+ brw_product_product_id = self.browse(product_product_id)
+ for product_id in brw_product_product_id.get_product_bom_flat_ids():
+ fillUpSrvPath(product_id)
+ return list(set(out_src))
+
class PlmTemporayMessage(models.TransientModel):
_name = "plm.temporary.message"
diff --git a/plm/models/res_groups.py b/plm/models/res_groups.py
index a94b3cea..6f30587d 100755
--- a/plm/models/res_groups.py
+++ b/plm/models/res_groups.py
@@ -36,7 +36,8 @@ class ResGroups(models.Model):
_inherit = 'res.groups'
@api.model
- def search(self, args, offset=0, limit=None, order=None, count=False):
+ @api.returns('self')
+ def search(self, args, offset=0, limit=None, order=None):
if self.env.context.get('odooPLM'):
available_types = [
self.env.ref('plm.group_plm_view_user').id,
@@ -56,6 +57,6 @@ def search(self, args, offset=0, limit=None, order=None, count=False):
if additional_obj:
available_types.append(additional_obj.id)
args = AND([args, [('id', 'in', available_types)]])
- return super(ResGroups, self).search(args, offset, limit, order, count)
+ return super(ResGroups, self).search(args, offset, limit, order)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
\ No newline at end of file
diff --git a/plm/tests/test_plm.py b/plm/tests/test_plm.py
index 337e1ba1..f0e3c673 100644
--- a/plm/tests/test_plm.py
+++ b/plm/tests/test_plm.py
@@ -48,7 +48,7 @@
#
#
-@tagged('-standard', 'odoo_plm','post_install', '-at_install')
+@tagged('-standard', 'odoo_plm')
class PlmDateBom(TransactionCase, PlmEntityCreator):
def test_1_some_wk(cls):
@@ -145,6 +145,7 @@ def test_1_some_wk(cls):
def test_2_attachment_wk(self):
attachment = self.create_document('document_wk_test')
+ attachment.is_plm=True
#
assert attachment.engineering_revision==0
assert attachment.ischecked_in()==True
diff --git a/plm/views/ir_attachment_relations.xml b/plm/views/ir_attachment_relations.xml
index 237bc36e..c10fe550 100755
--- a/plm/views/ir_attachment_relations.xml
+++ b/plm/views/ir_attachment_relations.xml
@@ -14,35 +14,44 @@
-
+
-
+
-
+
-
+
-
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
@@ -53,58 +62,78 @@
class="fa fa-dropbox fa-2x"
aria-label="Missing Component"
style="text-align: right; width: 150%; color:#ff8300;"
- attrs="{'invisible': [('parent_linked', 'not in', [False, []])]}"/>
+ invisible="parent_linked not in [False, []]"/>
+ invisible="parent_linked in [False, []]"/>
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
@@ -115,26 +144,36 @@
class="fa fa-dropbox fa-2x"
aria-label="Missing Component"
style="text-align: right; width: 150%; color:#ff8300;"
- attrs="{'invisible': [('child_linked', 'not in', [False, []])]}"/>
+ invisible="child_linked not in [False, []]"/>
+ invisible="child_linked in [False, []]"/>
-
+
-
+
-
+
-
+
-
+
@@ -321,13 +360,13 @@
Parent