~vauxoo/addons-vauxoo/7.0-demo_maintenance-dev_luis

« back to all changes in this revision

Viewing changes to commission_payment/commission.py

  • Committer: Miguel Delgado
  • Author(s): Vauxoo
  • Date: 2012-03-08 15:56:52 UTC
  • mto: (134.1.16 addons-vauxoo)
  • mto: This revision was merged to the branch mainline in revision 139.
  • Revision ID: miguel.delgado07@gmail.com-20120308155652-j4hgvzmuvxscaaty

[ADD] modulos referentes a las comisiones 

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- coding: utf-8 -*-
 
2
##############################################################################
 
3
#
 
4
#    OpenERP, Open Source Management Solution    
 
5
#    Copyright (C) 2011 Vauxoo (<http://www.vauxoo.com>). All Rights Reserved
 
6
#    hbto@vauxoo.com / humbertoarocha@gmail.com
 
7
#
 
8
#    This program is free software: you can redistribute it and/or modify
 
9
#    it under the terms of the GNU General Public License as published by
 
10
#    the Free Software Foundation, either version 3 of the License, or
 
11
#    (at your option) any later version.
 
12
#
 
13
#    This program is distributed in the hope that it will be useful,
 
14
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
#    GNU General Public License for more details.
 
17
#
 
18
#    You should have received a copy of the GNU General Public License
 
19
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
20
#
 
21
##############################################################################
 
22
 
 
23
from osv import osv, fields
 
24
import pooler
 
25
import time
 
26
import math
 
27
import mx.DateTime
 
28
 
 
29
from tools import config
 
30
from tools.translate import _
 
31
import decimal_precision as dp
 
32
 
 
33
 
 
34
 
 
35
class commission_payment(osv.osv):
 
36
    """
 
37
    OpenERP Model : commission_payment
 
38
    """
 
39
    
 
40
    _name = 'commission.payment'
 
41
    _description = __doc__
 
42
    
 
43
    _columns = {
 
44
        'name':fields.char('Concepto de Comisiones', size=256, required=True, readonly= True, states={'draft':[('readonly',False)]}),
 
45
        'bar_id': fields.many2one('baremo.book', 'Baremo', required=True, readonly= True, states={'draft':[('readonly',False)]}),
 
46
        'date_start':fields.date('Desde', required=True, readonly= True, states={'draft':[('readonly',False)]}),
 
47
        'date_stop':fields.date('Hasta', required=True, readonly= True, states={'draft':[('readonly',False)]}),
 
48
        'total_comm':fields.float('Total a Pagar', digits_compute=dp.get_precision('Commission'), readonly= True,states={'write':[('readonly',False)]}),
 
49
        #~ 'ret_notes':fields.text('Notas para las Retenciones',readonly= True, states={'draft':[('readonly',False)], 'open':[('readonly',False)]}),
 
50
        #~ 'uninvoiced_ids':fields.one2many('commission.uninvoiced', 'commission_id', 'Transacciones sin Facturas', readonly= True, states={'write':[('readonly',False)]}),
 
51
        #~ 'sale_noids':fields.one2many('commission.sale.noid', 'commission_id', 'Articulos sin asociacion', readonly= True, states={'write':[('readonly',False)]}),
 
52
        #~ 'noprice_ids':fields.one2many('commission.noprice', 'commission_id', 'Productos sin precio de lista historico', readonly= True, states={'write':[('readonly',False)]}),
 
53
        'comm_line_ids':fields.one2many('commission.lines', 'commission_id', 'Comision por productos', readonly= True, states={'write':[('readonly',False)]}),
 
54
        'saleman_ids':fields.one2many('commission.saleman', 'commission_id', 'Total de Comisiones por Vendedor', readonly= True, states={'write':[('readonly',False)]}),
 
55
        'user_ids': fields.many2many('res.users','commission_users','commission_id', 'user_id', 'Vendedores', required=True, readonly= True, states={'draft':[('readonly',False)]}),
 
56
        'voucher_ids': fields.many2many('account.voucher','commission_account_voucher','commission_id', 'voucher_id', 'Vouchers', readonly= True, states={'draft':[('readonly',False)],'open':[('readonly',False)],}),
 
57
        #~ 'comm_voucher_ids':fields.one2many('commission.voucher', 'commission_id', 'Vouchers afectados en esta comision', readonly= True, states={'write':[('readonly',False)]}),
 
58
        #~ 'comm_invoice_ids':fields.one2many('commission.invoice', 'commission_id', 'Facturas afectadas en esta comision', readonly= True, states={'write':[('readonly',False)]}),
 
59
        #~ 'comm_retention_ids':fields.one2many('commission.retention', 'commission_id', 'Facturas con Problemas de Retencion', readonly= True, states={'write':[('readonly',False)]}),
 
60
        'state': fields.selection([
 
61
            ('draft','Inicial'),
 
62
            ('open','En Proceso'),
 
63
            ('decide','Decidir'),
 
64
            ('write','Escribiendo'),
 
65
            ('done','Listo'),
 
66
            ('cancel','Cancelado')
 
67
        ],'Estado', readonly=True),
 
68
    }
 
69
    _defaults = {
 
70
        'name': lambda *a: None,
 
71
        'total_comm': lambda *a: 0.00,
 
72
        'state': lambda *a: 'draft',
 
73
        #~ 'ret_notes': lambda *a: 'Las Facturas que se mencionan ya tienen un pago registrado, pero presentan problemas con una o mas de las retenciones que se indican en el cuadro, se ha tratado bajo los medios existentes de identificar cuales son los porcentajes de retenciones pero no ha sido posible, para generar la comision sobre el pago de las mismas, es necesario el conocimiento de estos valores, por lo que le increpamos a que contacte a sus asociados para obtener esta informacion, su falta no afectara el calculo de la comision pero retardara su ejecucion. Si considera que ha habido un error por favor hable sobre el tema con el personal Administrativo y de Sistemas para determinar las causas del mismo y encontrar una solucion. De otra forma haga caso omiso de este mensaje y su contenido',
 
74
    }
 
75
 
 
76
    def prepare(self, cr, uid, ids, context=None):
 
77
        """
 
78
        Este metodo recorre los elementos de account_voucher y verifica al menos 
 
79
        tres (3) caracteristicas primordiales para continuar con los vouchers:
 
80
        estas caracteristicas son: 
 
81
        - bank_rec_voucher: quiere decir que el voucher es de un deposito bancario
 
82
        (aqui aun no se ha considerado el trato que se le da a los cheques devueltos).
 
83
        - posted: quiere decir que el voucher ya se ha contabilizado, 
 
84
        condicion necesaria pero no suficiente.
 
85
        - move_ids: si la longitud de estos es distinto de cero es porque este voucher es
 
86
        por completo valido, es decir, realmente tiene asientos contables registrados.
 
87
        
 
88
        Si estas tres (3) condiciones se cumplen entonces se puede proceder a realizar la revision
 
89
        de las lineas de pago.
 
90
        
 
91
        
 
92
        @param cr: cursor to database
 
93
        @param uid: id of current user
 
94
        @param ids: list of record ids to be process
 
95
        @param context: context arguments, like lang, time zone
 
96
        
 
97
        @return: return a result
 
98
        """
 
99
        
 
100
        self.write(cr, uid, ids, {
 
101
                'state': 'open',
 
102
            })
 
103
        
 
104
        #~ Consultas
 
105
        accounts = self.pool.get('account.account')
 
106
        vouchers = self.pool.get('account.voucher')
 
107
        payments = self.pool.get ('account.voucher.line')
 
108
        invoices = self.pool.get ('account.invoice')
 
109
        invoice_lines = self.pool.get ('account.invoice.line')
 
110
        prod_prices = self.pool.get ('product.historic')
 
111
        partner_ids = self.pool.get ('res.partner')
 
112
        
 
113
        #~ Elementos Internos
 
114
        uninvoiced_pays = self.pool.get ('commission.uninvoiced')
 
115
        sale_noids = self.pool.get ('commission.sale.noid')
 
116
        noprice_ids = self.pool.get ('commission.noprice')
 
117
        comm_line_ids = self.pool.get ('commission.lines')
 
118
        saleman_ids = self.pool.get ('commission.saleman')
 
119
        #~ users_ids = self.pool.get ('commission.users')
 
120
        comm_voucher_ids = self.pool.get ('commission.voucher')
 
121
        comm_invoice_ids = self.pool.get ('commission.invoice')
 
122
        comm_retention_ids = self.pool.get ('commission.retention')
 
123
        
 
124
        ## Retenciones
 
125
        # de IVA
 
126
        ret_iva_lines = self.pool.get ('account.retention.line')
 
127
        # de ISLR
 
128
        ret_islr_lines = self.pool.get ('account.retencion.islr.line')
 
129
        # de IM
 
130
        ret_im_lines = self.pool.get ('account.retencion.munici.line')
 
131
        
 
132
        #commissions = self.pool.get('commission.payment')
 
133
        commissions = self.browse(cr, uid, ids, context=None)
 
134
        
 
135
        for commission in commissions:
 
136
            # Desvincular lineas existentes, si las hubiere
 
137
            self._unlink(cr, uid, ids, context=None)            
 
138
            
 
139
            date_start = commission.date_start
 
140
            date_stop = commission.date_stop
 
141
            
 
142
            #~ Obtener la lista de asesores/vendedores a los cuales se les hara el calculo de comisiones
 
143
            user_ids = []
 
144
            user_ids = [line.id for line in commission.user_ids]
 
145
            
 
146
            #~ Obtener la lista de vouchers que se seleccionaron manualmente en el widget many2many
 
147
            voucher_ids = []
 
148
            voucher_ids = [line.id for line in commission.voucher_ids]
 
149
            
 
150
            #~ Aqui verificamos que si no hay ningun voucher nosotros nos encargaremos de hacer la lista
 
151
            if not voucher_ids:
 
152
                # En esta busqueda restringimos que el voucher se haya contabilizado y que 
 
153
                # sea un cobro bancario y este dentro de la fecha estipulada
 
154
                voucher_ids = vouchers.search(cr, uid, [('state', '=', 'posted'), ('type', '=', 'receipt'),('date', '>=', date_start),('date', '<=', date_stop)])
 
155
                
 
156
                commission.write({
 
157
                                'voucher_ids': [(6, commission.id, voucher_ids)],
 
158
                                },context=None) 
 
159
            
 
160
            for vid in voucher_ids:
 
161
                    pay = vouchers.read(cr,uid,vid,['name', 'date', 'amount', 'line_cr_ids','move_ids'],context=None)
 
162
                    print 'pay: ',pay
 
163
                    if pay['move_ids'] and pay['line_cr_ids']:
 
164
                        # Con la negacion de esta condicion se termina de realizar la revision de las lineas de pago que cumplen con las tres
 
165
                        # condiciones estipuladas inicialmente, ahora se debe proseguir con la revision de las lineas de pago
 
166
                        print 'PASO POR AQUI'
 
167
                        for pid in pay['line_cr_ids']:
 
168
                            payment_brw = payments.browse(cr, uid, pid, context=None)
 
169
                            pay_line_vendor = payment_brw.partner_id.user_id and payment_brw.partner_id.user_id.id or False
 
170
                            if pay_line_vendor in user_ids:
 
171
 
 
172
                                # Leer cada una de las lineas de los vouchers
 
173
                                pay_line = payments.read(cr,uid,pid,['name', 'invoice_id', 'amount', 'account_id', 'paid_comm'],context=None)
 
174
                                print 'pay_line ',pay_line
 
175
                                
 
176
                                # Verificar si esta linea tiene factura y la comision del pago no se ha pagado
 
177
                                if pay_line['invoice_id'] and not pay_line['paid_comm']:
 
178
                                    print 'ENTRO EN DOS (2)'
 
179
                                    # Si esta aqui dentro es porque esta linea tiene una id valida de una factura.
 
180
                                    inv_id = pay_line['invoice_id'][0]
 
181
                                    inv = invoices.read(cr,uid,inv_id,['number', 'amount_untaxed', 'amount_total', 'invoice_line', 'date_invoice', 'partner_id'],context=None)
 
182
                                    
 
183
                                    # Obtener % IVA 
 
184
                                    #~ perc_IVA = round(((  inv['amount_total'] /  inv['amount_untaxed'])-1)*100,0)
 
185
                                    #~ print 'perc_IVA: ',perc_IVA,'\n'
 
186
                                    
 
187
                                    # Obtener el Valor de Porcentaje Retencion de esta factura
 
188
                                    
 
189
                                    # Las maneras faciles son las dos primeras que el cliente no retenga y la factura sea solo de productos
 
190
                                    # por lo que las retenciones de islr y im no aplican
 
191
                                    # o que el cliente retenga el 100% (algo poco visto) y sea una factura de productos
 
192
                                    #~ no_ret_iva = True
 
193
                                    #~ no_ret_islr = True
 
194
                                    #~ no_ret_im = True
 
195
                                    
 
196
                                    #~ if abs(inv['amount_total'] - pay_line['amount'])<= 1.0:
 
197
                                        #~ perc_Ret_IVA = 0.0
 
198
                                        #~ perc_Ret_ISLR = 0.0
 
199
                                        #~ perc_Ret_IM = 0.0
 
200
                                        #~ no_ret_iva = False
 
201
                                        #~ no_ret_islr = False
 
202
                                        #~ no_ret_im = False
 
203
                                    #~ elif abs((inv['amount_untaxed']*(1+(perc_IVA/100)*(1-75.0/100))) - pay_line['amount'])<= 1.0:
 
204
                                        #~ perc_Ret_IVA = 75.0
 
205
                                        #~ perc_Ret_ISLR = 0.0
 
206
                                        #~ perc_Ret_IM = 0.0
 
207
                                        #~ no_ret_iva = False
 
208
                                        #~ no_ret_islr = False
 
209
                                        #~ no_ret_im = False
 
210
                                    #~ elif ret_iva_lines.search(cr, uid, [('invoice_id', '=', inv_id)]):                                
 
211
                                        #~ lines_ret_iva = ret_iva_lines.search(cr, uid, [('invoice_id', '=', inv_id)])
 
212
                                        #~ for line in lines_ret_iva:
 
213
                                            #~ perc_Ret_IVA = ret_iva_lines.browse(cr, uid, line, context=None).retention_rate
 
214
                                        #~ no_ret_iva = False
 
215
 
 
216
                                    #~ if no_ret_islr == True and ret_islr_lines.search(cr, uid, [('invoice_id', '=', inv_id)]):
 
217
                                        #~ lines_ret_islr = ret_islr_lines.search(cr, uid, [('invoice_id', '=', inv_id)])
 
218
                                        #~ perc_Ret_ISLR = 0
 
219
                                        #~ for line in lines_ret_islr:
 
220
                                            #~ perc_Ret_ISLR += ret_islr_lines.browse(cr, uid, line, context=None).retencion_islr
 
221
                                        #~ no_ret_islr = False
 
222
                                        
 
223
                                    #~ if no_ret_im == True and ret_im_lines.search(cr, uid, [('invoice_id', '=', inv_id)]):
 
224
                                        #~ lines_ret_im = ret_im_lines.search(cr, uid, [('invoice_id', '=', inv_id)])
 
225
                                        #~ perc_Ret_IM = 0
 
226
                                        #~ for line in lines_ret_im:
 
227
                                            #~ perc_Ret_IM += ret_im_lines.browse(cr, uid, line, context=None).retencion_munici
 
228
                                        #~ no_ret_im = False
 
229
                                    
 
230
                                    # Tratando de obtener la perc_Ret_IVA cuando se tiene el valor de impuesto municipal 
 
231
                                    # y considerando que el islr es cero, como en el caso de las empresas que solo cargan un impuesto social
 
232
                                    
 
233
                                    #~ if no_ret_im == False and no_ret_iva == True:
 
234
                                        #~ for valor in [0, 75.0, 100.0]:
 
235
                                            #~ if abs((inv['amount_untaxed']*(1+(perc_IVA/100)*(1-valor/100.0)-(perc_Ret_IM/100.0))) - pay_line['amount'])<= 1.0:
 
236
                                                #~ perc_Ret_IVA = valor
 
237
                                                #~ no_ret_iva = False
 
238
                                    
 
239
                                    # Tratando de obtener la perc_Ret_IVA cuando se tiene el valor de impuesto slr 
 
240
                                    # y considerando que el im es cero, como en el caso de las empresas que solo cargan el islr y no el im
 
241
                                    
 
242
                                    #~ if no_ret_islr == False and no_ret_iva == True:
 
243
                                        #~ for valor in [0, 75.0, 100.0]:
 
244
                                            #~ if abs((inv['amount_untaxed']*(1+(perc_IVA/100)*(1-valor/100.0)-(perc_Ret_ISLR/100.0))) - pay_line['amount'])<= 1.0:
 
245
                                                #~ perc_Ret_IVA = valor
 
246
                                                #~ no_ret_iva = False
 
247
                                    
 
248
                                    # Tratando de obtener la perc_Ret_IVA cuando se tienen tanto el islr como el im
 
249
                                    
 
250
                                    #~ if no_ret_islr == False and no_ret_im == False and no_ret_iva == True:
 
251
                                        #~ for valor in [0, 75.0, 100.0]:
 
252
                                            #~ if abs((inv['amount_untaxed']*(1+(perc_IVA/100)*(1-valor/100.0)-(perc_Ret_IM/100.0)-(perc_Ret_ISLR/100.0))) - pay_line['amount'])<= 1.0:
 
253
                                                #~ perc_Ret_IVA = valor
 
254
                                                #~ no_ret_iva = False
 
255
                                    
 
256
                                    # Tratando de obtener el islr cuando se tienen tanto el perc_Ret_IVA como el im
 
257
                                    #~ if no_ret_islr == True and no_ret_im == False and no_ret_iva == False:
 
258
                                        #~ for valor in [0, 2.0, 3.0, 5.0]:
 
259
                                            #~ if abs((inv['amount_untaxed']*(1+(perc_IVA/100)*(1-perc_Ret_IVA/100.0)-(perc_Ret_IM/100.0)-(valor/100.0))) - pay_line['amount'])<= 1.0:
 
260
                                                #~ perc_Ret_ISLR = valor
 
261
                                                #~ no_ret_islr = False
 
262
                                                                    
 
263
                                    # Obtener el vendedor del partner
 
264
                                    saleman = partner_ids.read(cr,uid,inv['partner_id'][0],['user_id'],context=None)['user_id']
 
265
                                    print 'SALEMAN (4) ', saleman
 
266
                                    # si ha sido posible calcular u obtener todas las retenciones por los medios convencionales
 
267
                                    # entonces se puede proceder con el calculo de retencion de las lineas, de lo contrario se 
 
268
                                    # genera una bitacora para que se obtengan las retenciones faltantes para proceder nuevament
 
269
                                    # con la preparacion de las comisiones.
 
270
                                    if saleman:
 
271
                                        print 'DENTRO DEL CALCULO PARA LAS RETENCIONES'
 
272
                                        # Revision de cada linea de factura (productos)
 
273
                                        for l_id in inv['invoice_line']:
 
274
                                            
 
275
                                            #Obtener valores de las lineas
 
276
                                            inv_lin = invoice_lines.read(cr,uid,l_id,['name', 'price_unit', 'price_subtotal', 'quantity', 'product_id'],context=None)
 
277
                                            
 
278
                                            #~ print 'Producto: ', inv_lin['name'], '\n'
 
279
                                            
 
280
                                            # Verificar si tiene producto asociado
 
281
                                            if inv_lin['product_id']:
 
282
                                                # Si esta aqui es porque hay un producto asociado
 
283
                                                prod_id = inv_lin['product_id'][0]
 
284
                                                
 
285
                                                # se obtienen las listas de precio, vienen ordenadas por defecto, de acuerdo al objeto
 
286
                                                # product.historic de mayor a menor fecha
 
287
                                                #~ price_ids = prod_prices.search(cr, uid, [('product_id', '=', prod_id)])
 
288
                                                
 
289
                                                # Buscar Precio Historico de Venta de este 
 
290
                                                # producto @ la fecha de facturacion
 
291
                                                no_price = True
 
292
                                                #~ for price_id in price_ids:
 
293
                                                    #~ if inv['date_invoice'] >= prod_prices.browse(cr, uid, price_id, context=None).name:
 
294
                                                        #~ list_price = prod_prices.browse(cr, uid, price_id, context=None).price
 
295
                                                        #~ list_date = prod_prices.browse(cr, uid, price_id, context=None).name
 
296
                                                        #~ no_price = False
 
297
                                                        #~ print '[date_invoice : list_price : list_date]: [', inv['date_invoice'],' : ', list_price,' : ', list_date,'] \n' 
 
298
                                                        #~ break
 
299
                                                if no_price:
 
300
                                                    # Determinar cuanto fue el descuento en este producto en aquel momento de la venta
 
301
                                                    #~ if (inv_lin['price_subtotal']/inv_lin['quantity'])< inv_lin['price_unit']:
 
302
                                                    #~ if abs((inv_lin['price_subtotal']/inv_lin['quantity']) - inv_lin['price_unit']) > 0.05:
 
303
                                                        # con esto se asegura que no se esta pasando por alto el descuento en linea
 
304
                                                        #~ price_unit = round((inv_lin['price_subtotal']/inv_lin['quantity']),2)
 
305
                                                    #~ else:
 
306
                                                        #~ price_unit = inv_lin['price_unit']
 
307
                                                    
 
308
                                                    #~ dcto= round((list_price - price_unit)*100/list_price,1)
 
309
                                                    rate_item= 10.0/100
 
310
                                                    
 
311
                                                    # Determinar dias entre la emision de la factura del producto y el pago del mismo
 
312
                                                    pay_date = mx.DateTime.strptime(pay['date'], '%Y-%m-%d')
 
313
                                                    inv_date = mx.DateTime.strptime(inv['date_invoice'], '%Y-%m-%d')
 
314
                                                    emission_days = (pay_date - inv_date).day
 
315
 
 
316
                                                    # Teniendose dias y descuento por producto se procede a buscar en el baremo
 
317
                                                    # el correspondiente valor de comision para el producto en cuestion.
 
318
                                                    # se entra con el numero de dias
 
319
                                                    
 
320
                                                    # Esta busqueda devuelve los dias ordenadados de menor a mayor dia, de acuerdo
 
321
                                                    # con lo estipulado que se ordenaria en el modulo baremo
 
322
                                                    bid = 1
 
323
                                                    comm_res = self.pool.get('baremo.book')._calc_comm(cr, uid, bid, rate_item, emission_days)
 
324
                                                    
 
325
                                                    #############################################
 
326
                                                    # CALCULO DE COMISION POR LINEA DE PRODUCTO #
 
327
                                                    #############################################
 
328
                                                    
 
329
                                                    ## TODO: ESTE VALOR DEBE DESAPARECER DE AQUI
 
330
                                                    #  este valor se debe sustituir por un valor que viene de la factura
 
331
                                                    #  son solo demostrativos y no deberian quedar aqui luego de enviar
 
332
                                                    #  este modulo a produccion.
 
333
                                                    #
 
334
                                                    ## 
 
335
                                                    
 
336
                                                    PenBxLinea = pay_line['amount']*(inv_lin['price_subtotal']/inv['amount_untaxed'])
 
337
                                                    #~ Fact_Sup = 1 - perc_Ret_ISLR/100 - perc_Ret_IM/100
 
338
                                                    #~ Fact_Inf = 1 + (perc_IVA/100) * (1 - perc_Ret_IVA/100) - perc_Ret_ISLR/100 - perc_Ret_IM/100
 
339
                                                    
 
340
                                                    #~ comm_line =  PenBxLinea * Fact_Sup * (bar_dcto_comm / 100) / Fact_Inf
 
341
                                                    comm_line =  PenBxLinea * (comm_res['rate_comm'] / 100)
 
342
                                                    #~ comm_line =  PenBxLinea * (bar_dcto_comm / 100)
 
343
                                                    # Generar las lineas de comision por cada producto
 
344
                                                    comm_line_ids.create(cr, uid,{
 
345
                                                        'commission_id': commission.id,
 
346
                                                        'voucher_id': vid,
 
347
                                                        'name':  pay['name'] and pay['name'] or '/', 
 
348
                                                        'pay_date': pay['date'], 
 
349
                                                        'pay_off': pay['amount'], 
 
350
                                                        'concept': pid  ,
 
351
                                                        'invoice_id': pay_line['invoice_id'][0] ,
 
352
                                                        'invoice_num':  inv['number'],
 
353
                                                        'partner_id': inv['partner_id'][0] ,
 
354
                                                        'saleman_name': saleman[1] ,
 
355
                                                        'saleman_id': saleman[0] ,
 
356
                                                        'pay_inv': pay_line['amount'], 
 
357
                                                        'inv_date': inv['date_invoice'],
 
358
                                                        'days': emission_days and emission_days or 0.0,
 
359
                                                        'inv_subtotal': inv['amount_untaxed'],
 
360
                                                        'item': inv_lin['name'],
 
361
                                                        #~ 'price_unit':  price_unit, 
 
362
                                                        'price_subtotal':  inv_lin['price_subtotal'], 
 
363
                                                        #~ 'price_list':  list_price, 
 
364
                                                        #~ 'price_date': list_date ,
 
365
                                                        #~ 'perc_Ret_ISLR' : perc_Ret_ISLR,
 
366
                                                        #~ 'perc_Ret_IM' : perc_Ret_IM,
 
367
                                                        #~ 'perc_Ret_IVA' : perc_Ret_IVA,
 
368
                                                        #~ 'perc_IVA' : perc_IVA,
 
369
                                                        'rate_item': rate_item and rate_item or 0.0, 
 
370
                                                        'rate_number': comm_res['rate_number'] and comm_res['rate_number'] or 0.0,
 
371
                                                        'timespan': comm_res['timespan'] and comm_res['timespan']  or 0.0,
 
372
                                                        'baremo_comm': comm_res['rate_comm'] and comm_res['rate_comm'] or 0.0,
 
373
                                                        'commission': comm_line and comm_line or 0.0,
 
374
                                                    },context=None) 
 
375
                                                    print 'CREANDO LINEAS DE COMISIONES (5)'
 
376
                                                else:
 
377
                                                    # Se genera un lista de tuplas con las lineas, productos y sus correspondientes fechas
 
378
                                                    # en las cuales no aparece precio de lista, luego al final se escriben los
 
379
                                                    # valores en la correspondiente bitacora para su inspeccion.
 
380
                                                    #~ print 'No hubo precio de lista para la fecha estipulada, hay que generar el precio en este producto \n'
 
381
                                                    noprice_ids.create(cr, uid,{
 
382
                                                        'commission_id': commission.id,
 
383
                                                        'product_id': prod_id,
 
384
                                                        'date': inv['date_invoice'],
 
385
                                                        'invoice_num': inv['number'],
 
386
                                                    },context=None)  
 
387
                                            else:
 
388
                                                # cuando una linea no tiene product_id asociado se escribe en una tabla para alertar al operador
 
389
                                                # sobre esta parte no llego a un acuerdo de si se podria permitir al operador cambiar las lineas
 
390
                                                # de la factura puesto que es un asunto muy delicado.
 
391
                                                pass
 
392
                                                sale_noids.create(cr, uid,{
 
393
                                                    'commission_id' :   commission.id,
 
394
                                                    'inv_line_id'   :   l_id,
 
395
                                                },context=None)  
 
396
                                    else:
 
397
                                        print 'ENTRO EN EL CREATE (3)'
 
398
                                        # generar campo y vista donde se han de cargar las facturas que tienen problemas
 
399
                                        # se debe grabar los tres campos de las retenciones y el numero de la factura para 
 
400
                                        # tener detalles concisos y porcion de voucher de pago de la factura en cuestion
 
401
                                        comm_retention_ids.create(cr, uid,{
 
402
                                            'commission_id' :   commission.id,
 
403
                                            'invoice_id': pay_line['invoice_id'][0],
 
404
                                            'voucher_id':vid,
 
405
                                            'date': pay['date'],
 
406
                                            'ret_iva': no_ret_iva,
 
407
                                            'ret_islr':  no_ret_islr,
 
408
                                            'ret_im': no_ret_im,
 
409
                                        },context=None)
 
410
                                elif (pay_line['invoice_id']==False and pay_line['paid_comm']==False):
 
411
                                    # Si esta aqui dentro es porque esta linea (transaccion) no tiene factura valida, se escribe
 
412
                                    # entonces una linea en una vista donde se muestran las transacciones que no tienen factura 
 
413
                                    # asociada para su correccion si aplica. tampoco se ha pagado la comision del mismo
 
414
                                    # solo se incluiran pagos que sean de cuentas cobrables, puesto que las de otra naturaleza,
 
415
                                    # no tienen sentido mostrarlas aqui.
 
416
                                    if accounts.read(cr, uid, pay_line['account_id'][0],['type'], context=None)['type']== 'receivable':
 
417
                                        uninvoiced_pays.create(cr, uid,{
 
418
                                            'commission_id' :   commission.id,
 
419
                                            'payment_id'    :   pid,
 
420
                                        },context=None)
 
421
                            else:
 
422
                                #~ No se hace nada por que el vendedor del pago que se esta consultando no se incorporo
 
423
                                #~ a la lista de asesores a los que se debe calcular la comision
 
424
                                pass
 
425
        # habiendo recorrido todos los vouchers, mostrado todos los elementos que necesitan correccion
 
426
        # se procede a agrupar las comisiones por vendedor para mayor facilidad de uso
 
427
        
 
428
        # comm_line_ids.unlink(cr, uid, [line_ids.id for line_ids in commission.comm_line_ids])
 
429
        
 
430
        # recargando las lineas que se han creado
 
431
        commissions = self.browse(cr, uid, ids, context=None)
 
432
        saleman_ids = self.pool.get ('commission.saleman')
 
433
        comm_voucher_ids = self.pool.get ('commission.voucher')
 
434
        comm_retention_ids = self.pool.get ('commission.retention')
 
435
        #~ print 'antes de calcular totales\n'
 
436
        
 
437
        for commission in commissions:
 
438
            #~ # recoge todos los vendedores y suma el total de sus comisiones
 
439
            sale_comm = {}
 
440
            #~ # ordena en un arbol todas las lineas de comisiones de producto
 
441
            criba = {}
 
442
            for comm_line in commission.comm_line_ids:
 
443
#~ 
 
444
                vendor_id = comm_line.saleman_id.id
 
445
                voucher_id = comm_line.voucher_id.id
 
446
                invoice_id = comm_line.invoice_id.id
 
447
                comm_line_id = comm_line.id
 
448
                #~ 
 
449
                if not vendor_id in sale_comm.keys():
 
450
                    sale_comm[vendor_id]=[comm_line.saleman_name, 0.0]
 
451
                sale_comm[vendor_id][1] += comm_line.commission
 
452
                #~ 
 
453
                if not vendor_id in criba.keys():
 
454
                     criba[vendor_id] = {}
 
455
                     #~ 
 
456
                #~ if not voucher_id in criba[vendor_id].keys():
 
457
                     #~ criba[vendor_id][voucher_id] = [comm_line.pay_date,{}]
 
458
                     #~ 
 
459
                #~ if not invoice_id in criba[vendor_id][voucher_id][1].keys():
 
460
                     #~ criba[vendor_id][voucher_id][1][invoice_id] = {}
 
461
                     #~ 
 
462
                #~ if len(criba[vendor_id][voucher_id][1][invoice_id])==0:
 
463
                     #~ criba[vendor_id][voucher_id][1][invoice_id]=[[], comm_line.pay_inv, comm_line.perc_Ret_IVA, comm_line.perc_Ret_ISLR, comm_line.perc_Ret_IM]
 
464
                #~ 
 
465
                #~ criba[vendor_id][voucher_id][1][invoice_id][0].append(comm_line_id)
 
466
#~ 
 
467
            #~ ## escribir el total para cada vendedor encontrado
 
468
            total_comm = 0
 
469
            for vendor_key in criba.keys():
 
470
                vendor_id = saleman_ids.create(cr, uid,{
 
471
                    'commission_id': commission.id,
 
472
                    'saleman_id': vendor_key,
 
473
                    'saleman_name':  sale_comm[vendor_key][0],
 
474
                    'comm_total': sale_comm[vendor_key][1],
 
475
                }, context=None)
 
476
#~ 
 
477
                total_comm += sale_comm[vendor_key][1]
 
478
#~ 
 
479
                #~ for voucher_key in criba[vendor_key].keys():
 
480
                    #~ voucher_id = comm_voucher_ids.create(cr, uid,{
 
481
                        #~ 'commission_id': commission.id,
 
482
                        #~ 'comm_sale_id': vendor_id,
 
483
                        #~ 'voucher_id':  voucher_key,
 
484
                        #~ 'date':  criba[vendor_key][voucher_key][0],
 
485
                    #~ }, context=None)
 
486
                        #~ 
 
487
                    #~ for inv_key in criba[vendor_key][voucher_key][1].keys():
 
488
                        #~ invoice_id = comm_invoice_ids.create(cr, uid,{
 
489
                            #~ 'commission_id': commission.id,
 
490
                            #~ 'comm_voucher_id': voucher_id,
 
491
                            #~ 'invoice_id':  inv_key,
 
492
                            #~ 'pay_inv':  criba[vendor_key][voucher_key][1][inv_key][1],
 
493
                            #~ 'ret_iva':  criba[vendor_key][voucher_key][1][inv_key][2],
 
494
                            #~ 'ret_islr':  criba[vendor_key][voucher_key][1][inv_key][3],
 
495
                            #~ 'ret_im':  criba[vendor_key][voucher_key][1][inv_key][4],
 
496
                        #~ }, context=None)
 
497
                        #~ 
 
498
                        #~ for id in criba[vendor_key][voucher_key][1][inv_key][0]:
 
499
                            #~ comm_line_ids.write(cr, uid, id, {
 
500
                                #~ 'comm_invoice_id': invoice_id,
 
501
                            #~ }, context=None)
 
502
            #~ 
 
503
            self.write(cr, uid, ids, {
 
504
                'total_comm': total_comm,
 
505
            })
 
506
        #~ 
 
507
        result = True
 
508
        return result
 
509
 
 
510
    def pre_process(self, cr, uid, ids, context={}):
 
511
        commissions = self.browse(cr, uid, ids, context=None)
 
512
        for commission in commissions:
 
513
            self.prepare(cr, uid, ids, context=None)
 
514
            
 
515
            if commission.comm_line_ids:
 
516
                self.write(cr, uid, ids, {
 
517
                        'state': 'decide',
 
518
                    })
 
519
            else:
 
520
                raise osv.except_osv(_('Atencion !'), _('No Existen Lineas de Comision x Producto que procesar !!!'))
 
521
            
 
522
            #~ if not commission.noprice_ids:
 
523
                #~ self.write(cr, uid, ids, {
 
524
                        #~ 'state': 'decide',
 
525
                    #~ })
 
526
            #~ else:
 
527
                #~ raise osv.except_osv(_('Atencion !'), _('Debe primero solucionar el asunto de los Productos sin Listas de Precio \npara las fechas especificadas antes de continuar'))
 
528
            #~ 
 
529
    
 
530
    def delete(self, cr, uid, ids, context={}):
 
531
        commissions = self.browse(cr, uid, ids, context=None)
 
532
        
 
533
        for commission in commissions:
 
534
            self._unlink(cr, uid, ids, context=None)
 
535
            self.write(cr, uid, ids, {
 
536
                        'state': 'draft',
 
537
                        'total_comm':None,
 
538
                    })
 
539
        return True
 
540
        
 
541
    def _unlink(self, cr, uid, ids, context={}):
 
542
        
 
543
        uninvoiced_pays = self.pool.get ('commission.uninvoiced')
 
544
        sale_noids = self.pool.get ('commission.sale.noid')
 
545
        noprice_ids = self.pool.get ('commission.noprice')
 
546
        comm_line_ids = self.pool.get ('commission.lines')
 
547
        saleman_ids = self.pool.get ('commission.saleman')
 
548
        #~ users_ids = self.pool.get ('commission.users')
 
549
        comm_voucher_ids = self.pool.get ('commission.voucher')
 
550
        comm_invoice_ids = self.pool.get ('commission.invoice')
 
551
        comm_retention_ids = self.pool.get ('commission.retention')
 
552
                
 
553
        commissions = self.browse(cr, uid, ids, context=None)
 
554
        
 
555
        for commission in commissions:
 
556
            ###
 
557
            # Desvincular todos los elementos que esten conectados a este calculo de comisiones
 
558
            # * Desvinculando los pagos sin facturas
 
559
            #~ uninvoiced_pays.unlink(cr, uid, [line.id for line in commission.uninvoiced_ids])
 
560
            # * Desvinculando los articulos sin id
 
561
            #~ sale_noids.unlink(cr, uid, [line.id for line in commission.sale_noids])
 
562
            # * Desvinculando los productos sin fecha
 
563
            #~ noprice_ids.unlink(cr, uid, [line.id for line in commission.noprice_ids])
 
564
            # * Desvinculando las lineas de comisiones
 
565
            comm_line_ids.unlink(cr, uid, [line.id for line in commission.comm_line_ids])
 
566
            # * Desvinculando los totales por vendedor
 
567
            saleman_ids.unlink(cr, uid, [line.id for line in commission.saleman_ids])
 
568
            # * Desvinculando los vendedores
 
569
            #~ users_ids.unlink(cr, uid, [line.id for line in commission.users_ids])
 
570
            # * Desvinculando los vouchers afectados
 
571
            #~ comm_voucher_ids.unlink(cr, uid, [line.id for line in commission.comm_voucher_ids])
 
572
            # * Desvinculando los vouchers afectados
 
573
            #~ comm_invoice_ids.unlink(cr, uid, [line.id for line in commission.comm_invoice_ids])
 
574
            # * Desvinculando las facturas con problemas de retenciones
 
575
            #~ comm_retention_ids.unlink(cr, uid, [line.id for line in commission.comm_retention_ids])
 
576
            ###
 
577
            
 
578
    def decide(self, cr, uid, ids, context={}):
 
579
        commissions = self.browse(cr, uid, ids, context=None)
 
580
        avl = self.pool.get('account.voucher.line')
 
581
        # escribir en el avl el estado buleano de paid_comm a True para indicar que ya esta comision se esta pagando
 
582
        for commission in commissions:
 
583
            avl.write(cr, uid, [line.concept.id for line in commission.comm_line_ids],{
 
584
                'paid_comm': True,
 
585
            })
 
586
            
 
587
        self.write(cr, uid, ids, {
 
588
            'state': 'done',
 
589
        })
 
590
    
 
591
    def going_back(self, cr, uid, ids, context={}):
 
592
        self.write(cr, uid, ids, {
 
593
                'state': 'open',
 
594
            })
 
595
            
 
596
commission_payment()
 
597
 
 
598
class commission_uninvoiced(osv.osv):
 
599
    """
 
600
    Commission Payment Uninvoiced : commission_uninvoiced
 
601
    """
 
602
 
 
603
    _name = 'commission.uninvoiced'
 
604
    
 
605
    _columns = {
 
606
        'name':fields.char('Comentario', size=256),
 
607
        'commission_id':fields.many2one('commission.payment', 'Comision'),
 
608
        'payment_id':fields.many2one('account.voucher.line', 'Descripcion de Transaccion'),
 
609
    }
 
610
    _defaults = {
 
611
        'name': lambda *a: None,
 
612
    }
 
613
commission_uninvoiced()
 
614
 
 
615
class commission_sale_noid(osv.osv):
 
616
    """
 
617
    Commission Payment : commission_sale_noid
 
618
    """
 
619
    
 
620
    _name = 'commission.sale.noid'
 
621
    
 
622
    _columns = {
 
623
        'name':fields.char('Comentario', size=256),
 
624
        'commission_id':fields.many2one('commission.payment', 'Comision'),
 
625
        'inv_line_id':fields.many2one('account.invoice.line', 'Descripcion de Articulo'),
 
626
    }
 
627
    _defaults = {
 
628
        'name': lambda *a: None,
 
629
    }
 
630
commission_sale_noid()
 
631
 
 
632
class commission_noprice(osv.osv):
 
633
    """
 
634
    Commission Payment : commission_sale_noid
 
635
    """
 
636
    
 
637
    _name = 'commission.noprice'
 
638
    _order = 'product_id'
 
639
    
 
640
    _columns = {
 
641
        'name':fields.char('Comentario', size=256),
 
642
        'commission_id':fields.many2one('commission.payment', 'Comision'),
 
643
        'product_id':fields.many2one('product.product', 'Producto'),
 
644
        'date':fields.date('Fecha'),
 
645
        'invoice_num':fields.integer('Numero de Factura'),
 
646
        
 
647
    }
 
648
    _defaults = {
 
649
        'name': lambda *a: None,
 
650
    }
 
651
commission_noprice()
 
652
 
 
653
class commission_lines(osv.osv):
 
654
    """
 
655
    Commission Payment : commission_lines
 
656
    """
 
657
    
 
658
    _name = 'commission.lines'
 
659
    _order = 'saleman_id'
 
660
    
 
661
    _columns = {
 
662
        'commission_id':fields.many2one('commission.payment', 'Comision', required=True),
 
663
        'name':fields.char('Transaccion', size=256, required=True),
 
664
        'pay_date':fields.date('Fecha', required=True),
 
665
        'pay_off':fields.float('Pago', digits_compute=dp.get_precision('Commission')),
 
666
        
 
667
        'voucher_id': fields.many2one('account.voucher', 'Voucher'),
 
668
        
 
669
        'concept': fields.many2one('account.voucher.line', 'Concepto'),
 
670
        'invoice_id': fields.many2one('account.invoice', 'Doc.'),
 
671
        'invoice_num': fields.char('Doc.', size=256),
 
672
        'partner_id': fields.many2one('res.partner', 'Empresa'),
 
673
        'saleman_name': fields.char('Vendedor', size=256, required=True),
 
674
        'saleman_id': fields.many2one('res.users', 'Vendedor', required=True),
 
675
        'pay_inv': fields.float('Abono Fact.', digits_compute=dp.get_precision('Commission')),
 
676
        
 
677
        'inv_date': fields.date('Fecha Doc.'),
 
678
        'days':fields.float('Dias', digits_compute=dp.get_precision('Commission')),
 
679
        
 
680
        'inv_subtotal': fields.float('SubTot. Doc.', digits_compute=dp.get_precision('Commission')),
 
681
        
 
682
        'item': fields.char('Item', size=256, required=True),
 
683
        'price_unit': fields.float('Prec. Unit.', digits_compute=dp.get_precision('Commission')),
 
684
        'price_subtotal': fields.float('SubTot. Item', digits_compute=dp.get_precision('Commission')),
 
685
        
 
686
        'price_list': fields.float('Precio Lista', digits_compute=dp.get_precision('Commission')),
 
687
        'price_date': fields.date('Fecha Lista'),
 
688
        
 
689
        
 
690
        #~ 'perc_Ret_ISLR': fields.float('Ret ISLR (%)', digits_compute=dp.get_precision('Commission')),
 
691
        #~ 'perc_Ret_IM': fields.float('Ret IM (%)', digits_compute=dp.get_precision('Commission')),
 
692
        #~ 'perc_Ret_IVA': fields.float('Ret IVA (%)', digits_compute=dp.get_precision('Commission')),
 
693
        #~ 'perc_IVA': fields.float('IVA (%)', digits_compute=dp.get_precision('Commission')),
 
694
        
 
695
        'rate_item':fields.float('Dcto. (%)', digits_compute=dp.get_precision('Commission')),
 
696
        
 
697
        'rate_number':fields.float('Bar. Rate (%)', digits_compute=dp.get_precision('Commission')),
 
698
        'timespan':fields.float('Bar. Dias', digits_compute=dp.get_precision('Commission')),
 
699
        'baremo_comm':fields.float('Baremo %Comm.', digits_compute=dp.get_precision('Commission')),
 
700
        'commission':fields.float('Comm. / Item', digits_compute=dp.get_precision('Commission')),
 
701
    }
 
702
    _defaults = {
 
703
        'name': lambda *a: None,
 
704
    }
 
705
commission_lines()
 
706
 
 
707
class commission_saleman(osv.osv):
 
708
    """
 
709
    Commission Payment : commission_saleman
 
710
    """
 
711
    
 
712
    _name = 'commission.saleman'
 
713
    _order = 'saleman_name'
 
714
    
 
715
    _columns = {
 
716
        'name':fields.char('Comentario', size=256),
 
717
        'commission_id':fields.many2one('commission.payment', 'Comision'),
 
718
        'saleman_name': fields.char('Vendedor', size=256, required=True),
 
719
        'saleman_id': fields.many2one('res.users', 'Vendedor', required=True),
 
720
        'comm_total':fields.float('Comision a pagar', digits_compute=dp.get_precision('Commission')),
 
721
        'comm_voucher_ids':fields.one2many('commission.voucher', 'comm_sale_id', 'Vouchers afectados en esta comision', required=False),
 
722
    }
 
723
    _defaults = {
 
724
        'name': lambda *a: None,
 
725
    }
 
726
commission_saleman()
 
727
 
 
728
 
 
729
class commission_voucher(osv.osv):
 
730
    """
 
731
    Commission Payment : commission_voucher
 
732
    """
 
733
    
 
734
    _name = 'commission.voucher'
 
735
    _order = 'date'
 
736
    
 
737
    _columns = {
 
738
        'name':fields.char('Comentario', size=256),
 
739
        'commission_id':fields.many2one('commission.payment', 'Comision'),
 
740
        'comm_sale_id':fields.many2one('commission.saleman', 'Vendedor'),
 
741
        'voucher_id':fields.many2one('account.voucher', 'Voucher'),
 
742
        'comm_invoice_ids':fields.one2many('commission.invoice', 'comm_voucher_id', 'Facturas afectadas en esta comision', required=False),
 
743
        'date': fields.date('Fecha'),
 
744
    }
 
745
    _defaults = {
 
746
        'name': lambda *a: None,
 
747
    }
 
748
commission_voucher()
 
749
 
 
750
class commission_invoice(osv.osv):
 
751
    """
 
752
    Commission Payment : commission_invoice
 
753
    """
 
754
    
 
755
    _name = 'commission.invoice'
 
756
    _order = 'invoice_id'
 
757
    
 
758
    _columns = {
 
759
        'name':fields.char('Comentario', size=256),
 
760
        'commission_id':fields.many2one('commission.payment', 'Comision'),
 
761
        'comm_voucher_id':fields.many2one('commission.voucher', 'Voucher'),
 
762
        'invoice_id':fields.many2one('account.invoice', 'Factura'), 
 
763
        'comm_line_ids':fields.one2many('commission.lines', 'comm_invoice_id', 'Comision por productos', required=False),
 
764
        'pay_inv': fields.float('Abono Fact.', digits_compute=dp.get_precision('Commission')),
 
765
        'ret_iva': fields.float('% Ret. IVA', digits_compute=dp.get_precision('Commission')),
 
766
        'ret_islr': fields.float('% Ret. ISLR', digits_compute=dp.get_precision('Commission')),
 
767
        'ret_im': fields.float('% Ret. IM', digits_compute=dp.get_precision('Commission')),
 
768
    }
 
769
    _defaults = {
 
770
        'name': lambda *a: None,
 
771
    }
 
772
commission_invoice()
 
773
 
 
774
class commission_lines_2(osv.osv):
 
775
    """
 
776
    Commission Payment : commission_lines_2
 
777
    """
 
778
    
 
779
    _inherit = 'commission.lines'
 
780
    
 
781
    _columns = {
 
782
        'comm_invoice_id':fields.many2one('commission.invoice', 'Factura Relacional Interna'),
 
783
    }
 
784
commission_lines_2()
 
785
 
 
786
 
 
787
class commission_retention(osv.osv):
 
788
    """
 
789
    Commission Payment : commission_retention
 
790
    """
 
791
    
 
792
    _name = 'commission.retention'
 
793
    _order = 'invoice_id'
 
794
    
 
795
    _columns = {
 
796
        'name':fields.char('Comentario', size=256),
 
797
        'commission_id':fields.many2one('commission.payment', 'Comision'),
 
798
        'invoice_id':fields.many2one('account.invoice', 'Factura'),
 
799
        'voucher_id':fields.many2one('account.voucher', 'Pagado con...'),
 
800
        'date': fields.date('Fecha'),
 
801
        'ret_iva':fields.boolean('Ret. IVA'),
 
802
        'ret_islr':fields.boolean('Ret. ISLR'),
 
803
        'ret_im':fields.boolean('Ret. IM'),
 
804
    }
 
805
    _defaults = {
 
806
        'name': lambda *a: None,
 
807
    }
 
808
commission_retention()
 
809
 
 
810
class VoucherLines(osv.osv):
 
811
    _inherit = 'account.voucher.line'
 
812
    
 
813
    _columns = {
 
814
        'paid_comm' : fields.boolean('Comision Pagada?'),
 
815
    }
 
816
    _defaults = {
 
817
        'paid_comm': lambda *a: False,
 
818
    }
 
819
 
 
820
VoucherLines()
 
821
 
 
822
#~ class commission_users(osv.osv):
 
823
    #~ _name='commission.users'
 
824
    #~ _columns={
 
825
        #~ 'name':fields.char('Nombre', size=8),
 
826
        #~ 'commission_id':fields.many2one('commission.payment', 'Comision'),
 
827
        #~ 'user_id': fields.many2one('res.users', 'Vendedor', required=True),
 
828
    #~ }
 
829
#~ commission_users()