102 lines
4.6 KiB
Python
102 lines
4.6 KiB
Python
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
|
|
from odoo import api, fields, models, _
|
|
from odoo.fields import Domain
|
|
|
|
|
|
class DocumentsDocument(models.Model):
|
|
_inherit = 'documents.document'
|
|
|
|
product_template_id = fields.Many2one('product.template', string="Product", compute='_compute_product', search='_search_product_template_id')
|
|
product_id = fields.Many2one('product.product', string="Product Variant", compute='_compute_product', search='_search_product_id')
|
|
|
|
@api.depends('res_id', 'res_model')
|
|
def _compute_product(self):
|
|
ProductTemplate = self.env['product.template']
|
|
Product = self.env['product.product']
|
|
for document in self:
|
|
document.product_template_id = document.res_model == 'product.template' and ProductTemplate.browse(document.res_id)
|
|
document.product_id = document.res_model == 'product.product' and Product.browse(document.res_id)
|
|
|
|
@api.model
|
|
def _search_product_template_id(self, operator, value):
|
|
return self._search_related_product_field(operator, value, 'product_template_id')
|
|
|
|
@api.model
|
|
def _search_product_id(self, operator, value):
|
|
return self._search_related_product_field(operator, value, 'product_id')
|
|
|
|
@api.model
|
|
def _search_related_product_field(self, operator, value, field_name) -> Domain:
|
|
assert field_name in ('product_template_id', 'product_id')
|
|
Model = self.env[self._fields[field_name].comodel_name]
|
|
if operator == 'in':
|
|
if True in value:
|
|
# support for True value
|
|
return Domain(field_name, 'not in', [False]) | Domain(field_name, 'in', value - {True})
|
|
if False in value:
|
|
return Domain('res_model', '!=', Model._name) | self._search_related_product_field(operator, value - {False}, field_name)
|
|
query_model = Model._search(Domain.OR(
|
|
Domain(Model._rec_name if isinstance(v, str) else 'id', operator, v)
|
|
for v in value
|
|
if v
|
|
))
|
|
elif operator == 'any' and isinstance(value, Domain):
|
|
query_model = Model._search(value)
|
|
elif operator.endswith('like') and not operator.startswith('not'):
|
|
query_model = Model._search([(Model._rec_name, operator, value)])
|
|
else:
|
|
return NotImplemented
|
|
return (Domain.FALSE if query_model.is_empty() else Domain('res_id', 'in', query_model)) & Domain('res_model', '=', Model._name)
|
|
|
|
def create_product_template(self):
|
|
# JUC: WTF? A single product for many documents, and the created
|
|
# product has the image of the first document?!
|
|
|
|
product = self.env['product.template'].create({
|
|
'name': _('Product created from Documents')
|
|
})
|
|
|
|
for document in self:
|
|
if document.res_model or document.res_id:
|
|
att_copy = document.attachment_id.with_context(no_document=True).copy()
|
|
document = document.copy({'attachment_id': att_copy.id})
|
|
document.write({
|
|
'res_model': product._name,
|
|
'res_id': product.id,
|
|
})
|
|
is_image = (document.mimetype or '').partition('/')[0] == 'image'
|
|
if is_image and not product.image_1920:
|
|
product.write({'image_1920': document.datas})
|
|
|
|
view_id = product.get_formview_id()
|
|
return {
|
|
'type': 'ir.actions.act_window',
|
|
'res_model': 'product.template',
|
|
'name': "New product template",
|
|
'context': self.env.context,
|
|
'view_mode': 'form',
|
|
'views': [(view_id, "form")],
|
|
'res_id': product.id,
|
|
'view_id': view_id,
|
|
}
|
|
|
|
def write(self, vals):
|
|
"""Sync product.document attachment when a document sharing a common
|
|
attachment with a product/template is updated."""
|
|
documents_for_products = self.filtered(
|
|
lambda d: d.res_model in ('product.template', 'product.product')
|
|
and d.attachment_id
|
|
)
|
|
if 'attachment_id' not in vals or not documents_for_products:
|
|
return super().write(vals)
|
|
document_by_old_attachment = documents_for_products.grouped('attachment_id')
|
|
res = super().write(vals)
|
|
product_docs = self.env['product.document'].search([
|
|
('ir_attachment_id', 'in', [a.id for a in document_by_old_attachment])
|
|
])
|
|
for product_doc in product_docs:
|
|
updated_related_document = document_by_old_attachment[product_doc.ir_attachment_id]
|
|
product_doc.ir_attachment_id = updated_related_document.attachment_id
|
|
return res
|