/grails-app/controllers/contabilidad/TransaccionController.groovy
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}