[IMP]: Added Upstream Patch for product
This commit is contained in:
parent
8a22829f5e
commit
7255e401de
@ -149,6 +149,9 @@ class ProductProduct(models.Model):
|
|||||||
('barcode_uniq', 'unique(barcode)', "A barcode can only be assigned to one product !"),
|
('barcode_uniq', 'unique(barcode)', "A barcode can only be assigned to one product !"),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
def _get_invoice_policy(self):
|
||||||
|
return False
|
||||||
|
|
||||||
def _compute_product_price(self):
|
def _compute_product_price(self):
|
||||||
prices = {}
|
prices = {}
|
||||||
pricelist_id_or_name = self._context.get('pricelist')
|
pricelist_id_or_name = self._context.get('pricelist')
|
||||||
@ -219,6 +222,7 @@ class ProductProduct(models.Model):
|
|||||||
for supplier_info in self.seller_ids:
|
for supplier_info in self.seller_ids:
|
||||||
if supplier_info.name.id == self._context.get('partner_id'):
|
if supplier_info.name.id == self._context.get('partner_id'):
|
||||||
self.code = supplier_info.product_code or self.default_code
|
self.code = supplier_info.product_code or self.default_code
|
||||||
|
break
|
||||||
else:
|
else:
|
||||||
self.code = self.default_code
|
self.code = self.default_code
|
||||||
|
|
||||||
@ -227,9 +231,10 @@ class ProductProduct(models.Model):
|
|||||||
for supplier_info in self.seller_ids:
|
for supplier_info in self.seller_ids:
|
||||||
if supplier_info.name.id == self._context.get('partner_id'):
|
if supplier_info.name.id == self._context.get('partner_id'):
|
||||||
product_name = supplier_info.product_name or self.default_code
|
product_name = supplier_info.product_name or self.default_code
|
||||||
else:
|
|
||||||
product_name = self.name
|
|
||||||
self.partner_ref = '%s%s' % (self.code and '[%s] ' % self.code or '', product_name)
|
self.partner_ref = '%s%s' % (self.code and '[%s] ' % self.code or '', product_name)
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
self.partner_ref = self.name_get()[0][1]
|
||||||
|
|
||||||
@api.one
|
@api.one
|
||||||
@api.depends('image_variant', 'product_tmpl_id.image')
|
@api.depends('image_variant', 'product_tmpl_id.image')
|
||||||
@ -428,7 +433,12 @@ class ProductProduct(models.Model):
|
|||||||
limit2 = (limit - len(products)) if limit else False
|
limit2 = (limit - len(products)) if limit else False
|
||||||
products += self.search(args + [('name', operator, name), ('id', 'not in', products.ids)], limit=limit2)
|
products += self.search(args + [('name', operator, name), ('id', 'not in', products.ids)], limit=limit2)
|
||||||
elif not products and operator in expression.NEGATIVE_TERM_OPERATORS:
|
elif not products and operator in expression.NEGATIVE_TERM_OPERATORS:
|
||||||
products = self.search(args + ['&', ('default_code', operator, name), ('name', operator, name)], limit=limit)
|
domain = expression.OR([
|
||||||
|
['&', ('default_code', operator, name), ('name', operator, name)],
|
||||||
|
['&', ('default_code', '=', False), ('name', operator, name)],
|
||||||
|
])
|
||||||
|
domain = expression.AND([args, domain])
|
||||||
|
products = self.search(domain, limit=limit)
|
||||||
if not products and operator in positive_operators:
|
if not products and operator in positive_operators:
|
||||||
ptrn = re.compile('(\[(.*?)\])')
|
ptrn = re.compile('(\[(.*?)\])')
|
||||||
res = ptrn.search(name)
|
res = ptrn.search(name)
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
from flectra import api, fields, models, _
|
from flectra import api, fields, models, _
|
||||||
from flectra.addons import decimal_precision as dp
|
from flectra.addons import decimal_precision as dp
|
||||||
from flectra.exceptions import UserError, ValidationError
|
from flectra.exceptions import UserError, ValidationError
|
||||||
|
from flectra.osv import expression
|
||||||
|
|
||||||
|
|
||||||
class ProductAttribute(models.Model):
|
class ProductAttribute(models.Model):
|
||||||
@ -107,6 +108,6 @@ class ProductAttributeLine(models.Model):
|
|||||||
# search on a m2o and one on a m2m, probably this will quickly become
|
# search on a m2o and one on a m2m, probably this will quickly become
|
||||||
# difficult to compute - check if performance optimization is required
|
# difficult to compute - check if performance optimization is required
|
||||||
if name and operator in ('=', 'ilike', '=ilike', 'like', '=like'):
|
if name and operator in ('=', 'ilike', '=ilike', 'like', '=like'):
|
||||||
args = ['|', ('attribute_id', operator, name), ('value_ids', operator, name)]
|
args = expression.AND([['|', ('attribute_id', operator, name), ('value_ids', operator, name)], args])
|
||||||
return self.search(args, limit=limit).name_get()
|
return self.search(args, limit=limit).name_get()
|
||||||
return super(ProductAttributeLine, self).name_search(name=name, args=args, operator=operator, limit=limit)
|
return super(ProductAttributeLine, self).name_search(name=name, args=args, operator=operator, limit=limit)
|
||||||
|
@ -45,6 +45,11 @@
|
|||||||
[<span t-esc="product.code"/>]
|
[<span t-esc="product.code"/>]
|
||||||
</t>
|
</t>
|
||||||
<span t-esc="product.name"/>
|
<span t-esc="product.name"/>
|
||||||
|
<span t-foreach="product.attribute_value_ids" t-as="attribute_value">
|
||||||
|
<span t-if="attribute_value_first">-</span>
|
||||||
|
<span t-if="not attribute_value_last" t-esc="attribute_value.name+','"/>
|
||||||
|
<span t-else="" t-esc="attribute_value.name"/>
|
||||||
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<t t-foreach="data['quantities']" t-as="quantity">
|
<t t-foreach="data['quantities']" t-as="quantity">
|
||||||
<td><strong t-esc="categ_data['prices'][product.id][quantity]"
|
<td><strong t-esc="categ_data['prices'][product.id][quantity]"
|
||||||
|
@ -17,7 +17,9 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
<tr style="width: 1in;">
|
<tr style="width: 1in;">
|
||||||
<td style="border: 2px solid black;text-align: center; vertical-align: middle;" class="col-xs-5">
|
<td style="border: 2px solid black;text-align: center; vertical-align: middle;" class="col-xs-5">
|
||||||
<img t-if="product.barcode" t-att-src="'/report/barcode/?type=%s&value=%s&width=%s&height=%s' % ('EAN13', product.barcode, 600, 150)" style="width:100%;height:20%;"/>
|
<img t-if="product.barcode and len(product.barcode) == 13" t-att-src="'/report/barcode/?type=%s&value=%s&width=%s&height=%s' % ('EAN13', product.barcode, 600, 150)" style="width:100%;height:20%;"/>
|
||||||
|
<img t-elif="product.barcode and len(product.barcode) == 8" t-att-src="'/report/barcode/?type=%s&value=%s&width=%s&height=%s' % ('EAN8', product.barcode, 600, 150)" style="width:100%;height:20%;"/>
|
||||||
|
<img t-else="" t-att-src="'/report/barcode/?type=%s&value=%s&width=%s&height=%s' % ('Code128', product.barcode, 600, 150)" style="width:100%;height:20%;"/>
|
||||||
<span t-field="product.barcode"/>
|
<span t-field="product.barcode"/>
|
||||||
</td>
|
</td>
|
||||||
<td style="border: 2px solid black; text-align: center;" class="col-xs-7">
|
<td style="border: 2px solid black; text-align: center;" class="col-xs-7">
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# Part of Odoo, Flectra. See LICENSE file for full copyright and licensing details.
|
# Part of Odoo, Flectra. See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
from . import test_variants, test_uom, test_pricelist, test_product_pricelist
|
from . import test_seller, test_variants, test_uom, test_pricelist, test_product_pricelist
|
||||||
|
28
addons/product/tests/test_seller.py
Normal file
28
addons/product/tests/test_seller.py
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Part of Odoo, Flectra. See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
|
from flectra.tests.common import TransactionCase
|
||||||
|
|
||||||
|
|
||||||
|
class TestSeller(TransactionCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestSeller, self).setUp()
|
||||||
|
self.product_service = self.env.ref('product.product_product_2')
|
||||||
|
self.product_service.default_code = 'DEFCODE'
|
||||||
|
self.asustec = self.env.ref('base.res_partner_1')
|
||||||
|
self.camptocamp = self.env.ref('base.res_partner_12')
|
||||||
|
|
||||||
|
def test_10_sellers(self):
|
||||||
|
self.product_service.write({'seller_ids': [
|
||||||
|
(0, 0, {'name': self.asustec.id, 'product_code': 'ASUCODE'}),
|
||||||
|
(0, 0, {'name': self.camptocamp.id, 'product_code': 'C2CCODE'}),
|
||||||
|
]})
|
||||||
|
|
||||||
|
default_code = self.product_service.code
|
||||||
|
self.assertEqual("DEFCODE", default_code, "Default code not used in product name")
|
||||||
|
|
||||||
|
context_code = self.product_service\
|
||||||
|
.with_context(partner_id=self.camptocamp.id)\
|
||||||
|
.code
|
||||||
|
self.assertEqual('C2CCODE', context_code, "Partner's code not used in product name with context set")
|
@ -40,6 +40,15 @@ class TestVariantsSearch(TransactionCase):
|
|||||||
self.assertIn(self.product_shirt_template, search_value,
|
self.assertIn(self.product_shirt_template, search_value,
|
||||||
'Shirt should be found searching L')
|
'Shirt should be found searching L')
|
||||||
|
|
||||||
|
def test_name_search(self):
|
||||||
|
self.product_slip_template = self.env['product.template'].create({
|
||||||
|
'name': 'Slip',
|
||||||
|
})
|
||||||
|
res = self.env['product.product'].name_search('Shirt', [], 'not ilike', None)
|
||||||
|
res_ids = [r[0] for r in res]
|
||||||
|
self.assertIn(self.product_slip_template.product_variant_ids.id, res_ids,
|
||||||
|
'Slip should be found searching \'not ilike\'')
|
||||||
|
|
||||||
|
|
||||||
class TestVariants(common.TestProductCommon):
|
class TestVariants(common.TestProductCommon):
|
||||||
|
|
||||||
|
@ -90,6 +90,11 @@
|
|||||||
</group>
|
</group>
|
||||||
</page>
|
</page>
|
||||||
<page string="Notes" name="notes">
|
<page string="Notes" name="notes">
|
||||||
|
<group name="description_internal">
|
||||||
|
<group string="Description for Internal">
|
||||||
|
<field name="description" nolabel="1" placeholder="This note is only for internal purposes."/>
|
||||||
|
</group>
|
||||||
|
</group>
|
||||||
<group name="description">
|
<group name="description">
|
||||||
<group string="Description for Customers" attrs="{'invisible': [('sale_ok','=',False)]}">
|
<group string="Description for Customers" attrs="{'invisible': [('sale_ok','=',False)]}">
|
||||||
<field name="description_sale" nolabel="1" placeholder="This note will show up on sales orders."/>
|
<field name="description_sale" nolabel="1" placeholder="This note will show up on sales orders."/>
|
||||||
|
Loading…
Reference in New Issue
Block a user