Browse Source

Lista de precios adrielso

sebastian 5 years ago
commit
977b93e43e

+ 3 - 0
__init__.py

@@ -0,0 +1,3 @@
+# -*- coding: utf-8 -*-
+
+import models

BIN
__init__.pyc


+ 21 - 0
__openerp__.py

@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+{
+    'name': "Product Price list Utility",
+    'description': "Mejora el calculo de la lista de precio  ",
+    'author': "Adrielso Kunert",
+    'category': 'sale, purchase, Account',
+    'version': '0.1',
+    'depends': [
+        'base',
+        'sale',
+        'product_pricelist_prices'
+    ],
+    'data': [
+        'views/template.xml',
+        'views/product_product.xml',
+    ],
+    'qweb' : [
+        'static/src/xml/*.xml',
+        'static/src/xml/modal/*.xml'
+    ]
+}

+ 3 - 0
models/__init__.py

@@ -0,0 +1,3 @@
+# -*- coding: utf-8 -*-
+
+import product_pricelist_porcent

BIN
models/__init__.pyc


+ 232 - 0
models/product_pricelist_porcent.py

@@ -0,0 +1,232 @@
+# -*- coding: utf-8 -*-
+
+import logging
+from openerp import models, fields, api, _
+from openerp.exceptions import Warning
+
+_logger = logging.getLogger(__name__)
+
+class ProductPricelistPorcent(models.Model):
+    _name = 'product.pricelist.porcent'
+
+    minimum_percent = fields.Float(digits=(5, 2))
+    maximum_percent = fields.Float(digits=(5, 2))
+
+    price_minimum = fields.Float(string="Price Minimo")
+    price_maximum = fields.Float(string="Price Maximo")
+    price_coste = fields.Float(string="Price coste")
+
+    product_id  = fields.Many2one('product.product', 'Product Variant')
+    product_tmpl_id = fields.Many2one('product.template', 'Product')
+    pricelist_id = fields.Many2one('product.pricelist', 'Pricelist')
+
+''' PRODUCT TEMPLATE '''
+class ProductTemplatePricelist(models.Model):
+    _inherit = 'product.template'
+
+    pricelist_procent_id = fields.One2many('product.pricelist.porcent', 'product_tmpl_id', string='pricelist porcent',)
+
+''' PRODUCT PRODUCT '''
+class ProductProductPricelist(models.Model):
+    _inherit = 'product.product'
+
+    pricelist_procent_id = fields.One2many('product.pricelist.porcent', 'product_id', string='pricelist porcent',)
+
+''' PRODUCT PRICELIST '''
+class ProductPricelistUtility(models.Model):
+    _inherit = 'product.pricelist'
+
+    product_price_minimum = fields.Float(compute="_get_product_price_minimum",string="Price Minimo")
+    pricelist_procent_id = fields.One2many('product.pricelist.porcent', 'pricelist_id', string='pricelist porcent',)
+
+    @api.one
+    def _get_product_price_minimum(self):
+        product_id = self._get_product_id()
+        if product_id:
+            percent = self.env['product.pricelist.porcent'].search([('product_id', '=', product_id),('pricelist_id', '=', self.id)])
+            self.product_price_minimum = percent.price_minimum or self.price_get(product_id, 1).get(self.id, 0.0)
+
+    @api.model
+    def get_pricelist_sale(self, productId):
+        product = self.env['product.product'].browse(productId)
+
+        standard_price = 0.0
+        if (product):
+            standard_price = product.standard_price or 0.0
+
+        priceList = self.env['product.pricelist'].search([('type', '=', 'sale'),('active', '=', True),('show_on_products', '=', True)])
+        if (not priceList):
+            return False
+
+        listPrice = []
+        for list in priceList:
+
+            percent = self.env['product.pricelist.porcent'].search([('product_id', '=', productId),('pricelist_id', '=', list.id)])
+            listPrice.append({
+                'id': list.id,
+                'name': list.name,
+                'showOnProducts': list.show_on_products,
+                'productPrice': list.product_price,
+                'productPriceManual': list.product_price_manual,
+                'productId': list.product_id,
+                'productPriceMinimum': list.product_price_minimum,
+                'standardPrice': standard_price,
+                'minimumPercent': percent.minimum_percent or 0.0,
+                'maximumPercent': percent.maximum_percent or 0.0,
+                'priceMinimum': percent.price_minimum or 0.0,
+                'priceMaximum': percent.price_maximum or 0.0,
+                'currency': {
+    				'id': list.currency_id.id,
+    				'symbol': list.currency_id.symbol,
+    				'decimalSeparator': list.currency_id.decimal_separator,
+    				'decimalPlaces': list.currency_id.decimal_places,
+    				'thousandsSeparator': list.currency_id.thousands_separator,
+        		},
+            })
+
+        if (not listPrice):
+            return False
+
+        return listPrice
+
+    @api.model
+    def calculate_priceList_percent(self, coste, percent):
+        decimal_precision = self.env['decimal.precision'].precision_get('Account')
+        coste = float(coste)
+        percent = float(percent)
+        amount = round(coste * (1 + (percent/100)), decimal_precision)
+        return amount or 0
+
+    @api.model
+    def update_priceList_percent(self, values):
+        for line in values:
+            ''' product.product '''
+            product = self.env['product.product'].browse(line['product_id'])
+            if (not product):
+                return {'state': False, 'message': "Error en obtener el producto"}
+
+            ''' product.pricelist '''
+            pricelist = self.env['product.pricelist'].browse(line['list_id'])
+            if (not pricelist):
+                return {'state': False, 'message': "Error en obtener la Lista de precio"}
+
+            ''' product.pricelist.porcent '''
+            pricelistPercent = self.env['product.pricelist.porcent'].search([('product_id', '=', product.id), ('pricelist_id', '=', pricelist.id)])
+            if (pricelistPercent):
+                pricelistPercent.unlink()
+
+            percent = {
+                'minimum_percent': line['minimum_percent'],
+                'maximum_percent': line['maximum_percent'],
+                'price_minimum': line['price_minimum'],
+                'price_maximum': line['price_maximum'],
+                'price_coste': line['standard_price'],
+                'product_id':product.id ,
+                'product_tmpl_id': product.product_tmpl_id.id,
+                'pricelist_id':pricelist.id ,
+            }
+            pricelistPercent = self.env['product.pricelist.porcent'].create(percent)
+            newPrice = pricelist.price_set(product.product_tmpl_id, line['price_maximum'], product.id)
+            product.write({'lst_price': line['price_maximum']})
+
+        return {
+            'state': False,
+            'message': "Lista de precio Actualizada"
+        }
+
+    @api.multi
+    def price_set(self, product_template, new_price, product=False):
+        """
+        Set the price of the product in current pricelist
+        if different from price through  pricerules
+        :param product_template: product_template object
+        :param product: product_id change price
+        :param new_price: new price
+        :return:
+        """
+        if new_price:
+            version = self.get_active_pricelist_version()
+            if not version:
+                return False
+            items = self.env['product.pricelist.item'].search(
+                    [
+                        ('product_tmpl_id','=', product_template.id),
+                        ('price_version_id', '=', version.id),
+                        ('product_id', '=', product)
+                    ]
+            )
+            product_price_type_ids = self.env['product.price.type'].search(
+                    [
+                        ('field', '=', 'list_price')
+                    ]
+            )
+            if not items:
+                self.env['product.pricelist.item'].create(
+                        {
+                            'base': product_price_type_ids and product_price_type_ids[0].id,
+                            'sequence': 1,
+                            'name': product_template.name,
+                            'product_tmpl_id': product_template.id,
+                            'price_version_id': version.id,
+                            'price_surcharge': new_price,
+                            'price_discount': -1,
+                            'product_id': product,
+                        }
+                )
+            else:
+                for item in items:
+                    item.write(
+                            {
+                                'base': product_price_type_ids and product_price_type_ids[0].id,
+                                'sequence': 1,
+                                'name': product_template.name,
+                                'product_tmpl_id': product_template.id,
+                                'price_version_id': version.id,
+                                'price_surcharge': new_price,
+                                'product_id': product,
+                                'price_discount': -1
+                            }
+                    )
+            return True
+
+
+class SaleOrderPricelist(models.Model):
+    _inherit = 'sale.order'
+
+    @api.multi
+    def action_button_confirm(self):
+        message1 = ""
+        for xsale in self.order_line:
+            listPercent = self.env['product.pricelist.porcent'].search([('product_id', '=', xsale.product_id.id), ('pricelist_id', '=', self.pricelist_id.id)])
+            if (listPercent):
+                if (xsale.price_unit < listPercent.price_minimum):
+                    message1 += "\n Producto (%s)    Precio de Venta (%s)    Precio de Minimo (%s)" %(xsale.name.encode("utf-8") ,xsale.price_unit, listPercent.price_minimum)
+
+        message = "¡Precio de venta no permitido!\n¡El monto ingresado es menor  al precio mínimo permitido!\n"
+        message += message1
+        if message1:
+            raise Warning(_(message))
+
+        return super(SaleOrderPricelist, self).action_button_confirm()
+
+''' Sale Order LIne '''
+class SaleOrderLinePricelist(models.Model):
+    _inherit = 'sale.order.line'
+
+    @api.onchange('price_unit')
+    def _change_pricelist_validate(self):
+        if (not self.product_id):
+            return
+
+        if (not self.order_id.pricelist_id):
+            return
+
+        listPercent = self.env['product.pricelist.porcent'].search([('product_id', '=', self.product_id.id), ('pricelist_id', '=', self.order_id.pricelist_id.id)])
+        if (not listPercent):
+            return
+
+        if (self.price_unit < listPercent.price_minimum):
+            price = self.price_unit
+            msg = 'El valor ingresado es menor al precio mínimo permito.\
+                    Valor Ingresado %s precio  mínimo %s"' %(price,listPercent.price_minimum)
+            raise Warning(_(msg))

BIN
models/product_pricelist_porcent.pyc


BIN
static/description/icon.png


+ 151 - 0
static/src/css/style.css

@@ -0,0 +1,151 @@
+@media (min-width: 768px){
+    .expired-account-modal .modal-lg {
+        width: 800px !important;
+    }
+}
+.widget-content.widget-loading-product-pricelist-utility {
+    position: absolute;
+    width: 100%;
+    height: 100%;
+    color : #000;
+    display: none;
+    z-index: 1100;
+    background: #8080806b;
+    align-items: center;
+    justify-content: center;
+}
+
+.pricelist-utility-input-percent {
+    width: 60px !important;
+    height: 30px !important;
+    font-size: 10pt;
+    text-align: right;
+    margin-top: 2px;
+    margin-left: 0px;
+    margin-right: 0px;
+}
+.pricelist-utility-input-amount {
+    width: 126px !important;
+    height: 30px !important;
+    background-color: #eee !important;
+    font-size: 10pt;
+    margin-top: 2px;
+    text-align: right;
+    margin-left: 0px;
+    margin-right: 0px;
+}
+/*____________ TABLE _____________*/
+ .product-pricelist-utility-table {
+     margin-top: 0px !important;
+ }
+.expired-account-modal .modal-head-wrapper-product-pricelist-utility {
+     width: 100%;
+}
+.expired-account-modal .modal-item-product-pricelist-utility {
+    width: 100%;
+    height: 246px;
+    overflow-y: auto;
+}
+
+/* Table Header */
+.expired-account-modal .product-pricelist-utility-table table thead tr {
+    height: 40px !important;
+}
+
+.expired-account-modal .product-pricelist-utility-table table thead tr th:nth-child(1) {
+    width: 220px;
+    text-align: center;
+    font-size: 10pt;
+    font-weight: bold;
+    display: flex !important;
+    height: 40px !important;
+    padding-top: 10px;
+    float: left;
+}
+.expired-account-modal .product-pricelist-utility-table table thead tr th:nth-child(2) {
+    width: 130px;
+    font-size: 10pt;
+    font-weight: bold;
+    display: flex !important;
+    height: 40px !important;
+    padding-top: 10px;
+}
+.expired-account-modal .product-pricelist-utility-table table thead tr th:nth-child(3){
+    width: 64px;
+    font-size: 10pt;
+    font-weight: bold;
+    padding-left: 2px;
+    padding-right: 2px;
+}
+.expired-account-modal .product-pricelist-utility-table table thead tr th:nth-child(4){
+    width: 130px;
+    font-size: 10pt;
+    font-weight: bold;
+}
+.expired-account-modal .product-pricelist-utility-table table thead tr th:nth-child(5){
+    width: 64px;
+    font-size: 10pt;
+    font-weight: bold;
+    padding-left: 0px;
+    padding-right: 1px;
+}
+.expired-account-modal .product-pricelist-utility-table table thead tr th:nth-child(6){
+    width: 130px;
+    font-size: 10pt;
+    font-weight: bold;
+}
+.expired-account-modal .product-pricelist-utility-table table thead tr th:nth-child(7){
+    display: none;
+}
+
+/* TBODY */
+.expired-account-modal .product-pricelist-utility-table table tbody tr {
+    height: 35px;
+}
+.expired-account-modal .product-pricelist-utility-table table tbody tr td:nth-child(1) {
+    width: 221px;
+    font-size: 10pt;
+    padding-left: 10px;
+    padding-top: 8px;
+}
+.expired-account-modal .product-pricelist-utility-table table tbody tr td:nth-child(2) {
+    width: 130px;
+    padding-left: 2px;
+    padding-right: 2px;
+}
+.expired-account-modal .product-pricelist-utility-table table tbody tr td:nth-child(3) {
+    width: 64px;
+    padding-left: 2px;
+    padding-right: 2px;
+}
+.expired-account-modal .product-pricelist-utility-table table tbody tr td:nth-child(4) {
+    width: 130px;
+    padding-left: 2px;
+    padding-right: 2px;
+}
+.expired-account-modal .product-pricelist-utility-table table tbody tr td:nth-child(5) {
+    width: 64px;
+    padding-left: 2px;
+    padding-right: 2px;
+}
+.expired-account-modal .product-pricelist-utility-table table tbody tr td:nth-child(6) {
+    width: 130px;
+    padding-left: 2px;
+    padding-right: 2px;
+}
+.expired-account-modal .product-pricelist-utility-table table tbody tr td:nth-child(7) {
+    display: none;
+}
+
+/*---------------------
+        Button
+------------------------*/
+.term-configurator-footer {
+    padding-top: 10px;
+    padding-bottom: 10px;
+}
+.term-configurator-button {
+    font-size: 12pt !important;
+    width: 130px;
+    height: 35px;
+}

+ 310 - 0
static/src/js/eiru_payment_term_configurator.js

@@ -0,0 +1,310 @@
+(function() {
+    openerp.widgetInstanceProductPricelistUtility = null;
+    openerp.parentInstanceProductPricelistUtility = null;
+    var Qweb = openerp.web.qweb;
+    var instance = openerp;
+    var instanceWeb = openerp.web;
+
+    openerp.ProductPricelistUtility = instance.Widget.extend({
+        template: 'productPricelistUtility.Percent',
+        id: undefined,
+
+        priceList: [],
+        percentFormat: {
+            'decimalSeparator': ',',
+            'decimalPlaces': 2,
+            'thousandsSeparator': '.'
+        },
+
+        init: function(parent) {
+            this._super(parent);
+            this.buttons = parent.$buttons;
+        },
+        start: function() {
+            var self = this;
+
+            this.$el.click(function(){
+                self.fectchInitial();
+            });
+            self.buttons.click(function(e) {
+                /* E (Editar) */
+                if (e.target.accessKey === 'E')
+                    self.$el.css('display','none');
+                /* S (Guarrdar) */
+                if (e.target.accessKey === 'S')
+                    self.$el.css('display','flex');
+                /* D (Cancelar) */
+                if (e.target.accessKey === 'D')
+                    self.$el.css('display','flex');
+                /* CREAR */
+                if (e.target.accessKey === 'C')
+                    self.$el.css('display','none');
+            });
+        },
+
+        updateId: function(id) {
+            var self = this;
+            self.id = id;
+
+            self.$el.css('display','flex');
+            if (!id)
+                self.$el.css('display','none');
+        },
+        /* Remover */
+        removeModal: function() {
+            $('.expired-account-modal').remove();
+            $('.modal-backdrop').remove();
+        },
+        /* Reloada */
+        reloadPage: function() {
+            openerp.parentInstanceProductPricelistUtility.reload();
+        },
+        /* Metodo Inicial */
+        fectchInitial: function() {
+            var self = this;
+
+            self.fetchPriceList(self.id).then(function(priceList) {
+                return priceList;
+            }).then(function(priceList) {
+                self.priceList = _.sortBy(priceList, 'name');
+
+                return self.showModal();
+
+            });
+        },
+        /* Get SALE ORDER */
+        fetchPriceList: function(productID) {
+            var list = new openerp.web.Model('product.pricelist');
+            return list.call('get_pricelist_sale',[productID],{
+                context: new openerp.web.CompoundContext()
+            });
+        },
+
+        fornatPriceList: function(){
+            var self = this;
+            _.each(self.priceList, function(list){
+                list.standardPriceFormat = instanceWeb.formatCurrency(list.standardPrice, list.currency);
+                list.priceMinimumFormat = instanceWeb.formatCurrency(list.priceMinimum, list.currency);
+                list.priceMaximumFormat = instanceWeb.formatCurrency(list.priceMaximum, list.currency);
+                list.minimumPercentFormat = instanceWeb.formatCurrency(list.minimumPercent, self.percentFormat);
+                list.maximumPercentFormat = instanceWeb.formatCurrency(list.maximumPercent, self.percentFormat);
+            });
+        },
+
+        /* Modal */
+        showModal: function() {
+            var self = this;
+            var defer = $.Deferred();
+            var state = true;
+            self.fornatPriceList();
+            var lists = self.priceList
+            var currency = lists[0].currency;
+            /* Modal */
+            var modal = Qweb.render('productPricelistUtility.ModalPercent', {'lists':lists});
+            $('.openerp_webclient_container').after(modal);
+            $('.expired-account-modal').modal();
+
+            // /* table */
+            var tableRow = $('.expired-account-modal').find('.table-tbody').find('tr');
+            var buttonAccept = $('.expired-account-modal').find('.priceList-utility-button');
+
+            /*##################################################################
+            #######     PERCENT MINIMUM         ################################
+            ##################################################################*/
+            tableRow.focusin(function(e) {
+                if (($(e.target).index() !== 0) && ($(e.target)[0].className !== 'pricelist-utility-input-percent'))
+                    return false;
+
+                var itemClass = ($(e.target)[0].className).split(" ")
+                /* MINIMO */
+                if (!!_.contains(itemClass,'minimum-percent')) {
+                    var percent = $($(e.target).closest('tr').children()[2]).find('.minimum-percent');
+                    var values = instanceWeb.unFormatCurrency(percent.val());
+                    if (values === 0)
+                        percent.val('');
+                }
+                /* MAXIMO */
+                if (!!_.contains(itemClass,'maximum-percent')) {
+                    var percent = $($(e.target).closest('tr').children()[4]).find('.maximum-percent');
+                    var values = instanceWeb.unFormatCurrency(percent.val());
+                    if (values === 0)
+                        percent.val('');
+                }
+            });
+            tableRow.keyup(function(e) {
+                if (($(e.target).index() !== 0) && ($(e.target)[0].className !== 'pricelist-utility-input-percent'))
+                    return false;
+
+                var itemClass = ($(e.target)[0].className).split(" ")
+                /* MINIMO */
+                if (!!_.contains(itemClass,'minimum-percent')) {
+                    var percent = $($(e.target).closest('tr').children()[2]).find('.minimum-percent');
+                    var values = instanceWeb.unFormatCurrency(percent.val());
+
+                    if (e.key === self.percentFormat.decimalSeparator && self.percentFormat.decimalPlaces > 0)
+                        return false ;
+
+                    percent.val(instanceWeb.formatCurrency(values, self.percentFormat));
+                }
+                /* MAXIMO */
+                if (!!_.contains(itemClass,'maximum-percent')) {
+                    var percent = $($(e.target).closest('tr').children()[4]).find('.maximum-percent');
+                    var values = instanceWeb.unFormatCurrency(percent.val());
+
+                    if (e.key === self.percentFormat.decimalSeparator && self.percentFormat.decimalPlaces > 0)
+                        return false ;
+
+                    percent.val(instanceWeb.formatCurrency(values, self.percentFormat));
+                }
+
+            });
+            tableRow.focusout(function(e) {
+                if (($(e.target).index() !== 0) && ($(e.target)[0].className !== 'pricelist-utility-input-percent'))
+                    return false;
+
+                var itemClass = ($(e.target)[0].className).split(" ")
+                /* MINIMO */
+                if (!!_.contains(itemClass,'minimum-percent')) {
+                    var percent = $($(e.target).closest('tr').children()[2]).find('.minimum-percent');
+                    var values = instanceWeb.unFormatCurrency(percent.val());
+                    var minimo  = $($(e.target).closest('tr').children()[3]).find('.price-minimum');
+
+                    if (values<= 0) {
+                        minimo.val("0")
+                        return false
+                    }
+
+                    var standardPrice  = $($(e.target).closest('tr').children()[1]).find('.standard-price');
+                    var coste = instanceWeb.unFormatCurrency(standardPrice.val());
+
+                    self.calculatePriceList(coste,values).then(function(calculate){
+                        return calculate
+                    }).then(function(calculate){
+                        minimo.val(instanceWeb.formatCurrency(calculate,currency))
+                    })
+
+                }
+                /* MAXIMO */
+                if (!!_.contains(itemClass,'maximum-percent')) {
+                    var percent = $($(e.target).closest('tr').children()[4]).find('.maximum-percent');
+                    var values = instanceWeb.unFormatCurrency(percent.val());
+                    var maximo  = $($(e.target).closest('tr').children()[5]).find('.price-maximum');
+
+                    if (values<= 0) {
+                        maximo.val("0")
+                        return false
+                    }
+
+                    var standardPrice  = $($(e.target).closest('tr').children()[1]).find('.standard-price');
+                    var coste = instanceWeb.unFormatCurrency(standardPrice.val());
+
+                    self.calculatePriceList(coste,values).then(function(calculate){
+                        return calculate
+                    }).then(function(calculate){
+                        maximo.val(instanceWeb.formatCurrency(calculate,currency))
+                    })
+                }
+            });
+
+            /*#######################################################
+            ########    ACEPTAR / GUARDAR       #####################
+            #######################################################*/
+            buttonAccept.click(function(e) {
+                var listPrice = [];
+
+                _.each(tableRow, function(tr) {
+                    var idList = parseInt(($(tr).children()[6].textContent).trim());
+                    var nameList = ($(tr).children()[0].textContent).trim();
+                    var coste = instanceWeb.unFormatCurrency(($($(tr).children()[1]).find('.standard-price')).val());
+                    var percentMinimum = instanceWeb.unFormatCurrency(($($(tr).children()[2]).find('.minimum-percent')).val());
+                    var priceMinimum = instanceWeb.unFormatCurrency(($($(tr).children()[3]).find('.price-minimum')).val());
+                    var precentMaximum = instanceWeb.unFormatCurrency(($($(tr).children()[4]).find('.maximum-percent')).val());
+                    var priceMaximum = instanceWeb.unFormatCurrency(($($(tr).children()[5]).find('.price-maximum')).val());
+
+                    listPrice.push({
+                        'list_id': idList,
+                        'name_list': nameList,
+                        'standard_price': coste,
+                        'minimum_percent': percentMinimum,
+                        'price_minimum': priceMinimum,
+                        'maximum_percent': precentMaximum,
+                        'price_maximum': priceMaximum,
+                        'product_id': self.id,
+                    })
+                });
+
+                if (!listPrice.length) {
+                    instanceWeb.notification.do_warn("Atencion", "No existe lista de precio para ser Guardada.");
+                    return false
+                }
+
+                $('.expired-account-modal').find('.widget-content widget-loading-product-pricelist-utility').css('display','flex');
+                self.updatePricelistpercent(listPrice).then(function(list){
+                    return list;
+                }).then(function(list){
+                    $('.expired-account-modal').find('.widget-content widget-loading-product-pricelist-utility').css('display','none');
+                    if (!list.state){
+                        instanceWeb.notification.do_warn("Atencion", list.message);
+                    }
+
+                    self.removeModal(e);
+                    state = list.state;
+                    self.reloadPage();
+                })
+
+                defer.resolve(state);
+            });
+            /*-----------
+                CERRAR
+            -----------*/
+            $('.expired-account-modal').on('hidden.bs.modal', function (e) {
+                defer.resolve(false);
+                self.removeModal(e);
+            });
+
+            return defer;
+        },
+        calculatePriceList: function(coste, percent){
+            var list = new openerp.web.Model('product.pricelist');
+            return list.call('calculate_priceList_percent',[coste, percent],{
+                context: new openerp.web.CompoundContext()
+            });
+        },
+
+        updatePricelistpercent: function(listPrice) {
+            var list = new openerp.web.Model('product.pricelist');
+            return list.call('update_priceList_percent',[listPrice],{
+                context: new openerp.web.CompoundContext()
+            });
+        },
+    });
+
+    if (instance.web && instance.web.FormView) {
+        instance.web.FormView.include({
+            load_record: function(record) {
+                this._super.apply(this, arguments);
+
+                if (this.model !== 'product.product')
+                    return;
+
+                openerp.parentInstanceProductPricelistUtility = this;
+
+                if (openerp.widgetInstanceProductPricelistUtility) {
+                    openerp.widgetInstanceProductPricelistUtility.updateId(record.id);
+                    if (this.$el.find('.button-config-percent').length !== 0){
+                        return
+                    }
+                }
+                if (this.$el.find('.button-config-percent').length !== 0 )
+                    return;
+
+                openerp.widgetInstanceProductPricelistUtility = new openerp.ProductPricelistUtility(this);
+                var elemento = this.$el.find('.oe_form').find('.product-pricelist-utility-config');
+
+                openerp.widgetInstanceProductPricelistUtility.appendTo(elemento);
+                openerp.widgetInstanceProductPricelistUtility.updateId(record.id);
+            },
+
+        });
+    }
+})();

+ 77 - 0
static/src/xml/modal/modal_eiru_payment_term_configurator.xml

@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<template xml:space="preserve">
+    <t t-name="productPricelistUtility.ModalPercent">
+        <div class="modal in expired-account-modal" tabindex="-1" role="dialog"  data-backdrop="static">
+            <div class="modal-dialog modal-lg" role="document">
+                <div class="modal-content openerp">
+                    <div class="widget-content widget-loading-product-pricelist-utility">
+                        <i class='fa fa-cog fa-spin fa-3x fa-fw'></i>
+                    </div>
+                    <!-- title  -->
+                    <div class="modal-header term-configurator-header">
+                        <button type="button" class="close" data-dismiss="modal" aria-label="Close" aria-hidden="true">×</button>
+                        <h3 class="modal-title">Configuración de Precio </h3>
+                    </div>
+                    <!-- Body -->
+                    <div class="modal-body">
+                        <!-- Table -->
+                        <div class="oe_view_manager_body product-pricelist-utility-table">
+                            <div class="modal-head-wrapper-product-pricelist-utility">
+                                <table class="oe_list_content">
+                                    <thead >
+                                        <tr class="oe_list_header_columns"  >
+                                            <th class="oe_list_header_char oe_sortable">Lista de precio</th>
+                                            <th class="oe_list_header_char oe_sortable">Coste</th>
+                                            <th class="oe_list_header_char oe_sortable">% Mínimo</th>
+                                            <th class="oe_list_header_char oe_sortable">Precio Mínimo </th>
+                                            <th class="oe_list_header_char oe_sortable">% Máximo</th>
+                                            <th class="oe_list_header_char oe_sortable">Precio Máximo</th>
+                                            <th class="oe_list_header_char oe_sortable"></th>
+
+                                        </tr>
+                                    </thead>
+                                </table>
+                            </div>
+                            <div class="modal-item-product-pricelist-utility">
+                                <table class="oe_list_content">
+                                    <tbody class="table-tbody">
+                                        <tr t-foreach="lists" t-as="list">
+                                            <td>
+                                                <t t-esc="list_value.name"/>
+                                            </td>
+                                            <td>
+                                                <input type="text" class="pricelist-utility-input-amount standard-price" t-attf-value="{{list_value.standardPriceFormat}}" readonly="readonly" disabled="disabled"></input>
+                                            </td>
+                                            <td>
+                                                <input type="text" class="pricelist-utility-input-percent minimum-percent" t-attf-value="{{list_value.minimumPercentFormat}}"></input>
+                                            </td>
+                                            <td>
+                                                <input type="text" class="pricelist-utility-input-amount price-minimum" t-attf-value="{{list_value.priceMinimumFormat}}" readonly="readonly" disabled="disabled"></input>
+
+                                            </td>
+                                            <td>
+                                                <input type="text" class="pricelist-utility-input-percent maximum-percent" t-attf-value="{{list_value.maximumPercentFormat}}"></input>
+                                            </td>
+                                            <td>
+                                                <input type="text" class="pricelist-utility-input-amount price-maximum" t-attf-value="{{list_value.priceMaximumFormat}}" readonly="readonly" disabled="disabled"></input>
+                                            </td>
+                                            <td>
+                                                <t t-esc="list_value.id"/>
+                                            </td>
+                                        </tr>
+                                    </tbody>
+                                </table>
+                            </div>
+                        </div>
+                    </div>
+                    <!-- Pie de Pagina -->
+                    <div class="modal-footer term-configurator-footer">
+                        <button type="button" class="oe_button oe_form_button oe_highlight button-accept priceList-utility-button">Guardar</button>
+                        <button type="button" class="oe_button oe_form_button oe_link dismmis-modal term-configurator-button" data-dismiss="modal">Salir</button>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </t>
+
+</template>

+ 8 - 0
static/src/xml/product_pricelist_utility.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<template xml:space="preserve">
+    <t t-name="productPricelistUtility.Percent">
+        <button type="button" class="button-config-percent button-action-term oe_button oe_highlight">
+            Configuración de Precio
+        </button>
+    </t>
+</template>

+ 18 - 0
views/product_product.xml

@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+    <data>
+        <record id="product_pricelist_utility_product_product" model="ir.ui.view">
+            <field name="name">product_pricelist_utility.product_product</field>
+            <field name="model">product.product</field>
+            <field name="inherit_id" ref="product_pricelist_prices.product_normal_form_view"/>
+            <field name="arch" type="xml">
+                <field name="pricelists" position="before">
+                    <div class="product-pricelist-utility-config"></div>
+                </field>
+                <field name="product_price" position="before">
+                    <field name="product_price_minimum" string="Minimo"/>
+                </field>
+            </field>
+        </record>
+    </data>
+</openerp>

+ 11 - 0
views/template.xml

@@ -0,0 +1,11 @@
+<openerp>
+    <data>
+        <!-- product_pricelist_utility -->
+        <template id="product_pricelist_utility.assets_backend" name="product_pricelist_utility_assets" inherit_id="eiru_assets.assets">
+            <xpath expr="." position="inside">
+                <link rel="stylesheet" href="/product_pricelist_utility/static/src/css/style.css"/>
+                <script type="text/javascript" src="/product_pricelist_utility/static/src/js/eiru_payment_term_configurator.js"/>
+            </xpath>
+        </template>
+    </data>
+</openerp>