diff --git a/addons/account/account.py b/addons/account/account.py index 59c4b2acf9b..34b421c7e6f 100644 --- a/addons/account/account.py +++ b/addons/account/account.py @@ -139,7 +139,7 @@ class account_account(osv.osv): context=None, count=False): if context is None: context = {} - pos = 0 + pos = 0 while pos take this date + if context.has_key('date_p') and context['date_p']: + date=context['date_p'] + else: + date = time.strftime('%Y-%m-%d') cr.execute('SELECT account_id, reconcile_id \ FROM account_move_line \ @@ -435,9 +439,15 @@ class account_move_line(osv.osv): self_credit = 0.0 self_debit = -writeoff + # If comment exist in context, take it + if context['comment']: + libelle=context['comment'] + else: + libelle='Write-Off' + writeoff_lines = [ (0, 0, { - 'name':'Write-Off', + 'name':libelle, 'debit':self_debit, 'credit':self_credit, 'account_id':account_id, @@ -447,7 +457,7 @@ class account_move_line(osv.osv): 'amount_currency': account.currency_id.id and -currency or 0.0 }), (0, 0, { - 'name':'Write-Off', + 'name':libelle, 'debit':debit, 'credit':credit, 'account_id':writeoff_acc_id, @@ -735,7 +745,9 @@ class account_move_line(osv.osv): } self.create(cr, uid, data, context) if check: - self.pool.get('account.move').validate(cr, uid, [vals['move_id']], context) + tmp = self.pool.get('account.move').validate(cr, uid, [vals['move_id']], context) + if journal.entry_posted and tmp: + self.pool.get('account.move').write(cr,uid, [vals['move_id']],{'state':'posted'}) return result account_move_line() diff --git a/addons/account/account_view.xml b/addons/account/account_view.xml index b3e5b24960e..01b32235907 100644 --- a/addons/account/account_view.xml +++ b/addons/account/account_view.xml @@ -256,6 +256,7 @@ + diff --git a/addons/account/invoice.py b/addons/account/invoice.py index 9a49a871f42..89e47a1ac43 100644 --- a/addons/account/invoice.py +++ b/addons/account/invoice.py @@ -499,14 +499,18 @@ class account_invoice(osv.osv): _('Can not create invoice move on centralized journal')) move = {'name': name, 'line_id': line, 'journal_id': journal_id} - if inv.period_id: - move['period_id'] = inv.period_id.id + period_id=inv.period_id and inv.period_id.id or False + if not period_id: + period_ids= self.pool.get('account.period').search(cr,uid,[('date_start','<=',inv.date_invoice),('date_stop','>=',inv.date_invoice)]) + if len(period_ids): + period_id=period_ids[0] + if period_id: + move['period_id'] = period_id for i in line: - i[2]['period_id'] = inv.period_id.id - + i[2]['period_id'] = period_id move_id = self.pool.get('account.move').create(cr, uid, move) # make the invoice point to that move - self.write(cr, uid, [inv.id], {'move_id': move_id}) + self.write(cr, uid, [inv.id], {'move_id': move_id,'period_id':period_id}) self.pool.get('account.move').post(cr, uid, [move_id]) self._log_event(cr, uid, ids) return True @@ -681,20 +685,30 @@ class account_invoice(osv.osv): invoice = self.browse(cr, uid, ids[0]) src_account_id = invoice.account_id.id journal = self.pool.get('account.journal').browse(cr, uid, pay_journal_id) - if not name: - if journal.sequence_id: - name = self.pool.get('ir.sequence').get_id(cr, uid, journal.sequence_id.id) - else: - raise osv.except_osv(_('No piece number !'), _('Can not create an automatic sequence for this piece !\n\nPut a sequence in the journal definition for automatic numbering or create a sequence manually for this piece.')) + if journal.sequence_id: + name = self.pool.get('ir.sequence').get_id(cr, uid, journal.sequence_id.id) + else: + raise osv.except_osv(_('No piece number !'), _('Can not create an automatic sequence for this piece !\n\nPut a sequence in the journal definition for automatic numbering or create a sequence manually for this piece.')) + # Take the seq as name for move + if journal.sequence_id: + seq = self.pool.get('ir.sequence').get_id(cr, uid, journal.sequence_id.id) + else: + raise osv.except_osv('No piece number !', 'Can not create an automatic sequence for this piece !\n\nPut a sequence in the journal definition for automatic numbering or create a sequence manually for this piece.') types = {'out_invoice': -1, 'in_invoice': 1, 'out_refund': 1, 'in_refund': -1} direction = types[invoice.type] + #take the choosen date + if context.has_key('date_p') and context['date_p']: + date=context['date_p'] + else: + date=time.strftime('%Y-%m-%d') l1 = { 'name': name, 'debit': direction * pay_amount>0 and direction * pay_amount, 'credit': direction * pay_amount<0 and - direction * pay_amount, 'account_id': src_account_id, 'partner_id': invoice.partner_id.id, - 'date': time.strftime('%Y-%m-%d'), + 'date': date, + 'ref':invoice.number, } l2 = { 'name':name, @@ -702,11 +716,12 @@ class account_invoice(osv.osv): 'credit': direction * pay_amount>0 and direction * pay_amount, 'account_id': pay_account_id, 'partner_id': invoice.partner_id.id, - 'date': time.strftime('%Y-%m-%d'), + 'date': date, + 'ref':invoice.number, } lines = [(0, 0, l1), (0, 0, l2)] - move = {'name': name, 'line_id': lines, 'journal_id': pay_journal_id, 'period_id': period_id} + move = {'name': seq, 'line_id': lines, 'journal_id': pay_journal_id, 'period_id': period_id} move_id = self.pool.get('account.move').create(cr, uid, move) line_ids = [] diff --git a/addons/account/wizard/wizard_pay_invoice.py b/addons/account/wizard/wizard_pay_invoice.py index c8f1197571e..3503070ee21 100644 --- a/addons/account/wizard/wizard_pay_invoice.py +++ b/addons/account/wizard/wizard_pay_invoice.py @@ -68,6 +68,13 @@ def _pay_and_reconcile(self, cr, uid, data, context): ctx = {'date':data['form']['date']} amount = cur_obj.compute(cr, uid, journal.currency.id, invoice.company_id.currency_id.id, amount, context=ctx) + + # Take the choosen date + if form.has_key('comment'): + context={'date_p':form['date'],'comment':form['comment']} + else: + context={'date_p':form['date'],'comment':False} + acc_id = journal.default_credit_account_id and journal.default_credit_account_id.id if not acc_id: raise wizard.except_wizard(_('Error !'), _('Your journal must have a default credit and debit account.')) @@ -80,7 +87,7 @@ def _wo_check(self, cr, uid, data, context): pool = pooler.get_pool(cr.dbname) invoice = pool.get('account.invoice').browse(cr, uid, data['id'], context) journal = pool.get('account.journal').browse(cr, uid, data['form']['journal_id'], context) - if invoice.company_id.currency_id.id<>journal.currency.id: + if invoice.company_id.currency_id.id<>journal.currency.id or journal.currency.id <> invoice.currency_id.id: return 'addendum' if pool.get('res.currency').is_zero(cr, uid, invoice.currency_id, (data['form']['amount'] - invoice.amount_total)): @@ -92,11 +99,13 @@ _transaction_add_form = ''' + ''' _transaction_add_fields = { 'writeoff_acc_id': {'string':'Write-Off account', 'type':'many2one', 'relation':'account.account', 'required':True}, 'writeoff_journal_id': {'string': 'Write-Off journal', 'type': 'many2one', 'relation':'account.journal', 'required':True}, + 'comment': {'string': 'Entry Name', 'type':'char', 'size': 64, 'required':True}, } def _get_value_addendum(self, cr, uid, data, context={}): diff --git a/addons/base_setup/wizard/wizard_base_setup.py b/addons/base_setup/wizard/wizard_base_setup.py index ce512679722..83bb13644cf 100644 --- a/addons/base_setup/wizard/wizard_base_setup.py +++ b/addons/base_setup/wizard/wizard_base_setup.py @@ -62,6 +62,20 @@ view_form_charts = """ """ +view_form_vatcheck = """ +
+ + + + + + + +
""" + view_form_company = """
@@ -97,6 +111,8 @@ view_form_update = """ + + @@ -185,12 +201,16 @@ class wizard_base_setup(wizard.interface): def _update(self, cr, uid, data, context): pool=pooler.get_pool(cr.dbname) form=data['form'] - if 'profile' in data['form'] and data['form']['profile'] > 0: - module_obj=pool.get('ir.module.module') - module_obj.state_update(cr, uid, [data['form']['profile']], 'to install', ['uninstalled'], context) - if 'charts' in data['form'] and data['form']['charts'] > 0: - module_obj=pool.get('ir.module.module') - module_obj.state_update(cr, uid, [data['form']['charts']], 'to install', ['uninstalled'], context) + module_obj=pool.get('ir.module.module') + + if 'profile' in form and form['profile'] > 0: + module_obj.state_update(cr, uid, [form['profile']], 'to install', ['uninstalled'], context) + if 'charts' in form and form['charts'] > 0: + module_obj.state_update(cr, uid, [form['charts']], 'to install', ['uninstalled'], context) + if 'vatcheck' in form and form['vatcheck']: + mid = module_obj.search(cr, uid, [('name', '=', 'base_vat_check')], context=context) + if mid: + module_obj.state_update(cr, uid, mid, 'to install', ['uninstalled'], context) company_obj=pool.get('res.company') partner_obj=pool.get('res.partner') @@ -271,7 +291,7 @@ class wizard_base_setup(wizard.interface): def _previous(self, cr, uid, data, context): if 'profile' not in data['form'] or data['form']['profile'] <= 0: return 'init' - return 'charts' + return 'vatcheck' def _config(self, cr, uid, data, context=None): users_obj=pooler.get_pool(cr.dbname).get('res.users') @@ -307,6 +327,11 @@ class wizard_base_setup(wizard.interface): 'default': -1, 'required': True, }, + 'vatcheck':{ + 'string': "Install 'base_vat_check' module", + 'type': 'boolean', + 'default': False, + }, 'name':{ 'string': 'Company Name', 'type': 'char', @@ -402,6 +427,15 @@ IBAN: BE74 1262 0121 6907 - SWIFT: CPDF BE71 - VAT: BE0477.472.701""", 'result': {'type': 'form', 'arch': view_form_charts, 'fields': fields, 'state':[ ('init', 'Previous', 'gtk-go-back'), + ('vatcheck', 'Next', 'gtk-go-forward', True) + ] + } + }, + 'vatcheck':{ + 'actions':[], + 'result': {'type': 'form', 'arch': view_form_vatcheck, 'fields': fields, + 'state': [ + ('charts', 'Previous', 'gtk-go-back'), ('company', 'Next', 'gtk-go-forward', True) ] } @@ -424,7 +458,7 @@ IBAN: BE74 1262 0121 6907 - SWIFT: CPDF BE71 - VAT: BE0477.472.701""", 'result': {'type': 'form', 'arch': view_form_update, 'fields': fields, 'state': [ ('company', 'Previous', 'gtk-go-back'), - ('finish', 'Install', 'gtk-ok', True) + ('finish', 'Install', 'gtk-save', True) ] } }, diff --git a/addons/base_vat_check/__init__.py b/addons/base_vat_check/__init__.py new file mode 100644 index 00000000000..af7847dfb9d --- /dev/null +++ b/addons/base_vat_check/__init__.py @@ -0,0 +1,34 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# Copyright (c) 2004-2008 TINY SPRL. (http://tiny.be) All Rights Reserved. +# +# $Id$ +# +# WARNING: This program as such is intended to be used by professional +# programmers who take the whole responsability of assessing all potential +# consequences resulting from its eventual inadequacies and bugs +# End users who are looking for a ready-to-use solution with commercial +# garantees and support are strongly adviced to contract a Free Software +# Service Company +# +# 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 2 +# 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. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +############################################################################## + +import partner + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: + diff --git a/addons/base_vat_check/__terp__.py b/addons/base_vat_check/__terp__.py new file mode 100644 index 00000000000..48200c92fc9 --- /dev/null +++ b/addons/base_vat_check/__terp__.py @@ -0,0 +1,42 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# Copyright (c) 2004-2008 Tiny SPRL (http://tiny.be) All Rights Reserved. +# +# $Id$ +# +# WARNING: This program as such is intended to be used by professional +# programmers who take the whole responsability of assessing all potential +# consequences resulting from its eventual inadequacies and bugs +# End users who are looking for a ready-to-use solution with commercial +# garantees and support are strongly adviced to contract a Free Software +# Service Company +# +# 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 2 +# 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. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +############################################################################### +{ + "name": "VAT Check", + "description": "Add a check of the VAT Number. Idea and code from Tryton (c2bk)", + "version": "1.0", + "author": "Tiny", + "category": "Generic Modules/Base", + "depends": ["base", "base_vat"], + "update_xml": [], + "active": False, + "installable": True, +} + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: + diff --git a/addons/base_vat_check/partner.py b/addons/base_vat_check/partner.py new file mode 100644 index 00000000000..c5f9010cf91 --- /dev/null +++ b/addons/base_vat_check/partner.py @@ -0,0 +1,1027 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# Copyright (c) 2004-2008 Tiny SPRL (http://tiny.be) All Rights Reserved. +# +# $Id$ +# +# WARNING: This program as such is intended to be used by professional +# programmers who take the whole responsability of assessing all potential +# consequences resulting from its eventual inadequacies and bugs +# End users who are looking for a ready-to-use solution with commercial +# garantees and support are strongly adviced to contract a Free Software +# Service Company +# +# 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 2 +# 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. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +############################################################################### + +from osv import osv + + +class res_partner(osv.osv): + _inherit = 'res.partner' + + def check_vat(self, cr, uid, ids): + ''' + Check the VAT number depending of the country. + http://sima-pc.com/nif.php + ''' + for partner in self.browse(cr, uid, ids): + if not partner.vat_subject: + continue + if not partner.vat: + continue #FIXME return False? empty vat numbre is invalid? + + vat_country, vat_number = partner.vat[:2].lower(), partner.vat[2:] + if not getattr(self, 'check_vat_' + vat_country)(vat_number): + return False + + return True + + _constraints = [(check_vat, "The VAT doesn't seem to be correct.", ["vat"])] + + # code from the following methods come from Tryton (c2bk) + # http://www.tryton.org/hgwebdir.cgi/modules/relationship/file/544d1de586d9/party.py + def check_vat_at(self, vat): + ''' + Check Austria VAT number. + ''' + if len(vat) != 9: + return False + if vat[0] != 'U': + return False + num = vat[1:] + try: + int(num) + except: + return False + sum = int(num[0]) + mult_add(2, int(num[1])) + \ + int(num[2]) + mult_add(2, int(num[3])) + \ + int(num[4]) + mult_add(2, int(num[5])) + \ + int(num[6]) + check = 10 - ((sum + 4) % 10) + if check == 10: + check = 0 + if int(vat[-1:]) != check: + return False + return True + + def check_vat_be(self, vat): + ''' + Check Belgium VAT number. + ''' + if len(vat) != 10: + return False + try: + int(vat) + except: + return False + if int(vat[-2:]) != \ + 97 - (int(vat[:8]) % 97): + return False + return True + + def check_vat_bg(self, vat): + ''' + Check Bulgaria VAT number. + ''' + if len(vat) != 10: + return False + try: + int(vat) + except: + return False + if int(vat[0]) in (2, 3) and \ + int(vat[1:2]) != 22: + return False + sum = 4 * int(vat[0]) + 3 * int(vat[1]) + 2 * int(vat[2]) + \ + 7 * int(vat[3]) + 6 * int(vat[4]) + 5 * int(vat[5]) + \ + 4 * int(vat[6]) + 3 * int(vat[7]) + 2 * int(vat[8]) + check = 11 - (sum % 11) + if check == 11: + check = 0 + if check == 10: + return False + if check != int(vat[9]): + return False + return True + + def check_vat_cy(self, vat): + ''' + Check Cyprus VAT number. + ''' + if len(vat) != 9: + return False + try: + int(vat[:8]) + except: + return False + n0 = int(vat[0]) + n1 = int(vat[1]) + n2 = int(vat[2]) + n3 = int(vat[3]) + n4 = int(vat[4]) + n5 = int(vat[5]) + n6 = int(vat[6]) + n7 = int(vat[7]) + + def conv(x): + if x == 0: + return 1 + elif x == 1: + return 0 + elif x == 2: + return 5 + elif x == 3: + return 7 + elif x == 4: + return 9 + elif x == 5: + return 13 + elif x == 6: + return 15 + elif x == 7: + return 17 + elif x == 8: + return 19 + elif x == 9: + return 21 + return x + n0 = conv(n0) + n2 = conv(n2) + n4 = conv(n4) + n6 = conv(n6) + + sum = n0 + n1 + n2 + n3 + n4 + n5 + n6 + n7 + check = chr(sum % 26 + 65) + if check != vat[8]: + return False + return True + + def check_vat_cz(self, vat): + ''' + Check Czech Republic VAT number. + ''' + if len(vat) not in (8, 9, 10): + return False + try: + int(vat) + except: + return False + + if len(vat) == 8: + if int(vat[0]) not in (0, 1, 2, 3, 4, 5, 6, 7, 8): + return False + sum = 8 * int(vat[0]) + 7 * int(vat[1]) + 6 * int(vat[2]) + \ + 5 * int(vat[3]) + 4 * int(vat[4]) + 3 * int(vat[5]) + \ + 2 * int(vat[6]) + check = 11 - (sum % 11) + if check == 10: + check = 0 + if check == 11: + check = 1 + if check != int(vat[7]): + return False + elif len(vat) == 9 and int(vat[0]) == 6: + sum = 8 * int(vat[1]) + 7 * int(vat[2]) + 6 * int(vat[3]) + \ + 5 * int(vat[4]) + 4 * int(vat[5]) + 3 * int(vat[6]) + \ + 2 * int(vat[7]) + check = 9 - ((11 - (sum % 11)) % 10) + if check != int(vat[8]): + return False + elif len(vat) == 9: + if int(vat[0:2]) > 53 and int(vat[0:2]) < 80: + return False + if int(vat[2:4]) < 1: + return False + if int(vat[2:4]) > 12 and int(vat[2:4]) < 51: + return False + if int(vat[2:4]) > 62: + return False + if int(vat[2:4]) in (2, 52) and int(vat[0:2]) % 4 > 0: + if int(vat[4:6]) < 1: + return False + if int(vat[4:6]) > 28: + return False + if int(vat[2:4]) in (2, 52) and int(vat[0:2]) % 4 == 0: + if int(vat[4:6]) < 1: + return False + if int(vat[4:6]) > 29: + return False + if int(vat[2:4]) in (4, 6, 9, 11, 54, 56, 59, 61): + if int(vat[4:6]) < 1: + return False + if int(vat[4:6]) > 30: + return False + if int(vat[2:4]) in (1, 3, 5, 7, 8, 10, 12, 51, + 53, 55, 57, 58, 60, 62): + if int(vat[4:6]) < 1: + return False + if int(vat[4:6]) > 31: + return False + elif len(vat) == 10: + if int(vat[0:2]) < 54: + return False + if int(vat[2:4]) < 1: + return False + if int(vat[2:4]) > 12 and int(vat[2:4]) < 51: + return False + if int(vat[2:4]) > 62: + return False + if int(vat[2:4]) in (2, 52) and int(vat[0:2]) % 4 > 0: + if int(vat[4:6]) < 1: + return False + if int(vat[4:6]) > 28: + return False + if int(vat[2:4]) in (2, 52) and int(vat[0:2]) % 4 == 0: + if int(vat[4:6]) < 1: + return False + if int(vat[4:6]) > 29: + return False + if int(vat[2:4]) in (4, 6, 9, 11, 54, 56, 59, 61): + if int(vat[4:6]) < 1: + return False + if int(vat[4:6]) > 30: + return False + if int(vat[2:4]) in (1, 3, 5, 7, 8, 10, 12, 51, + 53, 55, 57, 58, 60, 62): + if int(vat[4:6]) < 1: + return False + if int(vat[4:6]) > 31: + return False + if (int(vat[0:2]) + int(vat[2:4]) + int(vat[4:6]) + int(vat[6:8]) + + int(vat[8:10])) % 11 != 0: + return False + if int(vat[0:10]) % 11 != 0: + return False + return True + + def check_vat_de(self, vat): + ''' + Check Germany VAT number. + ''' + if len(vat) != 9: + return False + try: + int(vat) + except: + return False + if int(vat[0:7]) <= 0: + return False + sum = 0 + for i in range(8): + sum = (2 * ((int(vat[i]) + sum + 9) % 10 + 1)) % 11 + check = 11 - sum + if check == 10: + check = 0 + if int(vat[8]) != check: + return False + return True + + def check_vat_dk(self, vat): + ''' + Check Denmark VAT number. + ''' + if len(vat) != 8: + return False + try: + int(vat) + except: + return False + if int(vat[0]) <= 0: + return False + sum = 2 * int(vat[0]) + 7 * int(vat[1]) + 6 * int(vat[2]) + \ + 5 * int(vat[3]) + 4 * int(vat[4]) + 3 * int(vat[5]) + \ + 2 * int(vat[6]) + int(vat[7]) + if sum % 11 != 0: + return False + return True + + def check_vat_ee(self, vat): + ''' + Check Estonia VAT number. + ''' + if len(vat) != 9: + return False + try: + int(vat) + except: + return False + sum = 3 * int(vat[0]) + 7 * int(vat[1]) + 1 * int(vat[2]) + \ + 3 * int(vat[3]) + 7 * int(vat[4]) + 1 * int(vat[5]) + \ + 3 * int(vat[6]) + 7 * int(vat[7]) + check = 10 - (sum % 10) + if check == 10: + check = 0 + if check != int(vat[8]): + return False + return True + + def check_vat_es(self, vat): + ''' + Check Spain VAT number. + ''' + if len(vat) != 9: + return False + + conv = { + 1: 'T', + 2: 'R', + 3: 'W', + 4: 'A', + 5: 'G', + 6: 'M', + 7: 'Y', + 8: 'F', + 9: 'P', + 10: 'D', + 11: 'X', + 12: 'B', + 13: 'N', + 14: 'J', + 15: 'Z', + 16: 'S', + 17: 'Q', + 18: 'V', + 19: 'H', + 20: 'L', + 21: 'C', + 22: 'K', + 23: 'E', + } + + if vat[0] in ('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'): + try: + int(vat[1:]) + except: + return False + sum = mult_add(2, int(vat[1])) + int(vat[2]) + \ + mult_add(2, int(vat[3])) + int(vat[4]) + \ + mult_add(2, int(vat[5])) + int(vat[6]) + \ + mult_add(2, int(vat[7])) + check = 10 - (sum % 10) + if check == 10: + check = 0 + if check != int(vat[8]): + return False + return True + elif vat[0] in ('N', 'P', 'Q', 'S'): + try: + int(vat[1:8]) + except: + return False + sum = mult_add(2, int(vat[1])) + int(vat[2]) + \ + mult_add(2, int(vat[3])) + int(vat[4]) + \ + mult_add(2, int(vat[5])) + int(vat[6]) + \ + mult_add(2, int(vat[7])) + check = 10 - (sum % 10) + check = chr(check + 64) + if check != vat[8]: + return False + return True + elif vat[0] in ('K', 'L', 'M', 'X'): + try: + int(vat[1:8]) + except: + return False + check = 1 + (int(vat[1:8]) % 23) + + check = conv[check] + if check != vat[8]: + return False + return True + else: + try: + int(vat[:8]) + except: + return False + check = 1 + (int(vat[:8]) % 23) + + check = conv[check] + if check != vat[8]: + return False + return True + + def check_vat_fi(self, vat): + ''' + Check Finland VAT number. + ''' + if len(vat) != 8: + return False + try: + int(vat) + except: + return False + sum = 7 * int(vat[0]) + 9 * int(vat[1]) + 10 * int(vat[2]) + \ + 5 * int(vat[3]) + 8 * int(vat[4]) + 4 * int(vat[5]) + \ + 2 * int(vat[6]) + check = 11 - (sum % 11) + if check == 11: + check = 0 + if check == 10: + return False + if check != int(vat[7]): + return False + return True + + def check_vat_fr(self, vat): + ''' + Check France VAT number. + ''' + if len(vat) != 11: + return False + + try: + int(vat[2:11]) + except: + return False + + system = None + try: + int(vat[0:2]) + system = 'old' + except: + system = 'new' + + if system == 'old': + check = ((int(vat[2:11]) * 100) + 12) % 97 + if check != int(vat[0:2]): + return False + return True + else: + conv = ['0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', + 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', + 'U', 'V', 'W', 'X', 'Y', 'Z'] + if vat[0] not in conv \ + or vat[1] not in conv: + return False + c1 = conv.index(vat[0]) + c2 = conv.index(vat[1]) + + if c1 < 10: + sum = c1 * 24 + c2 - 10 + else: + sum = c1 * 34 + c2 - 100 + + x = sum % 11 + sum = (int(sum) / 11) + 1 + y = (int(vat[2:11]) + sum) % 11 + if x != y: + return False + return True + + def check_vat_gb(self, vat): + ''' + Check United Kingdom VAT number. + ''' + + if len(vat) == 5: + try: + int(vat[2:5]) + except: + return False + + if vat[0:2] == 'GD': + if int(vat[2:5]) >= 500: + return False + return True + if vat[0:2] == 'HA': + if int(vat[2:5]) < 500: + return False + return True + return False + elif len(vat) in (9, 10): + try: + int(vat) + except: + return False + + if int(vat[0:7]) < 1: + return False + if int(vat[0:7]) > 19999 and int(vat[0:7]) < 1000000: + return False + if int(vat[7:9]) > 97: + return False + if len(vat) == 10 and int(vat[9]) != 3: + return False + + sum = 8 * int(vat[0]) + 7 * int(vat[1]) + 6 * int(vat[2]) + \ + 5 * int(vat[3]) + 4 * int(vat[4]) + 3 * int(vat[5]) + \ + 2 * int(vat[6]) + 10 * int(vat[7]) + int(vat[8]) + if sum % 97 != 0: + return False + return True + elif len(vat) in (12, 13): + try: + int(vat) + except: + return False + + if int(vat[0:3]) not in (0, 1): + return False + + if int(vat[3:10]) < 1: + return False + if int(vat[3:10]) > 19999 and int(vat[3:10]) < 1000000: + return False + if int(vat[10:12]) > 97: + return False + if len(vat) == 13 and int(vat[12]) != 3: + return False + + sum = 8 * int(vat[3]) + 7 * int(vat[4]) + 6 * int(vat[5]) + \ + 5 * int(vat[6]) + 4 * int(vat[7]) + 3 * int(vat[8]) + \ + 2 * int(vat[9]) + 10 * int(vat[10]) + int(vat[11]) + if sum % 97 != 0: + return False + return True + return False + + def check_vat_gr(self, vat): + ''' + Check Greece VAT number. + ''' + try: + int(vat) + except: + return False + if len(vat) == 8: + sum = 128 * int(vat[0]) + 64 * int(vat[1]) + 32 * int(vat[2]) + \ + 16 * int(vat[3]) + 8 * int(vat[4]) + 4 * int(vat[5]) + \ + 2 * int(vat[6]) + check = sum % 11 + if check == 10: + check = 0 + if check != int(vat[7]): + return False + return True + elif len(vat) == 9: + sum = 256 * int(vat[0]) + 128 * int(vat[1]) + 64 * int(vat[2]) + \ + 32 * int(vat[3]) + 16 * int(vat[4]) + 8 * int(vat[5]) + \ + 4 * int(vat[6]) + 2 * int(vat[7]) + check = sum % 11 + if check == 10: + check = 0 + if check != int(vat[8]): + return False + return True + return False + + def check_vat_el(self, vat): + return self.check_vat_gr(vat) + + def check_vat_hu(self, vat): + ''' + Check Hungary VAT number. + ''' + if len(vat) != 8: + return False + try: + int(vat) + except: + return False + if int(vat[0]) <= 0: + return False + sum = 9 * int(vat[0]) + 7 * int(vat[1]) + 3 * int(vat[2]) + \ + 1 * int(vat[3]) + 9 * int(vat[4]) + 7 * int(vat[5]) + \ + 3 * int(vat[6]) + check = 10 - (sum % 10) + if check == 10: + check = 0 + if check != int(vat[7]): + return False + return True + + def check_vat_ie(self, vat): + ''' + Check Ireland VAT number. + ''' + if len(vat) != 8: + return False + if (ord(vat[1]) >= 65 and ord(vat[1]) <= 90) \ + or vat[1] in ('+', '*'): + try: + int(vat[0]) + int(vat[2:7]) + except: + return False + + if int(vat[0]) <= 6: + return False + + sum = 7 * int(vat[2]) + 6 * int(vat[3]) + 5 * int(vat[4]) + \ + 4 * int(vat[5]) + 3 * int(vat[6]) + 2 * int(vat[0]) + check = sum % 23 + if check == 0: + check = 'W' + else: + check = chr(check + 64) + if check != vat[7]: + return False + return True + else: + try: + int(vat[0:7]) + except: + return False + + sum = 8 * int(vat[0]) + 7 * int(vat[1]) + 6 * int(vat[2]) + \ + 5 * int(vat[3]) + 4 * int(vat[4]) + 3 * int(vat[5]) + \ + 2 * int(vat[6]) + check = sum % 23 + if check == 0: + check = 'W' + else: + check = chr(check + 64) + if check != vat[7]: + return False + return True + + def check_vat_it(self, vat): + ''' + Check Italy VAT number. + ''' + if len(vat) != 11: + return False + try: + int(vat) + except: + return False + if int(vat[0:7]) <= 0: + return False + if int(vat[7:10]) <= 0: + return False + if int(vat[7:10]) > 100 and int(vat[7:10]) < 120: + return False + if int(vat[7:10]) > 121: + return False + + sum = int(vat[0]) + mult_add(2, int(vat[1])) + int(vat[2]) + \ + mult_add(2, int(vat[3])) + int(vat[4]) + \ + mult_add(2, int(vat[5])) + int(vat[6]) + \ + mult_add(2, int(vat[7])) + int(vat[8]) + \ + mult_add(2, int(vat[9])) + check = 10 - (sum % 10) + if check == 10: + check = 0 + if check != int(vat[10]): + return False + return True + + def check_vat_lt(self, vat): + ''' + Check Lithuania VAT number. + ''' + try: + int(vat) + except: + return False + + if len(vat) == 9: + if int(vat[7]) != 1: + return False + sum = 1 * int(vat[0]) + 2 * int(vat[1]) + 3 * int(vat[2]) + \ + 4 * int(vat[3]) + 5 * int(vat[4]) + 6 * int(vat[5]) + \ + 7 * int(vat[6]) + 8 * int(vat[7]) + if sum % 11 == 10: + sum = 3 * int(vat[0]) + 4 * int(vat[1]) + 5 * int(vat[2]) + \ + 6 * int(vat[3]) + 7 * int(vat[4]) + 8 * int(vat[5]) + \ + 9 * int(vat[6]) + 1 * int(vat[7]) + check = sum % 11 + if check == 10: + check = 0 + if check != int(vat[8]): + return False + return True + elif len(vat) == 12: + if int(vat[10]) != 1: + return False + sum = 1 * int(vat[0]) + 2 * int(vat[1]) + 3 * int(vat[2]) + \ + 4 * int(vat[3]) + 5 * int(vat[4]) + 6 * int(vat[5]) + \ + 7 * int(vat[6]) + 8 * int(vat[7]) + 9 * int(vat[8]) + \ + 1 * int(vat[9]) + 2 * int(vat[10]) + if sum % 11 == 10: + sum = 3 * int(vat[0]) + 4 * int(vat[1]) + 5 * int(vat[2]) + \ + 6 * int(vat[3]) + 7 * int(vat[4]) + 8 * int(vat[5]) + \ + 9 * int(vat[6]) + 1 * int(vat[7]) + 2 * int(vat[8]) + \ + 3 * int(vat[9]) + 4 * int(vat[10]) + check = sum % 11 + if check == 10: + check = 0 + if check != int(vat[11]): + return False + return True + return False + + def check_vat_lu(self, vat): + ''' + Check Luxembourg VAT number. + ''' + if len(vat) != 8: + return False + try: + int(vat) + except: + return False + if int(vat[0:6]) <= 0: + return False + check = int(vat[0:6]) % 89 + if check != int(vat[6:8]): + return False + return True + + def check_vat_lv(self, vat): + ''' + Check Latvia VAT number. + ''' + if len(vat) != 11: + return False + try: + int(vat) + except: + return False + if int(vat[0]) >= 4: + sum = 9 * int(vat[0]) + 1 * int(vat[1]) + 4 * int(vat[2]) + \ + 8 * int(vat[3]) + 3 * int(vat[4]) + 10 * int(vat[5]) + \ + 2 * int(vat[6]) + 5 * int(vat[7]) + 7 * int(vat[8]) + \ + 6 * int(vat[9]) + if sum % 11 == 4 and int(vat[0]) == 9: + sum = sum - 45 + if sum % 11 == 4: + check = 4 - (sum % 11) + elif sum % 11 > 4: + check = 14 - (sum % 11) + elif sum % 11 < 4: + check = 3 - (sum % 11) + if check != int(vat[10]): + return False + return True + else: + if int(vat[2:4]) == 2 and int(vat[4:6]) % 4 > 0: + if int(vat[0:2]) < 1 or int(vat[0:2]) > 28: + return False + if int(vat[2:4]) == 2 and int(vat[4:6]) % 4 == 0: + if int(vat[0:2]) < 1 or int(vat[0:2]) > 29: + return False + if int(vat[2:4]) in (4, 6, 9, 11): + if int(vat[0:2]) < 1 or int(vat[0:2]) > 30: + return False + if int(vat[2:4]) in (1, 3, 5, 7, 8, 10, 12): + if int(vat[0:2]) < 1 or int(vat[0:2]) > 31: + return False + if int(vat[2:4]) < 1 or int(vat[2:4]) > 12: + return False + return True + + def check_vat_mt(self, vat): + ''' + Check Malta VAT number. + ''' + if len(vat) != 8: + return False + try: + int(vat) + except: + return False + + if int(vat[0:6]) < 100000: + return False + + sum = 3 * int(vat[0]) + 4 * int(vat[1]) + 6 * int(vat[2]) + \ + 7 * int(vat[3]) + 8 * int(vat[4]) + 9 * int(vat[5]) + check = 37 - (sum % 37) + if check != int(vat[6:8]): + return False + return True + + def check_vat_nl(self, vat): + ''' + Check Netherlands VAT number. + ''' + if len(vat) != 12: + return False + try: + int(vat[0:9]) + int(vat[10:12]) + except: + return False + if int(vat[0:8]) <= 0: + return False + if vat[9] != 'B': + return False + + sum = 9 * int(vat[0]) + 8 * int(vat[1]) + 7 * int(vat[2]) + \ + 6 * int(vat[3]) + 5 * int(vat[4]) + 4 * int(vat[5]) + \ + 3 * int(vat[6]) + 2 * int(vat[7]) + + check = sum % 11 + if check == 10: + return False + if check != int(vat[8]): + return False + return True + + def check_vat_pl(self, vat): + ''' + Check Poland VAT number. + ''' + if len(vat) != 10: + return False + try: + int(vat) + except: + return False + + sum = 6 * int(vat[0]) + 5 * int(vat[1]) + 7 * int(vat[2]) + \ + 2 * int(vat[3]) + 3 * int(vat[4]) + 4 * int(vat[5]) + \ + 5 * int(vat[6]) + 6 * int(vat[7]) + 7 * int(vat[8]) + check = sum % 11 + if check == 10: + return False + if check != int(vat[9]): + return False + return True + + def check_vat_pt(self, vat): + ''' + Check Portugal VAT number. + ''' + if len(vat) != 9: + return False + try: + int(vat) + except: + return False + + if int(vat[0]) <= 0: + return False + + sum = 9 * int(vat[0]) + 8 * int(vat[1]) + 7 * int(vat[2]) + \ + 6 * int(vat[3]) + 5 * int(vat[4]) + 4 * int(vat[5]) + \ + 3 * int(vat[6]) + 2 * int(vat[7]) + check = 11 - (sum % 11) + if check == 10: + check = 0 + if check != int(vat[8]): + return False + return True + + def check_vat_ro(self, vat): + ''' + Check Romania VAT number. + ''' + try: + int(vat) + except: + return False + + if len(vat) == 10: + sum = 7 * int(vat[0]) + 5 * int(vat[1]) + 3 * int(vat[2]) + \ + 2 * int(vat[3]) + 1 * int(vat[4]) + 7 * int(vat[5]) + \ + 5 * int(vat[6]) + 3 * int(vat[7]) + 2 * int(vat[8]) + check = (sum * 10) % 11 + if check == 10: + check = 0 + if check != int(vat[9]): + return False + return True + elif len(vat) == 13: + if int(vat[0]) not in (1, 2, 3, 4, 6): + return False + if int(vat[3:5]) < 1 or int(vat[3:5]) > 12: + return False + if int(vat[3:5]) == 2 and int(vat[1:3]) % 4 > 0: + if int(vat[5:7]) < 1 or int(vat[5:7]) > 28: + return False + if int(vat[3:5]) == 2 and int(vat[1:3]) % 4 == 0: + if int(vat[5:7]) < 1 or int(vat[5:7]) > 29: + return False + if int(vat[3:5]) in (4, 6, 9, 11): + if int(vat[5:7]) < 1 or int(vat[5:7]) > 30: + return False + if int(vat[3:5]) in (1, 3, 5, 7, 8, 10, 12): + if int(vat[5:7]) < 1 or int(vat[5:7]) > 31: + return False + + sum = 2 * int(vat[0]) + 7 * int(vat[1]) + 9 * int(vat[2]) + \ + 1 * int(vat[3]) + 4 * int(vat[4]) + 6 * int(vat[5]) + \ + 3 * int(vat[6]) + 5 * int(vat[7]) + 8 * int(vat[8]) + \ + 2 * int(vat[9]) + 7 * int(vat[10]) + 9 * int(vat[11]) + check = sum % 11 + if check == 10: + check = 1 + if check != int(vat[12]): + return False + return True + return False + + def check_vat_se(self, vat): + ''' + Check Sweden VAT number. + ''' + if len(vat) != 12: + return False + try: + int(vat) + except: + return False + if int(vat[9:11]) <= 0: + return False + + sum = mult_add(2, int(vat[0])) + int(vat[1]) + \ + mult_add(2, int(vat[2])) + int(vat[3]) + \ + mult_add(2, int(vat[4])) + int(vat[5]) + \ + mult_add(2, int(vat[6])) + int(vat[7]) + \ + mult_add(2, int(vat[8])) + check = 10 - (sum % 10) + if check == 10: + check = 0 + if check != int(vat[9]): + return False + return True + + def check_vat_si(self, vat): + ''' + Check Slovenia VAT number. + ''' + if len(vat) != 8: + return False + try: + int(vat) + except: + return False + if int(vat[0:7]) <= 999999: + return False + + sum = 8 * int(vat[0]) + 7 * int(vat[1]) + 6 * int(vat[2]) + \ + 5 * int(vat[3]) + 4 * int(vat[4]) + 3 * int(vat[5]) + \ + 2 * int(vat[6]) + check = 11 - (sum % 11) + if check == 10: + check = 0 + if check == 11: + check = 1 + if check != int(vat[7]): + return False + return True + + def check_vat_sk(self, vat): + ''' + Check Slovakia VAT number. + ''' + try: + int(vat) + except: + return False + if len(vat) not in(9, 10): + return False + + if int(vat[0:2]) == 0 and len(vat) == 10: + return True + + if len(vat) == 10: + if int(vat[0:2]) < 54 or int(vat[0:2]) > 99: + return False + + if len(vat) == 9: + if int(vat[0:2]) > 53 : + return False + + if int(vat[2:4]) < 1: + return False + if int(vat[2:4]) > 12 and int(vat[2:4]) < 51: + return False + if int(vat[2:4]) > 62: + return False + if int(vat[2:4]) in (2, 52) and int(vat[0:2]) % 4 > 0: + if int(vat[4:6]) < 1 or int(vat[4:6]) > 28: + return False + if int(vat[2:4]) in (2, 52) and int(vat[0:2]) % 4 == 0: + if int(vat[4:6]) < 1 or int(vat[4:6]) > 29: + return False + if int(vat[2:4]) in (4, 6, 9, 11, 54, 56, 59, 61): + if int(vat[4:6]) < 1 or int(vat[4:6]) > 30: + return False + if int(vat[2:4]) in (1, 3, 5, 7, 8, 10, 12, + 51, 53, 55, 57, 58, 60, 62): + if int(vat[4:6]) < 1 or int(vat[4:6]) > 31: + return False + return True + +res_partner() + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: + diff --git a/addons/profile_accounting/__terp__.py b/addons/profile_accounting/__terp__.py index 0063ca497ed..80cbf278f3d 100644 --- a/addons/profile_accounting/__terp__.py +++ b/addons/profile_accounting/__terp__.py @@ -31,7 +31,7 @@ "version":"1.0", "author":"Tiny", "category":"Profile", - "depends":["account","report_analytic","board_account","account_followup"], + "depends":["account","report_analytic","board_account","account_followup",'invoice_payment_tab'], "demo_xml":[], "update_xml":[], "active":False, diff --git a/addons/sale/sale.py b/addons/sale/sale.py index ada1ef51a94..ddd56a3b300 100644 --- a/addons/sale/sale.py +++ b/addons/sale/sale.py @@ -239,6 +239,7 @@ class sale_order(osv.osv): 'amount_tax': fields.function(_amount_tax, method=True, string='Taxes'), 'amount_total': fields.function(_amount_total, method=True, string='Total'), 'invoice_quantity': fields.selection([('order','Ordered Quantities'),('procurement','Shipped Quantities')], 'Invoice on', help="The sale order will automatically create the invoice proposition (draft invoice). Ordered and delivered quantities may not be the same. You have to choose if you invoice based on ordered or shipped quantities. If the product is a service, shipped quantities means hours spent on the associated tasks."), + 'payment_term' : fields.many2one('account.payment.term', 'Payment Term'), } _defaults = { 'picking_policy': lambda *a: 'direct', @@ -281,10 +282,11 @@ class sale_order(osv.osv): def onchange_partner_id(self, cr, uid, ids, part): if not part: - return {'value':{'partner_invoice_id': False, 'partner_shipping_id':False, 'partner_order_id':False}} + return {'value':{'partner_invoice_id': False, 'partner_shipping_id':False, 'partner_order_id':False, 'payment_term' : False}} addr = self.pool.get('res.partner').address_get(cr, uid, [part], ['delivery','invoice','contact']) pricelist = self.pool.get('res.partner').browse(cr, uid, part).property_product_pricelist.id - return {'value':{'partner_invoice_id': addr['invoice'], 'partner_order_id':addr['contact'], 'partner_shipping_id':addr['delivery'], 'pricelist_id': pricelist}} + payment_term = self.pool.get('res.partner').browse(cr, uid, part).property_payment_term.id + return {'value':{'partner_invoice_id': addr['invoice'], 'partner_order_id':addr['contact'], 'partner_shipping_id':addr['delivery'], 'pricelist_id': pricelist, 'payment_term' : payment_term}} def button_dummy(self, cr, uid, ids, context={}): return True @@ -298,8 +300,8 @@ class sale_order(osv.osv): def _make_invoice(self, cr, uid, order, lines): a = order.partner_id.property_account_receivable.id - if order.partner_id and order.partner_id.property_payment_term.id: - pay_term = order.partner_id.property_payment_term.id + if order.payment_term: + pay_term = order.payment_term.id else: pay_term = False for preinv in order.invoice_ids: diff --git a/addons/sale/sale_view.xml b/addons/sale/sale_view.xml index 32c1d571df8..52b0a1a87a2 100644 --- a/addons/sale/sale_view.xml +++ b/addons/sale/sale_view.xml @@ -167,6 +167,7 @@ +
diff --git a/addons/stock/stock.py b/addons/stock/stock.py index dcf66f4a14a..5c50d3bead7 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -606,15 +606,14 @@ class stock_picking(osv.osv): for picking in self.browse(cursor, user, ids, context=context): if picking.invoice_state != '2binvoiced': continue - + payment_term_id = False partner = picking.address_id.partner_id if type in ('out_invoice', 'out_refund'): account_id = partner.property_account_receivable.id + payment_term_id= picking.sale_id.payment_term.id else: account_id = partner.property_account_payable.id - payment_term_id = False - if partner.property_payment_term: - payment_term_id = partner.property_payment_term.id +# payment_term_id = picking.purchase_id.payment_term.id address_contact_id, address_invoice_id = \ self._get_address_invoice(cursor, user, picking).values()