[IMP] English Improvement resolved conflicts
[odoo/odoo.git] / addons / account / account.py
index f6d540e..0229297 100644 (file)
@@ -1,24 +1,24 @@
-# -*- encoding: utf-8 -*-
+# -*- coding: utf-8 -*-
 ##############################################################################
 #
 #    OpenERP, Open Source Management Solution
-#    Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
-#    $Id$
+#    Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
 #
 #    This program is free software: you can redistribute it and/or modify
-#    it under the terms of the GNU General Public License as published by
-#    the Free Software Foundation, either version 3 of the License, or
-#    (at your option) any later version.
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
 #
 #    This program is distributed in the hope that it will be useful,
 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#    GNU General Public License for more details.
+#    GNU Affero General Public License for more details.
 #
-#    You should have received a copy of the GNU General Public License
+#    You should have received a copy of the GNU Affero General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #
 ##############################################################################
+
 import time
 import netsvc
 
@@ -30,6 +30,7 @@ import pooler
 import mx.DateTime
 from mx.DateTime import RelativeDateTime, now, DateTime, localtime
 
+from tools import config
 
 class account_payment_term(osv.osv):
     _name = "account.payment.term"
@@ -53,11 +54,11 @@ class account_payment_term(osv.osv):
         result = []
         for line in pt.line_ids:
             if line.value == 'fixed':
-                amt = round(line.value_amount, 2)
+                amt = round(line.value_amount, int(config['price_accuracy']))
             elif line.value == 'procent':
-                amt = round(value * line.value_amount, 2)
+                amt = round(value * line.value_amount, int(config['price_accuracy']))
             elif line.value == 'balance':
-                amt = round(amount, 2)
+                amt = round(amount, int(config['price_accuracy']))
             if amt:
                 next_date = mx.DateTime.strptime(date_ref, '%Y-%m-%d') + RelativeDateTime(days=line.days)
                 if line.days2 < 0:
@@ -76,8 +77,11 @@ class account_payment_term_line(osv.osv):
     _columns = {
         'name': fields.char('Line Name', size=32, required=True),
         'sequence': fields.integer('Sequence', required=True, help="The sequence field is used to order the payment term lines from the lowest sequences to the higher ones"),
-        'value': fields.selection([('procent', 'Percent'), ('balance', 'Balance'), ('fixed', 'Fixed Amount')], 'Value',required=True),
-        'value_amount': fields.float('Value Amount'),
+        'value': fields.selection([('procent', 'Percent'), ('balance', 'Balance'), ('fixed', 'Fixed Amount')], 'Value', required=True, help="""Example: 14 days 2%, 30 days net
+1. Line 1: percent 0.02 14 days
+2. Line 2: balance 30 days"""),
+
+        'value_amount': fields.float('Value Amount', help="For Value percent enter % 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." \
             "If Date=15/01, Number of Days=22, Day of Month=-1, then the due date is 28/02."),
         'days2': fields.integer('Day of the Month', required=True, help="Day of the month, set -1 for the last day of the current month. If it's positive, it gives the day of the next month. Set 0 for net days (otherwise it's based on the beginning of the month)."),
@@ -89,6 +93,17 @@ class account_payment_term_line(osv.osv):
         'days2': lambda *a: 0,
     }
     _order = "sequence"
+
+    def _check_percent(self, cr, uid, ids, context={}):
+        obj = self.browse(cr, uid, ids[0])
+        if obj.value == 'procent' and ( obj.value_amount < 0.0 or obj.value_amount > 1.0):
+            return False
+        return True
+
+    _constraints = [
+        (_check_percent, _('Percentages for Payment Term Line must be between 0 and 1, Example: 0.02 for 2% '), ['value_amount']),
+    ]
+
 account_payment_term_line()
 
 
@@ -267,9 +282,9 @@ class account_account(osv.osv):
         'child_parent_ids': fields.one2many('account.account','parent_id','Children'),
         'child_consol_ids': fields.many2many('account.account', 'account_account_consol_rel', 'child_id', 'parent_id', 'Consolidated Children'),
         'child_id': fields.function(_get_child_ids, method=True, type='many2many', relation="account.account", string="Child Accounts"),
-        'balance': fields.function(__compute, digits=(16, 2), method=True, string='Balance', multi='balance'),
-        'credit': fields.function(__compute, digits=(16, 2), method=True, string='Credit', multi='balance'),
-        'debit': fields.function(__compute, digits=(16, 2), method=True, string='Debit', multi='balance'),
+        'balance': fields.function(__compute, digits=(16, int(config['price_accuracy'])), method=True, string='Balance', multi='balance'),
+        'credit': fields.function(__compute, digits=(16, int(config['price_accuracy'])), method=True, string='Credit', multi='balance'),
+        'debit': fields.function(__compute, digits=(16, int(config['price_accuracy'])), method=True, string='Debit', multi='balance'),
         'reconcile': fields.boolean('Reconcile', help="Check this if the user is allowed to reconcile entries in this account."),
         'shortcut': fields.char('Shortcut', size=12),
         'tax_ids': fields.many2many('account.tax', 'account_account_tax_default_rel',
@@ -380,7 +395,7 @@ class account_account(osv.osv):
         if not default:
             default = {}
         default = default.copy()
-        default['parent_id'] = False
+        default['code'] = (account['code'] or '') + '(copy)'
         if not local:
             done_list = []
         if account.id in done_list:
@@ -403,7 +418,7 @@ class account_account(osv.osv):
             line_obj = self.pool.get('account.move.line')
             account_ids = self.search(cr, uid, [('id', 'child_of', ids)])
             if line_obj.search(cr, uid, [('account_id', 'in', account_ids)]):
-                raise osv.except_osv(_('Error !'), _('You can not deactivate an account that contains account moves.'))
+                raise osv.except_osv(_('Error !'), _('You can not deactivate an account that contains Ledger Postings.'))
         return super(account_account, self).write(cr, uid, ids, vals, context=context)
 account_account()
 
@@ -463,7 +478,8 @@ class account_journal(osv.osv):
         '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 Created Entries', help='Check this box if you don\'t want new account moves to pass through the \'draft\' state and instead goes directly to the \'posted state\' without any manual validation.'),
-        'company_id': fields.related('default_credit_account_id','company_id',type='many2one', relation="res.company", string="Company"),
+        #'company_id': fields.related('default_credit_account_id','company_id',type='many2one', relation="res.company", string="Company"),
+        'company_id': fields.many2one('res.company', 'Company', required=True,select=1),
         'invoice_sequence_id': fields.many2one('ir.sequence', 'Invoice Sequence', \
             help="The sequence used for invoice numbers in this journal."),
     }
@@ -471,6 +487,7 @@ class account_journal(osv.osv):
     _defaults = {
         'active': lambda *a: 1,
         '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,
     }
     def create(self, cr, uid, vals, context={}):
         journal_id = super(account_journal, self).create(cr, uid, vals, context)
@@ -505,15 +522,17 @@ class account_fiscalyear(osv.osv):
         'name': fields.char('Fiscal Year', size=64, required=True),
         'code': fields.char('Code', size=6, required=True),
         'company_id': fields.many2one('res.company', 'Company',
-            help="Keep empty if the fiscal year belongs to several companies."),
+            help="Keep empty if the fiscal year belongs to several companies.", required=True),
         'date_start': fields.date('Start Date', required=True),
         'date_stop': fields.date('End Date', required=True),
         'period_ids': fields.one2many('account.period', 'fiscalyear_id', 'Periods'),
-        'state': fields.selection([('draft','Draft'), ('done','Done')], 'Status', readonly=True),
+        'state': fields.selection([('draft','Draft'), ('done','Done')], 'State', readonly=True,
+                                  help='When fiscal year is created. The state is \'Draft\'. At the end of the year it is in \'Done\' state.'),
     }
 
     _defaults = {
         'state': lambda *a: 'draft',
+        'company_id': lambda self,cr,uid,c: self.pool.get('res.users').browse(cr, uid, uid, c).company_id.id,
     }
     _order = "date_start"
 
@@ -572,10 +591,13 @@ class account_period(osv.osv):
         'date_start': fields.date('Start of Period', required=True, states={'done':[('readonly',True)]}),
         'date_stop': fields.date('End of Period', required=True, states={'done':[('readonly',True)]}),
         'fiscalyear_id': fields.many2one('account.fiscalyear', 'Fiscal Year', required=True, states={'done':[('readonly',True)]}, select=True),
-        'state': fields.selection([('draft','Draft'), ('done','Done')], 'Status', readonly=True)
+        'state': fields.selection([('draft','Draft'), ('done','Done')], 'State', readonly=True,
+                                  help='When monthly periods are created. The state is \'Draft\'. At the end of monthly period it is in \'Done\' state.'),
+        'company_id': fields.many2one('res.company', 'Company', required=True)
     }
     _defaults = {
         'state': lambda *a: 'draft',
+        'company_id': lambda self,cr,uid,c: self.pool.get('res.users').browse(cr, uid, uid, c).company_id.id,
     }
     _order = "date_start"
 
@@ -652,9 +674,12 @@ class account_journal_period(osv.osv):
         'name': fields.char('Journal-Period Name', size=64, required=True),
         'journal_id': fields.many2one('account.journal', 'Journal', required=True, ondelete="cascade"),
         'period_id': fields.many2one('account.period', 'Period', required=True, ondelete="cascade"),
-        'icon': fields.function(_icon_get, method=True, string='Icon', type='string'),
+        'icon': fields.function(_icon_get, method=True, string='Icon', type='char', size=32),
         'active': fields.boolean('Active', required=True),
-        'state': fields.selection([('draft','Draft'), ('printed','Printed'), ('done','Done')], 'Status', required=True, readonly=True)
+        'state': fields.selection([('draft','Draft'), ('printed','Printed'), ('done','Done')], 'State', required=True, readonly=True,
+                                  help='When journal period is created. The state is \'Draft\'. If a report is printed it comes to \'Printed\' state. When all transactions are done, it comes in \'Done\' state.'),
+        'fiscalyear_id': fields.related('period_id', 'fiscalyear_id', string='Fiscal Year', type='many2one', relation='account.fiscalyear'),
+        'company_id' : fields.many2one('res.company', 'Company')
     }
 
     def _check(self, cr, uid, ids, context={}):
@@ -683,6 +708,7 @@ class account_journal_period(osv.osv):
     _defaults = {
         'state': lambda *a: 'draft',
         'active': lambda *a: True,
+        'company_id': lambda self,cr,uid,c: self.pool.get('res.users').browse(cr, uid, uid, c).company_id.id,
     }
     _order = "period_id"
 
@@ -727,7 +753,7 @@ class account_move(osv.osv):
 
     def _amount_compute(self, cr, uid, ids, name, args, context, where =''):
         if not ids: return {}
-        cr.execute('select move_id,sum(debit) from account_move_line where move_id in ('+','.join(map(str,ids))+') group by move_id')
+        cr.execute('select move_id,sum(debit) from account_move_line where move_id in ('+','.join(map(str,map(int, ids)))+') group by move_id')
         result = dict(cr.fetchall())
         for id in ids:
             result.setdefault(id, 0.0)
@@ -738,11 +764,12 @@ class account_move(osv.osv):
         'ref': fields.char('Ref', size=64),
         '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','Draft'), ('posted','Posted')], 'Status', required=True, readonly=True),
+        'state': fields.selection([('draft','Draft'), ('posted','Posted')], 'State', required=True, readonly=True,
+                                  help='When new account move is created the state will be \'Draft\'. When all the payments are done it will be in \'Posted\' state.'),
         'line_id': fields.one2many('account.move.line', 'move_id', 'Entries', states={'posted':[('readonly',True)]}),
         'to_check': fields.boolean('To Be Verified'),
         'partner_id': fields.related('line_id', 'partner_id', type="many2one", relation="res.partner", string="Partner"),
-        'amount': fields.function(_amount_compute, method=True, string='Amount', digits=(16,2)),
+        'amount': fields.function(_amount_compute, method=True, string='Amount', digits=(16,int(config['price_accuracy']))),
         'date': fields.date('Date', required=True),
         'type': fields.selection([
             ('pay_voucher','Cash Payment'),
@@ -754,6 +781,7 @@ class account_move(osv.osv):
             ('journal_pur_voucher','Journal Purchase'),
             ('journal_voucher','Journal Voucher'),
         ],'Type', readonly=True, select=True, states={'draft':[('readonly',False)]}),
+        'company_id': fields.many2one('res.company', 'Company', required=True),
     }
     _defaults = {
         'name': lambda *a: '/',
@@ -761,6 +789,7 @@ class account_move(osv.osv):
         'period_id': _get_period,
         'type' : lambda *a : 'journal_voucher',
         'date': lambda *a:time.strftime('%Y-%m-%d'),
+        'company_id': lambda self,cr,uid,c: self.pool.get('res.users').browse(cr, uid, uid, c).company_id.id,
     }
 
     def _check_centralisation(self, cursor, user, ids):
@@ -805,7 +834,7 @@ class account_move(osv.osv):
                     if new_name:
                         self.write(cr, uid, [move.id], {'name':new_name})
 
-            cr.execute('update account_move set state=%s where id in ('+','.join(map(str,ids))+')', ('posted',))
+            cr.execute('update account_move set state=%s where id in ('+','.join(map(str, ids))+')', ('posted',))
         else:
             raise osv.except_osv(_('Integrity Error !'), _('You can not validate a non-balanced entry !'))
         return True
@@ -818,7 +847,7 @@ class account_move(osv.osv):
             if not line.journal_id.update_posted:
                 raise osv.except_osv(_('Error !'), _('You can not modify a posted entry of this journal !\nYou should set the journal to allow cancelling entries if you want to do that.'))
         if len(ids):
-            cr.execute('update account_move set state=%s where id in ('+','.join(map(str,ids))+')', ('draft',))
+            cr.execute('update account_move set state=%s where id in ('+','.join(map(str, ids))+')', ('draft',))
         return True
 
     def write(self, cr, uid, ids, vals, context={}):
@@ -1108,7 +1137,7 @@ class account_tax_code(osv.osv):
                 for rec in record.child_ids:
                     amount += _rec_get(rec) * rec.sign
                 return amount
-            res[record.id] = round(_rec_get(record), 2)
+            res[record.id] = round(_rec_get(record), int(config['price_accuracy']))
         return res
 
     def _sum_year(self, cr, uid, ids, name, args, context):
@@ -1175,7 +1204,7 @@ class account_tax_code(osv.osv):
     def _check_recursion(self, cr, uid, ids):
         level = 100
         while len(ids):
-            cr.execute('select distinct parent_id from account_tax_code where id in ('+','.join(map(str,ids))+')')
+            cr.execute('select distinct parent_id from account_tax_code where id in ('+','.join(map(str, ids))+')')
             ids = filter(None, map(lambda x:x[0], cr.fetchall()))
             if not level:
                 return False
@@ -1205,7 +1234,7 @@ class account_tax(osv.osv):
     _columns = {
         'name': fields.char('Tax Name', size=64, required=True, translate=True, help="This name will be displayed on reports"),
         'sequence': fields.integer('Sequence', required=True, help="The sequence field is used to order the tax lines from the lowest sequences to the higher ones. The order is important if you have a tax with several tax children. In this case, the evaluation order is important."),
-        'amount': fields.float('Amount', required=True, digits=(14,4)),
+        'amount': fields.float('Amount', required=True, digits=(14,4), help="For Tax Type percent enter % ratio between 0-1."),
         'active': fields.boolean('Active'),
         'type': fields.selection( [('percent','Percent'), ('fixed','Fixed'), ('none','None'), ('code','Python Code'),('balance','Balance')], 'Tax Type', required=True,
             help="The computation method for the tax amount."),
@@ -1307,7 +1336,7 @@ class account_tax(osv.osv):
             # we compute the amount for the current tax object and append it to the result
 
             data = {'id':tax.id,
-                            'name':tax.name,
+                            '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,
                             'base_code_id': tax.base_code_id.id,
@@ -1327,11 +1356,8 @@ class account_tax(osv.osv):
                 data['amount'] = amount
 
             elif tax.type=='fixed':
-                print "her", quantity
-                print "data", data
                 data['amount'] = tax.amount
                 data['tax_amount']=quantity
-                print "DATA 2", data
                # data['amount'] = quantity
             elif tax.type=='code':
                 address = address_id and self.pool.get('res.partner.address').browse(cr, uid, address_id) or None
@@ -1366,7 +1392,6 @@ class account_tax(osv.osv):
                                 latest[name+'_code_id'] = False
             if tax.include_base_amount:
                 cur_price_unit+=amount2
-        print "rress final", res
         return res
 
     def compute(self, cr, uid, taxes, price_unit, quantity, address_id=None, product=None, partner=None):
@@ -1380,13 +1405,12 @@ class account_tax(osv.osv):
             one tax for each tax id in IDS and their childs
         """
         res = self._unit_compute(cr, uid, taxes, price_unit, address_id, product, partner, quantity)
-        print "res",res
         total = 0.0
         for r in res:
             if r.get('balance',False):
-                r['amount'] = round(r['balance'] * quantity, 2) - total
+                r['amount'] = round(r['balance'] * quantity, int(config['price_accuracy'])) - total
             else:
-                r['amount'] = round(r['amount'] * quantity, 2)
+                r['amount'] = round(r['amount'] * quantity, int(config['price_accuracy']))
                 total += r['amount']
 
         return res
@@ -1396,12 +1420,16 @@ class account_tax(osv.osv):
 
         res = []
         taxes.reverse()
-        cur_price_unit=price_unit
+        cur_price_unit = price_unit
 
         tax_parent_tot = 0.0
         for tax in taxes:
             if (tax.type=='percent') and not tax.include_base_amount:
-                tax_parent_tot+=tax.amount
+                tax_parent_tot += tax.amount
+
+        for tax in taxes:
+            if (tax.type=='fixed') and not tax.include_base_amount:
+                cur_price_unit -= tax.amount
 
         for tax in taxes:
             if tax.type=='percent':
@@ -1477,9 +1505,9 @@ class account_tax(osv.osv):
         total = 0.0
         for r in res:
             if r.get('balance',False):
-                r['amount'] = round(r['balance'] * quantity, 2) - total
+                r['amount'] = round(r['balance'] * quantity, int(config['price_accuracy'])) - total
             else:
-                r['amount'] = round(r['amount'] * quantity, 2)
+                r['amount'] = round(r['amount'] * quantity, int(config['price_accuracy']))
                 total += r['amount']
         return res
 account_tax()
@@ -1545,9 +1573,9 @@ class account_model_line(osv.osv):
     _columns = {
         'name': fields.char('Name', size=64, required=True),
         'sequence': fields.integer('Sequence', required=True, help="The sequence field is used to order the resources from lower sequences to higher ones"),
-        'quantity': fields.float('Quantity', digits=(16,2), help="The optional quantity on entries"),
-        'debit': fields.float('Debit', digits=(16,2)),
-        'credit': fields.float('Credit', digits=(16,2)),
+        'quantity': fields.float('Quantity', digits=(16, int(config['price_accuracy'])), help="The optional quantity on entries"),
+        'debit': fields.float('Debit', digits=(16, int(config['price_accuracy']))),
+        'credit': fields.float('Credit', digits=(16, int(config['price_accuracy']))),
 
         'account_id': fields.many2one('account.account', 'Account', required=True, ondelete="cascade"),
 
@@ -1555,7 +1583,7 @@ class account_model_line(osv.osv):
 
         'ref': fields.char('Ref.', size=16),
 
-        'amount_currency': fields.float('Amount Currency', help="The amount expressed in an optionnal other currency."),
+        'amount_currency': fields.float('Amount Currency', help="The amount expressed in an optional other currency."),
         'currency_id': fields.many2one('res.currency', 'Currency'),
 
         'partner_id': fields.many2one('res.partner', 'Partner Ref.'),
@@ -1589,7 +1617,7 @@ class account_subscription(osv.osv):
         'period_total': fields.integer('Number of Periods', required=True),
         'period_nbr': fields.integer('Period', required=True),
         'period_type': fields.selection([('day','days'),('month','month'),('year','year')], 'Period Type', required=True),
-        'state': fields.selection([('draft','Draft'),('running','Running'),('done','Done')], 'Status', required=True, readonly=True),
+        'state': fields.selection([('draft','Draft'),('running','Running'),('done','Done')], 'State', required=True, readonly=True),
 
         'lines_id': fields.one2many('account.subscription.line', 'subscription_id', 'Subscription Lines')
     }
@@ -1778,7 +1806,7 @@ class account_account_template(osv.osv):
             "can have children accounts for multi-company consolidations, payable/receivable are for "\
             "partners accounts (for debit/credit computations), closed for deprecated accounts."),
         'user_type': fields.many2one('account.account.type', 'Account Type', required=True,
-            "These types are defined according to your country. The type contain more information "\
+            help="These types are defined according to your country. The type contain more information "\
             "about the account and it's specificities."),
         'reconcile': fields.boolean('Allow Reconciliation', help="Check this option if you want the user to reconcile entries in this account."),
         'shortcut': fields.char('Shortcut', size=12),
@@ -1796,7 +1824,7 @@ class account_account_template(osv.osv):
     def _check_recursion(self, cr, uid, ids):
         level = 100
         while len(ids):
-            cr.execute('select parent_id from account_account_template where id in ('+','.join(map(str,ids))+')')
+            cr.execute('select parent_id from account_account_template where id in ('+','.join(map(str, ids))+')')
             ids = filter(None, map(lambda x:x[0], cr.fetchall()))
             if not level:
                 return False
@@ -1855,7 +1883,7 @@ class account_tax_code_template(osv.osv):
     def _check_recursion(self, cr, uid, ids):
         level = 100
         while len(ids):
-            cr.execute('select distinct parent_id from account_tax_code_template where id in ('+','.join(map(str,ids))+')')
+            cr.execute('select distinct parent_id from account_tax_code_template where id in ('+','.join(map(str, ids))+')')
             ids = filter(None, map(lambda x:x[0], cr.fetchall()))
             if not level:
                 return False
@@ -2152,7 +2180,7 @@ class wizard_multi_charts_accounts(osv.osv_memory):
 
         for key,value in todo_dict.items():
             if value['account_collected_id'] or value['account_paid_id']:
-                obj_acc_tax.write(cr, uid, [key], vals={
+                obj_acc_tax.write(cr, uid, [key], {
                     'account_collected_id': acc_template_ref[value['account_collected_id']],
                     'account_paid_id': acc_template_ref[value['account_paid_id']],
                 })
@@ -2205,9 +2233,11 @@ class wizard_multi_charts_accounts(osv.osv_memory):
             #create the account_account for this bank journal
             tmp = self.pool.get('res.partner.bank').name_get(cr, uid, [line.acc_no.id])[0][1]
             dig = obj_multi.code_digits
-            new_code = str(current_num)
             if ref_acc_bank.code:
-                new_code = str(ref_acc_bank.code.ljust(dig,'0') + str(current_num))
+                try:
+                    new_code = str(int(ref_acc_bank.code.ljust(dig,'0')) + current_num)
+                except Exception,e:
+                    new_code = str(ref_acc_bank.code.ljust(dig-len(str(current_num)),'0')) + str(current_num)
             vals = {
                 'name': line.acc_no.bank and line.acc_no.bank.name+' '+tmp or tmp,
                 'currency_id': line.currency_id and line.currency_id.id or False,
@@ -2290,7 +2320,7 @@ class wizard_multi_charts_accounts(osv.osv_memory):
                 for tax in position.tax_ids:
                     vals_tax = {
                                 'tax_src_id' : tax_template_ref[tax.tax_src_id.id],
-                                'tax_dest_id' : tax_template_ref[tax.tax_dest_id.id],
+                                'tax_dest_id' : tax.tax_dest_id and tax_template_ref[tax.tax_dest_id.id] or False,
                                 'position_id' : new_fp,
                                 }
                     obj_tax_fp.create(cr, uid, vals_tax)