[CLEAN] Set Withespaces to PEP8 format
[odoo/odoo.git] / addons / l10n_ch / invoice.py
1 # -*- coding: utf-8 -*-
2 #
3 #  bank.py
4 #  invoice.py
5 #
6 #  Created by Nicolas Bessi based on Credric Krier contribution
7 #
8 #  Copyright (c) 2009 CamptoCamp. All rights reserved.
9 ##############################################################################
10 # WARNING: This program as such is intended to be used by professional
11 # programmers who take the whole responsability of assessing all potential
12 # consequences resulting from its eventual inadequacies and bugs
13 # End users who are looking for a ready-to-use solution with commercial
14 # garantees and support are strongly adviced to contract a Free Software
15 # Service Company
16 #
17 # This program is Free Software; you can redistribute it and/or
18 # modify it under the terms of the GNU General Public License
19 # as published by the Free Software Foundation; either version 2
20 # of the License, or (at your option) any later version.
21 #
22 # This program is distributed in the hope that it will be useful,
23 # but WITHOUT ANY WARRANTY; without even the implied warranty of
24 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25 # GNU General Public License for more details.
26 #
27 # You should have received a copy of the GNU General Public License
28 # along with this program; if not, write to the Free Software
29 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
30 #
31 ##############################################################################
32
33 import time
34 from osv import fields, osv
35 from tools import mod10r
36 from mx import DateTime
37
38
39 class account_invoice(osv.osv):
40     """Inherit account.invoice in order to add bvr
41     printing functionnalites. BVR is a Swiss payment vector"""
42     _inherit = "account.invoice"
43
44     ## @param self The object pointer.
45     ## @param cursor a psycopg cursor
46     ## @param user res.user.id that is currently loged
47     ## @parma context a standard dict 
48     ## @return a list of tuple (name,value)
49     def _get_reference_type(self, cursor, user, context=None):
50         """Function use by the function field reference_type in order to initalise available 
51         BVR Reference Types"""
52         res = super(account_invoice, self)._get_reference_type(cursor, user,
53                 context=context)
54         res.append(('bvr', 'BVR'))
55         return res
56
57     ## @param self The object pointer.
58     ## @param cursor a psycopg cursor
59     ## @param user res.user.id that is currently loged
60     ## @parma context a standard dict
61     ## @param name of the files 
62     ## @param args a list of diverse argument 
63     ## @parma context a standard dict 
64     ## @return a  dict (invoice id,amount to pay)
65     def _amount_to_pay(self, cursor, user, ids, name, args, context=None):
66         '''Return the amount still to pay regarding all the payment orders'''
67         if not ids:
68             return {}
69         res = {}
70         for invoice in self.browse(cursor, user, ids, context=context):
71             res[invoice.id] = 0.0
72             if invoice.move_id:
73                 for line in invoice.move_id.line_id:
74                     if not line.date_maturity or \
75                             DateTime.strptime(line.date_maturity, '%Y-%m-%d') \
76                             < DateTime.now():
77                         res[invoice.id] += line.amount_to_pay
78         return res
79
80     _columns = {
81         ### BVR reference type BVR or FREE
82         'reference_type': fields.selection(_get_reference_type,
83             'Reference Type', required=True),
84         ### Partner bank link between bank and partner id   
85         'partner_bank': fields.many2one('res.partner.bank', 'Bank Account',
86             help='The partner bank account to pay\nKeep empty to use the default'
87             ),
88         ### Amount to pay
89         'amount_to_pay': fields.function(_amount_to_pay, method=True,
90             type='float', string='Amount to be paid',
91             help='The amount which should be paid at the current date\n' \
92                     'minus the amount which is already in payment order'),
93     }
94
95     ## @param self The object pointer.
96     ## @param cursor a psycopg cursor
97     ## @param user res.user.id that is currently loged
98     ## @parma ids invoices id
99     ## @return a boolean True if valid False if invalid 
100     def _check_bvr(self, cr, uid, ids):
101         """
102         Function to validate a bvr reference like :
103         0100054150009>132000000000000000000000014+ 1300132412>
104         The validation is based on l10n_ch
105         """
106         invoices = self.browse(cr, uid, ids)
107         for invoice in invoices:
108             if invoice.reference_type == 'bvr':
109                 if not invoice.reference:
110                     return False
111                 ## I need help for this bug because in this case
112                 # <010001000060190> 052550152684006+ 43435>
113                 # the reference 052550152684006 do not match modulo 10
114                 #
115                 if mod10r(invoice.reference[:-1]) != invoice.reference and \
116                     len(invoice.reference) == 15:
117                     return True
118                 #
119                 if mod10r(invoice.reference[:-1]) != invoice.reference:
120                     return False
121         return True
122     ## @param self The object pointer.
123     ## @param cursor a psycopg cursor
124     ## @param user res.user.id that is currently loged
125     ## @parma ids invoices id
126     ## @return a boolean True if valid False if invalid 
127     def _check_reference_type(self, cursor, user, ids):
128         """Check the customer invoice reference type depending 
129         on the BVR reference type and the invoice partner bank type"""
130         for invoice in self.browse(cursor, user, ids):
131             if invoice.type in 'in_invoice':
132                 if invoice.partner_bank and \
133                         invoice.partner_bank.state in \
134                         ('bvrbank', 'bvrpost') and \
135                         invoice.reference_type != 'bvr':
136                             return False
137         return True
138
139     _constraints = [
140         (_check_bvr, 'Error: Invalid Bvr Number (wrong checksum).',
141             ['reference']),
142         (_check_reference_type, 'Error: BVR reference is required.',
143             ['reference_type']),
144     ]
145
146     ## @param self The object pointer.
147     ## @param cr a psycopg cursor
148     ## @param uid res.user.id that is currently loged
149     ## @parma ids invoices id
150     ## @parma type the invoice type
151     ## @param partner_id the partner linked to the invoice
152     ## @parma date_invoice date of the invoice
153     ## @parma payment_term inoice payment term
154     ## @param partner_bank_id the partner linked invoice bank
155     ## @return the dict of values with the partner_bank value updated       
156     def onchange_partner_id(self, cr, uid, ids, type, partner_id,
157             date_invoice=False, payment_term=False, partner_bank_id=False):
158         """ Function that is call when the partner of the invoice is changed
159         it will retriev and set the good bank partner bank"""
160         res = super(account_invoice, self).onchange_partner_id(
161                                                                 cr,
162                                                                  uid,
163                                                                  ids,
164                                                                  type,
165                                                                  partner_id,
166                                                                  date_invoice,
167                                                                  payment_term
168                                                             )
169         bank_id = False
170         if partner_id:
171             p = self.pool.get('res.partner').browse(cr, uid, partner_id)
172             if p.bank_ids:
173                 bank_id = p.bank_ids[0].id
174
175         if type in ('in_invoice', 'in_refund'):
176             res['value']['partner_bank'] = bank_id
177
178         if partner_bank_id != bank_id:
179             to_update = self.onchange_partner_bank(cr, uid, ids, bank_id)
180             res['value'].update(to_update['value'])
181         return res
182
183     ## @param self The object pointer.
184     ## @param cursor a psycopg cursor
185     ## @param user res.user.id that is currently loged
186     ## @parma ids invoices id
187     ## @param partner_bank_id the partner linked invoice bank
188     ## @return the dict of values with the reference type  value updated 
189     def onchange_partner_bank(self, cursor, user, ids, partner_bank_id):
190         """update the reference type depending of the partner bank"""
191         res = {'value': {}}
192         partner_bank_obj = self.pool.get('res.partner.bank')
193         if partner_bank_id:
194             partner_bank = partner_bank_obj.browse(cursor, user, partner_bank_id)
195             if partner_bank.state in ('bvrbank', 'bvrpost'):
196                 res['value']['reference_type'] = 'bvr'
197         return res
198
199 account_invoice()
200
201 class account_tax_code(osv.osv):
202     """Inherit account tax code in order
203     to add a Case code"""
204     _name = 'account.tax.code'
205     _inherit = "account.tax.code"
206     _columns = {
207         ### The case code of the taxt code
208         'code': fields.char('Case Code', size=512),
209     }
210 account_tax_code()
211
212 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: