<file_sep>#! -*- coding: utf8 -*-

#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.pool import *
from trytond.model import ModelView, ModelSQL, fields
from trytond.pyson import Eval
from trytond.pyson import Id
from trytond.transaction import Transaction
from trytond.pool import Pool, PoolMeta
from decimal import Decimal
from trytond.wizard import (Wizard, StateView, StateAction, StateTransition,
    Button)
try:
    import bcrypt
except ImportError:
    bcrypt = None
import random
import hashlib
import string
from trytond.config import config

__all__ = ['Template', 'ListByProduct', 'UpdatePriceListByProduct',
    'WizardPriceListByProduct']
__metaclass__ = PoolMeta

STATES = {
    'readonly': ~Eval('active', True),
    }
DEPENDS = ['active']
DIGITS = int(config.get('digits', 'unit_price_digits', 4))

class Template:
    __name__ = 'product.template'

    listas_precios = fields.One2Many('product.list_by_product', 'template', 'Listas de precio',
        states=STATES,depends=DEPENDS)

    @classmethod
    def __setup__(cls):
        super(Template, cls).__setup__()
        cls.list_price_with_tax.states['readonly'] = Eval('active', True)

    @fields.depends('name')
    def on_change_name(self):
        if self.name:
            self.raise_user_error(u'No olvide configurar: \n-Categoria\n-Impuestos(Pestaña Contabilidad)')

    @fields.depends('cost_price', 'listas_precios', 'id', 'taxes_category',
        'category', 'list_price_with_tax', 'list_price')
    def on_change_cost_price(self):
        pool = Pool()
        Taxes1 = pool.get('product.category-customer-account.tax')
        Taxes2 = pool.get('product.template-customer-account.tax')

        Product = pool.get('product.product')
        products = Product.search([('template', '=', self.id)])
        for p in products:
            product = p
        PriceList = pool.get('product.price_list')
        User = pool.get('res.user')
        priceslist = PriceList.search([('incluir_lista', '=', True)])
        res= {}
        percentage = 0
        precio_final = Decimal(0.0)
        user =  User(Transaction().user)
        precio_total = Decimal(0.0)
        precio_total_iva = Decimal(0.0)
        iva = Decimal(0.0)
        precio_para_venta = Decimal(0.0)

        if self.taxes_category == True:
            if self.category.taxes_parent == True:
                taxes1= Taxes1.search([('category','=', self.category.parent)])
                taxes2 = Taxes2.search([('product','=', self.id)])
            else:
                taxes1= Taxes1.search([('category','=', self.category)])
        else:
            taxes1= Taxes1.search([('category','=', self.category)])
            taxes2 = Taxes2.search([('product','=', self.id)])

        if self.listas_precios:
            pass
        else:
            if self.cost_price:
                lineas = []
                for pricelist in priceslist:
                    for line in pricelist.lines:
                        if line.percentage > 0:
                            percentage = line.percentage/100
                        if line.use_new_formula == True:
                            if pricelist.definir_precio_tarjeta == True:
                                precio_final = precio_para_venta / (1 - percentage)
                            else:
                                precio_final = self.cost_price / (1 - percentage)
                        else:
                            if pricelist.definir_precio_tarjeta == True:
                                precio_final = precio_para_venta * (1 + percentage)
                            else:
                                precio_final = self.cost_price * (1 + percentage)

                        if user.company.currency:
                            precio_final = user.company.currency.round(precio_final)
                    if taxes1:
                        for t in taxes1:
                            iva = precio_final * t.tax.rate
                    elif taxes2:
                        for t in taxes2:
                            iva = precio_final * t.tax.rate

                    precio_total = precio_final + iva

                    lineas.append({
                        'lista_precio': pricelist.id,
                        'fijo' : precio_final,
                        'fijo_con_iva':precio_total,
                        'precio_venta' : pricelist.definir_precio_venta,
                    })
                    if pricelist.definir_precio_venta == True:
                        precio_para_venta = precio_final
                        precio_total_iva = precio_total
                res['listas_precios'] = lineas
                res['list_price'] = precio_para_venta
                res['list_price_with_tax'] = precio_total_iva
        return res

    @fields.depends('listas_precios', 'list_price', 'taxes_category', 'category',
        'list_price_with_tax', 'customer_taxes', 'cost_price')
    def on_change_listas_precios(self):
        if self.list_price_with_tax:
            price_with_tax = self.list_price_with_tax
        else:
            price_with_tax = Decimal(0.0)

        changes = {
            'list_price_with_tax': self.list_price,
            'list_price': price_with_tax,
            }
        if self.listas_precios:
            for lista in self.listas_precios:
                if (lista.fijo_con_iva > Decimal(0.0)) and  (lista.precio_venta == True):
                    changes['list_price_with_tax'] = lista.fijo_con_iva
                    changes['list_price'] = self.get_list_price_new(lista.fijo_con_iva)
                    return changes
        return changes

    def get_list_price_new(self, list_price_with_tax):
        Tax = Pool().get('account.tax')
        taxes = [Tax(t) for t in self.get_taxes('customer_taxes_used')]
        tax_amount = Tax.reverse_compute(list_price_with_tax, taxes)
        return tax_amount.quantize(Decimal(str(10.0 ** -DIGITS)))

    @classmethod
    def validate(cls, products):
        for product in products:
            for lists in product.listas_precios:
                if lists.fijo < product.cost_price:
                    super(Template, cls).validate(products)

    def pre_validate(self):
        pool = Pool()
        User = pool.get('res.user')
        Product = pool.get('product.template')
        Variante = pool.get('product.product')

        def in_group():
            pool = Pool()
            ModelData = pool.get('ir.model.data')
            User = pool.get('res.user')
            Group = pool.get('res.group')
            origin = str(self)
            user = User(Transaction().user)

            group = Group(ModelData.get_id('nodux_product_price_list_by_product',
                    'group_update_price_force'))
            transaction = Transaction()
            user_id = transaction.user
            if user_id == 0:
                user_id = transaction.context.get('user', user_id)
            if user_id == 0:
                return True
            user = User(user_id)
            return origin and group in user.groups

        for lists in self.listas_precios:
            if lists.fijo < self.cost_price:
                if not in_group():
                    self.raise_user_error("No esta autorizado a actualizar el precio de la lista de precio")
                self.raise_user_warning('precio_costo_menor',
                       'Precio de venta: "%s"'
                    'es menor al precio de costo "%s".', (str(lists.fijo), str(self.cost_price)))

class ListByProduct(ModelSQL, ModelView):
    "List By Product"
    __name__ = "product.list_by_product"

    template = fields.Many2One('product.template', 'Product Template',
        required=True, ondelete='CASCADE', select=True, states=STATES,
        depends=DEPENDS)
    lista_precio = fields.Many2One('product.price_list', 'Lista de Precio',
        required=True, ondelete='CASCADE', select=True, states=STATES,
        depends=DEPENDS)
    fijo = fields.Numeric('Precio sin IVA', digits=(16, 6))
    precio_venta = fields.Boolean('Definir como precio de VENTA')
    product = fields.Many2One('product.product', 'Product Template')
    fijo_con_iva = fields.Numeric('Precio con IVA', digits=(16, 6))

    @classmethod
    def __setup__(cls):
        super(ListByProduct, cls).__setup__()

    def get_rec_name(self, lista_precio):
        return self.lista_precio.name

    @classmethod
    def search_rec_name(cls, lista_precio, clause):
        return [('lista_precio',) + tuple(clause[1:])]

    @fields.depends('_parent_template.cost_price', 'lista_precio', 'fijo',
        '_parent_template.taxes_category', '_parent_template.category',
        '_parent_template.id', 'parent_template.list_price')
    def on_change_lista_precio(self):
        pool = Pool()
        res= {}
        percentage = 0
        precio_final = Decimal(0.0)
        Taxes1 = pool.get('product.category-customer-account.tax')
        Taxes2 = pool.get('product.template-customer-account.tax')
        use_new_formula = False
        if self.lista_precio:
            if self.lista_precio.lines:
                for line in self.lista_precio.lines:
                    if line.percentage > 0:
                        percentage = line.percentage/100
                    if line.use_new_formula == True:
                        use_new_formula = True
                    else:
                        use_new_formula = False

            if self.template.cost_price:
                if use_new_formula == True:
                    if self.lista_precio.definir_precio_tarjeta == True:
                        precio_final = self.template.list_price / (1 - percentage)
                    else:
                        precio_final = self.template.cost_price / (1 - percentage)
                else:
                    if self.lista_precio.definir_precio_tarjeta == True:
                        precio_final = self.template.list_price * (1 + percentage)
                    else:
                        precio_final = self.template.cost_price * (1 + percentage)
            if self.template.taxes_category == True:
                if self.template.category.taxes_parent == True:
                    taxes1= Taxes1.search([('category','=', self.template.category.parent)])
                    taxes2 = Taxes2.search([('product','=', self.template)])
                else:
                    taxes1= Taxes1.search([('category','=', self.template.category)])
            else:
                taxes1= Taxes1.search([('category','=', self.template.category)])
                taxes2 = Taxes2.search([('product','=', self.template)])

            if taxes1:
                for t in taxes1:
                    iva = precio_final * t.tax.rate
            elif taxes2:
                for t in taxes2:
                    iva = precio_final * t.tax.rate
            elif taxes3:
                for t in taxes3:
                    iva = precio_final * t.tax.rate
            precio_total = precio_final + iva

            res['fijo'] = Decimal(str(round(precio_final, 6)))
            res['fijo_con_iva'] = Decimal(str(round(precio_total, 6)))
        return res

    @fields.depends('_parent_template.cost_price', 'lista_precio', 'fijo',
        '_parent_template.taxes_category', '_parent_template.category',
        '_parent_template.id', 'fijo_con_iva', '_parent_template.list_price')
    def on_change_fijo_con_iva(self):
        pool = Pool()
        res= {}
        precio_total = self.fijo
        Taxes1 = pool.get('product.category-customer-account.tax')
        Taxes2 = pool.get('product.template-customer-account.tax')
        iva = Decimal(0.0)
        if self.fijo_con_iva:
            if self.template.taxes_category == True:
                    if self.template.category.taxes_parent == True:
                        taxes1= Taxes1.search([('category','=', self.template.category.parent)])
                        taxes2 = Taxes2.search([('product','=', self.template)])
                    else:
                        taxes1= Taxes1.search([('category','=', self.template.category)])
            else:
                taxes1= Taxes1.search([('category','=', self.template.category)])
                taxes2 = Taxes2.search([('product','=', self.template)])

            if taxes1:
                for t in taxes1:
                    iva = t.tax.rate
            elif taxes2:
                for t in taxes2:
                    iva = t.tax.rate

            precio_total = self.fijo_con_iva /(1+iva)
            res['fijo'] =  Decimal(str(round(precio_total, 6)))
            return res


    @fields.depends('_parent_template.cost_price', 'lista_precio', 'fijo',
        '_parent_template.taxes_category', '_parent_template.category',
        '_parent_template.id', 'fijo_con_iva', '_parent_template.list_price')
    def on_change_fijo(self):
        pool = Pool()
        res={}
        precio_total_iva = self.fijo_con_iva
        Taxes1 = pool.get('product.category-customer-account.tax')
        Taxes2 = pool.get('product.template-customer-account.tax')
        iva = Decimal(0.0)

        if self.fijo_iva:
            if self.template.taxes_category == True:
                if self.template.category.taxes_parent == True:
                    taxes1 = Taxes1.search([('category','=', self.template.category.parent)])
                    taxes2 = Taxes2.search([('product', '=', self.template)])
                else:
                    taxes1 = Taxes1.search([('category', '=', self.template.category)])
            else:
                taxes1 = Taxes1.search([('category', '=', self.template.category)])
                taxes2 = Taxes2.search([('product', '=', self.template)])

            if taxes1:
                for t in taxes1:
                    iva = t.tax.rate
            elif taxes2:
                for t in taxes2:
                    iva = t.tax.rate

            precio_total_con_iva = self.fijo*(1+iva)
            res['fijo_con_iva'] = Decimal(str(round(precio_total_con_iva, 6)))
            return res

    @fields.depends('_parent_template.list_price', '_parent_template.id', 'fijo', 'precio_venta')
    def on_change_precio_venta(self):
        res= {}
        res['list_price'] = self.fijo
        self.template.list_price = res['list_price']
        return res

class UpdatePriceListByProduct(ModelView):
    'Update Price List By Product'
    __name__ = 'nodux_product_price_list_by_product.update_price.start'

    password = fields.Char('<PASSWORD>', required=True, size=20)
    user = fields.Char('Usuario', required=True, readonly=True)

    def hash_password(self, password):
        if not password:
            return ''
        return getattr(self, 'hash_' + self.hash_method())(password)

    @staticmethod
    def hash_method():
        return 'bcrypt' if bcrypt else 'sha1'

    @classmethod
    def hash_sha1(cls, password):
        if isinstance(password, unicode):
            password = password.encode('utf-8')
        salt = ''.join(random.sample(string.ascii_letters + string.digits, 8))
        hash_ = hashlib.sha1(password + salt).hexdigest()
        return '$'.join(['sha1', hash_, salt])

    def check_password(self, password, hash_):
        if not hash_:
            return False
        hash_method = hash_.split('$', 1)[0]
        return getattr(self, 'check_' + hash_method)(password, hash_)

    @classmethod
    def check_sha1(cls, password, hash_):
        if isinstance(password, unicode):
            password = password.encode('utf-8')
        if isinstance(hash_, unicode):
            hash_ = hash_.encode('utf-8')
        hash_method, hash_, salt = hash_.split('$', 2)
        salt = salt or ''
        assert hash_method == 'sha1'
        return hash_ == hashlib.sha1(password + salt).hexdigest()

    @classmethod
    def hash_bcrypt(cls, password):
        if isinstance(password, unicode):
            password = password.encode('utf-8')
        hash_ = bcrypt.hashpw(password, bcrypt.gensalt())
        return '$'.join(['bcrypt', hash_])

    @classmethod
    def check_bcrypt(cls, password, hash_):
        if isinstance(password, unicode):
            password = password.encode('utf-8')
        if isinstance(hash_, unicode):
            hash_ = hash_.encode('utf-8')
        hash_method, hash_ = hash_.split('$', 1)
        assert hash_method == 'bcrypt'
        return hash_ == bcrypt.hashpw(password, hash_)

    @fields.depends('password')
    def on_change_password(self):
        res = {}
        User = Pool().get('res.user')
        user = None
        value = False
        if self.password:
            users = User.search([('password_hash', '!=', None)])
            if users:
                for u in users:
                    value = self.check_password(self.password, u.password_hash)
                    if value == True:
                        res['user'] = u.name
                        break
                if value == False:
                    self.raise_user_error(u'Invalid password')
        return res

class WizardPriceListByProduct(Wizard):
    'Wizard Price List By Product'
    __name__ = 'nodux_product_price_list_by_product.update_price'

    start = StateView('nodux_product_price_list_by_product.update_price.start',
        'nodux_product_price_list_by_product.update_price_list_start_view_form', [
        Button('Cancel', 'end', 'tryton-cancel'),
        Button('Ok', 'accept', 'tryton-ok', default=True),
        ])
    accept = StateTransition()

    def transition_accept(self):
        pool = Pool()
        User = pool.get('res.user')
        Product = pool.get('product.template')
        Variante = pool.get('product.product')
        Variante = pool.get('product.product')
        products = Product.browse(Transaction().context['active_ids'])
        p = Product(Transaction().context['active_id'])
        percentage = 0
        precio_final = Decimal(0.0)
        new_list_price = Decimal(0.0)
        use_new_formula = False
        def in_group():
            pool = Pool()
            ModelData = pool.get('ir.model.data')
            User = pool.get('res.user')
            Group = pool.get('res.group')
            origin = str(p)
            user = User(Transaction().user)

            group = Group(ModelData.get_id('nodux_product_price_list_by_product',
                    'group_update_price_force'))
            transaction = Transaction()
            user_id = transaction.user
            if user_id == 0:
                user_id = transaction.context.get('user', user_id)
            if user_id == 0:
                return True
            user = User(user_id)
            return origin and group in user.groups

        if not in_group():
            self.raise_user_error("No esta autorizado a actualizar el precio de la lista de precio")

        for product in products:
            if product.listas_precios:
                for listas in product.listas_precios:
                    if listas.lista_precio.lines:
                        for line in listas.lista_precio.lines:
                            if line.use_new_formula == True:
                                use_new_formula = True
                            else:
                                use_new_formula = False

                            if line.percentage:
                                if line.percentage > 0:
                                    percentage = line.percentage/100
                            else:
                                self.raise_user_error('No ha definido el porcentaje de ganancia en las listas de precio')
                    if product.cost_price:
                        if use_new_formula == True:
                            if listas.definir_precio_tarjeta == True:
                                precio_final = product.list_price / (1 - percentage)

                            else:
                                precio_final = product.cost_price / (1 - percentage)
                        else:
                            if listas.definir_precio_tarjeta  == True:
                                precio_final = product.list_price * (1 + percentage)
                            else:
                                precio_final = product.cost_price * (1 + percentage)

                    if listas.precio_venta == True:
                        new_list_price = precio_final

                    listas.fijo = precio_final
                    listas.save()
                product.list_price = new_list_price
                product.save()

        return 'end'
<file_sep>#! -*- coding: utf8 -*-

#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.pool import *
from trytond.report import Report
from trytond.transaction import Transaction
from trytond.modules.company import CompanyReport
from trytond.pool import Pool
from decimal import Decimal
from trytond.model import ModelSQL, Workflow, fields, ModelView
from trytond.pyson import Bool, Eval, Or, If, Id
from trytond.wizard import (Wizard, StateView, StateAction, StateTransition,
    Button)
try:
    import bcrypt
except ImportError:
    bcrypt = None
import random
import hashlib
import string

__all__ = ['PriceList', 'UpdateListByProduct', 'WizardListByProduct', 'PriceListLine']
__metaclass__ = PoolMeta

class PriceList():
    'Price List'
    __name__ = 'product.price_list'

    incluir_lista = fields.Boolean('Incluir lista de precio en producto', states={
        'readonly': (Eval('definir_precio_venta', True)) | (Eval('definir_precio_tarjeta', True))
    })

    definir_precio_venta = fields.Boolean('Definir como precio de venta', help="Definir como precio de venta principal")

    definir_precio_tarjeta = fields.Boolean('Precio tarjeta de credito', help="Definir como precio de tarjeta de credito")

    @classmethod
    def __setup__(cls):
        super(PriceList, cls).__setup__()

    @fields.depends('incluir_lista', 'definir_precio_venta')
    def on_change_definir_precio_venta(self):
        res = {}
        if self.definir_precio_venta == True:
            res['incluir_lista'] = True
        else:
            if self.incluir_lista:
                res['incluir_lista'] = self.incluir_lista
            else:
                res['incluir_lista'] = False
        return res

    @fields.depends('incluir_lista', 'definir_precio_tarjeta')
    def on_change_definir_precio_tarjeta(self):
        res = {}
        if self.definir_precio_tarjeta == True:
            res['incluir_lista'] = True
        else:
            if self.incluir_lista:
                res['incluir_lista'] = self.incluir_lista
            else:
                res['incluir_lista'] = False
        return res

    @classmethod
    def validate(cls, price_lists):
        for price_list in price_lists:
            for price_list in price_lists:
                super(PriceList, cls).validate(price_lists)

    def pre_validate(self):
        pool = Pool()
        User = pool.get('res.user')
        Product = pool.get('product.template')
        Variante = pool.get('product.product')

        def in_group():
            pool = Pool()
            ModelData = pool.get('ir.model.data')
            User = pool.get('res.user')
            Group = pool.get('res.group')
            origin = str(self)
            user = User(Transaction().user)

            group = Group(ModelData.get_id('nodux_product_price_list_by_product',
                    'group_update_price_force'))
            transaction = Transaction()
            user_id = transaction.user
            if user_id == 0:
                user_id = transaction.context.get('user', user_id)
            if user_id == 0:
                return True
            user = User(user_id)
            return origin and group in user.groups

        if not in_group():
            self.raise_user_error("No esta autorizado a cambiar/crear una lista de precio")

class PriceListLine():
    'Price List Line'
    __name__ = 'product.price_list.line'

    new_formula = fields.Char('Formula', readonly = True)
    use_new_formula = fields.Boolean('Utilizar formula')

    @classmethod
    def __setup__(cls):
        super(PriceListLine, cls).__setup__()

    @staticmethod
    def default_new_formula():
        return 'costo/(1-%)'

    @fields.depends('percentage', 'formula', '_parent_price_list.definir_precio_tarjeta')
    def on_change_percentage(self):
        pool = Pool()
        res= {}
        if self.percentage:
            if self.percentage > 0:
                percentage = self.percentage/100
                p = str(percentage)
                if self.price_list.definir_precio_tarjeta == True:
                    formula = 'product.list_price * (1 + ' +p+')'
                else:
                    formula = 'product.cost_price * (1 + ' +p+')'
                res['formula'] = formula
            else:
                res['formula'] = ""
        else:
            res['formula'] = ""
        return res

    @fields.depends('percentage', 'formula', 'new_formula', 'use_new_formula',
        '_parent_price_list.definir_precio_tarjeta')
    def on_change_use_new_formula(self):
        pool = Pool()
        res= {}
        p = '0'
        if self.percentage > 0:
            percentage = self.percentage/100
            p = str(percentage)
        if self.use_new_formula:
            if self.use_new_formula == True:
                if self.price_list.definir_precio_tarjeta == True:
                    formula = 'product.list_price / (1 - ' +p+')'
                else:
                    formula = 'product.cost_price / (1 - ' +p+')'
                res['formula'] = formula
            else:
                if self.price_list.definir_precio_tarjeta == True:
                    formula = 'product.list_price * (1 + ' +p+')'
                else:
                    formula = 'product.cost_price * (1 +' +p+')'
                res['formula'] = formula
        else:
            if self.price_list.definir_precio_tarjeta == True:
                formula = 'product.list_price * (1 + '+p+')'
            else:
                formula = 'product.cost_price * (1 +' +p+')'
            res['formula'] = formula
        return res

class UpdateListByProduct(ModelView):
    'Update List By Product'
    __name__ = 'nodux_product_price_list_by_product.update.start'

    password = fields.Char('Password', required=True, size=20)
    user = fields.Char('Usuario', required=True, readonly=True)

    def hash_password(self, password):
        if not password:
            return ''
        return getattr(self, 'hash_' + self.hash_method())(password)

    @staticmethod
    def hash_method():
        return 'bcrypt' if bcrypt else 'sha1'

    @classmethod
    def hash_sha1(cls, password):
        if isinstance(password, unicode):
            password = password.encode('utf-8')
        salt = ''.join(random.sample(string.ascii_letters + string.digits, 8))
        hash_ = hashlib.sha1(password + salt).hexdigest()
        return '$'.join(['sha1', hash_, salt])

    def check_password(self, password, hash_):
        if not hash_:
            return False
        hash_method = hash_.split('$', 1)[0]
        return getattr(self, 'check_' + hash_method)(password, hash_)

    @classmethod
    def check_sha1(cls, password, hash_):
        if isinstance(password, unicode):
            password = <PASSWORD>.encode('<PASSWORD>')
        if isinstance(hash_, unicode):
            hash_ = hash_.encode('utf-8')
        hash_method, hash_, salt = hash_.split('$', 2)
        salt = salt or ''
        assert hash_method == 'sha1'
        return hash_ == hashlib.sha1(password + salt).hexdigest()

    @classmethod
    def hash_bcrypt(cls, password):
        if isinstance(password, unicode):
            password = password.encode('utf-8')
        hash_ = bcrypt.hashpw(password, bcrypt.gensalt())
        return '$'.join(['bcrypt', hash_])

    @classmethod
    def check_bcrypt(cls, password, hash_):
        if isinstance(password, unicode):
            password = password.encode('utf-8')
        if isinstance(hash_, unicode):
            hash_ = hash_.encode('utf-8')
        hash_method, hash_ = hash_.split('$', 1)
        assert hash_method == 'bcrypt'
        return hash_ == bcrypt.hashpw(password, hash_)

    @fields.depends('password')
    def on_change_password(self):
        res = {}
        User = Pool().get('res.user')
        user = None
        value = False
        if self.password:
            users = User.search([('password_hash', '!=', None)])
            if users:
                for u in users:
                    value = self.check_password(self.password, u.password_hash)
                    if value == True:
                        res['user'] = u.name
                        break
                if value == False:
                    self.raise_user_error(u'Contraseña no valida')
        return res

class WizardListByProduct(Wizard):
    'Wizard List By Product'
    __name__ = 'nodux_product_price_list_by_product.update'

    start = StateView('nodux_product_price_list_by_product.update.start',
        'nodux_product_price_list_by_product.update_list_start_view_form', [
        Button('Cancel', 'end', 'tryton-cancel'),
        Button('Ok', 'accept', 'tryton-ok', default=True),
        ])
    accept = StateTransition()

    def transition_accept(self):
        pool = Pool()
        User = pool.get('res.user')
        Product = pool.get('product.template')
        Variante = pool.get('product.product')
        Taxes1 = pool.get('product.category-customer-account.tax')
        Taxes2 = pool.get('product.template-customer-account.tax')
        ListByProduct = pool.get('product.list_by_product')
        PriceList = pool.get('product.price_list')
        priceslists = PriceList.browse(Transaction().context['active_ids'])
        pls = PriceList(Transaction().context['active_id'])
        user =  User(Transaction().user)
        incluido = False
        lineas = None

        def in_group():
            pool = Pool()
            ModelData = pool.get('ir.model.data')
            User = pool.get('res.user')
            Group = pool.get('res.group')
            origin = str(pls)
            user = User(Transaction().user)

            group = Group(ModelData.get_id('nodux_product_price_list_by_product',
                    'group_update_price_force'))
            transaction = Transaction()
            user_id = transaction.user
            if user_id == 0:
                user_id = transaction.context.get('user', user_id)
            if user_id == 0:
                return True
            user = User(user_id)
            return origin and group in user.groups

        if not in_group():
            self.raise_user_error("No esta autorizado a agregar las listas de precio en todos los productos")

        lineas = []

        for pricelist in priceslists:
            if pricelist.incluir_lista == False:
                pass
            elif pricelist.incluir_lista == True:
                products = Product.search([('id', '>', 0)])

                for p in products:
                    variantes = Variante.search([('template', '=', p.id)])
                    for v in variantes:
                        variante = v
                    if p.listas_precios:
                        for listas in p.listas_precios:
                            if pricelist == listas.lista_precio:
                                incluido = True
                                break

                        if incluido == True:
                            pass
                        else:
                            for line in pricelist.lines:
                                if line.percentage:
                                    if line.percentage > 0:
                                        percentage = line.percentage/100
                                    if line.use_new_formula == True:
                                        if line.price_list.definir_precio_tarjeta == True:
                                            precio_final = p.list_price / (1 - percentage)
                                        else:
                                            precio_final = p.cost_price / (1 - percentage)
                                    else:
                                        if line.price_list.definir_precio_tarjeta == True:
                                            precio_final = p.list_price * (1 + percentage)
                                        else:
                                            precio_final = p.cost_price * (1 + percentage)
                                else:
                                    self.raise_user_error('No ha definido el porcentaje, modifique la lista de precio')
                                if user.company.currency:
                                    precio_final = user.company.currency.round(precio_final)

                            if p.taxes_category == True:
                                if p.category.taxes_parent == True:
                                    taxes1= Taxes1.search([('category','=', p.category.parent)])
                                    taxes2 = Taxes2.search([('product','=', p)])
                                else:
                                    taxes1= Taxes1.search([('category','=', p.category)])
                            else:
                                taxes1= Taxes1.search([('category','=', p.category)])
                                taxes2 = Taxes2.search([('product','=', p)])

                            if taxes1:
                                for t in taxes1:
                                    iva = precio_final * t.tax.rate
                            elif taxes2:
                                for t in taxes2:
                                    iva = precio_final * t.tax.rate

                            precio_total = precio_final + iva

                            if pricelist.definir_precio_venta == True:
                                p.list_price = precio_final
                                p.list_price_with_tax = precio_total
                                p.save()

                            lineas.append({
                                'template': p.id,
                                'lista_precio': pricelist.id,
                                'fijo' : precio_final,
                                'fijo_con_iva': precio_total,
                                'precio_venta': pricelist.definir_precio_venta,
                                'product': variante.id
                            })

                    else:
                        for line in pricelist.lines:
                            if line.percentage:
                                if line.percentage > 0:
                                    percentage = line.percentage/100
                                if line.use_new_formula == True:
                                    if line.price_list.definir_precio_tarjeta == True:
                                        precio_final = p.list_price / (1 - percentage)
                                    else:
                                        precio_final = p.cost_price / (1 - percentage)
                                else:
                                    if line.price_list.definir_precio_tarjeta == True:
                                        precio_final = p.list_price * (1 + percentage)
                                    else:
                                        precio_final = p.cost_price * (1 + percentage)
                            else:
                                self.raise_user_error('Debe asignar el porcentaje de ganancia en la lista de precio')
                            if user.company.currency:
                                precio_final = user.company.currency.round(precio_final)

                        if p.taxes_category == True:
                            if p.category.taxes_parent == True:
                                taxes1= Taxes1.search([('category','=', p.category.parent)])
                                taxes2 = Taxes2.search([('product','=', p)])
                            else:
                                taxes1= Taxes1.search([('category','=', p.category)])
                        else:
                            taxes1= Taxes1.search([('category','=', p.category)])
                            taxes2 = Taxes2.search([('product','=', p)])

                        if taxes1:
                            for t in taxes1:
                                iva = precio_final * t.tax.rate
                        elif taxes2:
                            for t in taxes2:
                                iva = precio_final * t.tax.rate

                        precio_total = precio_final + iva

                        if pricelist.definir_precio_venta == True:
                            p.list_price = precio_final
                            p.list_price_with_tax = precio_total
                            p.save()

                        lineas.append({
                            'template': p.id,
                            'lista_precio': pricelist.id,
                            'fijo' : precio_final,
                            'fijo_con_iva': precio_total,
                            'precio_venta': pricelist.definir_precio_venta,
                            'product' : variante.id
                        })
        listas_precios = ListByProduct.create(lineas)
        return 'end'
<file_sep>#This file is part of Tryton.  The COPYRIGHT file at the top level of
#this repository contains the full copyright notices and license terms.#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.pool import Pool
from .product import *
from .price_list import *

def register():
    Pool.register(
        Template,
        ListByProduct,
        PriceList,
        PriceListLine,
        UpdateListByProduct,
        UpdatePriceListByProduct,
        module='nodux_product_price_list_by_product', type_='model')
    Pool.register(
        WizardListByProduct,
        WizardPriceListByProduct,
        module='nodux_product_price_list_by_product', type_='wizard')
