PageRenderTime 33ms CodeModel.GetById 10ms RepoModel.GetById 1ms app.codeStats 0ms

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