PageRenderTime 929ms CodeModel.GetById 122ms app.highlight 628ms RepoModel.GetById 79ms app.codeStats 1ms

/grails-app/controllers/contabilidad/TransaccionController.groovy

http://github.com/jdmr/mateo
Groovy | 566 lines | 475 code | 31 blank | 60 comment | 145 complexity | 40d3e673629ed38fcc1dadb871dfd53e MD5 | raw file
  1package contabilidad
  2
  3import grails.converters.JSON
  4import grails.plugins.springsecurity.Secured
  5import general.Tag
  6
  7@Secured(['ROLE_USER'])
  8class TransaccionController {
  9
 10    def springSecurityService
 11    def folioService
 12
 13    static allowedMethods = [crea: "POST", actualiza: "POST"]
 14
 15    def index = {
 16        redirect(controller:'poliza', action: "lista", params: params)
 17    }
 18
 19    def nueva = {
 20        Transaccion.withTransaction {
 21            def usuario = springSecurityService.currentUser
 22            def poliza = Poliza.get(params.id)
 23            def transaccion = new Transaccion (
 24                folio : folioService.temporal()
 25                , descripcion : 'Introduzca una descripcič´¸n'
 26                , poliza : poliza
 27                , empresa : usuario.empresa
 28            ).save()
 29
 30            if (poliza.tipo == 'INGRESOS') {
 31                render(view:'ingresos', model:[transaccion:transaccion])
 32            } else if (poliza.tipo == 'EGRESOS') {
 33                render(view:'egresos', model:[transaccion:transaccion])
 34            } else if (poliza.tipo == 'DIARIO') {
 35                render(view:'diario', model:[transaccion:transaccion])
 36            } else {
 37                render(view:'edita',model:[transaccion:transaccion])
 38            }
 39        }
 40    }
 41
 42    def edita = {
 43        def transaccion = Transaccion.get(params.id)
 44        if (transaccion) {
 45            def origenes = obtieneMovimientos(transaccion.origenes)
 46            def destinos = obtieneMovimientos(transaccion.destinos)
 47            if (transaccion.poliza.tipo == 'INGRESOS') {
 48                render(view:'ingresos', model:[transaccion:transaccion,origenes:origenes,destinos:destinos])
 49            } else if (transaccion.poliza.tipo == 'EGRESOS') {
 50                render(view:'egresos', model:[transaccion:transaccion,origenes:origenes,destinos:destinos])
 51            } else if (transaccion.poliza.tipo == 'DIARIO') {
 52                render(view:'diario', model:[transaccion:transaccion,origenes:origenes,destinos:destinos])
 53            } else {
 54                return [transaccion: transaccion]
 55            }
 56        }
 57    }
 58
 59    def actualizaIngreso = {
 60        Transaccion.withTransaction {
 61            def transaccion = Transaccion.get(params.id)
 62            if (transaccion) {
 63                def importeAnterior = transaccion.importe
 64                transaccion.properties = params
 65                transaccion.importe = importeAnterior
 66                def usuario = springSecurityService.currentUser
 67                transaccion.empresa = usuario.empresa
 68
 69                log.debug("TAGS: ${transaccion.tags}")
 70                def tags = transaccion.tags?.tokenize(',')
 71                log.debug("TOKENS: ${tags}")
 72                for(tag in tags) {
 73                    tag = tag.tr('A-Z','a-z')
 74                    def x = Tag.findByOrganizacionAndNombre(usuario.empresa.organizacion, tag)
 75                    if (!x) {
 76                        new Tag(nombre: tag, organizacion: usuario.empresa.organizacion).save()
 77                    }
 78                }
 79
 80                if (params.importe) {
 81                    if (params.cuentaId) {
 82                        def cuenta = Cuenta.findByOrganizacionAndId(usuario.empresa.organizacion, params.cuentaId)
 83                        if (cuenta) {
 84                            if (cuenta.tieneAuxiliares && !params.auxiliarId) {
 85                                throw new RuntimeException("No se puede crear el movimiento porque falta el auxiliar")
 86                            }
 87                            def importe = new BigDecimal(params.importe)
 88                            def movimiento = new Movimiento (
 89                                cuenta : cuenta
 90                                , importe : importe
 91                            )
 92                            def auxiliar
 93                            if (params.auxiliarId) {
 94                                auxiliar = Auxiliar.findByOrganizacionAndId(usuario.empresa.organizacion, params.auxiliarId)
 95                                movimiento.auxiliar = auxiliar
 96                            }
 97                            if (params.esDebe != null) {
 98                                // Valido si esta distribuyendo los pagos
 99                                // Si quiere distribuir algo que no esta pagado
100                                // no lo deja
101                                if (transaccion.importe >= importe) {
102                                    // Si el importe de la distribucion es igual
103                                    // a lo que llevo en la transaccion
104                                    // no importan los origenes, solo crea uno nuevo
105                                    if (transaccion.importe == importe) {
106                                        def origenes = new ArrayList(transaccion.origenes)
107                                        transaccion.origenes.clear()
108                                        for(origen in origenes) {
109                                            origen.delete()
110                                        }
111                                        transaccion.addToOrigenes(movimiento)
112                                    } else {
113                                        // Si la cantidad es menor, entonces hay que distribuirlos
114                                        // Primero valido si ya existe entre los movimientos
115                                        // alguno a la misma cuenta, de ser asi, le sumo el importe
116                                        // creo uno nuevo con este importe y borro el anterior.
117                                        def x
118                                        for(origen in transaccion.origenes) {
119                                            if ((movimiento.auxiliar && origen.auxiliar == movimiento.auxiliar)
120                                                    || (!movimiento.auxiliar && movimiento.cuenta == origen.cuenta)) {
121                                                x = origen
122                                            }
123                                        }
124                                        if (x) {
125                                            movimiento.importe = movimiento.importe.add(importe)
126                                            transaccion.origenes.remove(x)
127                                            x.delete()
128                                        }
129                                        for(origen in transaccion.origenes) {
130                                            if (origen.importe < importe) {
131                                                // Si el importe es mayor a este movimiento
132                                                // elmimina el movimiento, restale al importe
133                                                // y ve a la siguiente iteracion para hacer
134                                                // nuevamente la comparacion
135                                                importe = importe.subtract(origen.importe)
136                                                transaccion.origenes.remove(origen)
137                                                origen.delete()
138                                            } else if (origen.importe == importe) {
139                                                // Si el importe ya es igual a este movimiento
140                                                // solo eliminalo y crea el nuevo movimiento
141                                                transaccion.origenes.remove(origen)
142                                                origen.delete()
143                                                transaccion.addToOrigenes(movimiento)
144                                                break;
145                                            } else {
146                                                // Si el importe es menor a este movimiento
147                                                // restale el importe y crea el nuevo movimiento
148                                                origen.importe = origen.importe.subtract(importe)
149                                                transaccion.addToOrigenes(movimiento)
150                                                break;
151                                            }
152                                        }
153                                    }
154                                    transaccion.save(flush:true)
155
156                                } else {
157                                    // No se puede distribuir dinero que no se ha especificado
158                                    // a quien se le va a entregar
159                                    transaccion.discard()
160                                    flash.message = "El importe no puede ser mayor a ${transaccion.importe}"
161                                    redirect(action:"edita", id:transaccion.id)
162                                    return
163                                }
164                            } else {
165                                def movimiento2
166                                def cuenta2 = Cuenta.findByOrganizacionAndCodigo(usuario.empresa.organizacion,'1104')
167                                for(origen in transaccion.origenes) {
168                                    if (origen.cuenta == cuenta2) {
169                                        movimiento2 = origen
170                                        movimiento2.importe = movimiento2.importe.add(importe)
171                                        break;
172                                    }
173                                }
174                                if (!movimiento2) {
175                                    movimiento2 = new Movimiento (
176                                        cuenta: cuenta2
177                                        , importe: importe
178                                    )
179                                    log.debug("Validando que cuenta tenga auxiliares : $cuenta2.tieneAuxiliares")
180                                    if (cuenta2.tieneAuxiliares) {
181                                        def x = Auxiliar.find("from Auxiliar a inner join a.cuentas cuenta where cuenta = ?",[cuenta2],[max:1])
182                                        log.debug("Asignando el auxiliar : ${x}")
183                                        movimiento2.auxiliar = x[0]
184                                    }
185                                }
186                                transaccion.addToOrigenes(movimiento2)
187                                transaccion.addToDestinos(movimiento)
188                                transaccion.importe = transaccion.importe.add(importe)
189                                transaccion.save(flush:true)
190
191                            }
192                        } // si encontro la cuenta
193                    } // si trae una cuenta
194                } // si trae importe
195                flash.message = message(code:'transaccion.actualiza.message')
196                redirect(action:'edita',id:transaccion.id)
197            } // Si se encuentra la transaccion
198        } // Termina transaccion
199    }
200
201    def actualizaEgreso = {
202        Transaccion.withTransaction {
203            def transaccion = Transaccion.get(params.id)
204            if (transaccion) {
205                def importeAnterior = transaccion.importe
206                transaccion.properties = params
207                transaccion.importe = importeAnterior
208                def usuario = springSecurityService.currentUser
209                transaccion.empresa = usuario.empresa
210
211                log.debug("TAGS: ${transaccion.tags}")
212                def tags = transaccion.tags?.tokenize(',')
213                log.debug("TOKENS: ${tags}")
214                for(tag in tags) {
215                    tag = tag.tr('A-Z','a-z')
216                    def x = Tag.findByOrganizacionAndNombre(usuario.empresa.organizacion, tag)
217                    if (!x) {
218                        new Tag(nombre: tag, organizacion: usuario.empresa.organizacion).save()
219                    }
220                }
221
222                if (params.importe) {
223                    if (params.cuentaId) {
224                        def cuenta = Cuenta.findByOrganizacionAndId(usuario.empresa.organizacion, params.cuentaId)
225                        if (cuenta) {
226                            if (cuenta.tieneAuxiliares && !params.auxiliarId) {
227                                throw new RuntimeException("No se puede crear el movimiento porque falta el auxiliar")
228                            }
229                            def importe = new BigDecimal(params.importe)
230                            def movimiento = new Movimiento (
231                                cuenta : cuenta
232                                , importe : importe
233                            )
234                            def auxiliar
235                            if (params.auxiliarId) {
236                                auxiliar = Auxiliar.findByOrganizacionAndId(usuario.empresa.organizacion, params.auxiliarId)
237                                movimiento.auxiliar = auxiliar
238                            }
239                            if (params.esHaber != null) {
240                                // Valido si esta distribuyendo los pagos
241                                // Si quiere distribuir algo que no esta pagado
242                                // no lo deja
243                                if (transaccion.importe >= importe) {
244                                    // Si el importe de la distribucion es igual
245                                    // a lo que llevo en la transaccion
246                                    // no importan los destinos, solo crea uno nuevo
247                                    if (transaccion.importe == importe) {
248                                        def destinos = new ArrayList(transaccion.destinos)
249                                        transaccion.destinos.clear()
250                                        for(destino in destinos) {
251                                            destino.delete()
252                                        }
253                                        transaccion.addToDestinos(movimiento)
254                                    } else {
255                                        // Si la cantidad es menor, entonces hay que distribuirlos
256                                        // Primero valido si ya existe entre los movimientos
257                                        // alguno a la misma cuenta, de ser asi, le sumo el importe
258                                        // creo uno nuevo con este importe y borro el anterior.
259                                        def x
260                                        for(destino in transaccion.destinos) {
261                                            if ((movimiento.auxiliar && destino.auxiliar == movimiento.auxiliar)
262                                                    || (!movimiento.auxiliar && movimiento.cuenta == destino.cuenta)) {
263                                                x = destino
264                                            }
265                                        }
266                                        if (x) {
267                                            movimiento.importe = movimiento.importe.add(importe)
268                                            transaccion.destinos.remove(x)
269                                            x.delete()
270                                        }
271                                        for(destino in transaccion.destinos) {
272                                            if (destino.importe < importe) {
273                                                // Si el importe es mayor a este movimiento
274                                                // elmimina el movimiento, restale al importe
275                                                // y ve a la siguiente iteracion para hacer
276                                                // nuevamente la comparacion
277                                                importe = importe.subtract(destino.importe)
278                                                transaccion.destinos.remove(destino)
279                                                destino.delete()
280                                            } else if (destino.importe == importe) {
281                                                // Si el importe ya es igual a este movimiento
282                                                // solo eliminalo y crea el nuevo movimiento
283                                                transaccion.destinos.remove(destino)
284                                                destino.delete()
285                                                transaccion.addToDestinos(movimiento)
286                                                break;
287                                            } else {
288                                                // Si el importe es menor a este movimiento
289                                                // restale el importe y crea el nuevo movimiento
290                                                destino.importe = destino.importe.subtract(importe)
291                                                transaccion.addToDestinos(movimiento)
292                                                break;
293                                            }
294                                        }
295                                    }
296                                    transaccion.save(flush:true)
297
298                                } else {
299                                    // No se puede distribuir dinero que no se ha especificado
300                                    // a quien se le va a entregar
301                                    transaccion.discard()
302                                    flash.message = "El importe no puede ser mayor a ${transaccion.importe}"
303                                    redirect(action:"edita", id:transaccion.id)
304                                    return
305                                }
306                            } else {
307                                def movimiento2
308                                def cuenta2 = Cuenta.findByOrganizacionAndCodigo(usuario.empresa.organizacion,'1104')
309                                for(destino in transaccion.destinos) {
310                                    if (destino.cuenta == cuenta2) {
311                                        movimiento2 = destino
312                                        movimiento2.importe = movimiento2.importe.add(importe)
313                                        break;
314                                    }
315                                }
316                                if (!movimiento2) {
317                                    movimiento2 = new Movimiento (
318                                        cuenta: cuenta2
319                                        , importe: importe
320                                    )
321                                    log.debug("Validando que cuenta tenga auxiliares : $cuenta2.tieneAuxiliares")
322                                    if (cuenta2.tieneAuxiliares) {
323                                        def x = Auxiliar.find("from Auxiliar a inner join a.cuentas cuenta where cuenta = ?",[cuenta2],[max:1])
324                                        log.debug("Asignando el auxiliar : ${x}")
325                                        movimiento2.auxiliar = x[0]
326                                    }
327                                }
328                                transaccion.addToOrigenes(movimiento)
329                                transaccion.addToDestinos(movimiento2)
330                                transaccion.importe = transaccion.importe.add(importe)
331                                transaccion.save(flush:true)
332
333                            }
334                        } // si encontro la cuenta
335                    } // si trae una cuenta
336                } // si trae importe
337                flash.message = message(code:'transaccion.actualiza.message')
338                redirect(action:'edita',id:transaccion.id)
339            } // Si se encuentra la transaccion
340        } // Termina transaccion
341    }
342
343    def actualizaDiario = {
344        Transaccion.withTransaction {
345            def transaccion = Transaccion.get(params.id)
346            if (transaccion) {
347                def importeAnterior = transaccion.importe
348                transaccion.properties = params
349                transaccion.importe = importeAnterior
350                def usuario = springSecurityService.currentUser
351                transaccion.empresa = usuario.empresa
352
353                def tags = transaccion.tags?.tokenize(',')
354                for(tag in tags) {
355                    tag = tag.tr('A-Z','a-z')
356                    def x = Tag.findByOrganizacionAndNombre(usuario.empresa.organizacion, tag)
357                    if (!x) {
358                        new Tag(nombre: tag, organizacion: usuario.empresa.organizacion).save()
359                    }
360                }
361
362                if (params.importe) {
363                    if (params.cuentaId) {
364                        def cuenta = Cuenta.findByOrganizacionAndId(usuario.empresa.organizacion, params.cuentaId)
365                        if (cuenta) {
366                            if (cuenta.tieneAuxiliares && !params.auxiliarId) {
367                                throw new RuntimeException("No se puede crear el movimiento porque falta el auxiliar")
368                            }
369                            def importe = new BigDecimal(params.importe)
370                            def movimiento = new Movimiento (
371                                cuenta : cuenta
372                                , importe : importe
373                            )
374                            def auxiliar
375                            if (params.auxiliarId) {
376                                auxiliar = Auxiliar.findByOrganizacionAndId(usuario.empresa.organizacion, params.auxiliarId)
377                                movimiento.auxiliar = auxiliar
378                            }
379                            if (params.esHaber != null) {
380                                // Valido si esta distribuyendo los pagos
381                                // Si quiere distribuir algo que no esta pagado
382                                // no lo deja
383                                if (transaccion.importe >= importe) {
384                                    // Si el importe de la distribucion es igual
385                                    // a lo que llevo en la transaccion
386                                    // no importan los destinos, solo crea uno nuevo
387                                    if (transaccion.importe == importe) {
388                                        def destinos = new ArrayList(transaccion.destinos)
389                                        transaccion.destinos.clear()
390                                        for(destino in destinos) {
391                                            destino.delete()
392                                        }
393                                        transaccion.addToDestinos(movimiento)
394                                    } else {
395                                        // Si la cantidad es menor, entonces hay que distribuirlos
396                                        // Primero valido si ya existe entre los movimientos
397                                        // alguno a la misma cuenta, de ser asi, le sumo el importe
398                                        // creo uno nuevo con este importe y borro el anterior.
399                                        def x
400                                        for(destino in transaccion.destinos) {
401                                            if ((movimiento.auxiliar && destino.auxiliar == movimiento.auxiliar)
402                                                    || (!movimiento.auxiliar && movimiento.cuenta == destino.cuenta)) {
403                                                x = destino
404                                            }
405                                        }
406                                        if (x) {
407                                            movimiento.importe = movimiento.importe.add(importe)
408                                            transaccion.destinos.remove(x)
409                                            x.delete()
410                                        }
411                                        for(destino in transaccion.destinos) {
412                                            if (destino.importe < importe) {
413                                                // Si el importe es mayor a este movimiento
414                                                // elmimina el movimiento, restale al importe
415                                                // y ve a la siguiente iteracion para hacer
416                                                // nuevamente la comparacion
417                                                importe = importe.subtract(destino.importe)
418                                                transaccion.destinos.remove(destino)
419                                                destino.delete()
420                                            } else if (destino.importe == importe) {
421                                                // Si el importe ya es igual a este movimiento
422                                                // solo eliminalo y crea el nuevo movimiento
423                                                transaccion.destinos.remove(destino)
424                                                destino.delete()
425                                                transaccion.addToDestinos(movimiento)
426                                                break;
427                                            } else {
428                                                // Si el importe es menor a este movimiento
429                                                // restale el importe y crea el nuevo movimiento
430                                                destino.importe = destino.importe.subtract(importe)
431                                                transaccion.addToDestinos(movimiento)
432                                                break;
433                                            }
434                                        }
435                                    }
436                                    transaccion.save(flush:true)
437
438                                } else {
439                                    // No se puede distribuir dinero que no se ha especificado
440                                    // a quien se le va a entregar
441                                    transaccion.discard()
442                                    flash.message = "El importe no puede ser mayor a ${transaccion.importe}"
443                                    redirect(action:"edita", id:transaccion.id)
444                                    return
445                                }
446                            } else {
447                                def movimiento2
448                                def cuenta2 = Cuenta.findByOrganizacionAndCodigo(usuario.empresa.organizacion,'1104')
449                                for(destino in transaccion.destinos) {
450                                    if (destino.cuenta == cuenta2) {
451                                        movimiento2 = destino
452                                        movimiento2.importe = movimiento2.importe.add(importe)
453                                        break;
454                                    }
455                                }
456                                if (!movimiento2) {
457                                    movimiento2 = new Movimiento (
458                                        cuenta: cuenta2
459                                        , importe: importe
460                                    )
461                                    log.debug("Validando que cuenta tenga auxiliares : $cuenta2.tieneAuxiliares")
462                                    if (cuenta2.tieneAuxiliares) {
463                                        def x = Auxiliar.find("from Auxiliar a inner join a.cuentas cuenta where cuenta = ?",[cuenta2],[max:1])
464                                        log.debug("Asignando el auxiliar : ${x}")
465                                        movimiento2.auxiliar = x[0]
466                                    }
467                                }
468                                transaccion.addToOrigenes(movimiento)
469                                transaccion.addToDestinos(movimiento2)
470                                transaccion.importe = transaccion.importe.add(importe)
471                                transaccion.save(flush:true)
472
473                            }
474                        } // si encontro la cuenta
475                    } // si trae una cuenta
476                } // si trae importe
477                flash.message = message(code:'transaccion.actualiza.message')
478                redirect(action:'edita',id:transaccion.id)
479            } // Si se encuentra la transaccion
480        } // Termina transaccion
481    }
482
483    def cuentas = {
484        def usuario = springSecurityService.currentUser
485        def auxiliares = Auxiliar.buscaPorFiltro(params.term, usuario.empresa.id).list([max:10])
486        def cuentas = Cuenta.buscaPorFiltro(params.term, usuario.empresa.id).list([max:10])
487        def lista = []
488        for(auxiliar in auxiliares) {
489            for(cuenta in auxiliar.cuentas) {
490                lista << [id:cuenta.id,value:"${auxiliar.numero} | ${auxiliar.descripcion} (AUXILIAR de ${cuenta.descripcion})",tieneAuxiliares:false,auxiliar:true,cuenta:"${cuenta.numero} | ${cuenta.descripcion}",auxiliarId:auxiliar.id]
491            }
492        }
493        for(cuenta in cuentas) {
494            lista << [id:cuenta.id,value:"$cuenta.numero | $cuenta.descripcion",tieneAuxiliares:cuenta.tieneAuxiliares,auxiliar:false]
495        }
496        def resultado = lista as grails.converters.JSON
497        render resultado
498    }
499
500    def auxiliares = {
501        def usuario = springSecurityService.currentUser
502        def auxiliares = Auxiliar.buscaPorFiltro(params.term, usuario.empresa.id).list([max:10])
503        def lista = []
504        for(auxiliar in auxiliares) {
505            for(cuenta in auxiliar.cuentas) {
506                lista << [id:auxiliar.id,value:"${auxiliar.numero} | ${auxiliar.descripcion} (AUXILIAR de ${cuenta.descripcion})",cuenta:"${cuenta.numero} | ${cuenta.descripcion}",cuentaId:cuenta.id]
507            }
508        }
509        def resultado = lista as grails.converters.JSON
510        render resultado
511    }
512
513    def obtieneMovimientos = { lista ->
514		def resultado = []
515		def cuentas = [:] as TreeMap
516		def movimientos = [:] as TreeMap
517		for(movimiento in lista) {
518			def cuenta = cuentas[movimiento.cuenta.id]
519			if (!cuenta) {
520				cuenta = [movimiento.cuenta, new BigDecimal('0')]
521				cuentas[movimiento.cuenta.id] = cuenta
522			}
523			cuenta[1] = cuenta[1].add(movimiento.importe)
524			
525			def mov = movimientos[movimiento.cuenta.id]
526			if (!mov) {
527				movimientos[movimiento.cuenta.id] = []
528			}
529			movimientos[movimiento.cuenta.id] << movimiento
530		}
531		
532		for (id in cuentas.keySet()) {
533			def encabezado = cuentas[id]
534			if (encabezado[0].tieneAuxiliares) {
535				resultado << new Movimiento(cuenta:encabezado[0],importe:encabezado[1], padre:true)
536                def size = movimientos[id].size()
537                def movimiento = movimientos[id][size-1]
538                movimiento.ultimo = true
539				resultado.addAll(movimientos[id])
540			} else {
541				resultado << new Movimiento(cuenta:encabezado[0],importe:encabezado[1])
542			}
543		}
544
545        return resultado
546    }
547
548    def elimina = {
549        Transaccion.withTransaction {
550            def usuario = springSecurityService.currentUser
551            def transaccion = Transaccion.get(params.id)
552            def poliza = transaccion.poliza
553            def folio = transaccion.folio
554            if (transaccion.poliza.estatus == 'ABIERTA' && poliza.empresa == usuario.empresa) {
555                transaccion.delete()
556            }
557            flash.message = message(code: 'default.deleted.message', args: [message(code: 'transaccion.label'), folio])
558            redirect(controller:'poliza',action:'edita',id:poliza.id)
559        }
560    }
561
562    def tags = {
563        def usuario = springSecurityService.currentUser
564        render Tag.buscaPorFiltro("%${params.term}%",usuario.empresa.organizacion.id).list([max:10])*.nombre as JSON
565    }
566}