investment-proposals.component.ts 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555
  1. import { Component, ViewChild, OnInit } from "@angular/core";
  2. import { MatPaginator } from "@angular/material/paginator";
  3. import { MatSort } from "@angular/material/sort";
  4. import { MatTableDataSource } from "@angular/material/table";
  5. import Swal from "sweetalert2";
  6. import { CatalogsService } from "src/app/services/catalogs.service";
  7. import { InvestmentsService } from "@app/services/investments.service";
  8. import { AuthService } from "@app/services/auth2.service";
  9. import { JwtHelperService } from "@auth0/angular-jwt";
  10. import { InvestmentProposal } from "@app/models/investment-proposal";
  11. import { from } from "rxjs";
  12. import { FormInvestmentProposalService } from "@app/services/form-investment-proposal.service";
  13. import { Router } from "@angular/router";
  14. @Component({
  15. selector: "app-investment-proposals",
  16. templateUrl: "./investment-proposals.component.html",
  17. styleUrls: ["./investment-proposals.component.scss"]
  18. })
  19. export class InvestmentProposalsComponent implements OnInit {
  20. helper = new JwtHelperService();
  21. title: string = "Propuestas de inversión";
  22. displayedColumns: string[] = [
  23. "codigo_inversion",
  24. "asunto",
  25. "id_empresa",
  26. "id_inversion_instrumento",
  27. "id_estado_inversion",
  28. "id"
  29. ];
  30. //displayedColumns: string[] = ['state'];
  31. listProposals: InvestmentProposal[];
  32. dataSource = new MatTableDataSource(this.listProposals);
  33. resultsLength = 0;
  34. isLoadingResults = true;
  35. isRateLimitReached = false;
  36. userRole: any;
  37. @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
  38. @ViewChild(MatSort, { static: true }) sort: MatSort;
  39. role_number: any;
  40. test: string;
  41. userList: any;
  42. reviewProposal: { id_inversion: number; step: string; comentario: any };
  43. constructor(
  44. private catalogService: CatalogsService,
  45. private investmentsService: InvestmentsService,
  46. private authService: AuthService,
  47. private formInvestmentProposal: FormInvestmentProposalService,
  48. private router: Router
  49. ) {
  50. const decodedToken = this.helper.decodeToken(
  51. this.authService.getJwtToken()
  52. );
  53. this.userRole = decodedToken.groups;
  54. this.dataSource.filterPredicate = (data, filter) => {
  55. const dataStr =
  56. data.id_inversion_instrumento.id_tipo_instrumento.nombre.toLowerCase() +
  57. data.id_estado_inversion.nombre.toLowerCase() +
  58. data.codigo_inversion.toLowerCase() +
  59. data.nombre_inversion.toLowerCase() +
  60. data.asunto.toLowerCase() +
  61. data.id_empresa.nombre.toLowerCase() +
  62. data.comentario.toLowerCase() +
  63. data.justificacion.toLowerCase();
  64. return dataStr.indexOf(filter) != -1;
  65. };
  66. Swal.fire({
  67. allowOutsideClick: false,
  68. icon: "info",
  69. text: "Espere por favor..."
  70. });
  71. Swal.showLoading();
  72. }
  73. ngOnInit() {
  74. this.investmentsService.getProposalInvestmentsList("propuestas").subscribe(
  75. ans => {
  76. this.listProposals = ans.result;
  77. /*
  78. if (this.userType(this.userRole, "analistas")) {
  79. this.listProposals;
  80. } else if (this.userType(this.userRole, "contabilidad")) {
  81. this.listProposals = this.listProposals.filter(proposals =>
  82. ["COMPR", "LIQUI"].includes(
  83. proposals["id_estado_inversion"]["codigo"]
  84. )
  85. );
  86. } else if (this.userType(this.userRole, "autorizadores")) {
  87. this.listProposals = this.listProposals.filter(proposals =>
  88. ["REVIS", "APROB", "FINAL"].includes(
  89. proposals["id_estado_inversion"]["codigo"]
  90. )
  91. );
  92. } else if (this.userType(this.userRole, "supervisores")) {
  93. this.listProposals = this.listProposals.filter(proposals =>
  94. ["PENDI", "REVIS", "FINAL"].includes(
  95. proposals["id_estado_inversion"]["codigo"]
  96. )
  97. );
  98. }*/
  99. this.dataSource.data = this.listProposals;
  100. this.dataSource.paginator = this.paginator;
  101. this.dataSource.sortingDataAccessor = (item, property) => {
  102. switch (property) {
  103. case "id_inversion_instrumento":
  104. return item.id_inversion_instrumento.id_tipo_instrumento.nombre;
  105. case "id_estado_inversion":
  106. return item.id_estado_inversion.nombre;
  107. case "id_empresa":
  108. return item.id_empresa.nombre;
  109. default:
  110. return item[property];
  111. }
  112. };
  113. this.dataSource.sort = this.sort;
  114. Swal.close();
  115. },
  116. err => {
  117. Swal.fire({
  118. icon: "error",
  119. title: "Error en el servidor",
  120. text: err.message
  121. });
  122. }
  123. );
  124. }
  125. applyFilter(event: Event) {
  126. const filterValue = (event.target as HTMLInputElement).value.toLowerCase();
  127. this.dataSource.filter = filterValue;
  128. if (this.dataSource.paginator) {
  129. this.dataSource.paginator.firstPage();
  130. }
  131. }
  132. upload_liquidation_file(id: string) {
  133. this.formInvestmentProposal.resetFormData();
  134. Swal.fire({
  135. allowOutsideClick: false,
  136. icon: "info",
  137. text: "Espere por favor..."
  138. });
  139. Swal.showLoading();
  140. setTimeout(() => {
  141. this.router.navigate([`/investment-proposal/${id}/upload-file`]);
  142. }, 1000);
  143. }
  144. view_investment_proposal(id: string) {
  145. this.formInvestmentProposal.resetFormData();
  146. Swal.fire({
  147. allowOutsideClick: false,
  148. icon: "info",
  149. text: "Espere por favor..."
  150. });
  151. Swal.showLoading();
  152. setTimeout(() => {
  153. this.router.navigate([`/investment-proposal/${id}`]);
  154. }, 1000);
  155. }
  156. modify_investment_proposal(id: string) {
  157. this.formInvestmentProposal.resetFormData();
  158. Swal.fire({
  159. allowOutsideClick: false,
  160. icon: "info",
  161. text: "Espere por favor..."
  162. });
  163. Swal.showLoading();
  164. setTimeout(() => {
  165. this.router.navigate(["/investment-proposal/general-info"], {
  166. queryParams: { id: id }
  167. });
  168. }, 1000);
  169. }
  170. create_investment_proposal() {
  171. this.formInvestmentProposal.resetFormData();
  172. Swal.fire({
  173. allowOutsideClick: false,
  174. icon: "info",
  175. text: "Espere por favor..."
  176. });
  177. Swal.showLoading();
  178. setTimeout(() => {
  179. this.router.navigate(["/investment-proposal/general-info"], {});
  180. }, 1000);
  181. }
  182. can_modify(status: string) {
  183. if (
  184. status == "NUEVA" ||
  185. status == "RECHA" ||
  186. status == "APROB" ||
  187. status == "PGNPR" ||
  188. status == "LIQUI"
  189. ) {
  190. return true;
  191. } else {
  192. return false;
  193. }
  194. }
  195. can_upload_file(status: string, file: string) {
  196. if (
  197. (status == "APROB" ||
  198. status == "LIQUI" ||
  199. status == "COMPR" ||
  200. status == "PGAPR" ||
  201. status == "PGNPR" ||
  202. status == "LIQUI") &&
  203. file == null
  204. ) {
  205. return true;
  206. } else {
  207. return false;
  208. }
  209. }
  210. // Verifica permisos para mostrar boton de edicion y/o envio a revision,
  211. // segun los permisos del usuario y el estado de la propuesta
  212. can_modify_or_send_to_review(status: string) {
  213. if (status == "NUEVA" || status == "RECHA") {
  214. return true;
  215. } else {
  216. return false;
  217. }
  218. }
  219. can_review(status: string) {
  220. if (status == "PENDI" || status == "NOAPR") {
  221. return true;
  222. } else {
  223. return false;
  224. }
  225. }
  226. can_approve(status: string) {
  227. if (status == "REVIS") {
  228. return true;
  229. } else {
  230. return false;
  231. }
  232. }
  233. can_write_payment_info(status: string) {
  234. if (status == "APROB" || status == "PGNPR") {
  235. return true;
  236. } else {
  237. return false;
  238. }
  239. }
  240. can_review_payment(status: string) {
  241. if (status == "COMPR") {
  242. return true;
  243. } else {
  244. return false;
  245. }
  246. }
  247. can_upload_payment(status: string) {
  248. if (status == "PGAPR") {
  249. return true;
  250. } else {
  251. return false;
  252. }
  253. }
  254. can_finish_proposal(status: string) {
  255. if (status == "LIQUI") {
  256. return true;
  257. } else {
  258. return false;
  259. }
  260. }
  261. sendToReview(investmentProposalID: number, investmentCode: string) {
  262. this.investmentsService
  263. .getAvailableUsers(investmentProposalID)
  264. .subscribe(res => {
  265. this.userList = res["usuarios_next"];
  266. this.test = "<div>Notificar a:</div>";
  267. if (this.userList.length > 0) {
  268. for (let i = 0; i < this.userList.length; i++) {
  269. if (this.userList[i].default_email == true) {
  270. this.test += `<div class='form-check form-check-inline'><input type='checkbox' class='form-check-input' id='next-${this.userList[i].name}' name='users' value='${this.userList[i].name}' checked='true'><label class='form-check-label' for='next-${this.userList[i].name}'>${this.userList[i].name}</label></div>`;
  271. } else {
  272. this.test += `<div class='form-check form-check-inline'><input type='checkbox' class='form-check-input' id='next-${this.userList[i].name}' name='users' value='${this.userList[i].name}'><label class='form-check-label' for='next-${this.userList[i].name}'>${this.userList[i].name}</label></div>`;
  273. }
  274. }
  275. }
  276. });
  277. this.reviewProposal = undefined;
  278. (async () => {
  279. Swal.fire({
  280. title: `<h3>Enviar a revisión propuesta de inversión ${investmentCode}</h3>`,
  281. icon: "info",
  282. html: `<p style="text-align:left;">Comentario:</p>`,
  283. input: "textarea",
  284. showCancelButton: true,
  285. confirmButtonText: "Enviar propuesta",
  286. cancelButtonText: "Cancelar",
  287. allowEscapeKey: true,
  288. preConfirm: comentario => {
  289. this.reviewProposal = {
  290. id_inversion: investmentProposalID,
  291. step: "next",
  292. comentario: comentario == null ? "" : comentario
  293. };
  294. }
  295. }).then(result => {
  296. if (result.dismiss) {
  297. return false;
  298. }
  299. Swal.fire({
  300. title: `<h3>Enviar a revisión propuesta de inversión ${investmentCode}</h3>`,
  301. icon: "info",
  302. html: `${this.test}`,
  303. confirmButtonText: "Siguiente",
  304. showCancelButton: true,
  305. cancelButtonText: "Cancelar",
  306. showLoaderOnConfirm: true,
  307. allowEscapeKey: true,
  308. preConfirm: () => {
  309. let array = [];
  310. for (let i = 0; i < this.userList.length; i++) {
  311. let html_input: HTMLInputElement = document.getElementById(
  312. "next-" + this.userList[i].name
  313. ) as HTMLInputElement;
  314. if (html_input != null) {
  315. let html_value: string = html_input.value;
  316. if (html_input.checked == true) {
  317. array.push(html_value);
  318. }
  319. } else {
  320. array;
  321. }
  322. }
  323. this.reviewProposal["notificar"] = array.toString();
  324. }
  325. }).then(result1 => {
  326. if (result1.dismiss) {
  327. return false;
  328. }
  329. Swal.fire({
  330. allowOutsideClick: false,
  331. title: "Espere por favor...",
  332. icon: "info"
  333. });
  334. Swal.showLoading();
  335. this.investmentsService
  336. .sendReviewProposalInvestment(this.reviewProposal)
  337. .subscribe(
  338. success => {
  339. if (success) {
  340. Swal.fire({
  341. allowOutsideClick: false,
  342. icon: "success",
  343. showCancelButton: false,
  344. title: "Exito",
  345. confirmButtonText: "La propuesta ha sido enviada a revisión"
  346. }).then(result => {
  347. Swal.close();
  348. window.location.reload();
  349. });
  350. }
  351. },
  352. err => {
  353. if (err.code == 405) {
  354. Swal.fire({
  355. icon: "error",
  356. title: "Operacion no permitida",
  357. text: err.message
  358. }).then(result => {
  359. Swal.close();
  360. window.location.href = "#/investment-proposals";
  361. });
  362. } else {
  363. Swal.fire({
  364. icon: "error",
  365. title: "Error al guardar",
  366. text: err.message
  367. });
  368. }
  369. }
  370. );
  371. });
  372. //window.location.reload();
  373. });
  374. })();
  375. }
  376. //Enviar a revision la propuesta de inversion
  377. finishProposal(investmentProposalID: number, investmentCode: string) {
  378. this.investmentsService
  379. .getAvailableUsers(investmentProposalID)
  380. .subscribe(res => {
  381. this.userList = res["usuarios_next"];
  382. this.test = "";
  383. if (this.userList.length > 0) {
  384. for (let i = 0; i < this.userList.length; i++) {
  385. if (this.userList[i].default_email == true) {
  386. this.test += `<div class='form-check form-check-inline'><input type='checkbox' class='form-check-input' id='next-${
  387. this.userList[i].name
  388. }' name='users' value='${this.userList[i].name}' checked='${
  389. this.userList[i].default_email == "true" ? true : false
  390. }'><label class='form-check-label' for='next-${
  391. this.userList[i].name
  392. }'>${this.userList[i].name}</label></div>`;
  393. } else {
  394. this.test += `<div class='form-check form-check-inline'><input type='checkbox' class='form-check-input' id='next-${this.userList[i].name}' name='users' value='${this.userList[i].name}'><label class='form-check-label' for='next-${this.userList[i].name}'>${this.userList[i].name}</label></div>`;
  395. }
  396. }
  397. }
  398. });
  399. this.reviewProposal = undefined;
  400. (async () => {
  401. Swal.fire({
  402. title: `<h3>Finalizar propuesta de inversión: ${investmentCode}</h3>`,
  403. icon: "info",
  404. input: "textarea",
  405. html: `<p style="text-align:left;">Comentario:</p>`,
  406. showCancelButton: true,
  407. confirmButtonText: "Siguiente",
  408. cancelButtonText: "Cancelar",
  409. /*inputValidator: value => {
  410. if (!value) {
  411. return "Debe ingresar un comentario";
  412. }
  413. },*/
  414. preConfirm: comentario => {
  415. this.reviewProposal = {
  416. id_inversion: investmentProposalID,
  417. step: "next",
  418. comentario: comentario == null ? "" : comentario
  419. };
  420. },
  421. allowOutsideClick: () => !Swal.isLoading()
  422. }).then(result => {
  423. if (result.dismiss) {
  424. return false;
  425. }
  426. Swal.fire({
  427. title: `<h3>Finalizar propuesta de inversión ${investmentCode}</h3>`,
  428. icon: "info",
  429. html: `${this.test}`,
  430. confirmButtonText: "Finalizar",
  431. showCancelButton: true,
  432. cancelButtonText: "Cancelar",
  433. showLoaderOnConfirm: true,
  434. preConfirm: () => {
  435. let array = [];
  436. for (let i = 0; i < this.userList.length; i++) {
  437. let html_input: HTMLInputElement = document.getElementById(
  438. this.userList[i].name
  439. ) as HTMLInputElement;
  440. if (html_input != null) {
  441. let html_value: string = html_input.value;
  442. if (html_input.checked == true) {
  443. array.push(html_value);
  444. }
  445. } else {
  446. array;
  447. }
  448. }
  449. this.reviewProposal["notificar"] = array.toString();
  450. }
  451. }).then(result1 => {
  452. if (result1.dismiss) {
  453. return false;
  454. }
  455. Swal.fire({
  456. allowOutsideClick: false,
  457. title: "Espere por favor...",
  458. icon: "info"
  459. });
  460. Swal.showLoading();
  461. this.investmentsService
  462. .sendReviewProposalInvestment(this.reviewProposal)
  463. .subscribe(
  464. success => {
  465. if (success) {
  466. Swal.fire({
  467. allowOutsideClick: false,
  468. icon: "success",
  469. showCancelButton: false,
  470. title: "Exito",
  471. confirmButtonText: "La propuesta ha sido finalizada"
  472. }).then(result => {
  473. Swal.close();
  474. window.location.reload();
  475. });
  476. }
  477. },
  478. err => {
  479. if (err.code == 405) {
  480. Swal.fire({
  481. icon: "error",
  482. title: "Operacion no permitida",
  483. text: err.message
  484. }).then(result => {
  485. Swal.close();
  486. window.location.href = "#/investment-proposals";
  487. });
  488. } else {
  489. Swal.fire({
  490. icon: "error",
  491. title: "Error al guardar",
  492. text: err.message
  493. });
  494. }
  495. this.router.navigate(["/investment-proposals"]);
  496. }
  497. );
  498. });
  499. //window.location.reload();
  500. });
  501. })();
  502. }
  503. userType(userRole: any, requiredRole: any) {
  504. if (userRole.length == 0) {
  505. return true;
  506. }
  507. return userRole.includes(requiredRole);
  508. }
  509. }