Merge with addons-trunk revno 7150
authorAlexis de Lattre <alexis@via.ecp.fr>
Thu, 2 Aug 2012 13:40:12 +0000 (15:40 +0200)
committerAlexis de Lattre <alexis@via.ecp.fr>
Thu, 2 Aug 2012 13:40:12 +0000 (15:40 +0200)
Adapt views accordingly

bzr revid: alexis@via.ecp.fr-20120802134012-fjk20wld5rv9v45i

1  2 
addons/account/account.py
addons/account/account_invoice.py
addons/account/account_move_line.py
addons/account/partner_view.xml
addons/purchase/purchase.py
addons/purchase/purchase_view.xml
addons/purchase/stock.py
addons/purchase/wizard/purchase_line_invoice.py
addons/stock/stock.py

@@@ -29,6 -29,8 +29,8 @@@ import poole
  from osv import fields, osv
  import decimal_precision as dp
  from tools.translate import _
+ from tools.float_utils import float_round
  _logger = logging.getLogger(__name__)
  
  def check_cycle(self, cr, uid, ids, context=None):
@@@ -101,7 -103,7 +103,7 @@@ class account_payment_term_line(osv.osv
          'value': fields.selection([('procent', 'Percent'),
                                     ('balance', 'Balance'),
                                     ('fixed', 'Fixed Amount')], 'Valuation',
-                                    required=True, help="""Select here the kind of valuation related to this payment term line. Note that you should have your last line with the type 'Balance' to ensure that the whole amount will be threated."""),
+                                    required=True, help="""Select here the kind of valuation related to this payment term line. Note that you should have your last line with the type 'Balance' to ensure that the whole amount will be treated."""),
  
          'value_amount': fields.float('Amount To Pay', digits_compute=dp.get_precision('Payment Term'), help="For percent enter a ratio between 0-1."),
          'days': fields.integer('Number of Days', required=True, help="Number of days to add before computation of the day of month." \
@@@ -313,8 -315,8 +315,8 @@@ class account_account(osv.osv)
              cr.execute(request, params)
              _logger.debug('Status: %s',(cr.statusmessage))
  
-             for res in cr.dictfetchall():
-                 accounts[res['id']] = res
+             for row in cr.dictfetchall():
+                 accounts[row['id']] = row
  
              # consolidate accounts with direct children
              children_and_consolidated.reverse()
          'shortcut': fields.char('Shortcut', size=12),
          'tax_ids': fields.many2many('account.tax', 'account_account_tax_default_rel',
              'account_id', 'tax_id', 'Default Taxes'),
-         'note': fields.text('Note'),
+         'note': fields.text('Internal Notes'),
          'company_currency_id': fields.function(_get_company_currency, type='many2one', relation='res.currency', string='Company Currency'),
          'company_id': fields.many2one('res.company', 'Company', required=True),
          'active': fields.boolean('Active', select=2, help="If the active field is set to False, it will allow you to hide the account without removing it."),
@@@ -714,6 -716,7 +716,7 @@@ class account_journal(osv.osv)
      _name = "account.journal"
      _description = "Journal"
      _columns = {
+         'with_last_closing_balance' : fields.boolean('Opening With Last Closing Balance'),
          'name': fields.char('Journal Name', size=64, required=True),
          'code': fields.char('Code', size=5, required=True, help="The code will be displayed on reports."),
          'type': fields.selection([('sale', 'Sale'),('sale_refund','Sale Refund'), ('purchase', 'Purchase'), ('purchase_refund','Purchase Refund'), ('cash', 'Cash'), ('bank', 'Bank and Cheques'), ('general', 'General'), ('situation', 'Opening/Closing Situation')], 'Type', size=32, required=True,
          'centralisation': fields.boolean('Centralised counterpart', help="Check this box to determine that each entry of this journal won't create a new counterpart but will share the same counterpart. This is used in fiscal year closing."),
          'update_posted': fields.boolean('Allow Cancelling Entries', help="Check this box if you want to allow the cancellation the entries related to this journal or of the invoice related to this journal"),
          'group_invoice_lines': fields.boolean('Group Invoice Lines', help="If this box is checked, the system will try to group the accounting lines when generating them from invoices."),
-         'sequence_id': fields.many2one('ir.sequence', 'Entry Sequence', help="This field contains the informatin related to the numbering of the journal entries of this journal.", required=True),
+         'sequence_id': fields.many2one('ir.sequence', 'Entry Sequence', help="This field contains the information related to the numbering of the journal entries of this journal.", required=True),
          'user_id': fields.many2one('res.users', 'User', help="The user responsible for this journal"),
          'groups_id': fields.many2many('res.groups', 'account_journal_group_rel', 'journal_id', 'group_id', 'Groups'),
          'currency': fields.many2one('res.currency', 'Currency', help='The currency used to enter statement'),
          'entry_posted': fields.boolean('Skip \'Draft\' State for Manual Entries', help='Check this box if you don\'t want new journal entries to pass through the \'draft\' state and instead goes directly to the \'posted state\' without any manual validation. \nNote that journal entries that are automatically created by the system are always skipping that state.'),
          'company_id': fields.many2one('res.company', 'Company', required=True, select=1, help="Company related to this journal"),
          'allow_date':fields.boolean('Check Date in Period', help= 'If set to True then do not accept the entry if the entry date is not into the period dates'),
+         'profit_account_id' : fields.many2one('account.account', 'Profit Account'),
+         'loss_account_id' : fields.many2one('account.account', 'Loss Account'),
+         'internal_account_id' : fields.many2one('account.account', 'Internal Transfers Account', select=1),
      }
  
      _defaults = {
+         'with_last_closing_balance' : False,
          'user_id': lambda self, cr, uid, context: uid,
          'company_id': lambda self, cr, uid, c: self.pool.get('res.users').browse(cr, uid, uid, c).company_id.id,
      }
@@@ -1263,7 -1271,7 +1271,7 @@@ class account_move(osv.osv)
          'period_id': fields.many2one('account.period', 'Period', required=True, states={'posted':[('readonly',True)]}),
          'journal_id': fields.many2one('account.journal', 'Journal', required=True, states={'posted':[('readonly',True)]}),
          'state': fields.selection([('draft','Unposted'), ('posted','Posted')], 'Status', required=True, readonly=True,
-             help='All manually created new journal entries are usually in the state \'Unposted\', but you can set the option to skip that state on the related journal. In that case, they will be behave as journal entries automatically created by the system on document validation (invoices, bank statements...) and will be created in \'Posted\' state.'),
+             help='All manually created new journal entries are usually in the state \'Unposted\', but you can set the option to skip that state on the related journal. In that case, they will behave as journal entries automatically created by the system on document validation (invoices, bank statements...) and will be created in \'Posted\' state.'),
          'line_id': fields.one2many('account.move.line', 'move_id', 'Entries', states={'posted':[('readonly',True)]}),
          'to_check': fields.boolean('To Review', help='Check this box if you are unsure of that journal entry and if you want to note it as \'to be reviewed\' by an accounting expert.'),
          'partner_id': fields.related('line_id', 'partner_id', type="many2one", relation="res.partner", string="Partner", store=True),
@@@ -1782,7 -1790,7 +1790,7 @@@ class account_tax_code(osv.osv)
          'line_ids': fields.one2many('account.move.line', 'tax_code_id', 'Lines'),
          'company_id': fields.many2one('res.company', 'Company', required=True),
          'sign': fields.float('Coefficent for parent', required=True, help='You can specify here the coefficient that will be used when consolidating the amount of this case into its parent. For example, set 1/-1 if you want to add/substract it.'),
-         'notprintable':fields.boolean("Not Printable in Invoice", help="Check this box if you don't want any VAT related to this Tax Code to appear on invoices"),
+         'notprintable':fields.boolean("Not Printable in Invoice", help="Check this box if you don't want any tax related to this tax code to appear on invoices"),
          'sequence': fields.integer('Sequence', help="Determine the display order in the report 'Accounting \ Reporting \ Generic Reporting \ Taxes \ Taxes Report'"),
      }
  
@@@ -1862,8 -1870,10 +1870,10 @@@ class account_tax(osv.osv)
          'applicable_type': fields.selection( [('true','Always'), ('code','Given by Python Code')], 'Applicability', required=True,
              help="If not applicable (computed through a Python code), the tax won't appear on the invoice."),
          'domain':fields.char('Domain', size=32, help="This field is only used if you develop your own module allowing developers to create specific taxes in a custom domain."),
-         'account_collected_id':fields.many2one('account.account', 'Invoice Tax Account'),
-         'account_paid_id':fields.many2one('account.account', 'Refund Tax Account'),
+         'account_collected_id':fields.many2one('account.account', 'Invoice Tax Account', help="Set the account that will be set by default on invoice tax lines for invoices. Leave empty to use the expense account."),
+         'account_paid_id':fields.many2one('account.account', 'Refund Tax Account', help="Set the account that will be set by default on invoice tax lines for refunds. Leave empty to use the expense account."),
+         'account_analytic_collected_id':fields.many2one('account.analytic.account', 'Invoice Tax Analytic Account', help="Set the analytic account that will be used by default on the invoice tax lines for invoices. Leave empty if you don't want to use an analytic account on the invoice tax lines by default."),
+         'account_analytic_paid_id':fields.many2one('account.analytic.account', 'Refund Tax Analytic Account', help="Set the analytic account that will be used by default on the invoice tax lines for refunds. Leave empty if you don't want to use an analytic account on the invoice tax lines by default."),
          'parent_id':fields.many2one('account.tax', 'Parent Tax Account', select=True),
          'child_ids':fields.one2many('account.tax', 'parent_id', 'Child Tax Accounts'),
          'child_depend':fields.boolean('Tax on Children', help="Set if the tax computation is based on the computation of child taxes rather than on the total amount."),
          'python_applicable':fields.text('Python Code'),
  
          #
-         # Fields used for the VAT declaration
+         # Fields used for the Tax declaration
          #
-         'base_code_id': fields.many2one('account.tax.code', 'Account Base Code', help="Use this code for the VAT declaration."),
-         'tax_code_id': fields.many2one('account.tax.code', 'Account Tax Code', help="Use this code for the VAT declaration."),
+         'base_code_id': fields.many2one('account.tax.code', 'Account Base Code', help="Use this code for the tax declaration."),
+         'tax_code_id': fields.many2one('account.tax.code', 'Account Tax Code', help="Use this code for the tax declaration."),
          'base_sign': fields.float('Base Code Sign', help="Usually 1 or -1."),
          'tax_sign': fields.float('Tax Code Sign', help="Usually 1 or -1."),
  
          # Same fields for refund invoices
  
-         'ref_base_code_id': fields.many2one('account.tax.code', 'Refund Base Code', help="Use this code for the VAT declaration."),
-         'ref_tax_code_id': fields.many2one('account.tax.code', 'Refund Tax Code', help="Use this code for the VAT declaration."),
+         'ref_base_code_id': fields.many2one('account.tax.code', 'Refund Base Code', help="Use this code for the tax declaration."),
+         'ref_tax_code_id': fields.many2one('account.tax.code', 'Refund Tax Code', help="Use this code for the tax declaration."),
          'ref_base_sign': fields.float('Base Code Sign', help="Usually 1 or -1."),
          'ref_tax_sign': fields.float('Tax Code Sign', help="Usually 1 or -1."),
          'include_base_amount': fields.boolean('Included in base amount', help="Indicates if the amount of tax must be included in the base amount for the computation of the next taxes"),
                      'name':tax.description and tax.description + " - " + tax.name or tax.name,
                      'account_collected_id':tax.account_collected_id.id,
                      'account_paid_id':tax.account_paid_id.id,
+                     'account_analytic_collected_id': tax.account_analytic_collected_id.id,
+                     'account_analytic_paid_id': tax.account_analytic_paid_id.id,
                      'base_code_id': tax.base_code_id.id,
                      'ref_base_code_id': tax.ref_base_code_id.id,
                      'sequence': tax.sequence,
                  'taxes': []                  # List of taxes, see compute for the format
              }
          """
+         # By default, for each tax, tax amount will first be computed
+         # and rounded at the 'Account' decimal precision for each
+         # PO/SO/invoice line and then these rounded amounts will be
+         # summed, leading to the total amount for that tax. But, if the
+         # company has tax_calculation_rounding_method = round_globally,
+         # we still follow the same method, but we use a much larger
+         # precision when we round the tax amount for each line (we use
+         # the 'Account' decimal precision + 5), and that way it's like
+         # rounding after the sum of the tax amounts of each line
          precision = self.pool.get('decimal.precision').precision_get(cr, uid, 'Account')
-         totalin = totalex = round(price_unit * quantity, precision)
+         tax_compute_precision = precision
+         if taxes and taxes[0].company_id.tax_calculation_rounding_method == 'round_globally':
+             tax_compute_precision += 5
+         totalin = totalex = float_round(price_unit * quantity, precision)
          tin = []
          tex = []
          for tax in taxes:
                  tex.append(tax)
              else:
                  tin.append(tax)
-         tin = self.compute_inv(cr, uid, tin, price_unit, quantity, product=product, partner=partner)
+         tin = self.compute_inv(cr, uid, tin, price_unit, quantity, product=product, partner=partner, precision=tax_compute_precision)
          for r in tin:
              totalex -= r.get('amount', 0.0)
          totlex_qty = 0.0
              totlex_qty = totalex/quantity
          except:
              pass
-         tex = self._compute(cr, uid, tex, totlex_qty, quantity,product=product, partner=partner)
+         tex = self._compute(cr, uid, tex, totlex_qty, quantity, product=product, partner=partner, precision=tax_compute_precision)
          for r in tex:
              totalin += r.get('amount', 0.0)
          return {
          _logger.warning("Deprecated, use compute_all(...)['taxes'] instead of compute(...) to manage prices with tax included")
          return self._compute(cr, uid, taxes, price_unit, quantity, product, partner)
  
-     def _compute(self, cr, uid, taxes, price_unit, quantity, product=None, partner=None):
+     def _compute(self, cr, uid, taxes, price_unit, quantity, product=None, partner=None, precision=None):
          """
          Compute tax values for given PRICE_UNIT, QUANTITY and a buyer/seller ADDRESS_ID.
  
              tax = {'name':'', 'amount':0.0, 'account_collected_id':1, 'account_paid_id':2}
              one tax for each tax id in IDS and their children
          """
+         if not precision:
+             precision = self.pool.get('decimal.precision').precision_get(cr, uid, 'Account')
          res = self._unit_compute(cr, uid, taxes, price_unit, product, partner, quantity)
          total = 0.0
-         precision_pool = self.pool.get('decimal.precision')
          for r in res:
              if r.get('balance',False):
-                 r['amount'] = round(r.get('balance', 0.0) * quantity, precision_pool.precision_get(cr, uid, 'Account')) - total
+                 r['amount'] = round(r.get('balance', 0.0) * quantity, precision) - total
              else:
-                 r['amount'] = round(r.get('amount', 0.0) * quantity, precision_pool.precision_get(cr, uid, 'Account'))
+                 r['amount'] = round(r.get('amount', 0.0) * quantity, precision)
                  total += r['amount']
          return res
  
                  'amount': amount,
                  'account_collected_id': tax.account_collected_id.id,
                  'account_paid_id': tax.account_paid_id.id,
+                 'account_analytic_collected_id': tax.account_analytic_collected_id.id,
+                 'account_analytic_paid_id': tax.account_analytic_paid_id.id,
                  'base_code_id': tax.base_code_id.id,
                  'ref_base_code_id': tax.ref_base_code_id.id,
                  'sequence': tax.sequence,
              r['todo'] = 0
          return res
  
-     def compute_inv(self, cr, uid, taxes, price_unit, quantity, product=None, partner=None):
+     def compute_inv(self, cr, uid, taxes, price_unit, quantity, product=None, partner=None, precision=None):
          """
          Compute tax values for given PRICE_UNIT, QUANTITY and a buyer/seller ADDRESS_ID.
-         Price Unit is a VAT included price
+         Price Unit is a Tax included price
  
          RETURN:
              [ tax ]
              tax = {'name':'', 'amount':0.0, 'account_collected_id':1, 'account_paid_id':2}
              one tax for each tax id in IDS and their children
          """
+         if not precision:
+             precision = self.pool.get('decimal.precision').precision_get(cr, uid, 'Account')
          res = self._unit_compute_inv(cr, uid, taxes, price_unit, product, partner=None)
          total = 0.0
-         obj_precision = self.pool.get('decimal.precision')
          for r in res:
-             prec = obj_precision.precision_get(cr, uid, 'Account')
              if r.get('balance',False):
-                 r['amount'] = round(r['balance'] * quantity, prec) - total
+                 r['amount'] = round(r['balance'] * quantity, precision) - total
              else:
-                 r['amount'] = round(r['amount'] * quantity, prec)
+                 r['amount'] = round(r['amount'] * quantity, precision)
                  total += r['amount']
          return res
  
@@@ -2281,13 -2309,8 +2309,13 @@@ class account_model(osv.osv)
                      if not line.partner_id:
                          raise osv.except_osv(_('Error !'), _("Maturity date of entry line generated by model line '%s' of model '%s' is based on partner payment term!" \
                                                                  "\nPlease define partner on it!")%(line.name, model.name))
 -                    if line.partner_id.property_payment_term:
 +
 +                    payment_term_id = False
 +                    if model.journal_id.type in ('purchase', 'purchase_refund') and line.partner_id.property_supplier_payment_term:
 +                        payment_term_id = line.partner_id.property_supplier_payment_term.id
 +                    elif line.partner_id.property_payment_term:
                          payment_term_id = line.partner_id.property_payment_term.id
 +                    if payment_term_id:
                          pterm_list = pt_obj.compute(cr, uid, payment_term_id, value=1, date_ref=date_maturity)
                          if pterm_list:
                              pterm_list = [l[0] for l in pterm_list]
@@@ -2652,7 -2675,7 +2680,7 @@@ class account_tax_code_template(osv.osv
          'parent_id': fields.many2one('account.tax.code.template', 'Parent Code', select=True),
          'child_ids': fields.one2many('account.tax.code.template', 'parent_id', 'Child Codes'),
          'sign': fields.float('Sign For Parent', required=True),
-         'notprintable':fields.boolean("Not Printable in Invoice", help="Check this box if you don't want any VAT related to this Tax Code to appear on invoices"),
+         'notprintable':fields.boolean("Not Printable in Invoice", help="Check this box if you don't want any tax related to this tax Code to appear on invoices."),
      }
  
      _defaults = {
@@@ -2767,17 -2790,17 +2795,17 @@@ class account_tax_template(osv.osv)
          'python_applicable':fields.text('Python Code'),
  
          #
-         # Fields used for the VAT declaration
+         # Fields used for the Tax declaration
          #
-         'base_code_id': fields.many2one('account.tax.code.template', 'Base Code', help="Use this code for the VAT declaration."),
-         'tax_code_id': fields.many2one('account.tax.code.template', 'Tax Code', help="Use this code for the VAT declaration."),
+         'base_code_id': fields.many2one('account.tax.code.template', 'Base Code', help="Use this code for the tax declaration."),
+         'tax_code_id': fields.many2one('account.tax.code.template', 'Tax Code', help="Use this code for the tax declaration."),
          'base_sign': fields.float('Base Code Sign', help="Usually 1 or -1."),
          'tax_sign': fields.float('Tax Code Sign', help="Usually 1 or -1."),
  
          # Same fields for refund invoices
  
-         'ref_base_code_id': fields.many2one('account.tax.code.template', 'Refund Base Code', help="Use this code for the VAT declaration."),
-         'ref_tax_code_id': fields.many2one('account.tax.code.template', 'Refund Tax Code', help="Use this code for the VAT declaration."),
+         'ref_base_code_id': fields.many2one('account.tax.code.template', 'Refund Base Code', help="Use this code for the tax declaration."),
+         'ref_tax_code_id': fields.many2one('account.tax.code.template', 'Refund Tax Code', help="Use this code for the tax declaration."),
          'ref_base_sign': fields.float('Base Code Sign', help="Usually 1 or -1."),
          'ref_tax_sign': fields.float('Tax Code Sign', help="Usually 1 or -1."),
          'include_base_amount': fields.boolean('Include in Base Amount', help="Set if the amount of tax must be included in the base amount before computing the next taxes."),
@@@ -3330,15 -3353,7 +3358,7 @@@ class wizard_multi_charts_accounts(osv.
  
          # Create Bank journals
          self._create_bank_journals_from_o2m(cr, uid, obj_wizard, company_id, acc_template_ref, context=context)
-         action = {
-             'type': 'ir.actions.act_window',
-             'view_type': 'form',
-             'view_mode': 'form',
-             'res_model': 'board.board',
-             'view_id': self.pool.get('ir.model.data').get_object_reference(cr, uid, 'account', 'board_account_form')[1],
-             'menu_id': self.pool.get('ir.model.data').get_object_reference(cr, uid, 'account', 'menu_finance')[1]
-         }
-         return action
+         return {}
  
      def _prepare_bank_journal(self, cr, uid, line, current_num, default_account_id, company_id, context=None):
          '''
@@@ -195,7 -195,7 +195,7 @@@ class account_invoice(osv.osv)
          'number': fields.related('move_id','name', type='char', readonly=True, size=64, relation='account.move', store=True, string='Number'),
          'internal_number': fields.char('Invoice Number', size=32, readonly=True, help="Unique number of the invoice, computed automatically when the invoice is created."),
          'reference': fields.char('Invoice Reference', size=64, help="The partner reference of this invoice."),
-         'reference_type': fields.selection(_get_reference_type, 'Reference Type',
+         'reference_type': fields.selection(_get_reference_type, 'Payment Reference',
              required=True, readonly=True, states={'draft':[('readonly',False)]}),
          'comment': fields.text('Additional Information'),
  
          'date_invoice': fields.date('Invoice Date', readonly=True, states={'draft':[('readonly',False)]}, select=True, help="Keep empty to use the current date"),
          'date_due': fields.date('Due Date', states={'paid':[('readonly',True)], 'open':[('readonly',True)], 'close':[('readonly',True)]}, select=True,
              help="If you use payment terms, the due date will be computed automatically at the generation "\
 -                "of accounting entries. If you keep the payment term and the due date empty, it means direct payment. The payment term may compute several due dates, for example 50% now, 50% in one month."),
 +                "of accounting entries. If you want to force a due date, make sure that the payment term is not set on the invoice. If you keep the payment term and the due date empty, it means direct payment."),
          'partner_id': fields.many2one('res.partner', 'Partner', change_default=True, readonly=True, required=True, states={'draft':[('readonly',False)]}),
          'payment_term': fields.many2one('account.payment.term', 'Payment Term',readonly=True, states={'draft':[('readonly',False)]},
              help="If you use payment terms, the due date will be computed automatically at the generation "\
  
              if type in ('out_invoice', 'out_refund'):
                  acc_id = p.property_account_receivable.id
 +                partner_payment_term = p.property_payment_term and p.property_payment_term.id or False
              else:
                  acc_id = p.property_account_payable.id
 +                partner_payment_term = p.property_supplier_payment_term and p.property_supplier_payment_term.id or False
              fiscal_position = p.property_account_position and p.property_account_position.id or False
 -            partner_payment_term = p.property_payment_term and p.property_payment_term.id or False
              if p.bank_ids:
                  bank_id = p.bank_ids[0].id
  
              for tax in inv.tax_line:
                  if tax.manual:
                      continue
-                 key = (tax.tax_code_id.id, tax.base_code_id.id, tax.account_id.id)
+                 key = (tax.tax_code_id.id, tax.base_code_id.id, tax.account_id.id, tax.account_analytic_id.id)
                  tax_key.append(key)
                  if not key in compute_taxes:
                      raise osv.except_osv(_('Warning !'), _('Global taxes defined, but they are not in invoice lines !'))
@@@ -1346,7 -1345,7 +1346,7 @@@ class account_invoice_line(osv.osv)
      _name = "account.invoice.line"
      _description = "Invoice Line"
      _columns = {
-         'name': fields.char('Description', size=256, required=True),
+         'name': fields.text('Description', required=True),
          'origin': fields.char('Source', size=256, help="Reference of the document that produced this invoice."),
          'invoice_id': fields.many2one('account.invoice', 'Invoice Reference', ondelete='cascade', select=True),
          'uos_id': fields.many2one('product.uom', 'Unit of Measure', ondelete='set null'),
          'quantity': fields.float('Quantity', required=True),
          'discount': fields.float('Discount (%)', digits_compute= dp.get_precision('Account')),
          'invoice_line_tax_id': fields.many2many('account.tax', 'account_invoice_line_tax', 'invoice_line_id', 'tax_id', 'Taxes', domain=[('parent_id','=',False)]),
-         'note': fields.text('Notes'),
          'account_analytic_id':  fields.many2one('account.analytic.account', 'Analytic Account'),
          'company_id': fields.related('invoice_id','company_id',type='many2one',relation='res.company',string='Company', store=True, readonly=True),
          'partner_id': fields.related('invoice_id','partner_id',type='many2one',relation='res.partner',string='Partner',store=True)
  
          domain = {}
          result['uos_id'] = res.uom_id.id or uom or False
-         result['note'] = res.description
+         if res.description:
+             result['name'] += '\n'+res.description
          if result['uos_id']:
              res2 = res.uom_id.category_id.id
              if res2:
      def move_line_get_item(self, cr, uid, line, context=None):
          return {
              'type':'src',
-             'name': line.name[:64],
+             'name': line.name.split('\n')[0][:64],
              'price_unit':line.price_unit,
              'quantity':line.quantity,
              'price':line.price_subtotal,
@@@ -1579,6 -1578,7 +1579,7 @@@ class account_invoice_tax(osv.osv)
          'invoice_id': fields.many2one('account.invoice', 'Invoice Line', ondelete='cascade', select=True),
          'name': fields.char('Tax Description', size=64, required=True),
          'account_id': fields.many2one('account.account', 'Tax Account', required=True, domain=[('type','<>','view'),('type','<>','income'), ('type', '<>', 'closed')]),
+         'account_analytic_id': fields.many2one('account.analytic.account', 'Analytic account'),
          'base': fields.float('Base', digits_compute=dp.get_precision('Account')),
          'amount': fields.float('Amount', digits_compute=dp.get_precision('Account')),
          'manual': fields.boolean('Manual'),
                      val['base_amount'] = cur_obj.compute(cr, uid, inv.currency_id.id, company_currency, val['base'] * tax['base_sign'], context={'date': inv.date_invoice or time.strftime('%Y-%m-%d')}, round=False)
                      val['tax_amount'] = cur_obj.compute(cr, uid, inv.currency_id.id, company_currency, val['amount'] * tax['tax_sign'], context={'date': inv.date_invoice or time.strftime('%Y-%m-%d')}, round=False)
                      val['account_id'] = tax['account_collected_id'] or line.account_id.id
+                     val['account_analytic_id'] = tax['account_analytic_collected_id']
                  else:
                      val['base_code_id'] = tax['ref_base_code_id']
                      val['tax_code_id'] = tax['ref_tax_code_id']
                      val['base_amount'] = cur_obj.compute(cr, uid, inv.currency_id.id, company_currency, val['base'] * tax['ref_base_sign'], context={'date': inv.date_invoice or time.strftime('%Y-%m-%d')}, round=False)
                      val['tax_amount'] = cur_obj.compute(cr, uid, inv.currency_id.id, company_currency, val['amount'] * tax['ref_tax_sign'], context={'date': inv.date_invoice or time.strftime('%Y-%m-%d')}, round=False)
                      val['account_id'] = tax['account_paid_id'] or line.account_id.id
+                     val['account_analytic_id'] = tax['account_analytic_paid_id']
  
-                 key = (val['tax_code_id'], val['base_code_id'], val['account_id'])
+                 key = (val['tax_code_id'], val['base_code_id'], val['account_id'], val['account_analytic_id'])
                  if not key in tax_grouped:
                      tax_grouped[key] = val
                  else:
                  'price': t['amount'] or 0.0,
                  'account_id': t['account_id'],
                  'tax_code_id': t['tax_code_id'],
-                 'tax_amount': t['tax_amount']
+                 'tax_amount': t['tax_amount'],
+                 'account_analytic_id': t['account_analytic_id'],
              })
          return res
  
@@@ -19,6 -19,7 +19,7 @@@
  #
  ##############################################################################
  
+ import sys
  import time
  from datetime import datetime
  from operator import itemgetter
@@@ -326,7 -327,7 +327,7 @@@ class account_move_line(osv.osv)
  
          if account and ((not fields) or ('debit' in fields) or ('credit' in fields)):
              data['account_id'] = account.id
-             # Propose the price VAT excluded, the VAT will be added when confirming line
+             # Propose the price Tax excluded, the Tax will be added when confirming line
              if account.tax_ids:
                  taxes = fiscal_pos_obj.map_tax(cr, uid, part and part.property_account_position or False, account.tax_ids)
                  tax = tax_obj.browse(cr, uid, taxes)
              return {'value':val}
          if not date:
              date = datetime.now().strftime('%Y-%m-%d')
 +        jt = False
 +        if journal:
 +            jt = journal_obj.browse(cr, uid, journal).type
          part = partner_obj.browse(cr, uid, partner_id)
  
 -        if part.property_payment_term:
 -            res = payment_term_obj.compute(cr, uid, part.property_payment_term.id, 100, date)
 +        payment_term_id = False
 +        if jt and jt in ('purchase', 'purchase_refund') and part.property_supplier_payment_term:
 +            payment_term_id = part.property_supplier_payment_term.id
 +        elif jt and part.property_payment_term:
 +            payment_term_id = part.property_payment_term.id
 +        if payment_term_id:
 +            res = payment_term_obj.compute(cr, uid, payment_term_id, 100, date)
              if res:
                  val['date_maturity'] = res[0][0]
          if not account_id:
              id1 = part.property_account_payable.id
              id2 =  part.property_account_receivable.id
 -            if journal:
 -                jt = journal_obj.browse(cr, uid, journal).type
 +            if jt:
                  if jt in ('sale', 'purchase_refund'):
                      val['account_id'] = fiscal_pos_obj.map_account(cr, uid, part and part.property_account_position or False, id2)
                  elif jt in ('purchase', 'sale_refund'):
          if context.get('view_mode', False):
              return result
          fld = []
-         fields = {}
          flds = []
-         title = _("Accounting Entries") #self.view_header_get(cr, uid, view_id, view_type, context)
+         title = _("Accounting Entries")  # self.view_header_get(cr, uid, view_id, view_type, context)
  
-         ids = journal_pool.search(cr, uid, [])
+         ids = journal_pool.search(cr, uid, [], context=context)
          journals = journal_pool.browse(cr, uid, ids, context=context)
-         all_journal = [None]
-         common_fields = {}
-         total = len(journals)
          for journal in journals:
-             all_journal.append(journal.id)
              for field in journal.view_id.columns_id:
-                 # sometimes, it's possible that a defined column is not loaded (the module containing 
+                 # sometimes, it's possible that a defined column is not loaded (the module containing
                  # this field is not loaded) when we make an update.
-                 if field.name not in self._columns:
+                 if field.field not in self._columns:
                      continue
  
-                 if not field.field in fields:
-                     fields[field.field] = [journal.id]
+                 if not field.field in flds:
                      fld.append((field.field, field.sequence))
                      flds.append(field.field)
-                     common_fields[field.field] = 1
-                 else:
-                     fields.get(field.field).append(journal.id)
-                     common_fields[field.field] = common_fields[field.field] + 1
-         fld.append(('period_id', 3))
-         fld.append(('journal_id', 10))
-         flds.append('period_id')
-         flds.append('journal_id')
-         fields['period_id'] = all_journal
-         fields['journal_id'] = all_journal
+         default_columns = {
+             'period_id': 3,
+             'journal_id': 10,
+             'state': sys.maxint,
+         }
+         for d in default_columns:
+             if d not in flds:
+                 fld.append((d, default_columns[d]))
+                 flds.append(d)
          fld = sorted(fld, key=itemgetter(1))
          widths = {
              'statement_id': 50,
                                   colors="red:state=='draft';black:state=='valid'")
          fields_get = self.fields_get(cr, uid, flds, context)
          for field, _seq in fld:
-             if common_fields.get(field) == total:
-                 fields.get(field).append(None)
-             # if field=='state':
-             #     state = 'colors="red:state==\'draft\'"'
+             # TODO add string to element
              f = etree.SubElement(document, 'field', name=field)
  
              if field == 'debit':
                      }
                      if data['tax_code_id']:
                          self.create(cr, uid, data, context)
-                 #create the VAT movement
+                 #create the Tax movement
                  data = {
                      'move_id': vals['move_id'],
                      'name': tools.ustr(vals['name'] or '') + ' ' + tools.ustr(tax['name'] or ''),
              <field name="arch" type="xml">
                  <page string="History" position="before" version="7.0">
                  <page string="Accounting" col="4">
-                     <group col="4">
-                         <group string="Customer Accounting Properties" col="4">
-                             <field name="property_account_receivable" groups="account.group_account_invoice" />
-                             <field name="property_payment_term" widget="selection"/>
+                     <group>
+                         <group>
                              <field name="property_account_position" widget="selection"/>
                          </group>
-                         <group string="Supplier Accounting Properties" col="4">
-                             <field name="property_account_payable" groups="account.group_account_invoice"/>
-                             <field name="property_supplier_payment_term" widget="selection"/>
+                         <group>
+                             <field name="last_reconciliation_date"/>
                          </group>
-                         <group string="Customer Credit" col="4">
+                         <group>
+                             <field name="property_account_receivable" groups="account.group_account_invoice" />
+                             <field name="property_payment_term" widget="selection"/>
                              <field name="credit"/>
                              <field name="credit_limit"/>
                          </group>
-                         <group string="Supplier Debit" col="4">
+                         <group>
+                             <field name="property_account_payable" groups="account.group_account_invoice"/>
++                            <field name="property_supplier_payment_term" widget="selection"/>
                              <field name="debit"/>
                          </group>
-                         <field name="bank_ids">
-                             <form string="Bank account" version="7.0">
-                                 <field name="state"/>
-                                 <field name="acc_number"/>
-                                 <group>
-                                     <group name="owner" string="Bank Account Owner">
-                                         <field name="partner_id" on_change="onchange_partner_id(partner_id)"/>
-                                         <field name="owner_name"/>
-                                         <label for="street" string="Address"/>
+                     </group>
+                     <field name="bank_ids">
+                         <form string="Bank account" version="7.0">
+                             <field name="state"/>
+                             <field name="acc_number"/>
+                             <group>
+                                 <group name="owner" string="Bank Account Owner">
+                                     <field name="partner_id" on_change="onchange_partner_id(partner_id)"/>
+                                     <field name="owner_name"/>
+                                     <label for="street" string="Address"/>
+                                     <div>
+                                         <field name="street" placeholder="Street..."/>
                                          <div>
-                                             <field name="street" placeholder="Street..."/>
-                                             <div>
-                                                 <field name="zip" class="oe_inline" placeholder="ZIP"/>
-                                                 <field name="city" class="oe_inline" placeholder="City"/>
-                                             </div>
-                                             <field name="state_id" placeholder="State"/>
-                                             <field name="country_id" placeholder="Country"/>
+                                             <field name="zip" class="oe_inline" placeholder="ZIP"/>
+                                             <field name="city" class="oe_inline" placeholder="City"/>
                                          </div>
-                                     </group>
-                                     <group name="bank" string="Information About the Bank">
-                                         <field name="bank" on_change="onchange_bank_id(bank)"/>
-                                         <field name="bank_name"/>
-                                         <field name="bank_bic" placeholder="[Identifier code]"/>
-                                     </group>
+                                         <field name="state_id" placeholder="State"/>
+                                         <field name="country_id" placeholder="Country"/>
+                                     </div>
                                  </group>
-                             </form>
-                             <tree string="Bank Details">
-                                 <field name="sequence" invisible="1"/>
-                                 <field name="acc_number"/>
-                                 <field name="bank_name"/>
-                                 <field name="owner_name"/>
-                             </tree>
-                         </field>
-                     </group>
+                                 <group name="bank" string="Information About the Bank">
+                                     <field name="bank" on_change="onchange_bank_id(bank)"/>
+                                     <field name="bank_name"/>
+                                     <field name="bank_bic" placeholder="e.g. GEBABEBB"/>
+                                 </group>
+                             </group>
+                         </form>
+                         <tree string="Bank Details">
+                             <field name="sequence" invisible="1"/>
+                             <field name="acc_number"/>
+                             <field name="bank_name"/>
+                             <field name="owner_name"/>
+                         </tree>
+                     </field>
                  </page>
                  </page>
              </field>
              view_type="form"
              view_mode="tree,form,graph,calendar"/>
  
-         <record id="view_res_partner_reconcile" model="ir.ui.view">
-             <field name="name">res.partner.form.reconcile</field>
-             <field name="model">res.partner</field>
-             <field name="inherit_id" ref="base.view_partner_form"/>
-             <field name="arch" type="xml">
-                 <field name="credit_limit" position="after">
-                     <field name="last_reconciliation_date"/>
-                 </field>
-             </field>
-         </record>
      </data>
  </openerp>
@@@ -154,7 -154,7 +154,7 @@@ class purchase_order(osv.osv)
      ]
  
      _columns = {
-         'name': fields.char('Order Reference', size=64, required=True, select=True, help="unique number of the purchase order,computed automatically when the purchase order is created"),
+         'name': fields.char('Order Reference', size=64, required=True, select=True, help="Unique number of the purchase order, computed automatically when the purchase order is created."),
          'origin': fields.char('Source Document', size=64,
              help="Reference of the document that generated this purchase order request."
          ),
          'partner_id':fields.many2one('res.partner', 'Supplier', required=True, states={'confirmed':[('readonly',True)], 'approved':[('readonly',True)],'done':[('readonly',True)]}, change_default=True),
          'dest_address_id':fields.many2one('res.partner', 'Customer Address (Direct Delivery)',
              states={'confirmed':[('readonly',True)], 'approved':[('readonly',True)],'done':[('readonly',True)]},
-             help="Put an address if you want to deliver directly from the supplier to the customer." \
-                 "In this case, it will remove the warehouse link and set the customer location."
+             help="Put an address if you want to deliver directly from the supplier to the customer. " \
+                 "Otherwise, keep empty to deliver to your own company."
          ),
-         'warehouse_id': fields.many2one('stock.warehouse', 'Warehouse', states={'confirmed':[('readonly',True)], 'approved':[('readonly',True)],'done':[('readonly',True)]}),
+         'warehouse_id': fields.many2one('stock.warehouse', 'Destination Warehouse', states={'confirmed':[('readonly',True)], 'approved':[('readonly',True)],'done':[('readonly',True)]}),
          'location_id': fields.many2one('stock.location', 'Destination', required=True, domain=[('usage','<>','view')]),
          'pricelist_id':fields.many2one('product.pricelist', 'Pricelist', required=True, states={'confirmed':[('readonly',True)], 'approved':[('readonly',True)],'done':[('readonly',True)]}, help="The pricelist sets the currency used for this purchase order. It also computes the supplier price for the selected products/quantities."),
          'state': fields.selection(STATE_SELECTION, 'Status', readonly=True, help="The state of the purchase order or the quotation request. A quotation is a purchase order in a 'Draft' state. Then the order has to be confirmed by the user, the state switch to 'Confirmed'. Then the supplier must confirm the order to change the state to 'Approved'. When the purchase order is paid and received, the state becomes 'Done'. If a cancel action occurs in the invoice or in the reception of goods, the state becomes in exception.", select=True),
          'validator' : fields.many2one('res.users', 'Validated by', readonly=True),
          'notes': fields.text('Terms and Conditions'),
          'invoice_ids': fields.many2many('account.invoice', 'purchase_invoice_rel', 'purchase_id', 'invoice_id', 'Invoices', help="Invoices generated for a purchase order"),
-         'picking_ids': fields.one2many('stock.picking.in', 'purchase_id', 'Picking List', readonly=True, help="This is the list of incomming shipments that have been generated for this purchase order."),
+         'picking_ids': fields.one2many('stock.picking.in', 'purchase_id', 'Picking List', readonly=True, help="This is the list of incoming shipments that have been generated for this purchase order."),
          'shipped':fields.boolean('Received', readonly=True, select=True, help="It indicates that a picking has been done"),
          'shipped_rate': fields.function(_shipped_rate, string='Received', type='float'),
          'invoiced': fields.function(_invoiced, string='Invoice Received', type='boolean', help="It indicates that an invoice has been paid"),
                  'purchase.order.line': (_get_order, None, 10),
              }, multi="sums",help="The total amount"),
          'fiscal_position': fields.many2one('account.fiscal.position', 'Fiscal Position'),
 +        'payment_term': fields.many2one('account.payment.term', 'Payment Term'),
          'product_id': fields.related('order_line','product_id', type='many2one', relation='product.product', string='Product'),
          'create_uid':  fields.many2one('res.users', 'Responsible'),
          'company_id': fields.many2one('res.company','Company',required=True,select=1),
      def onchange_partner_id(self, cr, uid, ids, partner_id):
          partner = self.pool.get('res.partner')
          if not partner_id:
 -            return {'value':{'fiscal_position': False}}
 +            return {'value': {
 +                'fiscal_position': False,
 +                'payment_term': False,
 +                }}
          supplier_address = partner.address_get(cr, uid, [partner_id], ['default'])
          supplier = partner.browse(cr, uid, partner_id)
 -        pricelist = supplier.property_product_pricelist_purchase.id
 -        fiscal_position = supplier.property_account_position and supplier.property_account_position.id or False
 -        return {'value':{'pricelist_id': pricelist, 'fiscal_position': fiscal_position}}
 +        return {'value': {
 +            'pricelist_id': supplier.property_product_pricelist_purchase.id,
 +            'fiscal_position': supplier.property_account_position and supplier.property_account_position.id or False,
 +            'payment_term': supplier.property_supplier_payment_term.id or False,
 +            }}
  
      def view_invoice(self, cr, uid, ids, context=None):
          '''
                  'journal_id': len(journal_ids) and journal_ids[0] or False,
                  'invoice_line': [(6, 0, inv_lines)],
                  'origin': order.name,
 -                'fiscal_position': order.fiscal_position.id or order.partner_id.property_account_position.id,
 -                'payment_term': order.partner_id.property_payment_term and order.partner_id.property_payment_term.id or False,
 +                'fiscal_position': order.fiscal_position.id or False,
 +                'payment_term': order.payment_term.id or False,
                  'company_id': order.company_id.id,
              }
              inv_id = inv_obj.create(cr, uid, inv_data, context=context)
                      order_infos['origin'] = (order_infos['origin'] or '') + ' ' + porder.origin
  
              for order_line in porder.order_line:
-                 line_key = make_key(order_line, ('name', 'date_planned', 'taxes_id', 'price_unit', 'notes', 'product_id', 'move_dest_id', 'account_analytic_id'))
+                 line_key = make_key(order_line, ('name', 'date_planned', 'taxes_id', 'price_unit', 'product_id', 'move_dest_id', 'account_analytic_id'))
                  o_line = order_infos['order_line'].setdefault(line_key, {})
                  if o_line:
                      # merge the line with an existing line
@@@ -802,7 -796,7 +802,7 @@@ class purchase_order_line(osv.osv)
              return False
  
      _columns = {
-         'name': fields.char('Description', size=256, required=True),
+         'name': fields.text('Description', required=True),
          'product_qty': fields.float('Quantity', digits_compute=dp.get_precision('Product Unit of Measure'), required=True),
          'date_planned': fields.date('Scheduled Date', required=True, select=True),
          'taxes_id': fields.many2many('account.tax', 'purchase_order_taxe', 'ord_id', 'tax_id', 'Taxes'),
          'move_dest_id': fields.many2one('stock.move', 'Reservation Destination', ondelete='set null'),
          'price_unit': fields.float('Unit Price', required=True, digits_compute= dp.get_precision('Purchase Price')),
          'price_subtotal': fields.function(_amount_line, string='Subtotal', digits_compute= dp.get_precision('Purchase Price')),
-         'notes': fields.text('Notes'),
          'order_id': fields.many2one('purchase.order', 'Order Reference', select=True, required=True, ondelete='cascade'),
          'account_analytic_id':fields.many2one('account.analytic.account', 'Analytic Account',),
          'company_id': fields.related('order_id','company_id',type='many2one',relation='res.company',string='Company', store=True, readonly=True),
  
      def onchange_product_uom(self, cr, uid, ids, pricelist_id, product_id, qty, uom_id,
              partner_id, date_order=False, fiscal_position_id=False, date_planned=False,
-             name=False, price_unit=False, notes=False, context=None):
+             name=False, price_unit=False, context=None):
          """
          onchange handler of product_uom.
          """
          if not uom_id:
-             return {'value': {'price_unit': price_unit or 0.0, 'name': name or '', 'notes': notes or'', 'product_uom' : uom_id or False}}
+             return {'value': {'price_unit': price_unit or 0.0, 'name': name or '', 'product_uom' : uom_id or False}}
          return self.onchange_product_id(cr, uid, ids, pricelist_id, product_id, qty, uom_id,
              partner_id, date_order=date_order, fiscal_position_id=fiscal_position_id, date_planned=date_planned,
-             name=name, price_unit=price_unit, notes=notes, context=context)
+             name=name, price_unit=price_unit, context=context)
  
      def _get_date_planned(self, cr, uid, supplier_info, date_order_str, context=None):
          """Return the datetime value to use as Schedule Date (``date_planned``) for
  
      def onchange_product_id(self, cr, uid, ids, pricelist_id, product_id, qty, uom_id,
              partner_id, date_order=False, fiscal_position_id=False, date_planned=False,
-             name=False, price_unit=False, notes=False, context=None):
+             name=False, price_unit=False, context=None):
          """
          onchange handler of product_id.
          """
          if context is None:
              context = {}
  
-         res = {'value': {'price_unit': price_unit or 0.0, 'name': name or '', 'notes': notes or '', 'product_uom' : uom_id or False}}
+         res = {'value': {'price_unit': price_unit or 0.0, 'name': name or '', 'product_uom' : uom_id or False}}
          if not product_id:
              return res
  
          lang = res_partner.browse(cr, uid, partner_id).lang
          context_partner = {'lang': lang, 'partner_id': partner_id}
          product = product_product.browse(cr, uid, product_id, context=context_partner)
-         res['value'].update({'name': product.name, 'notes': notes or product.description_purchase})
+         name = product.name
+         if product.description_purchase:
+             name += '\n' + product.description_purchase
+         res['value'].update({'name': name})
  
          # - set a domain on product_uom
          res['domain'] = {'product_uom': [('category_id','=',product.uom_id.category_id.id)]}
  
          qty = qty or 1.0
          supplierinfo = False
-         supplierinfo_ids = product_supplierinfo.search(cr, uid, [('name','=',partner_id),('product_id','=',product.id)])
-         if supplierinfo_ids:
-             supplierinfo = product_supplierinfo.browse(cr, uid, supplierinfo_ids[0], context=context)
-             if supplierinfo.product_uom.id != uom_id:
-                 res['warning'] = {'title': _('Warning'), 'message': _('The selected supplier only sells this product by %s') % supplierinfo.product_uom.name }
-             min_qty = product_uom._compute_qty(cr, uid, supplierinfo.product_uom.id, supplierinfo.min_qty, to_uom_id=uom_id)
-             if qty < min_qty: # If the supplier quantity is greater than entered from user, set minimal.
-                 res['warning'] = {'title': _('Warning'), 'message': _('The selected supplier has a minimal quantity set to %s %s, you should not purchase less.') % (supplierinfo.min_qty, supplierinfo.product_uom.name)}
-                 qty = min_qty
+         for supplier in product.seller_ids:
+             if supplier.name.id == partner_id:
+                 supplierinfo = supplier
+                 if supplierinfo.product_uom.id != uom_id:
+                     res['warning'] = {'title': _('Warning'), 'message': _('The selected supplier only sells this product by %s') % supplierinfo.product_uom.name }
+                 min_qty = product_uom._compute_qty(cr, uid, supplierinfo.product_uom.id, supplierinfo.min_qty, to_uom_id=uom_id)
+                 if qty < min_qty: # If the supplier quantity is greater than entered from user, set minimal.
+                     res['warning'] = {'title': _('Warning'), 'message': _('The selected supplier has a minimal quantity set to %s %s, you should not purchase less.') % (supplierinfo.min_qty, supplierinfo.product_uom.name)}
+                     qty = min_qty
  
          dt = self._get_date_planned(cr, uid, supplierinfo, date_order, context=context).strftime(DEFAULT_SERVER_DATETIME_FORMAT)
  
@@@ -1055,15 -1051,17 +1057,17 @@@ class procurement_order(osv.osv)
              taxes_ids = procurement.product_id.product_tmpl_id.supplier_taxes_id
              taxes = acc_pos_obj.map_tax(cr, uid, partner.property_account_position, taxes_ids)
  
+             name = product.partner_ref
+             if product.description_purchase:
+                 name += '\n'+ product.description_purchase
              line_vals = {
-                 'name': product.partner_ref,
+                 'name': name,
                  'product_qty': qty,
                  'product_id': procurement.product_id.id,
                  'product_uom': uom_id,
                  'price_unit': price or 0.0,
                  'date_planned': schedule_date.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
                  'move_dest_id': res_id,
-                 'notes': product.description_purchase,
                  'taxes_id': [(6,0,taxes)],
              }
              name = seq_obj.get(cr, uid, 'purchase.order') or _('PO: %s') % procurement.name
                  'pricelist_id': pricelist_id,
                  'date_order': purchase_date.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
                  'company_id': procurement.company_id.id,
 -                'fiscal_position': partner.property_account_position and partner.property_account_position.id or False
 +                'fiscal_position': partner.property_account_position and partner.property_account_position.id or False,
 +                'payment_term': partner.property_supplier_payment_term.id or False,
              }
              res[procurement.id] = self.create_procurement_purchase_order(cr, uid, procurement, po_vals, line_vals, context=context)
              self.write(cr, uid, [procurement.id], {'state': 'running', 'purchase_id': res[procurement.id]})
@@@ -1,11 -1,14 +1,14 @@@
  <?xml version="1.0" encoding="utf-8"?>
  <openerp>
      <data>
-        <menuitem icon="terp-purchase" id="base.menu_purchase_root" name="Purchases" sequence="3"
-            groups="group_purchase_manager,group_purchase_user"
-            web_icon="images/purchases.png"
-            web_icon_hover="images/purchases-hover.png"/>
-        <menuitem id="menu_procurement_management" name="Purchase"
+         <!-- Top menu item -->
+         <menuitem name="Purchases"
+             id="base.menu_purchase_root"
+             groups="group_purchase_manager,group_purchase_user"
+             sequence="40"/>
+         <menuitem id="menu_procurement_management" name="Purchase"
              parent="base.menu_purchase_root" sequence="1" />
  
          <menuitem id="menu_purchase_config_purchase" name="Configuration"
              action="base.action_partner_category_form" id="menu_partner_categories_in_form" name="Partner Categories"
              parent="purchase.menu_purchase_partner_cat" groups="base.group_no_one"/>
  
-     <!--supplier menu-->
+     <!--Supplier menu-->
      <menuitem id="base.menu_procurement_management_supplier_name" name="Suppliers"
          parent="menu_procurement_management"
          action="base.action_partner_supplier_form" sequence="15"/>
  
-           <!--Inventory control-->
+       <!--Inventory control-->
        <menuitem id="menu_procurement_management_inventory" name="Receive Products"
              parent="base.menu_purchase_root" sequence="4"/>
        <menuitem action="stock.action_picking_tree4" id="menu_action_picking_tree4" parent="menu_procurement_management_inventory"
          <field name="domain">[('type','=','in_invoice')]</field>
          <field name="context">{'default_type':'in_invoice', 'type':'in_invoice', 'journal_type': 'purchase', 'search_default_draft': 1}</field>
          <field name="search_view_id" ref="account.view_account_invoice_filter"/>
-             <field name="help">
-                 Use this menu to control the invoices to be received from your supplier.
-                 OpenERP generates draft invoices from your purchase orders or receptions, according to your settings.
-                 Once you receive a supplier invoice, you can match it with the draft invoice and validate it.
-             </field>
+         <field name="help">
+             Use this menu to control the invoices to be received from your supplier.
+             OpenERP generates draft invoices from your purchase orders or receptions, according to your settings.
+             Once you receive a supplier invoice, you can match it with the draft invoice and validate it.
+         </field>
      </record>
  
       <menuitem name="Based on Draft Invoices"
@@@ -91,7 -94,7 +94,7 @@@
            parent="menu_procurement_management_invoice"
            sequence="13"/>
  
-       <!--product menu-->
+       <!-- Product menu-->
        <menuitem id="menu_procurement_management_product" name="Products"
            parent="base.menu_purchase_root" sequence="8"/>
  
              <field name="key2">client_action_multi</field>
          </record>
  
-        <record model="ir.ui.view" id="purchase_order_calendar">
+         <record model="ir.ui.view" id="purchase_order_calendar">
              <field name="name">purchase.order.calendar</field>
              <field name="model">purchase.order</field>
              <field name="type">calendar</field>
                      </div>
                      <group>
                          <group>
-                             <field name="partner_id" on_change="onchange_partner_id(partner_id)" context="{'search_default_supplier':1,'default_supplier':1,'default_customer':0}"/>
+                             <field name="partner_id" on_change="onchange_partner_id(partner_id)" context="{'search_default_supplier':1,'default_supplier':1,'default_customer':0}" domain="[('supplier','=',True)]"/>
                              <field name="partner_ref"/>
                              <field domain="[('type','=','purchase')]" name="pricelist_id" groups="product.group_purchase_pricelist"/>
                          </group>
                                      <field name="product_qty"/>
                                      <field name="product_uom" groups="product.group_uom"/>
                                      <field name="price_unit"/>
-                                     <field name="price_subtotal"/>  
+                                     <field name="price_subtotal"/>
                                  </tree>
                              </field>
                              <group class="oe_subtotal_footer oe_right">
                                  <field name="amount_untaxed"/>
                                  <field name="amount_tax"/>
-                                 <div class="oe_subtotal_footer_separator oe_inline" colspan="2">
-                                     <button name="button_dummy" states="draft" string="Compute" type="object" icon="gtk-execute" class="oe_inline oe_left"/>
-                                     <field name="amount_total"/>
+                                 <div class="oe_subtotal_footer_separator oe_inline">
+                                     <label for="amount_total"/>
+                                     <button name="button_dummy"
+                                         states="draft" string="(update)" type="object" class="oe_edit_only oe_link"/>
                                  </div>
-                             </group>                         
+                                 <field name="amount_total" nolabel="1" class="oe_subtotal_footer_separator"/>
+                             </group>
                              <div class="oe_clear"/>
                              <label for="notes"/>
                              <field name="notes"/>
                          </page>
                          <page string="Delivery &amp; Invoicing">
                              <group>
-                                 <group string="Delivery">
+                                 <group>
                                      <field name="dest_address_id" string="Customer Address" on_change="onchange_dest_address_id(dest_address_id)"/>
                                      <field name="minimum_planned_date"/>
                                      <field name="location_id" groups="stock.group_locations"/>
                                      <field name="shipped" groups="base.group_no_one"/>
                                  </group>
                                  <group>
-                                     <field name="validator" groups="base.group_no_one"/>
-                                     <field name="date_approve"/>
-                                 </group>
-                             </group>
-                             <group string="Invoicing">
-                                 <group>
                                      <field name="invoice_method"/>
                                      <field name="invoiced"/>
-                                 </group>
-                                 <group>
 +                                    <field name="payment_term" widget="selection"/>
                                      <field name="fiscal_position"/>
+                                     <!-- We do not need these fields anymore, the information is in open chatter -->
+                                     <field name="validator" groups="base.group_no_one"/>
+                                     <field name="date_approve" groups="base.group_no_one"/>
                                  </group>
                              </group>
                              <separator string="Invoices"/>
                          </page>
                      </notebook>
                  </sheet>
-                 <footer>
-                    <field name="message_ids" widget="mail_thread"/>
-                 </footer>
+                 <div class="oe_chatter">
+                     <field name="message_ids" widget="mail_thread"/>
+                 </div>
                  </form>
              </field>
          </record>
              <field name="type">search</field>
              <field name="arch" type="xml">
                  <search string="Search Purchase Order">
-                  <group>
                      <field name="name" string="Reference"/>
-                     <separator orientation="vertical"/>
                      <filter icon="terp-document-new" name="draft" string="Quotations" domain="[('state','=','draft')]" help="Purchase order which are in draft state"/>
                      <filter icon="terp-check" name="approved" string="Approved" domain="[('state','in',('approved','done'))]" help="Approved purchase order"/>
-                     <filter icon="terp-gtk-go-back-rtl" name="not_invoiced" string="Not Invoiced" domain="[('invoice_ids','=', False)]" help="Purchase orders that include lines not invoiced."/>
                      <filter icon="terp-emblem-important" name="exception" string="Exception" domain="[('state','in',('except_invoice','except_picking'))]" help="Purchase order which are in the exception state"/>
-                     <separator orientation="vertical"/>
+                     <separator/>
+                     <filter icon="terp-gtk-go-back-rtl" name="not_invoiced" string="Not Invoiced" domain="[('invoice_ids','=', False)]" help="Purchase orders that include lines not invoiced."/>
                      <field name="partner_id"/>
                      <field name="product_id"/>
                      <field name="create_uid"/>
-                 </group>
-                 <newline/>
-                 <group expand="0" string="Group By...">
-                     <filter string="Supplier" icon="terp-partner" domain="[]" context="{'group_by':'partner_id'}"/>
-                     <separator orientation="vertical"/>
-                     <filter string="Source" icon="terp-gtk-jump-to-rtl" domain="[]" context="{'group_by':'origin'}"/>
-                     <filter string="Status" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}"/>
-                     <separator orientation="vertical"/>
-                     <filter string="Order Date" icon="terp-go-month" domain="[]" context="{'group_by':'date_order'}"/>
-                     <filter string="Expected Date" icon="terp-go-month" domain="[]" context="{'group_by':'minimum_planned_date'}"/>
-                 </group>
-               </search>
+                     <group expand="0" string="Group By...">
+                         <filter string="Supplier" icon="terp-partner" domain="[]" context="{'group_by':'partner_id'}"/>
+                         <filter string="Source" icon="terp-gtk-jump-to-rtl" domain="[]" context="{'group_by':'origin'}"/>
+                         <filter string="Status" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}"/>
+                         <filter string="Order Date" icon="terp-go-month" domain="[]" context="{'group_by':'date_order'}"/>
+                         <filter string="Expected Date" icon="terp-go-month" domain="[]" context="{'group_by':'minimum_planned_date'}"/>
+                     </group>
+                 </search>
              </field>
          </record>
  
              <field name="type">search</field>
              <field name="arch" type="xml">
                  <search string="Search Purchase Order">
-                  <group>
                      <field name="name" string="Reference"/>
-                     <separator orientation="vertical"/>
-                     <filter icon="terp-mail-message-new"
-                         string="Inbox" help="Unread messages"
-                         name="needaction_pending"
-                         domain="[('needaction_pending','=',True)]"/>
-                     <separator orientation="vertical"/>
+                     <filter icon="terp-mail-message-new" string="Inbox" help="Unread messages" name="needaction_pending" domain="[('needaction_pending','=',True)]"/>
+                     <separator/>
                      <filter icon="terp-document-new" name="draft" string="Quotations" domain="[('state','=','draft')]" help="Purchase orders which are in draft state"/>
                      <filter icon="terp-check" name="approved" string="Purchase Orders" domain="[('state','not in',('draft','cancel'))]" help="Approved purchase orders"/>
-                     <filter icon="terp-gtk-go-back-rtl" name="not_invoiced" string="Not Invoiced" domain="[('invoice_ids','=', False)]" help="Purchase orders that include lines not invoiced."/>
                      <filter icon="terp-emblem-important" name="exception" string="Exception" domain="[('state','in',('except_invoice','except_picking'))]" help="Purchase orders which are in exception state"/>
-                     <separator orientation="vertical"/>
+                     <separator/>
+                     <filter icon="terp-gtk-go-back-rtl" name="not_invoiced" string="Not Invoiced" domain="[('invoice_ids','=', False)]" help="Purchase orders that include lines not invoiced."/>
                      <field name="partner_id"/>
                      <field name="product_id"/>
                      <field name="create_uid"/>
-                 </group>
-                 <newline/>
-                 <group expand="0" string="Group By...">
-                     <filter string="Supplier" icon="terp-partner" domain="[]" context="{'group_by':'partner_id'}"/>
-                     <separator orientation="vertical"/>
-                     <filter string="Source" icon="terp-gtk-jump-to-rtl" domain="[]" context="{'group_by':'origin'}"/>
-                     <filter string="Status" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}"/>
-                     <separator orientation="vertical"/>
-                     <filter string="Order Date" icon="terp-go-month" domain="[]" context="{'group_by':'date_order'}"/>
-                     <filter string="Expected Date" icon="terp-go-month" domain="[]" context="{'group_by':'minimum_planned_date'}"/>
-                 </group>
-               </search>
+                     <group expand="0" string="Group By...">
+                         <filter string="Supplier" icon="terp-partner" domain="[]" context="{'group_by':'partner_id'}"/>
+                         <filter string="Source" icon="terp-gtk-jump-to-rtl" domain="[]" context="{'group_by':'origin'}"/>
+                         <filter string="Status" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}"/>
+                         <filter string="Order Date" icon="terp-go-month" domain="[]" context="{'group_by':'date_order'}"/>
+                         <filter string="Expected Date" icon="terp-go-month" domain="[]" context="{'group_by':'minimum_planned_date'}"/>
+                     </group>
+                 </search>
              </field>
          </record>
  
                      <sheet>
                          <group>
                              <group>
-                                 <field name="product_id" on_change="onchange_product_id(parent.pricelist_id,product_id,product_qty,product_uom,parent.partner_id, parent.date_order,parent.fiscal_position,date_planned,name,price_unit,notes,context)"/>
+                                 <field name="product_id" on_change="onchange_product_id(parent.pricelist_id,product_id,product_qty,product_uom,parent.partner_id, parent.date_order,parent.fiscal_position,date_planned,name,price_unit,context)"/>
                                  <label for="product_qty"/>
                                  <div>
-                                     <field name="product_qty" on_change="onchange_product_id(parent.pricelist_id,product_id,product_qty,product_uom,parent.partner_id,parent.date_order,parent.fiscal_position,date_planned,name,price_unit,notes,context)" class="oe_inline"/>
-                                     <field name="product_uom" groups="product.group_uom" on_change="onchange_product_uom(parent.pricelist_id,product_id,product_qty,product_uom,parent.partner_id, parent.date_order,parent.fiscal_position,date_planned,name,price_unit,notes,context)" class="oe_inline"/>
+                                     <field name="product_qty" on_change="onchange_product_id(parent.pricelist_id,product_id,product_qty,product_uom,parent.partner_id,parent.date_order,parent.fiscal_position,date_planned,name,price_unit,context)" class="oe_inline"/>
+                                     <field name="product_uom" groups="product.group_uom" on_change="onchange_product_uom(parent.pricelist_id,product_id,product_qty,product_uom,parent.partner_id, parent.date_order,parent.fiscal_position,date_planned,name,price_unit,context)" class="oe_inline"/>
                                  </div>
                                  <field name="price_unit"/>
-                                 <field name="taxes_id" widget="many2many_tags" domain="[('parent_id','=',False),('type_tax_use','!=','sale')]"/> 
                              </group>
                              <group>
-                                 <field name="name"/>
+                                 <field name="taxes_id" widget="many2many_tags" domain="[('parent_id','=',False),('type_tax_use','!=','sale')]"/>
                                  <field name="date_planned" widget="date"/>
                                  <field name="account_analytic_id" colspan="2" groups="purchase.group_analytic_accounting" domain="[('parent_id','!=',False)]" />
                                  <field name="company_id" groups="base.group_multi_company" widget="selection"/>
                              </group>
-                             <group string="Notes" colspan="4">
-                                 <field name="notes" nolabel="1" placeholder="Add a note on the purchase line..."/>
-                             </group>
-                             <group string="Invoices" colspan="4">
-                                 <field name="invoice_lines" nolabel="1"/>
-                             </group>
-                             <group string="Stock Moves" colspan="4">
-                                 <field name="move_ids" nolabel="1"/>
-                             </group>
                          </group>
+                         <notebook>
+                         <page string="Notes">
+                             <field name="name"/>
+                         </page><page string="Invoices and Receptions">
+                             <field name="invoice_lines"/>
+                             <field name="move_ids"/>
+                         </page>
+                         </notebook>
                      </sheet>
                  </form>
              </field>
                          <label for="order_id" class="oe_edit_only"/>
                          <h1>
                              <field name="order_id" class="oe_inline"/>
-                             <label string="," attrs="{'invisible':[('date_order','=',False)]}"/> 
+                             <label string="," attrs="{'invisible':[('date_order','=',False)]}"/>
                              <field name="date_order" class="oe_inline"/>
                          </h1>
                          <label for="partner_id" class="oe_edit_only"/>
                          <h2><field name="partner_id"/></h2>
                          <group>
                              <group>
-                                 <field name="name"/>
                                  <field name="product_id" readonly="1"/>
                                  <label for="product_qty"/>
                                  <div>
                                  <field name="price_unit"/>
                              </group>
                              <group>
+                                 <field name="taxes_id" widget="many2many_tags"
+                                     domain="[('parent_id','=',False),('type_tax_use','!=','sale')]"/>
                                  <field name="date_planned" widget="date" readonly="1"/>
                                  <field name="company_id" groups="base.group_multi_company" widget="selection"/>
                                  <field name="account_analytic_id" colspan="4" groups="purchase.group_analytic_accounting" domain="[('parent_id','!=',False)]"/>
                                  <field name="invoiced"/>
                              </group>
                          </group>
+                         <field name="name"/>
                          <separator string="Manual Invoices"/>
                          <field name="invoice_lines"/>
-                         <separator string="Notes"/>
-                         <field name="notes"/>
                          <separator string="Stock Moves"/>
                          <field name="move_ids"/>
                      </sheet>
              <field name="type">search</field>
              <field name="arch" type="xml">
                  <search string="Search Purchase Order">
-                     <group>
-                         <field name="order_id"/>
-                         <field name="product_id"/>
-                         <field name="partner_id" string="Supplier"/>
-                     </group>
-                     <newline/>
+                     <field name="order_id"/>
+                     <field name="product_id"/>
+                     <field name="partner_id" string="Supplier"/>
                      <group expand="0" string="Group By...">
                          <filter string="Supplier" icon="terp-partner" domain="[]" context="{'group_by' : 'partner_id'}" />
-                         <separator orientation="vertical"/>
                          <filter string="Product" icon="terp-accessories-archiver" domain="[]" context="{'group_by' : 'product_id'}" />
                          <filter icon="terp-gtk-jump-to-rtl" string="Order Reference" domain="[]" context="{'group_by' :'order_id'}"/>
-                         <separator orientation="vertical"/>
                          <filter string="Status" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by' : 'state'}" />
                      </group>
-                </search>
+                 </search>
              </field>
          </record>
  
              parent="menu_procurement_management_invoice"
              sequence="72"/>
  
-         <!--
-             Procurements
-         -->
+         <!-- Procurements -->
  
          <record id="view_procurement_form_inherit" model="ir.ui.view">
              <field name="name">procurement.order.form.inherit</field>
                  </xpath>
              </field>
          </record>
      </data>
  </openerp>
diff --combined addons/purchase/stock.py
@@@ -40,6 -40,7 +40,7 @@@ class stock_picking(osv.osv)
          'purchase_id': fields.many2one('purchase.order', 'Purchase Order',
              ondelete='set null', select=True),
      }
      _defaults = {
          'purchase_id': False,
      }
@@@ -59,9 -60,6 +60,9 @@@
          invoice_vals = super(stock_picking, self)._prepare_invoice(cr, uid, picking, partner, inv_type, journal_id, context=context)
          if picking.purchase_id:
              invoice_vals['fiscal_position'] = picking.purchase_id.fiscal_position.id
 +            invoice_vals['payment_term'] = picking.purchase_id.payment_term.id
 +            if picking.purchase_id.payment_term and context.get('date_inv'):
 +                invoice_vals['date_due'] = self.pool.get('account.invoice').onchange_payment_term_date_invoice(cr, uid, [], picking.purchase_id.payment_term.id, context.get('invoice_date'))['value'].get('date_due')
          return invoice_vals
  
      def get_currency_id(self, cursor, user, picking):
                  'invoiced': True,
                  'invoice_lines': [(4, invoice_line_id)],
              })
-             invoice_line_obj.write(cursor, user, [invoice_line_id], {'note':  move_line.purchase_line_id.notes,})
          return super(stock_picking, self)._invoice_line_hook(cursor, user, move_line, invoice_line_id)
  
      def _invoice_hook(self, cursor, user, picking, invoice_id):
@@@ -137,5 -134,6 +137,6 @@@ class stock_picking_in(osv.osv)
      _columns = {
          'purchase_id': fields.many2one('purchase.order', 'Purchase Order',
              ondelete='set null', select=True),
+         'warehouse_id': fields.related('purchase_id', 'warehouse_id', type='many2one', relation='stock.warehouse', string='Destination Warehouse'),
      }
  # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
@@@ -74,6 -74,10 +74,6 @@@ class purchase_line_invoice(osv.osv_mem
                  journal_id = account_jrnl_obj.search(cr, uid, [('type', '=', 'purchase')], context=None)
                  journal_id = journal_id and journal_id[0] or False
                  a = partner.property_account_payable.id
 -                if partner and partner.property_payment_term.id:
 -                    pay_term = partner.property_payment_term.id
 -                else:
 -                    pay_term = False
                  inv = {
                      'name': name,
                      'origin': name,
@@@ -85,7 -89,7 +85,7 @@@
                      'invoice_line': [(6,0,lines_ids)],
                      'currency_id' : orders[0].pricelist_id.currency_id.id,
                      'comment': multiple_order_invoice_notes(orders),
 -                    'payment_term': pay_term,
 +                    'payment_term': orders[0].payment_term.id,
                      'fiscal_position': partner.property_account_position.id
                  }
                  inv_id = invoice_obj.create(cr, uid, inv)
                          'uos_id': line.product_uom.id,
                          'product_id': line.product_id.id or False,
                          'invoice_line_tax_id': [(6, 0, [x.id for x in line.taxes_id])],
-                         'note': line.notes,
                          'account_analytic_id': line.account_analytic_id and line.account_analytic_id.id or False,
                      })
                      purchase_line_obj.write(cr, uid, [line.id], {'invoiced': True, 'invoice_lines': [(4, inv_id)]})
diff --combined addons/stock/stock.py
@@@ -619,7 -619,7 +619,7 @@@ class stock_picking(osv.osv)
          'name': fields.char('Reference', size=64, select=True, states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}),
          'origin': fields.char('Source', size=64, states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}, help="Reference of the document", select=True),
          'backorder_id': fields.many2one('stock.picking', 'Back Order of', states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}, help="If this shipment was split, then this field links to the shipment which contains the already processed part.", select=True),
-         'type': fields.selection([('out', 'Sending Goods'), ('in', 'Getting Goods'), ('internal', 'Internal')], 'Shipping Type', required=True, select=True, states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}, help="Shipping type specify, goods coming in or going out."),
+         'type': fields.selection([('out', 'Sending Goods'), ('in', 'Getting Goods'), ('internal', 'Internal')], 'Shipping Type', required=True, select=True, readonly=True, help="Shipping type specify, goods coming in or going out."),
          'note': fields.text('Notes', states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}),
          'stock_journal_id': fields.many2one('stock.journal','Stock Journal', select=True, states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}),
          'location_id': fields.many2one('stock.location', 'Location', states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}, help="Keep empty if you produce at the location where the finished products are needed." \
              partner = self.pool.get('res.partner').browse(cr, uid, partner, context=context)
          if inv_type in ('out_invoice', 'out_refund'):
              account_id = partner.property_account_receivable.id
 +            payment_term = partner.property_payment_term.id or False
          else:
              account_id = partner.property_account_payable.id
 +            payment_term = partner.property_supplier_payment_term.id or False
          comment = self._get_comment_invoice(cr, uid, picking)
          invoice_vals = {
              'name': picking.name,
              'account_id': account_id,
              'partner_id': partner.id,
              'comment': comment,
 -            'payment_term': partner.property_payment_term and partner.property_payment_term.id or False,
 +            'payment_term': payment_term,
              'fiscal_position': partner.property_account_position.id,
              'date_invoice': context.get('date_inv', False),
              'company_id': picking.company_id.id,
@@@ -1728,10 -1726,15 +1728,15 @@@ class stock_move(osv.osv)
              if location_xml_id:
                  location_model, location_id = mod_obj.get_object_reference(cr, uid, 'stock', location_xml_id)
          return location_id
+     
+     def _default_destination_address(self, cr, uid, context=None):
+         user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
+         return user.company_id.partner_id.id
  
      _defaults = {
          'location_id': _default_location_source,
          'location_dest_id': _default_location_destination,
+         'partner_id': _default_destination_address,
          'state': 'draft',
          'priority': '1',
          'product_qty': 1.0,