title: Error"AttributeError: 'product.pricelist' object has no attribute 'get_product_pricelist'
body: <p>i'm using odoo 9 and i want to install module "product_print_zpl_barcode" with add a wizard on product variant which allows to generate and print a product barcode on a ZPL printer . When i press on the button "Print barcode" an error shows which said " AttributeError: 'product.pricelist' object has no attribute 'get_product_pricelist' " Any help please ??</p>
  
  <p>Product.xml </p>
  
  <pre><code> &lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;odoo&gt;
  &lt;record id="product_normal_form_view" model="ir.ui.view"&gt;
  &lt;field name="name"&gt;generate.weight.price.barcode.product.product.form&lt;/field&gt;
  &lt;field name="model"&gt;product.product&lt;/field&gt;
  &lt;field name="inherit_id" ref="product.product_normal_form_view" /&gt;
  &lt;field name="arch" type="xml"&gt;
      &lt;header position="inside"&gt;
          &lt;button name="%(product_print_zpl_barcode.product_print_zpl_barcode_action)d" type="action" string="Print Barcode"/&gt;
      &lt;/header&gt;
  &lt;/field&gt;
  &lt;/record&gt;
  &lt;/odoo&gt;
  </code></pre>
  
  <p>product_print_zpl_barcode.py</p>
  
  <h1>-<em>- coding: utf-8 -</em>-</h1>
  
  <pre><code> from openerp import models, fields, api, _
   from openerp.exceptions import UserError
   from openerp.tools import float_compare, float_is_zero
   import openerp.addons.decimal_precision as dp
   import base64
   import re
  
  
   class ProductPrintZplBarcode(models.TransientModel):
  _name = 'product.print.zpl.barcode'
  _description = 'Generate and print product barcodes in ZPL'
  
  @api.model
  def default_get(self, fields_list):
      res = super(ProductPrintZplBarcode, self).default_get(fields_list)
      assert self._context.get('active_model') == 'product.product',\
          'wrong active_model, should be product.product'
      product_id = self._context.get('active_id')
      product = self.env['product.product'].browse(product_id)
      if not product:
          raise UserError(_('Missing Product'))
      if not product.barcode:
          raise UserError(_(
              "Product '%s' doesn't have a barcode") % product.display_name)
      nomenclature = self.env.ref('barcodes.default_barcode_nomenclature')
      company = self.env.user.company_id
      posconfig = self.env['pos.config'].sudo().search(
          [('company_id', '=', company.id)], limit=1)
      if posconfig:
          pricelist = posconfig.pricelist_id
      else:
          pricelist = self.env['product.pricelist'].search([
              '|', ('company_id', '=', False),
              ('company_id', '=', company.id),
              ], limit=1)
      if not pricelist:
          raise UserError(_(
              "There are no pricelist in company %s ?") % company.name)
  
      printer = self.env['printing.printer'].get_default()
      res.update({
          'nomenclature_id': nomenclature.id,
          'pricelist_id': pricelist.id,
          'currency_id': pricelist.currency_id.id,
          'barcode': product.barcode,
          'product_name': product.name,
          'product_id': product_id,
          'zpl_printer_id': printer and printer.id or False,
      })
      return res
  
  product_id = fields.Many2one(
      'product.product', string='Product', required=True, readonly=True)
  uom_id = fields.Many2one(
      related='product_id.uom_id', readonly=True)
  # 1 line = un peu moins de 30
  product_name = fields.Char('Product Label', required=True, size=56)
  nomenclature_id = fields.Many2one(
      'barcode.nomenclature', 'Barcode Nomenclature', required=True)
  rule_id = fields.Many2one(
      'barcode.rule', string='Barcode Rule', readonly=True,
      compute='_compute_rule_id')
  barcode_type = fields.Selection(
      related='rule_id.type', readonly=True, string="Barcode Type")
  label_size = fields.Selection([
      ('38x25', '38x25 mm'),
      ], required=True, default='38x25', string='Label Size')
  pricelist_id = fields.Many2one(
      'product.pricelist', string='Pricelist', required=True)
  currency_id = fields.Many2one(
      related='pricelist_id.currency_id', readonly=True)
  # TODO: for the moment, we only support weight, but...
  quantity = fields.Float(digits=dp.get_precision('Stock Weight'))
  price_uom = fields.Monetary(
      readonly=True, string="Price per Unit of Measure",
      compute='_compute_price')  # given by pricelist
  price = fields.Monetary(compute='_compute_price', readonly=True)
  currency_id = fields.Many2one('res.currency', string='Currency')
  state = fields.Selection([
      ('step1', 'Step1'),
      ('step2', 'Step2'),
      ], default='step1', readonly=True)
  zpl_file = fields.Binary(string='ZPL File', readonly=True)
  zpl_filename = fields.Char('ZPL Filename')
  barcode = fields.Char(readonly=True)
  copies = fields.Integer(
      string='Number of Labels', default=1, required=True)
  zpl_printer_id = fields.Many2one(
      'printing.printer', string='ZPL Printer')
  
  @api.depends('pricelist_id', 'quantity', 'product_id')
  def _compute_price(self):
      # for regular barcodes
      for wiz in self:
          if wiz.pricelist_id and wiz.product_id:
              price_uom = wiz.pricelist_id.get_product_pricelist(
                  wiz.product_id, 1, False)
              wiz.price_uom = price_uom
              wiz.price = price_uom * wiz.quantity
      return wiz.price
  
  @api.one
  @api.depends('nomenclature_id')
  def _compute_rule_id(self):
      match_rule = False
      if self.nomenclature_id and self.barcode:
          for rule in self.nomenclature_id.rule_ids:
              match = self.nomenclature_id.match_pattern(
                  self.barcode, rule.pattern)
              if match.get('match'):
                  match_rule = rule.id
                  break
      self.rule_id = match_rule
  
  def _prepare_price_weight_barcode_type(self):
      dpo = self.env['decimal.precision']
      bno = self.env['barcode.nomenclature']
      prec = dpo.precision_get('Stock Weight')
      value = self.quantity
      pbarcode = self.barcode
      if float_is_zero(value, precision_digits=prec):
          raise UserError(_(
              "The quantity (%s) must be positive !") % value)
      # check prefix
      pattern = self.rule_id.pattern
      if '{' not in pattern:
          raise UserError(_(
              "The barcode rule '%s' has a pattern '%s' which doesn't "
              "contain a integer and decimal part between '{}'.")
              % (self.rule_id.name, pattern))
      prefix = pattern.split('{')[0]
      assert len(prefix) &gt;= 1
      if len(prefix) &gt; len(pbarcode):
          raise UserError(_(
              "The barcode of the product (%s) has %d characters, "
              "which is smaller than the %d characters of the prefix "
              "of the barcode pattern (%s).")
              % (pbarcode, len(pbarcode), len(prefix), prefix))
      barcode = pbarcode[0:len(prefix)]
      # print "barcode=", barcode
      # print "pattern=", pattern
      m = re.search('\{N+D+\}', pattern)
      # print "m=", m
      assert m
      pattern_val = m.group(0)
      pattern_val = pattern_val[1:-1]
      # print "pattern_val=", pattern_val
      max_value = 10**pattern_val.count('N')
      if float_compare(value, max_value, precision_digits=prec) != -1:
          raise UserError(_(
              "The value to encode in the barcode (%s) is superior "
              "to the maximum value allowed by the barcode pattern (%s).")
              % (value, max_value))
      value_u = unicode(value)
      value_u_split = value_u.split('.')
      assert len(value_u_split) == 2
      value_n = value_u_split[0]
      value_d = value_u_split[1]
      assert len(value_n) &lt;= pattern_val.count('N')
      barcode += value_n.zfill(pattern_val.count('N'))
      # end fill doesn't exists... so:
      # 1) make sure we have enough 0 after
      value_d_ext = value_d + '0' * pattern_val.count('D')
      # 2) cut at the right size
      barcode += value_d_ext[0:pattern_val.count('D')]
      # print "barcode=", barcode
      # Add checksum
      if self.rule_id.encoding == 'ean13':
          barcode = bno.sanitize_ean(barcode)
          # print "barcode FINAL=", barcode
      zpl_unicode = self._price_weight_barcode_type_zpl() % {
          'product_name': self.product_name,
          'ean13_no_checksum': barcode[:12],
          'price_uom': self.price_uom,
          'price': self.price,
          'currency_symbol': self.currency_id.symbol,
          'copies': self.copies,
          'quantity': value,
          'uom_name': self.uom_id.name,
      }
      zpl_encoded = zpl_unicode.encode('utf-8')
      vals = {
          'zpl_file': zpl_encoded.encode('base64'),
          'barcode': barcode,
          }
      return vals
  
  @api.model
  def _price_weight_barcode_type_zpl(self):
      label = u"""
   ^XA
   ^CI28
   ^PW304
   ^LL200
   ^LH0,20
   ^CF0,30
   ^FO15,0^FB270,1,0,C^FD%(price).2f %(currency_symbol)s^FS
   ^CF0,20
   ^FO15,30^FB270,3,0,C^FD%(product_name)s^FS
   ^CF0,25
   ^FO15,75^FB270,1,0,C^FD%(quantity).3f %(uom_name)s    %(price_uom).2f % 
    (currency_symbol)s/%(uom_name)s^FS
   ^FO60,110^BEN,50^FD%(ean13_no_checksum)s^FS
   ^PQ%(copies)s
   ^XZ
   """
      return label
  
  @api.model
  def _product_barcode_type_zpl(self):
      label = u"""
    ^XA
    ^CI28
    ^PW304
    ^LL200
    ^LH0,20
    ^CF0,30
    ^FO15,0^FB270,1,0,C^FD%(price_uom).2f %(currency_symbol)s^FS
    ^CF0,20
    ^FO15,30^FB270,3,0,C^FD%(product_name)s^FS
    ^FO60,100^BEN,60^FD%(ean13_no_checksum)s^FS
    ^PQ%(copies)s
    ^XZ
    """
      return label
  
  def _prepare_product_barcode_type(self):
      zpl_unicode = self._product_barcode_type_zpl() % {
          'product_name': self.product_name,
          'ean13_no_checksum': self.barcode[:12],
          'price_uom': self.price_uom,
          'currency_symbol': self.currency_id.symbol,  # symbol is a required field
          'copies': self.copies,
      }
      zpl_encoded = zpl_unicode.encode('utf-8')
      vals = {
          'zpl_file': zpl_encoded.encode('base64'),
          'barcode': self.barcode,  # unchanged
          }
      return vals
  
  def generate(self):
      assert self.barcode
      if len(self.barcode) != 13:
          raise UserError(_(
              "This wizard only supports EAN13 for the moment. Barcode '%s' "
              "has %d digits instead of 13") % (
              self.barcode,
              len(self.barcode)))
      if not self.copies:
          raise UserError(_("The number of copies cannot be 0"))
      if self.barcode_type in ('price', 'weight'):
          vals = self._prepare_price_weight_barcode_type()
      elif self.barcode_type == 'product':
          vals = self._prepare_product_barcode_type()
      else:
          raise UserError(_(
              "Barcode Type %s is not supported for the moment")
              % self.barcode_type)
      vals.update({
          'state': 'step2',
          'zpl_filename': 'barcode_%s.zpl' % vals['barcode'],
          })
      self.write(vals)
      action = self.env['ir.actions.act_window'].for_xml_id(
          'product_print_zpl_barcode',
          'product_print_zpl_barcode_action')
      action.update({
          'res_id': self.id,
          'context': self._context,
          'views': False})
      return action
  
  def print_zpl(self):
      if not self.zpl_printer_id:
          raise UserError(_(
              "You must select a ZPL Printer."))
      self.zpl_printer_id.print_document(
          self.zpl_filename, base64.decodestring(self.zpl_file), 'raw')
      action = True
      if self._context.get('print_and_new'):
          action = self.env['ir.actions.act_window'].for_xml_id(
              'product_print_zpl_barcode',
              'product_print_zpl_barcode_action')
          action.update({
              'views': False,
              'context': self._context,
              })
      return action
  </code></pre>
  
  <p>Traceback </p>
  
  <pre><code>    Traceback (most recent call last):
      File "D:\Projet_Odoo\Odoo 9.0-20180426\server\.\openerp\http.py", line 
     650, in _handle_exception
     File "D:\Projet_Odoo\Odoo 9.0-20180426\server\.\openerp\http.py", line 
     687, in dispatch
     File "D:\Projet_Odoo\Odoo 9.0-20180426\server\.\openerp\http.py", line 
     323, in _call_function
     File "D:\Projet_Odoo\Odoo 9.0- 
     20180426\server\.\openerp\service\model.py", line 118, in wrapper
     File "D:\Projet_Odoo\Odoo 9.0-20180426\server\.\openerp\http.py", line 
     316, in checked_call
     File "D:\Projet_Odoo\Odoo 9.0-20180426\server\.\openerp\http.py", line 
     966, in __call__
     File "D:\Projet_Odoo\Odoo 9.0-20180426\server\.\openerp\http.py", line 
     516, in response_wrap
     File "D:\Projet_Odoo\Odoo 9.0- 
     20180426\server\openerp\addons\web\controllers\main.py", line 896, in 
     call_kw
     File "D:\Projet_Odoo\Odoo 9.0- 
     20180426\server\openerp\addons\web\controllers\main.py", line 888, in 
     _call_kw
      File "D:\Projet_Odoo\Odoo 9.0-20180426\server\.\openerp\api.py", line 
     250, in wrapper
     File "D:\Projet_Odoo\Odoo 9.0-20180426\server\.\openerp\api.py", line 
     381, in old_api
     File "D:\Projet_Odoo\Odoo 9.0-20180426\server\.\openerp\models.py", line 
    6067, in onchange
    File "D:\Projet_Odoo\Odoo 9.0-20180426\server\.\openerp\models.py", line 
    5770, in __getitem__
   File "D:\Projet_Odoo\Odoo 9.0-20180426\server\.\openerp\fields.py", line 
   834, in __get__
   File "D:\Projet_Odoo\Odoo 9.0-20180426\server\.\openerp\fields.py", line 
  949, in determine_draft_value
  File "D:\Projet_Odoo\Odoo 9.0-20180426\server\.\openerp\fields.py", line 
  895, in compute_value
  File "D:\Projet_Odoo\Odoo 9.0-20180426\server\.\openerp\fields.py", line 
  885, in _compute_value
   File "D:\Projet_Odoo\Odoo 9.0-20180426\server\openerp\addons\product_print_zpl_barcode\models\product_print_zpl_barcode.py", line 98, in _compute_price
   AttributeError: 'product.pricelist' object has no attribute 
   'get_product_pricelist'
  </code></pre>