1
# -*- coding: utf-8 -*-
2
##############################################################################
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
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.
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.
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/>.
21
##############################################################################
23
from osv import osv, fields
29
from tools import config
30
from tools.translate import _
31
import decimal_precision as dp
35
class commission_payment(osv.osv):
37
OpenERP Model : commission_payment
40
_name = 'commission.payment'
41
_description = __doc__
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([
62
('open','En Proceso'),
64
('write','Escribiendo'),
66
('cancel','Cancelado')
67
],'Estado', readonly=True),
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',
76
def prepare(self, cr, uid, ids, context=None):
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.
88
Si estas tres (3) condiciones se cumplen entonces se puede proceder a realizar la revision
89
de las lineas de pago.
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
97
@return: return a result
100
self.write(cr, uid, ids, {
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')
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')
126
ret_iva_lines = self.pool.get ('account.retention.line')
128
ret_islr_lines = self.pool.get ('account.retencion.islr.line')
130
ret_im_lines = self.pool.get ('account.retencion.munici.line')
132
#commissions = self.pool.get('commission.payment')
133
commissions = self.browse(cr, uid, ids, context=None)
135
for commission in commissions:
136
# Desvincular lineas existentes, si las hubiere
137
self._unlink(cr, uid, ids, context=None)
139
date_start = commission.date_start
140
date_stop = commission.date_stop
142
#~ Obtener la lista de asesores/vendedores a los cuales se les hara el calculo de comisiones
144
user_ids = [line.id for line in commission.user_ids]
146
#~ Obtener la lista de vouchers que se seleccionaron manualmente en el widget many2many
148
voucher_ids = [line.id for line in commission.voucher_ids]
150
#~ Aqui verificamos que si no hay ningun voucher nosotros nos encargaremos de hacer la lista
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)])
157
'voucher_ids': [(6, commission.id, voucher_ids)],
160
for vid in voucher_ids:
161
pay = vouchers.read(cr,uid,vid,['name', 'date', 'amount', 'line_cr_ids','move_ids'],context=None)
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:
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
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)
184
#~ perc_IVA = round((( inv['amount_total'] / inv['amount_untaxed'])-1)*100,0)
185
#~ print 'perc_IVA: ',perc_IVA,'\n'
187
# Obtener el Valor de Porcentaje Retencion de esta factura
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
193
#~ no_ret_islr = True
196
#~ if abs(inv['amount_total'] - pay_line['amount'])<= 1.0:
197
#~ perc_Ret_IVA = 0.0
198
#~ perc_Ret_ISLR = 0.0
200
#~ no_ret_iva = False
201
#~ no_ret_islr = 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
207
#~ no_ret_iva = False
208
#~ no_ret_islr = 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
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)])
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
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)])
226
#~ for line in lines_ret_im:
227
#~ perc_Ret_IM += ret_im_lines.browse(cr, uid, line, context=None).retencion_munici
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
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
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
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
248
# Tratando de obtener la perc_Ret_IVA cuando se tienen tanto el islr como el im
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
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
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.
271
print 'DENTRO DEL CALCULO PARA LAS RETENCIONES'
272
# Revision de cada linea de factura (productos)
273
for l_id in inv['invoice_line']:
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)
278
#~ print 'Producto: ', inv_lin['name'], '\n'
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]
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)])
289
# Buscar Precio Historico de Venta de este
290
# producto @ la fecha de facturacion
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
297
#~ print '[date_invoice : list_price : list_date]: [', inv['date_invoice'],' : ', list_price,' : ', list_date,'] \n'
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)
306
#~ price_unit = inv_lin['price_unit']
308
#~ dcto= round((list_price - price_unit)*100/list_price,1)
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
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
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
323
comm_res = self.pool.get('baremo.book')._calc_comm(cr, uid, bid, rate_item, emission_days)
325
#############################################
326
# CALCULO DE COMISION POR LINEA DE PRODUCTO #
327
#############################################
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.
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
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,
347
'name': pay['name'] and pay['name'] or '/',
348
'pay_date': pay['date'],
349
'pay_off': pay['amount'],
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,
375
print 'CREANDO LINEAS DE COMISIONES (5)'
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'],
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.
392
sale_noids.create(cr, uid,{
393
'commission_id' : commission.id,
394
'inv_line_id' : l_id,
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],
406
'ret_iva': no_ret_iva,
407
'ret_islr': no_ret_islr,
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,
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
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
428
# comm_line_ids.unlink(cr, uid, [line_ids.id for line_ids in commission.comm_line_ids])
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'
437
for commission in commissions:
438
#~ # recoge todos los vendedores y suma el total de sus comisiones
440
#~ # ordena en un arbol todas las lineas de comisiones de producto
442
for comm_line in commission.comm_line_ids:
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
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
453
if not vendor_id in criba.keys():
454
criba[vendor_id] = {}
456
#~ if not voucher_id in criba[vendor_id].keys():
457
#~ criba[vendor_id][voucher_id] = [comm_line.pay_date,{}]
459
#~ if not invoice_id in criba[vendor_id][voucher_id][1].keys():
460
#~ criba[vendor_id][voucher_id][1][invoice_id] = {}
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]
465
#~ criba[vendor_id][voucher_id][1][invoice_id][0].append(comm_line_id)
467
#~ ## escribir el total para cada vendedor encontrado
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],
477
total_comm += sale_comm[vendor_key][1]
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],
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],
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,
503
self.write(cr, uid, ids, {
504
'total_comm': total_comm,
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)
515
if commission.comm_line_ids:
516
self.write(cr, uid, ids, {
520
raise osv.except_osv(_('Atencion !'), _('No Existen Lineas de Comision x Producto que procesar !!!'))
522
#~ if not commission.noprice_ids:
523
#~ self.write(cr, uid, ids, {
524
#~ 'state': 'decide',
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'))
530
def delete(self, cr, uid, ids, context={}):
531
commissions = self.browse(cr, uid, ids, context=None)
533
for commission in commissions:
534
self._unlink(cr, uid, ids, context=None)
535
self.write(cr, uid, ids, {
541
def _unlink(self, cr, uid, ids, context={}):
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')
553
commissions = self.browse(cr, uid, ids, context=None)
555
for commission in commissions:
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])
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],{
587
self.write(cr, uid, ids, {
591
def going_back(self, cr, uid, ids, context={}):
592
self.write(cr, uid, ids, {
598
class commission_uninvoiced(osv.osv):
600
Commission Payment Uninvoiced : commission_uninvoiced
603
_name = 'commission.uninvoiced'
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'),
611
'name': lambda *a: None,
613
commission_uninvoiced()
615
class commission_sale_noid(osv.osv):
617
Commission Payment : commission_sale_noid
620
_name = 'commission.sale.noid'
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'),
628
'name': lambda *a: None,
630
commission_sale_noid()
632
class commission_noprice(osv.osv):
634
Commission Payment : commission_sale_noid
637
_name = 'commission.noprice'
638
_order = 'product_id'
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'),
649
'name': lambda *a: None,
653
class commission_lines(osv.osv):
655
Commission Payment : commission_lines
658
_name = 'commission.lines'
659
_order = 'saleman_id'
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')),
667
'voucher_id': fields.many2one('account.voucher', 'Voucher'),
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')),
677
'inv_date': fields.date('Fecha Doc.'),
678
'days':fields.float('Dias', digits_compute=dp.get_precision('Commission')),
680
'inv_subtotal': fields.float('SubTot. Doc.', digits_compute=dp.get_precision('Commission')),
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')),
686
'price_list': fields.float('Precio Lista', digits_compute=dp.get_precision('Commission')),
687
'price_date': fields.date('Fecha Lista'),
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')),
695
'rate_item':fields.float('Dcto. (%)', digits_compute=dp.get_precision('Commission')),
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')),
703
'name': lambda *a: None,
707
class commission_saleman(osv.osv):
709
Commission Payment : commission_saleman
712
_name = 'commission.saleman'
713
_order = 'saleman_name'
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),
724
'name': lambda *a: None,
729
class commission_voucher(osv.osv):
731
Commission Payment : commission_voucher
734
_name = 'commission.voucher'
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'),
746
'name': lambda *a: None,
750
class commission_invoice(osv.osv):
752
Commission Payment : commission_invoice
755
_name = 'commission.invoice'
756
_order = 'invoice_id'
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')),
770
'name': lambda *a: None,
774
class commission_lines_2(osv.osv):
776
Commission Payment : commission_lines_2
779
_inherit = 'commission.lines'
782
'comm_invoice_id':fields.many2one('commission.invoice', 'Factura Relacional Interna'),
787
class commission_retention(osv.osv):
789
Commission Payment : commission_retention
792
_name = 'commission.retention'
793
_order = 'invoice_id'
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'),
806
'name': lambda *a: None,
808
commission_retention()
810
class VoucherLines(osv.osv):
811
_inherit = 'account.voucher.line'
814
'paid_comm' : fields.boolean('Comision Pagada?'),
817
'paid_comm': lambda *a: False,
822
#~ class commission_users(osv.osv):
823
#~ _name='commission.users'
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),
829
#~ commission_users()