Use mixin to copy of One2Many from product linked by template and product
This commit is contained in:
@@ -4,12 +4,16 @@ from decimal import Decimal
|
||||
|
||||
from trytond.model import (
|
||||
ModelSQL, ModelStorage, ModelView, fields, sequence_ordered)
|
||||
from trytond.modules.product import round_price
|
||||
from trytond.modules.product import (
|
||||
copy_product_filtered, copy_template_filtered, round_price)
|
||||
from trytond.pool import Pool, PoolMeta
|
||||
from trytond.pyson import Bool, Eval, If
|
||||
|
||||
|
||||
class Template(metaclass=PoolMeta):
|
||||
class Template(
|
||||
copy_template_filtered(
|
||||
'components', 'parent_template', 'parent_product'),
|
||||
metaclass=PoolMeta):
|
||||
__name__ = "product.template"
|
||||
|
||||
components = fields.One2Many(
|
||||
@@ -32,34 +36,11 @@ class Template(metaclass=PoolMeta):
|
||||
if self.type == 'kit':
|
||||
self.cost_price_method = 'fixed'
|
||||
|
||||
@classmethod
|
||||
def copy(cls, templates, default=None):
|
||||
pool = Pool()
|
||||
Component = pool.get('product.component')
|
||||
if default is None:
|
||||
default = {}
|
||||
else:
|
||||
default = default.copy()
|
||||
|
||||
copy_components = 'components' not in default
|
||||
default.setdefault('components', None)
|
||||
new_templates = super().copy(templates, default)
|
||||
if copy_components:
|
||||
old2new = {}
|
||||
to_copy = []
|
||||
for template, new_template in zip(templates, new_templates):
|
||||
to_copy.extend(
|
||||
c for c in template.components if not c.parent_product)
|
||||
old2new[template.id] = new_template.id
|
||||
if to_copy:
|
||||
Component.copy(to_copy, {
|
||||
'parent_template': (lambda d:
|
||||
old2new[d['parent_template']]),
|
||||
})
|
||||
return new_templates
|
||||
|
||||
|
||||
class Product(metaclass=PoolMeta):
|
||||
class Product(
|
||||
copy_product_filtered(
|
||||
'components', 'parent_template', 'parent_product'),
|
||||
metaclass=PoolMeta):
|
||||
__name__ = "product.product"
|
||||
|
||||
components = fields.One2Many(
|
||||
@@ -108,37 +89,6 @@ class Product(metaclass=PoolMeta):
|
||||
quantities[kit.id] = kit.default_uom.floor(min(qties, default=0))
|
||||
return quantities
|
||||
|
||||
@classmethod
|
||||
def copy(cls, products, default=None):
|
||||
pool = Pool()
|
||||
Component = pool.get('product.component')
|
||||
if default is None:
|
||||
default = {}
|
||||
else:
|
||||
default = default.copy()
|
||||
|
||||
copy_components = 'components' not in default
|
||||
if 'template' in default:
|
||||
default.setdefault('components', None)
|
||||
new_products = super().copy(products, default)
|
||||
if 'template' in default and copy_components:
|
||||
template2new = {}
|
||||
product2new = {}
|
||||
to_copy = []
|
||||
for product, new_product in zip(products, new_products):
|
||||
if product.components:
|
||||
to_copy.extend(product.components)
|
||||
template2new[product.template.id] = new_product.template.id
|
||||
product2new[product.id] = new_product.id
|
||||
if to_copy:
|
||||
Component.copy(to_copy, {
|
||||
'parent_product': (lambda d:
|
||||
product2new[d['parent_product']]),
|
||||
'parent_template': (lambda d:
|
||||
template2new[d['parent_template']]),
|
||||
})
|
||||
return new_products
|
||||
|
||||
|
||||
class ComponentMixin(sequence_ordered(), ModelStorage):
|
||||
|
||||
|
||||
@@ -10,7 +10,8 @@ from trytond.model import (
|
||||
Index, MatchMixin, ModelSQL, ModelView, fields, sequence_ordered)
|
||||
from trytond.modules.currency.fields import Monetary
|
||||
from trytond.modules.product import (
|
||||
ProductDeactivatableMixin, price_digits, round_price)
|
||||
ProductDeactivatableMixin, copy_product_filtered, copy_template_filtered,
|
||||
price_digits, round_price)
|
||||
from trytond.pool import Pool, PoolMeta
|
||||
from trytond.pyson import Bool, Eval, If, TimeDelta
|
||||
from trytond.tools import is_full_text, lstrip_wildcard
|
||||
@@ -19,7 +20,8 @@ from trytond.transaction import Transaction
|
||||
from .exceptions import PurchaseUOMWarning
|
||||
|
||||
|
||||
class Template(metaclass=PoolMeta):
|
||||
class Template(
|
||||
copy_template_filtered('product_suppliers'), metaclass=PoolMeta):
|
||||
__name__ = "product.template"
|
||||
purchasable = fields.Boolean("Purchasable")
|
||||
product_suppliers = fields.One2Many(
|
||||
@@ -84,33 +86,9 @@ class Template(metaclass=PoolMeta):
|
||||
raise PurchaseUOMWarning(
|
||||
name, gettext('purchase.msg_change_purchase_uom'))
|
||||
|
||||
@classmethod
|
||||
def copy(cls, templates, default=None):
|
||||
pool = Pool()
|
||||
ProductSupplier = pool.get('purchase.product_supplier')
|
||||
if default is None:
|
||||
default = {}
|
||||
else:
|
||||
default = default.copy()
|
||||
|
||||
copy_suppliers = 'product_suppliers' not in default
|
||||
default.setdefault('product_suppliers', None)
|
||||
new_templates = super().copy(templates, default)
|
||||
if copy_suppliers:
|
||||
old2new = {}
|
||||
to_copy = []
|
||||
for template, new_template in zip(templates, new_templates):
|
||||
to_copy.extend(
|
||||
ps for ps in template.product_suppliers if not ps.product)
|
||||
old2new[template.id] = new_template.id
|
||||
if to_copy:
|
||||
ProductSupplier.copy(to_copy, {
|
||||
'template': lambda d: old2new[d['template']],
|
||||
})
|
||||
return new_templates
|
||||
|
||||
|
||||
class Product(metaclass=PoolMeta):
|
||||
class Product(
|
||||
copy_product_filtered('product_suppliers'), metaclass=PoolMeta):
|
||||
__name__ = 'product.product'
|
||||
|
||||
product_suppliers = fields.One2Many(
|
||||
@@ -274,35 +252,6 @@ class Product(metaclass=PoolMeta):
|
||||
prices[product.id] = unit_price
|
||||
return prices
|
||||
|
||||
@classmethod
|
||||
def copy(cls, products, default=None):
|
||||
pool = Pool()
|
||||
ProductSupplier = pool.get('purchase.product_supplier')
|
||||
if default is None:
|
||||
default = {}
|
||||
else:
|
||||
default = default.copy()
|
||||
|
||||
copy_suppliers = 'product_suppliers' not in default
|
||||
if 'template' in default:
|
||||
default.setdefault('product_suppliers', None)
|
||||
new_products = super().copy(products, default)
|
||||
if 'template' in default and copy_suppliers:
|
||||
template2new = {}
|
||||
product2new = {}
|
||||
to_copy = []
|
||||
for product, new_product in zip(products, new_products):
|
||||
if product.product_suppliers:
|
||||
to_copy.extend(product.product_suppliers)
|
||||
template2new[product.template.id] = new_product.template.id
|
||||
product2new[product.id] = new_product.id
|
||||
if to_copy:
|
||||
ProductSupplier.copy(to_copy, {
|
||||
'product': lambda d: product2new[d['product']],
|
||||
'template': lambda d: template2new[d['template']],
|
||||
})
|
||||
return new_products
|
||||
|
||||
|
||||
class ProductSupplier(
|
||||
sequence_ordered(), ProductDeactivatableMixin, MatchMixin,
|
||||
|
||||
@@ -3,8 +3,9 @@
|
||||
|
||||
from trytond.model import (
|
||||
MatchMixin, ModelSQL, ModelView, fields, sequence_ordered)
|
||||
from trytond.modules.product import ProductDeactivatableMixin
|
||||
from trytond.pool import Pool, PoolMeta
|
||||
from trytond.modules.product import (
|
||||
ProductDeactivatableMixin, copy_product_filtered, copy_template_filtered)
|
||||
from trytond.pool import PoolMeta
|
||||
from trytond.pyson import Bool, Eval, If
|
||||
from trytond.tools import is_full_text, lstrip_wildcard
|
||||
|
||||
@@ -85,7 +86,8 @@ class ProductCustomer(
|
||||
]
|
||||
|
||||
|
||||
class Template(metaclass=PoolMeta):
|
||||
class Template(
|
||||
copy_template_filtered('product_customers'), metaclass=PoolMeta):
|
||||
__name__ = 'product.template'
|
||||
product_customers = fields.One2Many(
|
||||
'sale.product_customer', 'template', "Customers",
|
||||
@@ -98,33 +100,9 @@ class Template(metaclass=PoolMeta):
|
||||
if product_customer.match(pattern):
|
||||
yield product_customer
|
||||
|
||||
@classmethod
|
||||
def copy(cls, templates, default=None):
|
||||
pool = Pool()
|
||||
ProductCustomer = pool.get('sale.product_customer')
|
||||
if default is None:
|
||||
default = {}
|
||||
else:
|
||||
default = default.copy()
|
||||
|
||||
copy_customers = 'product_customers' not in default
|
||||
default.setdefault('product_customers', None)
|
||||
new_templates = super().copy(templates, default)
|
||||
if copy_customers:
|
||||
old2new = {}
|
||||
to_copy = []
|
||||
for template, new_template in zip(templates, new_templates):
|
||||
to_copy.extend(
|
||||
pc for pc in template.product_customers if not pc.product)
|
||||
old2new[template.id] = new_template.id
|
||||
if to_copy:
|
||||
ProductCustomer.copy(to_copy, {
|
||||
'template': lambda d: old2new[d['template']],
|
||||
})
|
||||
return new_templates
|
||||
|
||||
|
||||
class Product(metaclass=PoolMeta):
|
||||
class Product(
|
||||
copy_product_filtered('product_customers'), metaclass=PoolMeta):
|
||||
__name__ = 'product.product'
|
||||
product_customers = fields.One2Many(
|
||||
'sale.product_customer', 'product', "Customers",
|
||||
@@ -141,32 +119,3 @@ class Product(metaclass=PoolMeta):
|
||||
yield product_customer
|
||||
pattern['product'] = None
|
||||
yield from self.template.product_customer_used(**pattern)
|
||||
|
||||
@classmethod
|
||||
def copy(cls, products, default=None):
|
||||
pool = Pool()
|
||||
ProductCustomer = pool.get('sale.product_customer')
|
||||
if default is None:
|
||||
default = {}
|
||||
else:
|
||||
default = default.copy()
|
||||
|
||||
copy_customers = 'product_customers' not in default
|
||||
if 'template' in default:
|
||||
default.setdefault('product_customers', None)
|
||||
new_products = super().copy(products, default)
|
||||
if 'template' in default and copy_customers:
|
||||
template2new = {}
|
||||
product2new = {}
|
||||
to_copy = []
|
||||
for product, new_product in zip(products, new_products):
|
||||
if product.product_customers:
|
||||
to_copy.extend(product.product_customers)
|
||||
template2new[product.template.id] = new_product.template.id
|
||||
product2new[product.id] = new_product.id
|
||||
if to_copy:
|
||||
ProductCustomer.copy(to_copy, {
|
||||
'product': lambda d: product2new[d['product']],
|
||||
'template': lambda d: template2new[d['template']],
|
||||
})
|
||||
return new_products
|
||||
|
||||
@@ -12,7 +12,8 @@ from trytond.modules.account_product.exceptions import TaxError
|
||||
from trytond.modules.account_product.product import (
|
||||
account_used, template_property)
|
||||
from trytond.modules.currency.fields import Monetary
|
||||
from trytond.modules.product import price_digits, round_price
|
||||
from trytond.modules.product import (
|
||||
copy_product_filtered, copy_template_filtered, price_digits, round_price)
|
||||
from trytond.pool import Pool, PoolMeta
|
||||
from trytond.pyson import Eval, Id, If, TimeDelta
|
||||
from trytond.transaction import Transaction
|
||||
@@ -97,7 +98,7 @@ class CategoryCustomerRentalTax(ModelSQL):
|
||||
cls.__access__.add('tax')
|
||||
|
||||
|
||||
class Template(metaclass=PoolMeta):
|
||||
class Template(copy_template_filtered('rental_prices'), metaclass=PoolMeta):
|
||||
__name__ = 'product.template'
|
||||
|
||||
rentable = fields.Boolean(
|
||||
@@ -160,30 +161,8 @@ class Template(metaclass=PoolMeta):
|
||||
'invisible': ~Eval('rentable', False),
|
||||
})]
|
||||
|
||||
@classmethod
|
||||
def copy(cls, templates, default=None):
|
||||
pool = Pool()
|
||||
RentalPrice = pool.get('product.rental.price')
|
||||
default = default.copy() if default is not None else {}
|
||||
|
||||
copy_rental_prices = 'rental_prices' not in default
|
||||
default.setdefault('rental_prices', None)
|
||||
new_templates = super().copy(templates, default=default)
|
||||
if copy_rental_prices:
|
||||
old2new = {}
|
||||
to_copy = []
|
||||
for template, new_template in zip(templates, new_templates):
|
||||
to_copy.extend(
|
||||
rp for rp in template.rental_prices if not rp.product)
|
||||
old2new[template.id] = new_template.id
|
||||
if to_copy:
|
||||
RentalPrice.copy(to_copy, {
|
||||
'template': lambda d: old2new[d['template']],
|
||||
})
|
||||
return new_templates
|
||||
|
||||
|
||||
class Product(metaclass=PoolMeta):
|
||||
class Product(copy_product_filtered('rental_prices'), metaclass=PoolMeta):
|
||||
__name__ = 'product.product'
|
||||
|
||||
rental_prices = fields.One2Many(
|
||||
@@ -261,32 +240,6 @@ class Product(metaclass=PoolMeta):
|
||||
if price.match(quantity, duration, pattern):
|
||||
return price.get_unit_price(self.rental_unit)
|
||||
|
||||
@classmethod
|
||||
def copy(cls, products, default=None):
|
||||
pool = Pool()
|
||||
RentalPrice = pool.get('product.rental.price')
|
||||
default = default.copy() if default is not None else {}
|
||||
|
||||
copy_rental_prices = 'rental_prices' not in default
|
||||
if 'template' in default:
|
||||
default.setdefault('rental_prices', None)
|
||||
new_products = super().copy(products, default=default)
|
||||
if 'template' in default and copy_rental_prices:
|
||||
template2new = {}
|
||||
product2new = {}
|
||||
to_copy = []
|
||||
for product, new_product in zip(products, new_products):
|
||||
if product.rental_prices:
|
||||
to_copy.extend(product.rental_prices)
|
||||
template2new[product.template.id] = new_product.template.id
|
||||
product2new[product.id] = new_product.id
|
||||
if to_copy:
|
||||
RentalPrice.copy(to_copy, {
|
||||
'product': lambda d: product2new[d['product']],
|
||||
'template': lambda d: template2new[d['template']],
|
||||
})
|
||||
return new_products
|
||||
|
||||
|
||||
class RentalPrice(sequence_ordered(), ModelSQL, ModelView, MatchMixin):
|
||||
__name__ = 'product.rental.price'
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
# this repository contains the full copyright notices and license terms.
|
||||
from trytond.model import fields
|
||||
from trytond.pool import Pool, PoolMeta
|
||||
from trytond.modules.product import (
|
||||
copy_product_filtered, copy_template_filtered)
|
||||
from trytond.pool import PoolMeta
|
||||
from trytond.pyson import Eval
|
||||
|
||||
|
||||
class Template(metaclass=PoolMeta):
|
||||
class Template(copy_template_filtered('locations'), metaclass=PoolMeta):
|
||||
__name__ = 'product.template'
|
||||
locations = fields.One2Many('stock.product.location', 'template',
|
||||
"Default Locations",
|
||||
@@ -13,32 +15,8 @@ class Template(metaclass=PoolMeta):
|
||||
'invisible': ~Eval('type').in_(['goods', 'assets']),
|
||||
})
|
||||
|
||||
@classmethod
|
||||
def copy(cls, templates, default=None):
|
||||
pool = Pool()
|
||||
ProductLocation = pool.get('stock.product.location')
|
||||
if default is None:
|
||||
default = {}
|
||||
else:
|
||||
default = default.copy()
|
||||
|
||||
copy_locations = 'locations' not in default
|
||||
default.setdefault('locations', None)
|
||||
new_templates = super().copy(templates, default)
|
||||
if copy_locations:
|
||||
old2new = {}
|
||||
to_copy = []
|
||||
for template, new_template in zip(templates, new_templates):
|
||||
to_copy.extend(l for l in template.locations if not l.product)
|
||||
old2new[template.id] = new_template.id
|
||||
if to_copy:
|
||||
ProductLocation.copy(to_copy, {
|
||||
'template': lambda d: old2new[d['template']],
|
||||
})
|
||||
return new_templates
|
||||
|
||||
|
||||
class Product(metaclass=PoolMeta):
|
||||
class Product(copy_product_filtered('locations'), metaclass=PoolMeta):
|
||||
__name__ = 'product.product'
|
||||
locations = fields.One2Many('stock.product.location', 'product',
|
||||
"Default Locations",
|
||||
@@ -48,32 +26,3 @@ class Product(metaclass=PoolMeta):
|
||||
states={
|
||||
'invisible': ~Eval('type').in_(['goods', 'assets']),
|
||||
})
|
||||
|
||||
@classmethod
|
||||
def copy(cls, products, default=None):
|
||||
pool = Pool()
|
||||
ProductLocation = pool.get('stock.product.location')
|
||||
if default is None:
|
||||
default = {}
|
||||
else:
|
||||
default = default.copy()
|
||||
|
||||
copy_locations = 'locations' not in default
|
||||
if 'template' in default:
|
||||
default.setdefault('locations', None)
|
||||
new_products = super().copy(products, default)
|
||||
if 'template' in default and copy_locations:
|
||||
template2new = {}
|
||||
product2new = {}
|
||||
to_copy = []
|
||||
for product, new_product in zip(products, new_products):
|
||||
if product.locations:
|
||||
to_copy.extend(product.locations)
|
||||
template2new[product.template.id] = new_product.template.id
|
||||
product2new[product.id] = new_product.id
|
||||
if to_copy:
|
||||
ProductLocation.copy(to_copy, {
|
||||
'product': lambda d: product2new[d['product']],
|
||||
'template': lambda d: template2new[d['template']],
|
||||
})
|
||||
return new_products
|
||||
|
||||
@@ -2,11 +2,13 @@
|
||||
# this repository contains the full copyright notices and license terms.
|
||||
|
||||
from trytond.model import fields
|
||||
from trytond.pool import Pool, PoolMeta
|
||||
from trytond.modules.product import (
|
||||
copy_product_filtered, copy_template_filtered)
|
||||
from trytond.pool import PoolMeta
|
||||
from trytond.pyson import Eval
|
||||
|
||||
|
||||
class Template(metaclass=PoolMeta):
|
||||
class Template(copy_template_filtered('location_places'), metaclass=PoolMeta):
|
||||
__name__ = 'product.template'
|
||||
|
||||
location_places = fields.One2Many(
|
||||
@@ -22,29 +24,8 @@ class Template(metaclass=PoolMeta):
|
||||
and place.location == location):
|
||||
return place
|
||||
|
||||
@classmethod
|
||||
def copy(cls, templates, default=None):
|
||||
pool = Pool()
|
||||
ProductLocationPlace = pool.get('stock.product.location.place')
|
||||
default = default.copy() if default is not None else {}
|
||||
|
||||
copy_location_places = 'location_places' not in default
|
||||
default.setdefault('location_places', None)
|
||||
new_templates = super().copy(templates, default=default)
|
||||
if copy_location_places:
|
||||
old2new, to_copy = {}, []
|
||||
for template, new_template in zip(templates, new_templates):
|
||||
to_copy.extend(
|
||||
p for p in template.location_places if not p.product)
|
||||
old2new[template.id] = new_template.id
|
||||
if to_copy:
|
||||
ProductLocationPlace.copy(to_copy, {
|
||||
'template': lambda d: old2new[d['template']],
|
||||
})
|
||||
return new_templates
|
||||
|
||||
|
||||
class Product(metaclass=PoolMeta):
|
||||
class Product(copy_product_filtered('location_places'), metaclass=PoolMeta):
|
||||
__name__ = 'product.product'
|
||||
|
||||
location_places = fields.One2Many(
|
||||
@@ -59,27 +40,3 @@ class Product(metaclass=PoolMeta):
|
||||
if place.location == location:
|
||||
return place
|
||||
return self.template.get_place(location)
|
||||
|
||||
@classmethod
|
||||
def copy(cls, products, default=None):
|
||||
pool = Pool()
|
||||
ProductLocationPlace = pool.get('stock.product.location.place')
|
||||
default = default.copy() if default is not None else {}
|
||||
|
||||
copy_location_places = 'location_places' not in default
|
||||
if 'template' in default:
|
||||
default.setdefault('location_places', None)
|
||||
new_products = super().copy(products, default=default)
|
||||
if 'template' in default and copy_location_places:
|
||||
template2new, product2new, to_copy = {}, {}, []
|
||||
for product, new_product in zip(products, new_products):
|
||||
if product.location_places:
|
||||
to_copy.extend(product.location_places)
|
||||
template2new[product.template.id] = new_product.template.id
|
||||
product2new[product.id] = new_product.id
|
||||
if to_copy:
|
||||
ProductLocationPlace.copy(to_copy, {
|
||||
'product': lambda d: product2new[d['product']],
|
||||
'template': lambda d: template2new[d['template']],
|
||||
})
|
||||
return new_products
|
||||
|
||||
Reference in New Issue
Block a user