123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 |
- # -*- encoding: utf-8 -*-
- ##############################################################################
- # For copyright and license notices, see __openerp__.py file in root directory
- ##############################################################################
- from openerp import fields, models, api, _
- from openerp.osv import fields as old_fields
- from openerp.exceptions import Warning
- import math
- class product_product(models.Model):
- _inherit = 'product.product'
- pack_line_ids = fields.One2many(
- 'product.pack.line',
- 'parent_product_id',
- 'Pack Products',
- help='List of products that are part of this pack.'
- )
- used_pack_line_ids = fields.One2many(
- 'product.pack.line',
- 'product_id',
- 'On Packs',
- help='List of packs where product is used.'
- )
- # def _product_available(
- # self, cr, uid, ids, field_names=None, arg=False, context=None):
- # """
- # For product packs we get availability in a different way
- # """
- # pack_product_ids = self.search(cr, uid, [
- # ('pack', '=', True),
- # ('id', 'in', ids),
- # ])
- # res = super(product_product, self)._product_available(
- # cr, uid, list(set(ids) - set(pack_product_ids)),
- # field_names, arg, context)
- # for product in self.browse(cr, uid, pack_product_ids, context=context):
- # pack_qty_available = []
- # pack_virtual_available = []
- # for subproduct in product.pack_line_ids:
- # subproduct_stock = self._product_available(
- # cr, uid, [subproduct.product_id.id], field_names, arg,
- # context)[subproduct.product_id.id]
- # sub_qty = subproduct.quantity
- # if sub_qty:
- # pack_qty_available.append(math.floor(
- # subproduct_stock['qty_available'] / sub_qty))
- # pack_virtual_available.append(math.floor(
- # subproduct_stock['virtual_available'] / sub_qty))
- # # TODO calcular correctamente pack virtual available para negativos
- # res[product.id] = {
- # 'qty_available': (
- # pack_qty_available and min(pack_qty_available) or False),
- # 'incoming_qty': 0,
- # 'outgoing_qty': 0,
- # 'virtual_available': (
- # pack_virtual_available and
- # max(min(pack_virtual_available), 0) or False),
- # }
- # return res
- # def _search_product_quantity(self, cr, uid, obj, name, domain, context):
- # """
- # We use original search function
- # """
- # return super(product_product, self)._search_product_quantity(
- # cr, uid, obj, name, domain, context)
- # # overwrite ot this fields so that we can modify _product_available
- # # function to support packs
- # _columns = {
- # 'qty_available': old_fields.function(
- # _product_available, multi='qty_available',
- # fnct_search=_search_product_quantity),
- # 'virtual_available': old_fields.function(
- # _product_available, multi='qty_available',
- # fnct_search=_search_product_quantity),
- # 'incoming_qty': old_fields.function(
- # _product_available, multi='qty_available',
- # fnct_search=_search_product_quantity),
- # 'outgoing_qty': old_fields.function(
- # _product_available, multi='qty_available',
- # fnct_search=_search_product_quantity),
- # }
- @api.one
- @api.constrains('pack_line_ids')
- def check_recursion(self):
- """
- Check recursion on packs
- """
- pack_lines = self.pack_line_ids
- while pack_lines:
- if self in pack_lines.mapped('product_id'):
- raise Warning(_(
- 'Error! You cannot create recursive packs.\n'
- 'Product id: %s') % self.id)
- pack_lines = pack_lines.mapped('product_id.pack_line_ids')
- class product_template(models.Model):
- _inherit = 'product.template'
- # TODO rename a pack_type
- pack_price_type = fields.Selection([
- ('components_price', 'Detallado - Precios de los componentes'),
- ('totalice_price', 'Detallado - Precio total'),
- ('fixed_price', 'Detallado - Precio fijo'),
- ('none_detailed_assited_price', 'No detallado - Precio Asistido'),
- ('none_detailed_totaliced_price', 'No detallado - Precio total'),
- ],
- 'Pack Type',
- help="* Detailed - Components Prices: Detail lines with prices on "
- "sales order.\n"
- "* Detailed - Totaliced Price: Detail lines on sales order totalicing "
- "lines prices on pack (don't show component prices).\n"
- "* Detailed - Fixed Price: Detail lines on sales order and use product"
- " pack price (ignore line prices).\n"
- "* None Detailed - Assisted Price: Do not detail lines on sales "
- "order. Assist to get pack price using pack lines.",
- default='fixed_price'
- )
- pack = fields.Boolean(
- 'Pack?',
- help='Is a Product Pack?',
- )
- pack_line_ids = fields.One2many(
- related='product_variant_ids.pack_line_ids'
- )
- used_pack_line_ids = fields.One2many(
- related='product_variant_ids.used_pack_line_ids'
- )
- @api.constrains(
- 'product_variant_ids', 'pack_price_type')
- def check_relations(self):
- """
- Check assited packs dont have packs a childs
- """
- # check assited price has no packs child of them
- if self.pack_price_type == 'none_detailed_assited_price':
- child_packs = self.mapped(
- 'pack_line_ids.product_id').filtered('pack')
- if child_packs:
- raise Warning(_(
- 'A "None Detailed - Assisted Price Pack" can not have a '
- 'pack as a child!'))
- # TODO we also should check this
- # check if we are configuring a pack for a product that is partof a
- # assited pack
- # if self.pack:
- # for product in self.product_variant_ids
- # parent_assited_packs = self.env['product.pack.line'].search([
- # ('product_id', '=', self.id),
- # ('parent_product_id.pack_price_type', '=',
- # 'none_detailed_assited_price'),
- # ])
- # print 'parent_assited_packs', parent_assited_packs
- # if parent_assited_packs:
- # raise Warning(_(
- # 'You can not set this product as pack because it is part'
- # ' of a "None Detailed - Assisted Price Pack"'))
- @api.one
- @api.constrains('company_id', 'product_variant_ids', 'used_pack_line_ids')
- def check_pack_line_company(self):
- """
- Check packs are related to packs of same company
- """
- for line in self.pack_line_ids:
- if line.product_id.company_id != self.company_id:
- raise Warning(_(
- 'Pack lines products company must be the same as the\
- parent product company'))
- for line in self.used_pack_line_ids:
- if line.parent_product_id.company_id != self.company_id:
- raise Warning(_(
- 'Pack lines products company must be the same as the\
- parent product company'))
- @api.multi
- def write(self, vals):
- """
- We remove from prod.prod to avoid error
- """
- if vals.get('pack_line_ids', False):
- self.product_variant_ids.write(
- {'pack_line_ids': vals.pop('pack_line_ids')})
- return super(product_template, self).write(vals)
- @api.model
- def _price_get(self, products, ptype='list_price'):
- res = super(product_template, self)._price_get(
- products, ptype=ptype)
- for product in products:
- if (
- product.pack and
- product.pack_price_type in [
- 'totalice_price',
- 'none_detailed_assited_price',
- 'none_detailed_totaliced_price']):
- pack_price = 0.0
- for pack_line in product.pack_line_ids:
- product_line_price = pack_line.product_id.price_get()[
- pack_line.product_id.id] * (
- 1 - (pack_line.discount or 0.0) / 100.0)
- product_line_price
- pack_price += (product_line_price * pack_line.quantity)
- res[product.id] = pack_price
- return res
|