Sfoglia il codice sorgente

Avances sprint 6, instrumentos de prestamos personales y empresariales, modificaciones en modal

Oscar José Nuñez Chávez 5 anni fa
parent
commit
f90d96d685
22 ha cambiato i file con 3428 aggiunte e 733 eliminazioni
  1. 667 0
      src/app/components/instruments/pemp/pemp.component.html
  2. 331 0
      src/app/components/instruments/pemp/pemp.component.ts
  3. 980 0
      src/app/components/instruments/pper/pper.component.html
  4. 371 0
      src/app/components/instruments/pper/pper.component.ts
  5. 152 140
      src/app/components/investment-proposals/approve/approve.component.ts
  6. 1 1
      src/app/components/investment-proposals/general-info/general-info.component.ts
  7. 95 58
      src/app/components/investment-proposals/investment-proposals.component.ts
  8. 153 141
      src/app/components/investment-proposals/payment-approval/payment-approval.component.ts
  9. 102 87
      src/app/components/investment-proposals/payment-info/payment-info.component.ts
  10. 57 112
      src/app/components/investment-proposals/payment-requirement/payment-requirement.component.ts
  11. 10 0
      src/app/components/investment-proposals/proposal-detail/proposal-detail.component.html
  12. 80 49
      src/app/components/investment-proposals/result/result.component.ts
  13. 153 141
      src/app/components/investment-proposals/review/review.component.ts
  14. 12 0
      src/app/components/investments/investments.component.ts
  15. 6 0
      src/app/components/plugins/investment-print/investment-print.html
  16. 92 0
      src/app/components/plugins/investment-print/investment-print.ts
  17. 10 2
      src/app/layouts/admin/admin.module.ts
  18. 62 0
      src/app/services/instrument-calculations.service.ts
  19. 5 1
      src/app/services/instruments.service.ts
  20. 12 0
      src/app/services/pdfmake-script.service.spec.ts
  21. 60 0
      src/app/services/pdfmake-script.service.ts
  22. 17 1
      src/styles.scss

+ 667 - 0
src/app/components/instruments/pemp/pemp.component.html

@@ -0,0 +1,667 @@
+<div *ngIf="!summary">
+  <h4 class="card-title">
+    Préstamo empresarial
+  </h4>
+  <form
+    class="form-auth-small ng-untouched ng-pristine ng-valid"
+    [formGroup]="investmentProposalForm"
+  >
+    <div class="row">
+      <!-- Monto préstamo -->
+      <div class="col-lg-6 col-sm-12 pr-xl-3">
+        <div class="form-group">
+          <label for="monto_prestamo">Monto préstamo: </label>
+          <div class="input-box-container">
+            <p>
+              <i class="fas fa-dollar-sign"></i>
+            </p>
+            <input
+              type="text"
+              formControlName="monto_prestamo"
+              class="form-control"
+              [ngClass]="{
+                'is-invalid': submitted && f.monto_prestamo.errors
+              }"
+            />
+            <div
+              *ngIf="submitted && f.monto_prestamo.errors"
+              class="invalid-feedback"
+            >
+              <div *ngIf="f.monto_prestamo.errors.required">
+                Campo requerido
+              </div>
+              <div *ngIf="f.monto_prestamo.errors.pattern">
+                Debe ingresar una cifra válida
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <!-- Tasa -->
+      <div class="col-lg-6 col-sm-12 pr-xl-3">
+        <div class="form-group">
+          <label for="tasa_porcentaje">Tasa: </label>
+          <div class="input-box-container">
+            <p>
+              <i class="fas fa-percent" aria-hidden="true"></i>
+            </p>
+            <input
+              type="text"
+              formControlName="tasa_porcentaje"
+              class="form-control"
+              [ngClass]="{
+                'is-invalid': submitted && f.tasa_porcentaje.errors
+              }"
+            />
+            <div
+              *ngIf="submitted && f.tasa_porcentaje.errors"
+              class="invalid-feedback"
+            >
+              <div *ngIf="f.tasa_porcentaje.errors.required">
+                Campo requerido
+              </div>
+              <div *ngIf="f.tasa_porcentaje.errors.pattern">
+                Debe ingresar una cifra válida
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <!-- IVA -->
+      <div class="col-lg-6 col-sm-12 pr-xl-3">
+        <div class="form-group">
+          <label for="iva_porcentaje">IVA: </label>
+          <div class="input-box-container">
+            <p>
+              <i class="fas fa-percent" aria-hidden="true"></i>
+            </p>
+            <input
+              type="text"
+              formControlName="iva_porcentaje"
+              class="form-control"
+              [ngClass]="{
+                'is-invalid': submitted && f.iva_porcentaje.errors
+              }"
+            />
+            <div
+              *ngIf="submitted && f.iva_porcentaje.errors"
+              class="invalid-feedback"
+            >
+              <div *ngIf="f.iva_porcentaje.errors.required">
+                Campo requerido
+              </div>
+              <div *ngIf="f.iva_porcentaje.errors.pattern">
+                Debe ingresar una cifra válida
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <!-- Comisián desembolso -->
+      <div class="col-lg-6 col-sm-12 pr-xl-3">
+        <div class="form-group">
+          <label for="comision_desembolso_porcentaje"
+            >Comisión desembolso:
+          </label>
+          <div class="input-box-container">
+            <p>
+              <i class="fas fa-percent" aria-hidden="true"></i>
+            </p>
+            <input
+              type="text"
+              formControlName="comision_desembolso_porcentaje"
+              class="form-control"
+              [ngClass]="{
+                'is-invalid':
+                  submitted && f.comision_desembolso_porcentaje.errors
+              }"
+            />
+            <div
+              *ngIf="submitted && f.comision_desembolso_porcentaje.errors"
+              class="invalid-feedback"
+            >
+              <div *ngIf="f.comision_desembolso_porcentaje.errors.required">
+                Campo requerido
+              </div>
+              <div *ngIf="f.comision_desembolso_porcentaje.errors.pattern">
+                Debe ingresar una cifra válida
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <!-- Fecha operación -->
+      <div class="col-lg-6 col-sm-12 pr-xl-3">
+        <div class="form-group">
+          <label for="fecha_operacion">Fecha operación: </label>
+          <div class="input-box-container">
+            <p>
+              <i class="far fa-calendar" aria-hidden="true"></i>
+            </p>
+            <input
+              class="input-box form-control"
+              placeholder="Seleccione una fecha"
+              angular-mydatepicker
+              formControlName="fecha_operacion"
+              (click)="dp.toggleCalendar()"
+              [options]="myDpOptions"
+              #dp="angular-mydatepicker"
+              [ngClass]="{
+                'is-invalid': submitted && f.fecha_operacion.errors
+              }"
+            />
+          </div>
+
+          <div
+            *ngIf="submitted && f.fecha_operacion.errors"
+            class="invalid-feedback"
+          >
+            <div *ngIf="f.fecha_operacion.errors.required">
+              Campo requerido
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <!-- Fecha vencimiento -->
+      <div class="col-lg-6 col-sm-12 pr-xl-3">
+        <div class="form-group">
+          <label for="fecha_vencimiento">Fecha vencimiento: </label>
+
+          <div class="input-box-container">
+            <div>
+              <p>
+                <i class="far fa-calendar" aria-hidden="true"></i>
+              </p>
+              <input
+                class="input-box form-control"
+                placeholder="Seleccione una fecha"
+                angular-mydatepicker
+                formControlName="fecha_vencimiento"
+                (click)="dp1.toggleCalendar()"
+                [options]="myDpOptions"
+                #dp1="angular-mydatepicker"
+                [ngClass]="{
+                  'is-invalid': submitted && f.fecha_vencimiento.errors
+                }"
+              />
+            </div>
+          </div>
+
+          <div
+            *ngIf="submitted && f.fecha_vencimiento.errors"
+            class="invalid-feedback"
+          >
+            <div *ngIf="f.fecha_vencimiento.errors.required">
+              Campo requerido
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <div class="col-lg-12 col-sm-12 pr-xl-12">
+        <div class="form-group text-right">
+          <br />
+          <button
+            type="button"
+            class="btn btn-success center-component"
+            (click)="getCalculations(investmentProposalForm, false)"
+          >
+            Realizar cálculos
+          </button>
+        </div>
+      </div>
+    </div>
+
+    <br />
+    <!-- Calculos del instrumento-->
+    <div class="instrument-calcs">
+      <div class="row">
+        <div class="col-12">
+          <span class="badge badge-success badge-custom"
+            >Cálculos del instrumento</span
+          >
+        </div>
+
+        <div class="col-sm-6">
+          <h4>Monto préstamo:</h4>
+          <div class="field">$USD {{ monto_prestamo | number: "1.2-4" }}</div>
+        </div>
+        <div class="col-sm-6">
+          <h4>Tasa (%):</h4>
+          <div class="field">{{ tasa_porcentaje | number: "1.2-4" }}%</div>
+        </div>
+        <div class="col-sm-6">
+          <h4>IVA (%):</h4>
+          <div class="field">{{ iva_porcentaje | number: "1.2-4" }}%</div>
+        </div>
+        <div class="col-sm-6">
+          <h4>IVA ($):</h4>
+          <div class="field">$USD {{ iva | number: "1.2-4" }}</div>
+        </div>
+
+        <div class="col-sm-6">
+          <h4>Comisión desembolso (%):</h4>
+          <div class="field">
+            {{ comision_desembolso_porcentaje | number: "1.2-4" }}%
+          </div>
+        </div>
+        <div class="col-sm-6">
+          <h4>Comisión desembolso ($):</h4>
+          <div class="field">
+            $USD {{ comision_desembolso | number: "1.2-4" }}
+          </div>
+        </div>
+        <div class="col-sm-6">
+          <h4>Plazo:</h4>
+          <div class="field">{{ plazo | number: "1.2-4" }}</div>
+        </div>
+        <div class="col-sm-6">
+          <h4>Fecha de operacion:</h4>
+          <div class="field">{{ fecha_operacion }}</div>
+        </div>
+        <div class="col-sm-6">
+          <h4>Fecha de vencimiento:</h4>
+          <div class="field">{{ fecha_vencimiento }}</div>
+        </div>
+      </div>
+    </div>
+    <br />
+    <!-- Tabla de proyecciones del instrumento-->
+    <div class="instrument-calcs">
+      <div class="row">
+        <div class="col-12">
+          <span class="badge badge-success badge-custom"
+            >Proyecciones del instrumento</span
+          >
+        </div>
+
+        <div *ngIf="hasProjections" class="cete-table-container">
+          <table mat-table [dataSource]="dataSource" class="example-table">
+            <ng-container matColumnDef="posicion">
+              <th mat-header-cell *matHeaderCellDef>#</th>
+              <td mat-cell *matCellDef="let row">
+                {{ row.posicion }}
+              </td>
+              <td mat-footer-cell *matFooterCellDef>TOTAL</td>
+            </ng-container>
+
+            <ng-container matColumnDef="plazo">
+              <th mat-header-cell *matHeaderCellDef>Plazo</th>
+              <td mat-cell *matCellDef="let row">
+                {{ row.plazo }}
+              </td>
+              <td mat-footer-cell *matFooterCellDef></td>
+            </ng-container>
+
+            <ng-container matColumnDef="fecha_pago">
+              <th mat-header-cell *matHeaderCellDef>Fecha pago</th>
+              <td mat-cell *matCellDef="let row">
+                {{
+                  row.fecha_pago == "" || row.fecha_pago == undefined
+                    ? "-"
+                    : row.fecha_pago
+                }}
+              </td>
+              <td mat-footer-cell *matFooterCellDef></td>
+            </ng-container>
+
+            <ng-container matColumnDef="tasa_porcentaje">
+              <th mat-header-cell *matHeaderCellDef>Tasa (%)</th>
+              <td mat-cell *matCellDef="let row">
+                {{
+                  row.tasa_porcentaje == "" || row.tasa_porcentaje == undefined
+                    ? "0"
+                    : row.tasa_porcentaje
+                }}%
+              </td>
+              <td mat-footer-cell *matFooterCellDef>
+                {{
+                  consolidado_proyeccion.total_tasa_porcentaje
+                    | number: "1.2-4"
+                }}%
+              </td>
+            </ng-container>
+
+            <ng-container matColumnDef="ingreso_bruto">
+              <th mat-header-cell *matHeaderCellDef>Ingreso bruto</th>
+              <td mat-cell *matCellDef="let row">
+                ${{
+                  row.ingreso_bruto == "" || row.ingreso_bruto == undefined
+                    ? "0"
+                    : row.ingreso_bruto
+                }}
+              </td>
+              <td mat-footer-cell *matFooterCellDef>
+                ${{
+                  consolidado_proyeccion.total_ingreso_bruto | number: "1.2-4"
+                }}
+              </td>
+            </ng-container>
+
+            <ng-container matColumnDef="ingreso_neto">
+              <th mat-header-cell *matHeaderCellDef>Ingreso neto</th>
+              <td mat-cell *matCellDef="let row">
+                ${{
+                  row.ingreso_neto == "" || row.ingreso_neto == undefined
+                    ? "0"
+                    : row.ingreso_neto
+                }}
+              </td>
+              <td mat-footer-cell *matFooterCellDef>
+                ${{
+                  consolidado_proyeccion.total_ingreso_neto | number: "1.2-4"
+                }}
+              </td>
+            </ng-container>
+
+            <ng-container matColumnDef="iva">
+              <th mat-header-cell *matHeaderCellDef>IVA</th>
+              <td mat-cell *matCellDef="let row">
+                ${{ row.iva == "" || row.iva == undefined ? "0" : row.iva }}
+              </td>
+              <td mat-footer-cell *matFooterCellDef>
+                ${{ consolidado_proyeccion.total_iva | number: "1.2-4" }}
+              </td>
+            </ng-container>
+
+            <ng-container matColumnDef="amortizacion_capital">
+              <th mat-header-cell *matHeaderCellDef>Amortización capital</th>
+              <td mat-cell *matCellDef="let row">
+                ${{
+                  row.amortizacion_capital == "" ||
+                  row.amortizacion_capital == undefined
+                    ? "0"
+                    : (row.amortizacion_capital | number: "1.2-4")
+                }}
+              </td>
+              <td mat-footer-cell *matFooterCellDef>
+                ${{
+                  consolidado_proyeccion.total_amortizacion_capital
+                    | number: "1.2-4"
+                }}
+              </td>
+            </ng-container>
+
+            <ng-container matColumnDef="monto_recibir">
+              <th mat-header-cell *matHeaderCellDef>Monto a recibir</th>
+              <td mat-cell *matCellDef="let row">
+                ${{
+                  row.monto_recibir == "" || row.monto_recibir == undefined
+                    ? "0"
+                    : row.monto_recibir
+                }}
+              </td>
+              <td mat-footer-cell *matFooterCellDef>
+                ${{
+                  consolidado_proyeccion.total_monto_recibir | number: "1.2-4"
+                }}
+              </td>
+            </ng-container>
+
+            <ng-container matColumnDef="capital_restante">
+              <th mat-header-cell *matHeaderCellDef>Monto a recibir</th>
+              <td mat-cell *matCellDef="let row">
+                ${{
+                  row.capital_restante == "" ||
+                  row.capital_restante == undefined
+                    ? "0"
+                    : row.capital_restante
+                }}
+              </td>
+              <td mat-footer-cell *matFooterCellDef>
+                ${{
+                  consolidado_proyeccion.total_capital_restante
+                    | number: "1.2-4"
+                }}
+              </td>
+            </ng-container>
+
+            <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
+            <tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
+            <tr mat-footer-row *matFooterRowDef="displayedColumns"></tr>
+          </table>
+        </div>
+      </div>
+    </div>
+
+    <br />
+    <div class="form-group text-center space-20">
+      <button
+        type="button"
+        class="btn btn-default center-component margin-right"
+        (click)="goToPrevious()"
+      >
+        Anterior
+      </button>
+      <button
+        type="submit"
+        class="btn btn-primary center-component margin-right"
+        (click)="goToNext(investmentProposalForm)"
+      >
+        Siguiente
+      </button>
+    </div>
+  </form>
+</div>
+
+<div *ngIf="summary">
+  <div class="timeline-body">
+    <div class="row">
+      <div class="col-lg-3 col-md-4 col-sm-6">
+        <h4>Valor nominal:</h4>
+        <div class="field">
+          $USD {{ instrument_work.monto_prestamo | number: "1.2-4" }}
+        </div>
+      </div>
+
+      <div class="col-lg-3 col-md-4 col-sm-6">
+        <h4>Monto préstamo:</h4>
+        <div class="field">
+          $USD {{ instrument_work.monto_prestamo | number: "1.2-4" }}
+        </div>
+      </div>
+      <div class="col-lg-3 col-md-4 col-sm-6">
+        <h4>Tasa (%):</h4>
+        <div class="field">
+          {{ instrument_work.tasa_porcentaje | number: "1.2-4" }}%
+        </div>
+      </div>
+      <div class="col-lg-3 col-md-4 col-sm-6">
+        <h4>IVA (%):</h4>
+        <div class="field">
+          {{ instrument_work.iva_porcentaje | number: "1.2-4" }}%
+        </div>
+      </div>
+      <div class="col-lg-3 col-md-4 col-sm-6">
+        <h4>IVA ($):</h4>
+        <div class="field">
+          $USD {{ instrument_work.iva | number: "1.2-4" }}
+        </div>
+      </div>
+
+      <div class="col-lg-3 col-md-4 col-sm-6">
+        <h4>Comisión desembolso (%):</h4>
+        <div class="field">
+          {{
+            instrument_work.comision_desembolso_porcentaje | number: "1.2-4"
+          }}%
+        </div>
+      </div>
+      <div class="col-lg-3 col-md-4 col-sm-6">
+        <h4>Comisión desembolso ($):</h4>
+        <div class="field">
+          $USD {{ instrument_work.comision_desembolso | number: "1.2-4" }}
+        </div>
+      </div>
+      <div class="col-lg-3 col-md-4 col-sm-6">
+        <h4>Plazo:</h4>
+        <div class="field">{{ instrument_work.plazo | number: "1.2-4" }}</div>
+      </div>
+      <div class="col-lg-3 col-md-4 col-sm-6">
+        <h4>Fecha de operacion:</h4>
+        <div class="field">{{ instrument_work.fecha_operacion }}</div>
+      </div>
+      <div class="col-lg-3 col-md-4 col-sm-6">
+        <h4>Fecha de vencimiento:</h4>
+        <div class="field">{{ instrument_work.fecha_vencimiento }}</div>
+      </div>
+    </div>
+    <br />
+    <div *ngIf="hasProjections" class="instrument-calcs-summary">
+      <div class="row">
+        <div class="col-12">
+          <span class="badge-warning badge-custom-instrument"
+            >Proyecciones del instrumento</span
+          >
+        </div>
+
+        <div class="cete-table-container">
+          <table mat-table [dataSource]="dataSource2" class="example-table">
+            <ng-container matColumnDef="posicion">
+              <th mat-header-cell *matHeaderCellDef>#</th>
+              <td mat-cell *matCellDef="let row">
+                {{ row.posicion }}
+              </td>
+              <td mat-footer-cell *matFooterCellDef>TOTAL</td>
+            </ng-container>
+
+            <ng-container matColumnDef="plazo">
+              <th mat-header-cell *matHeaderCellDef>Plazo</th>
+              <td mat-cell *matCellDef="let row">
+                {{ row.plazo }}
+              </td>
+              <td mat-footer-cell *matFooterCellDef></td>
+            </ng-container>
+
+            <ng-container matColumnDef="fecha_pago">
+              <th mat-header-cell *matHeaderCellDef>Fecha pago</th>
+              <td mat-cell *matCellDef="let row">
+                {{
+                  row.fecha_pago == "" || row.fecha_pago == undefined
+                    ? "-"
+                    : row.fecha_pago
+                }}
+              </td>
+              <td mat-footer-cell *matFooterCellDef></td>
+            </ng-container>
+
+            <ng-container matColumnDef="tasa_porcentaje">
+              <th mat-header-cell *matHeaderCellDef>Tasa (%)</th>
+              <td mat-cell *matCellDef="let row">
+                {{
+                  row.tasa_porcentaje == "" || row.tasa_porcentaje == undefined
+                    ? "0"
+                    : row.tasa_porcentaje
+                }}%
+              </td>
+              <td mat-footer-cell *matFooterCellDef></td>
+            </ng-container>
+
+            <ng-container matColumnDef="ingreso_bruto">
+              <th mat-header-cell *matHeaderCellDef>Ingreso bruto</th>
+              <td mat-cell *matCellDef="let row">
+                ${{
+                  row.ingreso_bruto == "" || row.ingreso_bruto == undefined
+                    ? "0"
+                    : row.ingreso_bruto
+                }}
+              </td>
+              <td mat-footer-cell *matFooterCellDef>
+                ${{
+                  consolidado_proyeccion.total_ingreso_bruto | number: "1.2-4"
+                }}
+              </td>
+            </ng-container>
+
+            <ng-container matColumnDef="ingreso_neto">
+              <th mat-header-cell *matHeaderCellDef>Ingreso neto</th>
+              <td mat-cell *matCellDef="let row">
+                ${{
+                  row.ingreso_neto == "" || row.ingreso_neto == undefined
+                    ? "0"
+                    : row.ingreso_neto
+                }}
+              </td>
+              <td mat-footer-cell *matFooterCellDef>
+                ${{
+                  consolidado_proyeccion.total_ingreso_neto | number: "1.2-4"
+                }}
+              </td>
+            </ng-container>
+
+            <ng-container matColumnDef="iva">
+              <th mat-header-cell *matHeaderCellDef>IVA</th>
+              <td mat-cell *matCellDef="let row">
+                ${{ row.iva == "" || row.iva == undefined ? "0" : row.iva }}
+              </td>
+              <td mat-footer-cell *matFooterCellDef>
+                ${{ consolidado_proyeccion.total_iva | number: "1.2-4" }}
+              </td>
+            </ng-container>
+
+            <ng-container matColumnDef="amortizacion_capital">
+              <th mat-header-cell *matHeaderCellDef>Amortización capital</th>
+              <td mat-cell *matCellDef="let row">
+                ${{
+                  row.amortizacion_capital == "" ||
+                  row.amortizacion_capital == undefined
+                    ? "0"
+                    : (row.amortizacion_capital | number: "1.2-4")
+                }}
+              </td>
+              <td mat-footer-cell *matFooterCellDef>
+                ${{
+                  consolidado_proyeccion.total_amortizacion_capital
+                    | number: "1.2-4"
+                }}
+              </td>
+            </ng-container>
+
+            <ng-container matColumnDef="monto_recibir">
+              <th mat-header-cell *matHeaderCellDef>Monto a recibir</th>
+              <td mat-cell *matCellDef="let row">
+                ${{
+                  row.monto_recibir == "" || row.monto_recibir == undefined
+                    ? "0"
+                    : row.monto_recibir
+                }}
+              </td>
+              <td mat-footer-cell *matFooterCellDef>
+                ${{
+                  consolidado_proyeccion.total_monto_recibir | number: "1.2-4"
+                }}
+              </td>
+            </ng-container>
+
+            <ng-container matColumnDef="capital_restante">
+              <th mat-header-cell *matHeaderCellDef>Monto a recibir</th>
+              <td mat-cell *matCellDef="let row">
+                ${{
+                  row.capital_restante == "" ||
+                  row.capital_restante == undefined
+                    ? "0"
+                    : row.capital_restante
+                }}
+              </td>
+              <td mat-footer-cell *matFooterCellDef>
+                ${{
+                  consolidado_proyeccion.total_capital_restante
+                    | number: "1.2-4"
+                }}
+              </td>
+            </ng-container>
+
+            <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
+            <tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
+            <tr mat-footer-row *matFooterRowDef="displayedColumns"></tr>
+          </table>
+        </div>
+      </div>
+    </div>
+  </div>
+</div>

+ 331 - 0
src/app/components/instruments/pemp/pemp.component.ts

@@ -0,0 +1,331 @@
+import { Component, OnInit, Input, ViewChild } from "@angular/core";
+import { InstrumentComponent } from "@app/components/investment-proposals/instrument/instrument.component";
+import { FormBuilder, FormGroup, Validators } from "@angular/forms";
+import { IAngularMyDpOptions, IMyDateModel } from "angular-mydatepicker";
+import { formatDate, DatePipe } from "@angular/common";
+import { Router } from "@angular/router";
+import { FormInvestmentProposalService } from "@app/services/form-investment-proposal.service";
+import { CatalogsService } from "@app/services/catalogs.service";
+import { InstrumentCalculations } from "@app/services/instrument-calculations.service";
+import Swal from "sweetalert2";
+import { GeneralInfo } from "@app/models/investment-proposal-form";
+import { parse } from "date-fns";
+import { MatPaginator } from "@angular/material/paginator";
+import { MatSort } from "@angular/material/sort";
+import { MatTableDataSource } from "@angular/material/table";
+
+@Component({
+  selector: "app-pemp",
+  templateUrl: "./pemp.component.html"
+})
+export class PEMP implements InstrumentComponent {
+  title: string = "Préstamo empresarial";
+  @Input() data: any;
+  @Input() summary: boolean;
+  @Input() investmentID: string;
+
+  displayedColumns: string[] = [
+    "posicion",
+    "plazo",
+    "fecha_pago",
+    "tasa_porcentaje",
+    "ingreso_bruto",
+    "ingreso_neto",
+    "iva",
+    "amortizacion_capital",
+    "monto_recibir",
+    "capital_restante"
+  ];
+
+  @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
+  @ViewChild(MatSort, { static: true }) sort: MatSort;
+
+  form: any;
+  general: GeneralInfo;
+
+  // For daterange
+  daysLabels: any = {
+    su: "Dom",
+    mo: "Lun",
+    tu: "Mar",
+    we: "Mie",
+    th: "Jue",
+    fr: "Vie",
+    sa: "Sab"
+  };
+  monthsLabels: any = {
+    1: "Ene",
+    2: "Feb",
+    3: "Mar",
+    4: "Abr",
+    5: "May",
+    6: "Jun",
+    7: "Jul",
+    8: "Ago",
+    9: "Sep",
+    10: "Oct",
+    11: "Nov",
+    12: "Dic"
+  };
+  investmentProposalForm: FormGroup;
+  myDpOptions: IAngularMyDpOptions = {
+    dateRange: false,
+    dateFormat: "dd/mm/yyyy",
+    dayLabels: this.daysLabels,
+    monthLabels: this.monthsLabels
+  };
+  myDateInit: boolean = true;
+  m_fecha_operacion: IMyDateModel;
+  m_fecha_liquidacion: IMyDateModel;
+  m_fecha_rendencion: IMyDateModel;
+
+  submitted: boolean = false;
+  instrument_exists: boolean;
+  instrument_work: any = [];
+  financials: any;
+  base_types: any;
+
+  ingreso_bruto: number = 0.0;
+  ingreso_neto: number = 0.0;
+  monto_prestamo: number = 0.0;
+  tasa_porcentaje: number = 0.0;
+  plazo: number = 0.0;
+  iva_porcentaje: number = 0.0;
+  comision_desembolso_porcentaje: number = 0.0;
+  iva: number = 0.0;
+  proyecciones: any;
+
+  pempObject: {};
+  dataSource = new MatTableDataSource(this.proyecciones);
+  dataSource2 = new MatTableDataSource(this.proyecciones);
+  hasProjections: boolean;
+  fecha_vencimiento: any;
+  consolidado_proyeccion = {
+    total_ingreso_bruto: 0,
+    total_ingreso_neto: 0
+  };
+  fecha_operacion: any;
+  comision_desembolso: any;
+
+  constructor(
+    private formBuilder: FormBuilder,
+    private router: Router,
+    private formDataService: FormInvestmentProposalService,
+    private catalogService: CatalogsService,
+    private instrumentCalcService: InstrumentCalculations,
+    public datepipe: DatePipe
+  ) {
+    this.instrument_work = this.formDataService.getWork();
+    this.instrument_exists = this.instrument_work == undefined;
+    this.general = this.formDataService.getGeneralInfo();
+
+    if (
+      this.instrument_work != undefined &&
+      (this.instrument_work.proyecciones != "" ||
+        this.instrument_work != undefined)
+    ) {
+      this.consolidado_proyeccion = this.instrument_work.proyecciones[
+        this.instrument_work.proyecciones.length - 1
+      ];
+      this.hasProjections = true;
+      this.dataSource2.data = this.instrument_work.proyecciones.slice(0, -1);
+      this.dataSource2.paginator = this.paginator;
+      this.dataSource2.sort = this.sort;
+    } else {
+      this.hasProjections = false;
+    }
+
+    this.investmentProposalForm = this.formBuilder.group({
+      monto_prestamo: [
+        this.instrument_exists ? "" : this.instrument_work.monto_prestamo,
+        [
+          Validators.required,
+          Validators.pattern(/^[+]?([0-9]+(?:[\.][0-9]*)?|\.[0-9]+)$/)
+        ]
+      ],
+
+      tasa_porcentaje: [
+        this.instrument_exists ? "" : this.instrument_work.tasa_porcentaje,
+        [
+          Validators.required,
+          Validators.pattern(/^[+]?([0-9]+(?:[\.][0-9]*)?|\.[0-9]+)$/)
+        ]
+      ],
+      iva_porcentaje: [
+        this.instrument_exists ? "" : this.instrument_work.iva_porcentaje,
+        [
+          Validators.required,
+          Validators.pattern(/^[+]?([0-9]+(?:[\.][0-9]*)?|\.[0-9]+)$/)
+        ]
+      ],
+      comision_desembolso_porcentaje: [
+        this.instrument_exists
+          ? ""
+          : this.instrument_work.comision_desembolso_porcentaje,
+        [
+          Validators.required,
+          Validators.pattern(/^[+]?([0-9]+(?:[\.][0-9]*)?|\.[0-9]+)$/)
+        ]
+      ],
+      fecha_operacion: [
+        this.instrument_exists
+          ? ""
+          : {
+              isRange: false,
+              singleDate: {
+                jsDate: parse(
+                  this.instrument_work.fecha_operacion,
+                  "dd/MM/yyyy",
+                  new Date()
+                ),
+                formatted: this.instrument_work.fecha_operacion
+              }
+            },
+        Validators.required
+      ],
+      fecha_vencimiento: [
+        this.instrument_exists
+          ? ""
+          : {
+              isRange: false,
+              singleDate: {
+                jsDate: parse(
+                  this.instrument_work.fecha_vencimiento,
+                  "dd/MM/yyyy",
+                  new Date()
+                ),
+                formatted: this.instrument_work.fecha_vencimiento
+              }
+            }
+      ]
+    });
+  }
+
+  get f() {
+    return this.investmentProposalForm.controls;
+  }
+
+  save(form: any): boolean {
+    if (!form.valid) {
+      return false;
+    }
+
+    this.formDataService.setWork(this.pempObject);
+    return true;
+  }
+
+  getCalculations(form: any, saveForm: boolean) {
+    this.submitted = true;
+
+    if (!form.valid) {
+      return false;
+    }
+    Swal.fire({
+      allowOutsideClick: false,
+      icon: "info",
+      text: "Espere por favor..."
+    });
+    Swal.showLoading();
+    this.instrumentCalcService
+      .pempCalc(
+        "PEMP", // Codigo del instrumento
+        {
+          id_tipo_base: +this.general.base_anual,
+          id_formato_ingreso: +this.general.formato_ingreso,
+          id_periodicidad: +this.general.periodicidad
+        },
+        {
+          monto_prestamo: +this.f.monto_prestamo.value,
+          tasa_porcentaje: +this.f.tasa_porcentaje.value,
+          iva_porcentaje: +this.f.iva_porcentaje.value,
+          comision_desembolso_porcentaje: +this.f.comision_desembolso_porcentaje
+            .value,
+          fecha_operacion: this.f.fecha_operacion.value.singleDate.formatted,
+          fecha_vencimiento: this.f.fecha_vencimiento.value.singleDate.formatted
+          //fecha_vencimiento: this.f.fecha_vencimiento.value.singleDate.formatted
+        }
+      )
+      .subscribe(
+        ans => {
+          this.monto_prestamo = ans["result"]["instrumento"]["monto_prestamo"];
+          this.tasa_porcentaje =
+            ans["result"]["instrumento"]["tasa_porcentaje"];
+          this.plazo = ans["result"]["instrumento"]["plazo"];
+          this.iva_porcentaje = ans["result"]["instrumento"]["iva_porcentaje"];
+          this.comision_desembolso_porcentaje =
+            ans["result"]["instrumento"]["comision_desembolso_porcentaje"];
+          this.iva = ans["result"]["instrumento"]["iva"];
+          this.proyecciones = ans["result"]["instrumento"]["proyecciones"];
+          this.fecha_operacion =
+            ans["result"]["instrumento"]["fecha_operacion"];
+          this.fecha_vencimiento =
+            ans["result"]["instrumento"]["fecha_vencimiento"];
+          this.comision_desembolso =
+            ans["result"]["instrumento"]["comision_desembolso"];
+          this.proyecciones = ans["result"]["proyecciones"];
+
+          if (this.proyecciones != undefined && this.proyecciones.length > 0) {
+            this.hasProjections = true;
+            let proyecciones_temp = this.proyecciones;
+            this.consolidado_proyeccion =
+              proyecciones_temp[proyecciones_temp.length - 1];
+            this.proyecciones = ans["result"]["proyecciones"];
+          }
+          this.dataSource.data = this.proyecciones.slice(0, -1);
+          this.dataSource.paginator = this.paginator;
+          this.dataSource.sort = this.sort;
+
+          this.pempObject = {
+            monto_prestamo: this.investmentProposalForm.value.monto_prestamo,
+            tasa_porcentaje: this.investmentProposalForm.value.tasa_porcentaje,
+            iva_porcentaje: this.investmentProposalForm.value.iva_porcentaje,
+            comision_desembolso_porcentaje: this.investmentProposalForm.value
+              .comision_desembolso_porcentaje,
+            comision_desembolso: this.comision_desembolso,
+            fecha_operacion: this.f.fecha_operacion.value.singleDate.formatted,
+            fecha_vencimiento: this.f.fecha_vencimiento.value.singleDate
+              .formatted,
+
+            plazo: this.plazo,
+            iva: this.iva,
+            proyecciones: this.proyecciones
+          };
+
+          this.formDataService.setWork(this.pempObject);
+          Swal.close();
+          if (saveForm == true) {
+            if (this.investmentID != undefined) {
+              this.router.navigate(["/investment-proposal/complement-info"], {
+                queryParams: { id: this.investmentID }
+              });
+            } else {
+              this.router.navigate(["/investment-proposal/complement-info"]);
+            }
+          }
+        },
+        err => {
+          Swal.fire({
+            icon: "error",
+            title: "Error en el servidor",
+            text: "No su pudo obtener la informacion"
+          });
+          return false;
+        }
+      );
+  }
+
+  goToPrevious() {
+    this.submitted = true;
+    if (this.investmentID != undefined) {
+      this.router.navigate(["/investment-proposal/general-info"], {
+        queryParams: { id: this.investmentID }
+      });
+    } else {
+      this.router.navigate(["/investment-proposal/general-info"]);
+    }
+  }
+
+  goToNext(form: any) {
+    this.getCalculations(form, true);
+  }
+}

+ 980 - 0
src/app/components/instruments/pper/pper.component.html

@@ -0,0 +1,980 @@
+<div *ngIf="!summary">
+  <h4 class="card-title">
+    Préstamo personal
+  </h4>
+  <form
+    class="form-auth-small ng-untouched ng-pristine ng-valid"
+    [formGroup]="investmentProposalForm"
+  >
+    <div class="row">
+      <!-- Monto préstamo -->
+      <div class="col-lg-6 col-sm-12 pr-xl-3">
+        <div class="form-group">
+          <label for="monto_prestamo">Monto préstamo: </label>
+          <div class="input-box-container">
+            <p>
+              <i class="fas fa-dollar-sign"></i>
+            </p>
+            <input
+              type="text"
+              formControlName="monto_prestamo"
+              class="form-control"
+              [ngClass]="{
+                'is-invalid': submitted && f.monto_prestamo.errors
+              }"
+            />
+            <div
+              *ngIf="submitted && f.monto_prestamo.errors"
+              class="invalid-feedback"
+            >
+              <div *ngIf="f.monto_prestamo.errors.required">
+                Campo requerido
+              </div>
+              <div *ngIf="f.monto_prestamo.errors.pattern">
+                Debe ingresar una cifra válida
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <!-- Tasa -->
+      <div class="col-lg-6 col-sm-12 pr-xl-3">
+        <div class="form-group">
+          <label for="tasa_porcentaje">Tasa: </label>
+          <div class="input-box-container">
+            <p>
+              <i class="fas fa-percent" aria-hidden="true"></i>
+            </p>
+            <input
+              type="text"
+              formControlName="tasa_porcentaje"
+              class="form-control"
+              [ngClass]="{
+                'is-invalid': submitted && f.tasa_porcentaje.errors
+              }"
+            />
+            <div
+              *ngIf="submitted && f.tasa_porcentaje.errors"
+              class="invalid-feedback"
+            >
+              <div *ngIf="f.tasa_porcentaje.errors.required">
+                Campo requerido
+              </div>
+              <div *ngIf="f.tasa_porcentaje.errors.pattern">
+                Debe ingresar una cifra válida
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <!-- IVA -->
+      <div class="col-lg-6 col-sm-12 pr-xl-3">
+        <div class="form-group">
+          <label for="iva_porcentaje">IVA: </label>
+          <div class="input-box-container">
+            <p>
+              <i class="fas fa-percent" aria-hidden="true"></i>
+            </p>
+            <input
+              type="text"
+              formControlName="iva_porcentaje"
+              class="form-control"
+              [ngClass]="{
+                'is-invalid': submitted && f.iva_porcentaje.errors
+              }"
+            />
+            <div
+              *ngIf="submitted && f.iva_porcentaje.errors"
+              class="invalid-feedback"
+            >
+              <div *ngIf="f.iva_porcentaje.errors.required">
+                Campo requerido
+              </div>
+              <div *ngIf="f.iva_porcentaje.errors.pattern">
+                Debe ingresar una cifra válida
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <!-- Plazo -->
+      <div class="col-lg-6 col-sm-12 pr-xl-3">
+        <div class="form-group">
+          <label for="plazo_gracia">Plazo: </label>
+          <div class="input-box-container">
+            <p>
+              <i class="fas fa-list-ol" aria-hidden="true"></i>
+            </p>
+            <input
+              type="text"
+              formControlName="plazo_gracia"
+              class="form-control"
+              [ngClass]="{
+                'is-invalid': submitted && f.plazo_gracia.errors
+              }"
+            />
+            <div
+              *ngIf="submitted && f.plazo_gracia.errors"
+              class="invalid-feedback"
+            >
+              <div *ngIf="f.plazo_gracia.errors.required">
+                Campo requerido
+              </div>
+              <div *ngIf="f.plazo_gracia.errors.pattern">
+                Debe ingresar una cifra válida
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <!-- Pago seguro daño -->
+      <div class="col-lg-6 col-sm-12 pr-xl-3">
+        <div class="form-group">
+          <label for="pago_seguro_dano">Pago seguro daño: </label>
+          <div class="input-box-container">
+            <p>
+              <i class="fas fa-dollar-sign"></i>
+            </p>
+            <input
+              type="text"
+              formControlName="pago_seguro_dano"
+              class="form-control"
+              [ngClass]="{
+                'is-invalid': submitted && f.pago_seguro_dano.errors
+              }"
+            />
+            <div
+              *ngIf="submitted && f.pago_seguro_dano.errors"
+              class="invalid-feedback"
+            >
+              <div *ngIf="f.pago_seguro_dano.errors.required">
+                Campo requerido
+              </div>
+              <div *ngIf="f.pago_seguro_dano.errors.pattern">
+                Debe ingresar una cifra válida
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <!-- Pago seguro vivienda -->
+      <div class="col-lg-6 col-sm-12 pr-xl-3">
+        <div class="form-group">
+          <label for="pago_seguro_vivienda">Pago seguro vivienda: </label>
+          <div class="input-box-container">
+            <p>
+              <i class="fas fa-dollar-sign"></i>
+            </p>
+            <input
+              type="text"
+              formControlName="pago_seguro_vivienda"
+              class="form-control"
+              [ngClass]="{
+                'is-invalid': submitted && f.pago_seguro_vivienda.errors
+              }"
+            />
+            <div
+              *ngIf="submitted && f.pago_seguro_vivienda.errors"
+              class="invalid-feedback"
+            >
+              <div *ngIf="f.pago_seguro_vivienda.errors.required">
+                Campo requerido
+              </div>
+              <div *ngIf="f.pago_seguro_vivienda.errors.pattern">
+                Debe ingresar una cifra válida
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <!-- Total de cuotas mensuales -->
+      <div class="col-lg-6 col-sm-12 pr-xl-3">
+        <div class="form-group">
+          <label for="total_cuotas_mensuales"
+            >Total de cuotas mensuales:
+          </label>
+          <div class="input-box-container">
+            <p>
+              <i class="fas fa-list-ol" aria-hidden="true"></i>
+            </p>
+            <input
+              type="text"
+              formControlName="total_cuotas_mensuales"
+              class="form-control"
+              [ngClass]="{
+                'is-invalid': submitted && f.total_cuotas_mensuales.errors
+              }"
+            />
+            <div
+              *ngIf="submitted && f.total_cuotas_mensuales.errors"
+              class="invalid-feedback"
+            >
+              <div *ngIf="f.total_cuotas_mensuales.errors.required">
+                Campo requerido
+              </div>
+              <div *ngIf="f.total_cuotas_mensuales.errors.pattern">
+                Debe ingresar una cifra válida
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <!-- Fecha otorgamiento -->
+      <div class="col-lg-6 col-sm-12 pr-xl-3">
+        <div class="form-group">
+          <label for="fecha_otorgamiento">Fecha otorgamiento: </label>
+          <div class="input-box-container">
+            <p>
+              <i class="far fa-calendar" aria-hidden="true"></i>
+            </p>
+            <input
+              class="input-box form-control"
+              placeholder="Seleccione una fecha"
+              angular-mydatepicker
+              formControlName="fecha_otorgamiento"
+              (click)="dp.toggleCalendar()"
+              [options]="myDpOptions"
+              #dp="angular-mydatepicker"
+              [ngClass]="{
+                'is-invalid': submitted && f.fecha_otorgamiento.errors
+              }"
+            />
+          </div>
+
+          <div
+            *ngIf="submitted && f.fecha_otorgamiento.errors"
+            class="invalid-feedback"
+          >
+            <div *ngIf="f.fecha_otorgamiento.errors.required">
+              Campo requerido
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <!-- Nombre deudor -->
+      <div class="col-lg-6 col-sm-12 pr-xl-3">
+        <div class="form-group">
+          <label for="nombre_deudor">Nombre deudor: </label>
+          <div class="input-box-container">
+            <p>
+              <i class="far fa-user" aria-hidden="true"></i>
+            </p>
+            <input
+              class="input-box form-control"
+              formControlName="nombre_deudor"
+            />
+          </div>
+        </div>
+      </div>
+
+      <!-- Número deudor -->
+      <div class="col-lg-6 col-sm-12 pr-xl-3">
+        <div class="form-group">
+          <label for="numero_deudor">Número deudor: </label>
+          <div class="input-box-container">
+            <p>
+              <i class="far fa-user" aria-hidden="true"></i>
+            </p>
+            <input
+              class="input-box form-control"
+              formControlName="numero_deudor"
+            />
+          </div>
+        </div>
+      </div>
+
+      <div class="col-lg-12 col-sm-12 pr-xl-12">
+        <div class="form-group text-right">
+          <br />
+          <button
+            type="button"
+            class="btn btn-success center-component"
+            (click)="getCalculations(investmentProposalForm, false)"
+          >
+            Realizar cálculos
+          </button>
+        </div>
+      </div>
+    </div>
+
+    <br />
+    <!-- Calculos del instrumento-->
+    <div class="instrument-calcs">
+      <div class="row">
+        <div class="col-12">
+          <span class="badge badge-success badge-custom"
+            >Cálculos del instrumento</span
+          >
+        </div>
+
+        <div class="col-sm-6">
+          <h4>Monto préstamo:</h4>
+          <div class="field">$USD {{ monto_prestamo | number: "1.2-4" }}</div>
+        </div>
+
+        <div class="col-sm-6">
+          <h4>Tasa (%):</h4>
+          <div class="field">{{ tasa_porcentaje | number: "1.2-4" }}%</div>
+        </div>
+        <div class="col-sm-6">
+          <h4>IVA (%):</h4>
+          <div class="field">{{ iva_porcentaje | number: "1.2-4" }}%</div>
+        </div>
+        <div class="col-sm-6">
+          <h4>Plazo:</h4>
+          <div class="field">{{ plazo_gracia }}</div>
+        </div>
+
+        <div class="col-sm-6">
+          <h4>Pago de seguro por daño</h4>
+          <div class="field">$USD {{ pago_seguro_dano | number: "1.2-4" }}</div>
+        </div>
+
+        <div class="col-sm-6">
+          <h4>Pago seguro de vivienda:</h4>
+          <div class="field">
+            $USD {{ pago_seguro_vivienda | number: "1.2-4" }}
+          </div>
+        </div>
+
+        <div class="col-sm-6">
+          <h4>Total de cuotas mensuales:</h4>
+          <div class="field">
+            {{ total_cuotas_mensuales }}
+          </div>
+        </div>
+
+        <div class="col-sm-6">
+          <h4>Cuota sin seguros:</h4>
+          <div class="field">
+            $USD {{ cuota_sin_seguros | number: "1.2-4" }}
+          </div>
+        </div>
+
+        <div class="col-sm-6">
+          <h4>Fecha de otorgamiento:</h4>
+          <div class="field">{{ fecha_otorgamiento }}</div>
+        </div>
+        <div class="col-sm-6">
+          <h4>Fecha de gracia:</h4>
+          <div class="field">{{ fecha_gracia }}</div>
+        </div>
+        <div class="col-sm-6">
+          <h4>Fecha fin de otorgamiento:</h4>
+          <div class="field">{{ fecha_fin_otorgamiento }}</div>
+        </div>
+      </div>
+    </div>
+    <br />
+    <!-- Tabla de proyecciones del instrumento-->
+    <div class="instrument-calcs">
+      <div class="row">
+        <div class="col-12">
+          <span class="badge badge-success badge-custom"
+            >Proyecciones del instrumento</span
+          >
+        </div>
+
+        <div *ngIf="hasProjections" class="custom-table-container">
+          <table mat-table [dataSource]="dataSource" class="example-table">
+            <ng-container matColumnDef="posicion">
+              <th mat-header-cell *matHeaderCellDef>#</th>
+              <td mat-cell *matCellDef="let row">
+                {{ row.posicion }}
+              </td>
+              <td mat-footer-cell *matFooterCellDef>TOTAL</td>
+            </ng-container>
+
+            <ng-container matColumnDef="plazo">
+              <th mat-header-cell *matHeaderCellDef>Plazo</th>
+              <td mat-cell *matCellDef="let row">
+                {{ row.plazo }}
+              </td>
+              <td mat-footer-cell *matFooterCellDef></td>
+            </ng-container>
+
+            <ng-container matColumnDef="fecha_pago">
+              <th mat-header-cell *matHeaderCellDef>Fecha pago</th>
+              <td mat-cell *matCellDef="let row">
+                {{
+                  row.fecha_pago == "" || row.fecha_pago == undefined
+                    ? "-"
+                    : row.fecha_pago
+                }}
+              </td>
+              <td mat-footer-cell *matFooterCellDef></td>
+            </ng-container>
+            <ng-container matColumnDef="ingreso_bruto">
+              <th mat-header-cell *matHeaderCellDef>Ingreso bruto</th>
+              <td mat-cell *matCellDef="let row">
+                ${{
+                  row.ingreso_bruto == "" || row.ingreso_bruto == undefined
+                    ? "0"
+                    : (row.ingreso_bruto | number: "1.2-4")
+                }}
+              </td>
+              <td mat-footer-cell *matFooterCellDef>
+                ${{
+                  consolidado_proyeccion.total_ingreso_bruto | number: "1.2-4"
+                }}
+              </td>
+            </ng-container>
+
+            <ng-container matColumnDef="ingreso_neto">
+              <th mat-header-cell *matHeaderCellDef>Ingreso neto</th>
+              <td mat-cell *matCellDef="let row">
+                {{
+                  row.ingreso_neto == "" || row.ingreso_neto == undefined
+                    ? "0"
+                    : (row.ingreso_neto | number: "1.2-4")
+                }}
+              </td>
+              <td mat-footer-cell *matFooterCellDef>
+                ${{
+                  consolidado_proyeccion.total_ingreso_neto | number: "1.2-4"
+                }}
+              </td>
+            </ng-container>
+
+            <ng-container matColumnDef="tasa_porcentaje">
+              <th mat-header-cell *matHeaderCellDef>Tasa (%)</th>
+              <td mat-cell *matCellDef="let row">
+                {{
+                  row.tasa_porcentaje == "" || row.tasa_porcentaje == undefined
+                    ? "0"
+                    : (row.tasa_porcentaje | number: "1.2-4")
+                }}%
+              </td>
+              <td mat-footer-cell *matFooterCellDef></td>
+            </ng-container>
+
+            <ng-container matColumnDef="saldo_inicial">
+              <th mat-header-cell *matHeaderCellDef>Saldo inicial</th>
+              <td mat-cell *matCellDef="let row">
+                ${{
+                  row.saldo_inicial == "" || row.saldo_inicial == undefined
+                    ? "0"
+                    : (row.saldo_inicial | number: "1.2-4")
+                }}
+              </td>
+              <td mat-footer-cell *matFooterCellDef>
+                ${{
+                  consolidado_proyeccion.total_saldo_inicial | number: "1.2-4"
+                }}
+              </td>
+            </ng-container>
+
+            <ng-container matColumnDef="pago_cuota">
+              <th mat-header-cell *matHeaderCellDef>Pago cuota ($)</th>
+              <td mat-cell *matCellDef="let row">
+                ${{
+                  row.pago_cuota == "" || row.pago_cuota == undefined
+                    ? "0"
+                    : (row.pago_cuota | number: "1.2-4")
+                }}
+              </td>
+              <td mat-footer-cell *matFooterCellDef>
+                ${{ consolidado_proyeccion.total_pago_cuota | number: "1.2-4" }}
+              </td>
+            </ng-container>
+
+            <ng-container matColumnDef="iva_interes"
+              >`
+              <th mat-header-cell *matHeaderCellDef>IVA (%)</th>
+              <td mat-cell *matCellDef="let row">
+                {{
+                  row.iva_interes == "" || row.iva_interes == undefined
+                    ? "0"
+                    : (row.iva_interes | number: "1.2-4")
+                }}%
+              </td>
+              <td mat-footer-cell *matFooterCellDef>
+                {{
+                  consolidado_proyeccion.total_iva_interes | number: "1.2-4"
+                }}%
+              </td>
+            </ng-container>
+
+            <ng-container matColumnDef="abono_capital">
+              <th mat-header-cell *matHeaderCellDef>Abono capital</th>
+              <td mat-cell *matCellDef="let row">
+                ${{
+                  row.abono_capital == "" || row.abono_capital == undefined
+                    ? "0"
+                    : (row.abono_capital | number: "1.2-4")
+                }}
+              </td>
+              <td mat-footer-cell *matFooterCellDef>
+                ${{
+                  consolidado_proyeccion.total_abono_capital | number: "1.2-4"
+                }}
+              </td>
+            </ng-container>
+
+            <ng-container matColumnDef="capital_restante">
+              <th mat-header-cell *matHeaderCellDef>Capital restante</th>
+              <td mat-cell *matCellDef="let row">
+                ${{
+                  row.capital_restante == "" ||
+                  row.capital_restante == undefined
+                    ? "0"
+                    : (row.capital_restante | number: "1.2-4")
+                }}
+              </td>
+              <td mat-footer-cell *matFooterCellDef>
+                ${{
+                  consolidado_proyeccion.total_capital_restante
+                    | number: "1.2-4"
+                }}
+              </td>
+            </ng-container>
+
+            <ng-container matColumnDef="pago_seguro_dano">
+              <th mat-header-cell *matHeaderCellDef>Pago seguro daño</th>
+              <td mat-cell *matCellDef="let row">
+                ${{
+                  row.pago_seguro_dano == "" ||
+                  row.pago_seguro_dano == undefined
+                    ? "0"
+                    : (row.pago_seguro_dano | number: "1.2-4")
+                }}
+              </td>
+              <td mat-footer-cell *matFooterCellDef>
+                ${{
+                  consolidado_proyeccion.total_pago_seguro_dano
+                    | number: "1.2-4"
+                }}
+              </td>
+            </ng-container>
+
+            <ng-container matColumnDef="pago_seguro_vivienda">
+              <th mat-header-cell *matHeaderCellDef>Pago seguro vivienda</th>
+              <td mat-cell *matCellDef="let row">
+                ${{
+                  row.pago_seguro_vivienda == "" ||
+                  row.pago_seguro_vivienda == undefined
+                    ? "0"
+                    : (row.pago_seguro_vivienda | number: "1.2-4")
+                }}
+              </td>
+              <td mat-footer-cell *matFooterCellDef>
+                ${{
+                  consolidado_proyeccion.total_pago_seguro_vivienda
+                    | number: "1.2-4"
+                }}
+              </td>
+            </ng-container>
+
+            <ng-container matColumnDef="total_cuota">
+              <th mat-header-cell *matHeaderCellDef>Pago seguro vivienda</th>
+              <td mat-cell *matCellDef="let row">
+                ${{
+                  row.total_cuota == "" || row.total_cuota == undefined
+                    ? "0"
+                    : (row.total_cuota | number: "1.2-4")
+                }}
+              </td>
+              <td mat-footer-cell *matFooterCellDef>
+                ${{ consolidado_proyeccion.total_cuota | number: "1.2-4" }}
+              </td>
+            </ng-container>
+
+            <ng-container matColumnDef="amortizacion_capital">
+              <th mat-header-cell *matHeaderCellDef>Amortización capital</th>
+              <td mat-cell *matCellDef="let row">
+                ${{
+                  row.amortizacion_capital == "" ||
+                  row.amortizacion_capital == undefined
+                    ? "0"
+                    : (row.amortizacion_capital | number: "1.2-4")
+                }}
+              </td>
+              <td mat-footer-cell *matFooterCellDef>
+                ${{
+                  consolidado_proyeccion.total_amortizacion_capital
+                    | number: "1.2-4"
+                }}
+              </td>
+            </ng-container>
+
+            <ng-container matColumnDef="total_recibir">
+              <th mat-header-cell *matHeaderCellDef>Total a recibir</th>
+              <td mat-cell *matCellDef="let row">
+                ${{
+                  row.total_recibir == "" || row.total_recibir == undefined
+                    ? "0"
+                    : (row.total_recibir | number: "1.2-4")
+                }}
+              </td>
+              <td mat-footer-cell *matFooterCellDef>
+                ${{ consolidado_proyeccion.total_recibir | number: "1.2-4" }}
+              </td>
+            </ng-container>
+
+            <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
+            <tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
+            <tr mat-footer-row *matFooterRowDef="displayedColumns"></tr>
+          </table>
+        </div>
+      </div>
+    </div>
+
+    <br />
+    <div class="form-group text-center space-20">
+      <button
+        type="button"
+        class="btn btn-default center-component margin-right"
+        (click)="goToPrevious()"
+      >
+        Anterior
+      </button>
+      <button
+        type="submit"
+        class="btn btn-primary center-component margin-right"
+        (click)="goToNext(investmentProposalForm)"
+      >
+        Siguiente
+      </button>
+    </div>
+  </form>
+</div>
+
+<div *ngIf="summary">
+  <div class="timeline-body">
+    <div class="row">
+      <div class="col-lg-3 col-md-4 col-sm-6">
+        <h4>Valor nominal:</h4>
+        <div class="field">
+          $USD {{ instrument_work.monto_prestamo | number: "1.2-4" }}
+        </div>
+      </div>
+
+      <div class="col-lg-3 col-md-4 col-sm-6">
+        <h4>Monto préstamo:</h4>
+        <div class="field">
+          $USD {{ instrument_work.monto_prestamo | number: "1.2-4" }}
+        </div>
+      </div>
+      <div class="col-lg-3 col-md-4 col-sm-6">
+        <h4>IVA (%):</h4>
+        <div class="field">
+          {{ instrument_work.iva_porcentaje | number: "1.2-4" }}%
+        </div>
+      </div>
+      <div class="col-lg-3 col-md-4 col-sm-6">
+        <h4>Plazo:</h4>
+        <div class="field">{{ instrument_work.plazo_gracia }}</div>
+      </div>
+
+      <div class="col-lg-3 col-md-4 col-sm-6">
+        <h4>Pago de seguro por daño</h4>
+        <div class="field">
+          $USD {{ instrument_work.pago_seguro_dano | number: "1.2-4" }}
+        </div>
+      </div>
+
+      <div class="col-lg-3 col-md-4 col-sm-6">
+        <h4>Pago seguro de vivienda:</h4>
+        <div class="field">
+          $USD {{ instrument_work.pago_seguro_vivienda | number: "1.2-4" }}
+        </div>
+      </div>
+
+      <div class="col-lg-3 col-md-4 col-sm-6">
+        <h4>Total de cuotas mensuales:</h4>
+        <div class="field">
+          {{ instrument_work.total_cuotas_mensuales }}
+        </div>
+      </div>
+
+      <div class="col-lg-3 col-md-4 col-sm-6">
+        <h4>Cuota sin seguros:</h4>
+        <div class="field">
+          $USD {{ instrument_work.cuota_sin_seguros | number: "1.2-4" }}
+        </div>
+      </div>
+
+      <div class="col-lg-3 col-md-4 col-sm-6">
+        <h4>Fecha de otorgamiento:</h4>
+        <div class="field">{{ instrument_work.fecha_otorgamiento }}</div>
+      </div>
+      <div class="col-lg-3 col-md-4 col-sm-6">
+        <h4>Fecha de gracia:</h4>
+        <div class="field">{{ instrument_work.fecha_gracia }}</div>
+      </div>
+      <div class="col-lg-3 col-md-4 col-sm-6">
+        <h4>Fecha fin de otorgamiento:</h4>
+        <div class="field">{{ instrument_work.fecha_fin_otorgamiento }}</div>
+      </div>
+
+      <div class="col-lg-3 col-md-4 col-sm-6">
+        <h4>Nombre del deudor:</h4>
+        <div class="field">{{ instrument_work.nombre_deudor }}</div>
+      </div>
+      <div class="col-lg-3 col-md-4 col-sm-6">
+        <h4>Número del deudor:</h4>
+        <div class="field">{{ instrument_work.numero_deudor }}</div>
+      </div>
+    </div>
+    <br />
+    <div *ngIf="hasProjections" class="instrument-calcs-summary">
+      <div class="row">
+        <div class="col-12">
+          <span class="badge-warning badge-custom-instrument"
+            >Proyecciones del instrumento</span
+          >
+        </div>
+
+        <div class="custom-table-container">
+          <table mat-table [dataSource]="dataSource2" class="example-table">
+            <ng-container matColumnDef="posicion">
+              <th mat-header-cell *matHeaderCellDef>#</th>
+              <td mat-cell *matCellDef="let row">
+                {{ row.posicion }}
+              </td>
+              <td mat-footer-cell *matFooterCellDef>TOTAL</td>
+            </ng-container>
+
+            <ng-container matColumnDef="plazo">
+              <th mat-header-cell *matHeaderCellDef>Plazo</th>
+              <td mat-cell *matCellDef="let row">
+                {{ row.plazo }}
+              </td>
+              <td mat-footer-cell *matFooterCellDef></td>
+            </ng-container>
+
+            <ng-container matColumnDef="fecha_pago">
+              <th mat-header-cell *matHeaderCellDef>Fecha pago</th>
+              <td mat-cell *matCellDef="let row">
+                {{
+                  row.fecha_pago == "" || row.fecha_pago == undefined
+                    ? "-"
+                    : row.fecha_pago
+                }}
+              </td>
+              <td mat-footer-cell *matFooterCellDef></td>
+            </ng-container>
+            <ng-container matColumnDef="ingreso_bruto">
+              <th mat-header-cell *matHeaderCellDef>Ingreso bruto</th>
+              <td mat-cell *matCellDef="let row">
+                ${{
+                  row.ingreso_bruto == "" || row.ingreso_bruto == undefined
+                    ? "0"
+                    : (row.ingreso_bruto | number: "1.2-4")
+                }}
+              </td>
+              <td mat-footer-cell *matFooterCellDef>
+                ${{
+                  consolidado_proyeccion.total_ingreso_bruto | number: "1.2-4"
+                }}
+              </td>
+            </ng-container>
+
+            <ng-container matColumnDef="ingreso_neto">
+              <th mat-header-cell *matHeaderCellDef>Ingreso neto</th>
+              <td mat-cell *matCellDef="let row">
+                {{
+                  row.ingreso_neto == "" || row.ingreso_neto == undefined
+                    ? "0"
+                    : (row.ingreso_neto | number: "1.2-4")
+                }}
+              </td>
+              <td mat-footer-cell *matFooterCellDef>
+                ${{
+                  consolidado_proyeccion.total_ingreso_neto | number: "1.2-4"
+                }}
+              </td>
+            </ng-container>
+
+            <ng-container matColumnDef="tasa_porcentaje">
+              <th mat-header-cell *matHeaderCellDef>Tasa (%)</th>
+              <td mat-cell *matCellDef="let row">
+                {{
+                  row.tasa_porcentaje == "" || row.tasa_porcentaje == undefined
+                    ? "0"
+                    : (row.tasa_porcentaje | number: "1.2-4")
+                }}%
+              </td>
+              <td mat-footer-cell *matFooterCellDef></td>
+            </ng-container>
+
+            <ng-container matColumnDef="saldo_inicial">
+              <th mat-header-cell *matHeaderCellDef>Saldo inicial</th>
+              <td mat-cell *matCellDef="let row">
+                ${{
+                  row.saldo_inicial == "" || row.saldo_inicial == undefined
+                    ? "0"
+                    : (row.saldo_inicial | number: "1.2-4")
+                }}
+              </td>
+              <td mat-footer-cell *matFooterCellDef>
+                ${{
+                  consolidado_proyeccion.total_saldo_inicial | number: "1.2-4"
+                }}
+              </td>
+            </ng-container>
+
+            <ng-container matColumnDef="pago_cuota">
+              <th mat-header-cell *matHeaderCellDef>Pago cuota ($)</th>
+              <td mat-cell *matCellDef="let row">
+                ${{
+                  row.pago_cuota == "" || row.pago_cuota == undefined
+                    ? "0"
+                    : (row.pago_cuota | number: "1.2-4")
+                }}
+              </td>
+              <td mat-footer-cell *matFooterCellDef>
+                ${{ consolidado_proyeccion.total_pago_cuota | number: "1.2-4" }}
+              </td>
+            </ng-container>
+
+            <ng-container matColumnDef="iva_interes"
+              >`
+              <th mat-header-cell *matHeaderCellDef>IVA (%)</th>
+              <td mat-cell *matCellDef="let row">
+                {{
+                  row.iva_interes == "" || row.iva_interes == undefined
+                    ? "0"
+                    : (row.iva_interes | number: "1.2-4")
+                }}%
+              </td>
+              <td mat-footer-cell *matFooterCellDef>
+                {{
+                  consolidado_proyeccion.total_iva_interes | number: "1.2-4"
+                }}%
+              </td>
+            </ng-container>
+
+            <ng-container matColumnDef="abono_capital">
+              <th mat-header-cell *matHeaderCellDef>Abono capital</th>
+              <td mat-cell *matCellDef="let row">
+                ${{
+                  row.abono_capital == "" || row.abono_capital == undefined
+                    ? "0"
+                    : (row.abono_capital | number: "1.2-4")
+                }}
+              </td>
+              <td mat-footer-cell *matFooterCellDef>
+                ${{
+                  consolidado_proyeccion.total_abono_capital | number: "1.2-4"
+                }}
+              </td>
+            </ng-container>
+
+            <ng-container matColumnDef="capital_restante">
+              <th mat-header-cell *matHeaderCellDef>Capital restante</th>
+              <td mat-cell *matCellDef="let row">
+                ${{
+                  row.capital_restante == "" ||
+                  row.capital_restante == undefined
+                    ? "0"
+                    : (row.capital_restante | number: "1.2-4")
+                }}
+              </td>
+              <td mat-footer-cell *matFooterCellDef>
+                ${{
+                  consolidado_proyeccion.total_capital_restante
+                    | number: "1.2-4"
+                }}
+              </td>
+            </ng-container>
+
+            <ng-container matColumnDef="pago_seguro_dano">
+              <th mat-header-cell *matHeaderCellDef>Pago seguro daño</th>
+              <td mat-cell *matCellDef="let row">
+                ${{
+                  row.pago_seguro_dano == "" ||
+                  row.pago_seguro_dano == undefined
+                    ? "0"
+                    : (row.pago_seguro_dano | number: "1.2-4")
+                }}
+              </td>
+              <td mat-footer-cell *matFooterCellDef>
+                ${{
+                  consolidado_proyeccion.total_pago_seguro_dano
+                    | number: "1.2-4"
+                }}
+              </td>
+            </ng-container>
+
+            <ng-container matColumnDef="pago_seguro_vivienda">
+              <th mat-header-cell *matHeaderCellDef>Pago seguro vivienda</th>
+              <td mat-cell *matCellDef="let row">
+                ${{
+                  row.pago_seguro_vivienda == "" ||
+                  row.pago_seguro_vivienda == undefined
+                    ? "0"
+                    : (row.pago_seguro_vivienda | number: "1.2-4")
+                }}
+              </td>
+              <td mat-footer-cell *matFooterCellDef>
+                ${{
+                  consolidado_proyeccion.total_pago_seguro_vivienda
+                    | number: "1.2-4"
+                }}
+              </td>
+            </ng-container>
+
+            <ng-container matColumnDef="total_cuota">
+              <th mat-header-cell *matHeaderCellDef>Pago seguro vivienda</th>
+              <td mat-cell *matCellDef="let row">
+                ${{
+                  row.total_cuota == "" || row.total_cuota == undefined
+                    ? "0"
+                    : (row.total_cuota | number: "1.2-4")
+                }}
+              </td>
+              <td mat-footer-cell *matFooterCellDef>
+                ${{ consolidado_proyeccion.total_cuota | number: "1.2-4" }}
+              </td>
+            </ng-container>
+
+            <ng-container matColumnDef="amortizacion_capital">
+              <th mat-header-cell *matHeaderCellDef>Amortización capital</th>
+              <td mat-cell *matCellDef="let row">
+                ${{
+                  row.amortizacion_capital == "" ||
+                  row.amortizacion_capital == undefined
+                    ? "0"
+                    : (row.amortizacion_capital | number: "1.2-4")
+                }}
+              </td>
+              <td mat-footer-cell *matFooterCellDef>
+                ${{
+                  consolidado_proyeccion.total_amortizacion_capital
+                    | number: "1.2-4"
+                }}
+              </td>
+            </ng-container>
+
+            <ng-container matColumnDef="total_recibir">
+              <th mat-header-cell *matHeaderCellDef>Total a recibir</th>
+              <td mat-cell *matCellDef="let row">
+                ${{
+                  row.total_recibir == "" || row.total_recibir == undefined
+                    ? "0"
+                    : (row.total_recibir | number: "1.2-4")
+                }}
+              </td>
+              <td mat-footer-cell *matFooterCellDef>
+                ${{ consolidado_proyeccion.total_recibir | number: "1.2-4" }}
+              </td>
+            </ng-container>
+
+            <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
+            <tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
+            <tr mat-footer-row *matFooterRowDef="displayedColumns"></tr>
+          </table>
+        </div>
+      </div>
+    </div>
+  </div>
+</div>

+ 371 - 0
src/app/components/instruments/pper/pper.component.ts

@@ -0,0 +1,371 @@
+import { Component, OnInit, Input, ViewChild } from "@angular/core";
+import { InstrumentComponent } from "@app/components/investment-proposals/instrument/instrument.component";
+import { FormBuilder, FormGroup, Validators } from "@angular/forms";
+import { IAngularMyDpOptions, IMyDateModel } from "angular-mydatepicker";
+import { formatDate, DatePipe } from "@angular/common";
+import { Router } from "@angular/router";
+import { FormInvestmentProposalService } from "@app/services/form-investment-proposal.service";
+import { CatalogsService } from "@app/services/catalogs.service";
+import { InstrumentCalculations } from "@app/services/instrument-calculations.service";
+import Swal from "sweetalert2";
+import { GeneralInfo } from "@app/models/investment-proposal-form";
+import { parse } from "date-fns";
+import { MatPaginator } from "@angular/material/paginator";
+import { MatSort } from "@angular/material/sort";
+import { MatTableDataSource } from "@angular/material/table";
+
+@Component({
+  selector: "app-pper",
+  templateUrl: "./pper.component.html"
+})
+export class PPER implements InstrumentComponent {
+  title: string = "Préstamo personal";
+  @Input() data: any;
+  @Input() summary: boolean;
+  @Input() investmentID: string;
+
+  displayedColumns: string[] = [
+    "posicion",
+    "plazo",
+    "fecha_pago",
+    "tasa_porcentaje",
+    "saldo_inicial",
+    "pago_cuota",
+    "ingreso_bruto",
+    "iva_interes",
+    "ingreso_neto",
+    "abono_capital",
+    "capital_restante",
+    "pago_seguro_dano",
+    "pago_seguro_vivienda",
+    "total_cuota",
+    "amortizacion_capital",
+    "total_recibir"
+  ];
+
+  @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
+  @ViewChild(MatSort, { static: true }) sort: MatSort;
+
+  form: any;
+  general: GeneralInfo;
+
+  // For daterange
+  daysLabels: any = {
+    su: "Dom",
+    mo: "Lun",
+    tu: "Mar",
+    we: "Mie",
+    th: "Jue",
+    fr: "Vie",
+    sa: "Sab"
+  };
+  monthsLabels: any = {
+    1: "Ene",
+    2: "Feb",
+    3: "Mar",
+    4: "Abr",
+    5: "May",
+    6: "Jun",
+    7: "Jul",
+    8: "Ago",
+    9: "Sep",
+    10: "Oct",
+    11: "Nov",
+    12: "Dic"
+  };
+  investmentProposalForm: FormGroup;
+  myDpOptions: IAngularMyDpOptions = {
+    dateRange: false,
+    dateFormat: "dd/mm/yyyy",
+    dayLabels: this.daysLabels,
+    monthLabels: this.monthsLabels
+  };
+  myDateInit: boolean = true;
+  m_fecha_otorgamiento: IMyDateModel;
+  m_fecha_liquidacion: IMyDateModel;
+  m_fecha_rendencion: IMyDateModel;
+
+  submitted: boolean = false;
+  instrument_exists: boolean;
+  instrument_work: any = [];
+  financials: any;
+  base_types: any;
+
+  ingreso_bruto: number = 0.0;
+  ingreso_neto: number = 0.0;
+  monto_prestamo: number = 0.0;
+  tasa_porcentaje: number = 0.0;
+  plazo: number = 0.0;
+  iva_porcentaje: number = 0.0;
+  plazo_gracia: number = 0.0;
+  iva: number = 0.0;
+  proyecciones: any;
+
+  pperObject: {};
+  dataSource = new MatTableDataSource(this.proyecciones);
+  dataSource2 = new MatTableDataSource(this.proyecciones);
+  hasProjections: boolean;
+  fecha_vencimiento: any;
+  consolidado_proyeccion = {
+    total_ingreso_bruto: 0,
+    total_ingreso_neto: 0
+  };
+  fecha_otorgamiento: any;
+  comision_desembolso: any;
+  fecha_gracia: any;
+  fecha_fin_otorgamiento: any;
+  pago_seguro_dano: any;
+  pago_seguro_vivienda: any;
+  total_cuotas_mensuales: any;
+  cuota_sin_seguros: any;
+  proyecciones_array: any;
+
+  constructor(
+    private formBuilder: FormBuilder,
+    private router: Router,
+    private formDataService: FormInvestmentProposalService,
+    private catalogService: CatalogsService,
+    private instrumentCalcService: InstrumentCalculations,
+    public datepipe: DatePipe
+  ) {
+    this.instrument_work = this.formDataService.getWork();
+    this.instrument_exists = this.instrument_work == undefined;
+    this.general = this.formDataService.getGeneralInfo();
+
+    this.proyecciones_array = Object.values(
+      this.instrument_work.proyecciones
+    ).map(a => Object.values(a).every(x => x === null || x === ""));
+
+    this.proyecciones_array = this.proyecciones_array.toString() === true;
+
+    console.log(this.proyecciones_array);
+
+    if (
+      this.instrument_work != undefined &&
+      this.instrument_work.proyecciones != ""
+    ) {
+      this.consolidado_proyeccion = this.instrument_work.proyecciones[
+        this.instrument_work.proyecciones.length - 1
+      ];
+      this.hasProjections = true;
+      this.dataSource2.data = this.instrument_work.proyecciones.slice(0, -1);
+      this.dataSource2.paginator = this.paginator;
+      this.dataSource2.sort = this.sort;
+    } else {
+      this.hasProjections = false;
+    }
+
+    this.investmentProposalForm = this.formBuilder.group({
+      monto_prestamo: [
+        this.instrument_exists ? "" : this.instrument_work.monto_prestamo,
+        [
+          Validators.required,
+          Validators.pattern(/^[+]?([0-9]+(?:[\.][0-9]*)?|\.[0-9]+)$/)
+        ]
+      ],
+      tasa_porcentaje: [
+        this.instrument_exists ? "" : this.instrument_work.tasa_porcentaje,
+        [
+          Validators.required,
+          Validators.pattern(/^[+]?([0-9]+(?:[\.][0-9]*)?|\.[0-9]+)$/)
+        ]
+      ],
+      iva_porcentaje: [
+        this.instrument_exists ? "" : this.instrument_work.iva_porcentaje,
+        [
+          Validators.required,
+          Validators.pattern(/^[+]?([0-9]+(?:[\.][0-9]*)?|\.[0-9]+)$/)
+        ]
+      ],
+      plazo_gracia: [
+        this.instrument_exists ? "" : this.instrument_work.plazo_gracia,
+        [
+          Validators.required,
+          Validators.pattern(/^[+]?([0-9]+(?:[\.][0-9]*)?|\.[0-9]+)$/)
+        ]
+      ],
+      pago_seguro_dano: [
+        this.instrument_exists ? "" : this.instrument_work.pago_seguro_dano,
+        [
+          Validators.required,
+          Validators.pattern(/^[+]?([0-9]+(?:[\.][0-9]*)?|\.[0-9]+)$/)
+        ]
+      ],
+      pago_seguro_vivienda: [
+        this.instrument_exists ? "" : this.instrument_work.pago_seguro_vivienda,
+        [
+          Validators.required,
+          Validators.pattern(/^[+]?([0-9]+(?:[\.][0-9]*)?|\.[0-9]+)$/)
+        ]
+      ],
+      total_cuotas_mensuales: [
+        this.instrument_exists
+          ? ""
+          : this.instrument_work.total_cuotas_mensuales,
+        [
+          Validators.required,
+          Validators.pattern(/^[+]?([0-9]+(?:[\.][0-9]*)?|\.[0-9]+)$/)
+        ]
+      ],
+      nombre_deudor: [
+        this.instrument_exists ? "" : this.instrument_work.nombre_deudor
+      ],
+      numero_deudor: [
+        this.instrument_exists ? "" : this.instrument_work.numero_deudor
+      ],
+      fecha_otorgamiento: [
+        this.instrument_exists
+          ? ""
+          : {
+              isRange: false,
+              singleDate: {
+                jsDate: parse(
+                  this.instrument_work.fecha_otorgamiento,
+                  "dd/MM/yyyy",
+                  new Date()
+                ),
+                formatted: this.instrument_work.fecha_otorgamiento
+              }
+            },
+        Validators.required
+      ]
+    });
+  }
+
+  get f() {
+    return this.investmentProposalForm.controls;
+  }
+
+  save(form: any): boolean {
+    if (!form.valid) {
+      return false;
+    }
+
+    this.formDataService.setWork(this.pperObject);
+    return true;
+  }
+
+  getCalculations(form: any, saveForm: boolean) {
+    this.submitted = true;
+
+    if (!form.valid) {
+      return false;
+    }
+    Swal.fire({
+      allowOutsideClick: false,
+      icon: "info",
+      text: "Espere por favor..."
+    });
+    Swal.showLoading();
+    this.instrumentCalcService
+      .pperCalc(
+        "PPER", // Codigo del instrumento
+        {
+          id_tipo_base: +this.general.base_anual,
+          id_formato_ingreso: +this.general.formato_ingreso,
+          id_periodicidad: +this.general.periodicidad
+        },
+        {
+          monto_prestamo: this.f.monto_prestamo.value,
+          fecha_otorgamiento: this.f.fecha_otorgamiento.value.singleDate
+            .formatted,
+          plazo_gracia: this.f.plazo_gracia.value,
+          tasa_porcentaje: this.f.tasa_porcentaje.value,
+          iva_porcentaje: this.f.iva_porcentaje.value,
+          pago_seguro_dano: this.f.pago_seguro_dano.value,
+          pago_seguro_vivienda: this.f.pago_seguro_vivienda.value,
+          total_cuotas_mensuales: this.f.total_cuotas_mensuales.value
+        }
+      )
+      .subscribe(
+        ans => {
+          this.monto_prestamo = ans["result"]["instrumento"]["monto_prestamo"];
+          this.fecha_otorgamiento =
+            ans["result"]["instrumento"]["fecha_otorgamiento"];
+          this.fecha_gracia = ans["result"]["instrumento"]["fecha_gracia"];
+          this.fecha_fin_otorgamiento =
+            ans["result"]["instrumento"]["fecha_fin_otorgamiento"];
+          this.plazo_gracia = ans["result"]["instrumento"]["plazo_gracia"];
+          this.tasa_porcentaje =
+            ans["result"]["instrumento"]["tasa_porcentaje"];
+          this.iva_porcentaje = ans["result"]["instrumento"]["iva_porcentaje"];
+          this.pago_seguro_dano =
+            ans["result"]["instrumento"]["pago_seguro_dano"];
+          this.pago_seguro_vivienda =
+            ans["result"]["instrumento"]["pago_seguro_vivienda"];
+          this.total_cuotas_mensuales =
+            ans["result"]["instrumento"]["total_cuotas_mensuales"];
+          this.cuota_sin_seguros =
+            ans["result"]["instrumento"]["cuota_sin_seguros"];
+          this.proyecciones = ans["result"]["proyecciones"];
+
+          if (this.proyecciones != undefined && this.proyecciones.length > 0) {
+            this.hasProjections = true;
+            let proyecciones_temp = this.proyecciones;
+            this.consolidado_proyeccion =
+              proyecciones_temp[proyecciones_temp.length - 1];
+            this.proyecciones = ans["result"]["proyecciones"];
+          }
+          this.dataSource.data = this.proyecciones.slice(0, -1);
+          this.dataSource.paginator = this.paginator;
+          this.dataSource.sort = this.sort;
+
+          this.pperObject = {
+            monto_prestamo: this.investmentProposalForm.value.monto_prestamo,
+            plazo_gracia: this.investmentProposalForm.value.plazo_gracia,
+            tasa_porcentaje: this.investmentProposalForm.value.tasa_porcentaje,
+            iva_porcentaje: this.investmentProposalForm.value.iva_porcentaje,
+            pago_seguro_dano: this.investmentProposalForm.value
+              .pago_seguro_dano,
+            pago_seguro_vivienda: this.investmentProposalForm.value
+              .pago_seguro_vivienda,
+            total_cuotas_mensuales: this.investmentProposalForm.value
+              .total_cuotas_mensuales,
+            numero_deudor: this.investmentProposalForm.value.numero_deudor,
+            nombre_deudor: this.investmentProposalForm.value.nombre_deudor,
+            fecha_otorgamiento: this.f.fecha_otorgamiento.value.singleDate
+              .formatted,
+            fecha_fin_otorgamiento: this.fecha_fin_otorgamiento,
+            fecha_gracia: this.fecha_gracia,
+            cuota_sin_seguros: this.cuota_sin_seguros,
+            proyecciones: this.proyecciones
+          };
+
+          this.formDataService.setWork(this.pperObject);
+          Swal.close();
+          if (saveForm == true) {
+            if (this.investmentID != undefined) {
+              this.router.navigate(["/investment-proposal/complement-info"], {
+                queryParams: { id: this.investmentID }
+              });
+            } else {
+              this.router.navigate(["/investment-proposal/complement-info"]);
+            }
+          }
+        },
+        err => {
+          Swal.fire({
+            icon: "error",
+            title: "Error en el servidor",
+            text: "No su pudo obtener la informacion"
+          });
+          return false;
+        }
+      );
+  }
+
+  goToPrevious() {
+    this.submitted = true;
+    if (this.investmentID != undefined) {
+      this.router.navigate(["/investment-proposal/general-info"], {
+        queryParams: { id: this.investmentID }
+      });
+    } else {
+      this.router.navigate(["/investment-proposal/general-info"]);
+    }
+  }
+
+  goToNext(form: any) {
+    this.getCalculations(form, true);
+  }
+}

+ 152 - 140
src/app/components/investment-proposals/approve/approve.component.ts

@@ -350,171 +350,183 @@ export class InvestmentProposalApproveComponent implements OnInit {
 
   approve_proposal() {
     this.reviewProposal = undefined;
-    (async () => {
+
+    Swal.fire({
+      title: `<h3>Aprobación de propuesta de inversión</h3>`,
+      icon: "info",
+      html: `<p style="text-align:left;">Comentario:</p>`,
+      input: "textarea",
+      showCancelButton: true,
+      confirmButtonText: "Siguiente",
+      cancelButtonText: "Cancelar",
+      showLoaderOnConfirm: true,
+
+      preConfirm: comentario => {
+        this.reviewProposal = {
+          id_inversion: this.investmentProposalID,
+          step: "next",
+          comentario: comentario
+        };
+      },
+      allowOutsideClick: () => !Swal.isLoading()
+    }).then(result => {
+      if (result.dismiss) {
+        return false;
+      }
+
       Swal.fire({
         title: `<h3>Aprobación de propuesta de inversión</h3>`,
         icon: "info",
-        html: `<p style="text-align:left;">Comentario:</p>`,
-        input: "textarea",
+        html: `<div>Notificar a:</div>${this.generated_inputs_next}`,
+        confirmButtonText: "Aprobar propuesta",
         showCancelButton: true,
-        confirmButtonText: "Siguiente",
         cancelButtonText: "Cancelar",
         showLoaderOnConfirm: true,
-        inputValidator: value => {
-          if (!value) {
-            return "Debe ingresar un comentario";
-          }
-        },
 
-        preConfirm: comentario => {
-          this.reviewProposal = {
-            id_inversion: this.investmentProposalID,
-            step: "next",
-            comentario: comentario
-          };
-        },
-        allowOutsideClick: () => !Swal.isLoading()
-      }).then(result => {
-        if (result.value) {
-          Swal.fire({
-            title: `<h3>Aprobación de propuesta de inversión</h3>`,
-            icon: "info",
-            html: `<div>Notificar a:</div>${this.generated_inputs_next}`,
-            confirmButtonText: "Aprobar propuesta",
-            showCancelButton: true,
-            cancelButtonText: "Cancelar",
-            showLoaderOnConfirm: true,
-
-            preConfirm: () => {
-              let array = [];
-
-              for (let i = 0; i < this.userListNext.length; i++) {
-                let html_input: HTMLInputElement = document.getElementById(
-                  "next-" + this.userListNext[i]
-                ) as HTMLInputElement;
-                let html_value: string = html_input.value;
-                if (html_input.checked == true) {
-                  array.push(html_value);
-                }
-              }
+        preConfirm: () => {
+          let array = [];
 
-              this.reviewProposal["notificar"] = array.toString();
-
-              this.investmentService
-                .sendReviewProposalInvestment(this.reviewProposal)
-                .subscribe(
-                  success => {
-                    if (success) {
-                      Swal.fire({
-                        allowOutsideClick: false,
-                        icon: "success",
-                        showCancelButton: false,
-                        title: "Exito",
-                        confirmButtonText: "La propuesta ha sido aprobada"
-                      }).then(result => {
-                        Swal.close();
-                        window.location.href = "#/investment-proposals";
-                      });
-                    }
-                  },
-                  err => {
-                    Swal.fire({
-                      icon: "error",
-                      title: "Error al guardar",
-                      text: err.message
-                    });
-                  }
-                );
+          for (let i = 0; i < this.userListNext.length; i++) {
+            let html_input: HTMLInputElement = document.getElementById(
+              "next-" + this.userListNext[i]
+            ) as HTMLInputElement;
+            let html_value: string = html_input.value;
+            if (html_input.checked == true) {
+              array.push(html_value);
             }
-          });
+          }
+          this.reviewProposal["notificar"] = array.toString();
+        }
+      }).then(result1 => {
+        if (result1.dismiss) {
+          return false;
         }
+
+        Swal.fire({
+          allowOutsideClick: false,
+          title: "Espere por favor...",
+          icon: "info"
+        });
+        Swal.showLoading();
+
+        this.investmentService
+          .sendReviewProposalInvestment(this.reviewProposal)
+          .subscribe(
+            success => {
+              if (success) {
+                Swal.fire({
+                  allowOutsideClick: false,
+                  icon: "success",
+                  showCancelButton: false,
+                  title: "Exito",
+                  confirmButtonText: "La propuesta ha sido aprobada"
+                }).then(result => {
+                  Swal.close();
+                  window.location.href = "#/investment-proposals";
+                });
+              }
+            },
+            err => {
+              Swal.fire({
+                icon: "error",
+                title: "Error al guardar",
+                text: err.message
+              });
+            }
+          );
       });
-    })();
+    });
   }
 
   dismiss_proposal() {
     this.reviewProposal = undefined;
-    (async () => {
+
+    Swal.fire({
+      title: `<h3>Rechazar propuesta de inversión</h3>`,
+      icon: "info",
+      html: `<p style="text-align:left;">Comentario:</p>`,
+      input: "textarea",
+      showCancelButton: true,
+      confirmButtonColor: "#C82333",
+      confirmButtonText: "Siguiente",
+      cancelButtonText: "Cancelar",
+      showLoaderOnConfirm: true,
+
+      preConfirm: comentario => {
+        this.reviewProposal = {
+          id_inversion: this.investmentProposalID,
+          step: "previous",
+          comentario: comentario
+        };
+      },
+      allowOutsideClick: () => !Swal.isLoading()
+    }).then(result => {
+      if (result.dismiss) {
+        return false;
+      }
+
       Swal.fire({
-        title: `<h3>Aprobación de propuesta de inversión</h3>`,
+        title: `<h3>Rechazar propuesta de inversión</h3>`,
         icon: "info",
-        html: `<p style="text-align:left;">Comentario:</p>`,
-        input: "textarea",
+        html: `<div>Notificar a:</div>${this.generated_inputs_previous}`,
         showCancelButton: true,
         confirmButtonColor: "#C82333",
-        confirmButtonText: "Siguiente",
+        confirmButtonText: "Rechazar propuesta",
         cancelButtonText: "Cancelar",
         showLoaderOnConfirm: true,
-        inputValidator: value => {
-          if (!value) {
-            return "Debe ingresar un comentario";
-          }
-        },
 
-        preConfirm: comentario => {
-          this.reviewProposal = {
-            id_inversion: this.investmentProposalID,
-            step: "previous",
-            comentario: comentario
-          };
-        },
-        allowOutsideClick: () => !Swal.isLoading()
-      }).then(result => {
-        if (result.value) {
-          Swal.fire({
-            title: `<h3>Aprobación de propuesta de inversión</h3>`,
-            icon: "info",
-            html: `<div>Notificar a:</div>${this.generated_inputs_previous}`,
-            confirmButtonText: "Rechazar propuesta",
-            showCancelButton: true,
-            confirmButtonColor: "#C82333",
-            cancelButtonText: "Cancelar",
-            showLoaderOnConfirm: true,
-
-            preConfirm: () => {
-              let array = [];
-
-              for (let i = 0; i < this.userListPrevious.length; i++) {
-                let html_input: HTMLInputElement = document.getElementById(
-                  "previous-" + this.userListPrevious[i]
-                ) as HTMLInputElement;
-                let html_value: string = html_input.value;
-                if (html_input.checked == true) {
-                  array.push(html_value);
-                }
-              }
+        preConfirm: () => {
+          let array = [];
 
-              this.reviewProposal["notificar"] = array.toString();
-
-              this.investmentService
-                .sendReviewProposalInvestment(this.reviewProposal)
-                .subscribe(
-                  success => {
-                    if (success) {
-                      Swal.fire({
-                        allowOutsideClick: false,
-                        icon: "success",
-                        showCancelButton: false,
-                        title: "Exito",
-                        confirmButtonText: "La propuesta ha sido rechazada"
-                      }).then(result => {
-                        Swal.close();
-                        window.location.href = "#/investment-proposals";
-                      });
-                    }
-                  },
-                  err => {
-                    Swal.fire({
-                      icon: "error",
-                      title: "Error al guardar",
-                      text: err.message
-                    });
-                  }
-                );
+          for (let i = 0; i < this.userListPrevious.length; i++) {
+            let html_input: HTMLInputElement = document.getElementById(
+              "previous-" + this.userListPrevious[i]
+            ) as HTMLInputElement;
+            let html_value: string = html_input.value;
+            if (html_input.checked == true) {
+              array.push(html_value);
             }
-          });
+          }
+          this.reviewProposal["notificar"] = array.toString();
+        }
+      }).then(result1 => {
+        if (result1.dismiss) {
+          return false;
         }
+
+        Swal.fire({
+          allowOutsideClick: false,
+          title: "Espere por favor...",
+          icon: "info"
+        });
+        Swal.showLoading();
+
+        this.investmentService
+          .sendReviewProposalInvestment(this.reviewProposal)
+          .subscribe(
+            success => {
+              if (success) {
+                Swal.fire({
+                  allowOutsideClick: false,
+                  icon: "warning",
+                  showCancelButton: false,
+                  title: "Exito",
+                  confirmButtonText: "La propuesta ha sido rechazada"
+                }).then(result => {
+                  Swal.close();
+                  window.location.href = "#/investment-proposals";
+                });
+              }
+            },
+            err => {
+              Swal.fire({
+                icon: "error",
+                title: "Error al guardar",
+                text: err.message
+              });
+            }
+          );
       });
-    })();
+    });
   }
 }

+ 1 - 1
src/app/components/investment-proposals/general-info/general-info.component.ts

@@ -292,7 +292,7 @@ export class InvestmentProposalGeneralInfoComponent
     this.catalogService.getInstrumentTypes().subscribe(res => {
       res;
       this.instrumentTypes = [];
-
+      console.log(res);
       for (let property in res) {
         this.instrumentTypes.push({
           label: res[property]["nombre"],

+ 95 - 58
src/app/components/investment-proposals/investment-proposals.component.ts

@@ -108,7 +108,20 @@ export class InvestmentProposalsComponent implements OnInit {
 
         this.dataSource.data = this.listProposals;
         this.dataSource.paginator = this.paginator;
+        this.dataSource.sortingDataAccessor = (item, property) => {
+          switch (property) {
+            case "id_inversion_instrumento":
+              return item.id_inversion_instrumento.id_tipo_instrumento.nombre;
+            case "id_estado_inversion":
+              return item.id_estado_inversion.nombre;
+            case "id_empresa":
+              return item.id_empresa.nombre;
+            default:
+              return item[property];
+          }
+        };
         this.dataSource.sort = this.sort;
+
         Swal.close();
       },
       err => {
@@ -296,22 +309,19 @@ export class InvestmentProposalsComponent implements OnInit {
         showCancelButton: true,
         confirmButtonText: "Enviar propuesta",
         cancelButtonText: "Cancelar",
-        showLoaderOnConfirm: true,
-        inputValidator: value => {
-          if (!value) {
-            return "Debe ingresar un comentario";
-          }
-        },
-
+        allowEscapeKey: true,
         preConfirm: comentario => {
           this.reviewProposal = {
             id_inversion: investmentProposalID,
             step: "next",
             comentario: comentario
           };
-        },
-        allowOutsideClick: () => !Swal.isLoading()
+        }
       }).then(result => {
+        if (result.dismiss) {
+          return false;
+        }
+
         Swal.fire({
           title: `<h3>Enviar a revisión propuesta de inversión ${investmentCode}</h3>`,
           icon: "info",
@@ -320,6 +330,7 @@ export class InvestmentProposalsComponent implements OnInit {
           showCancelButton: true,
           cancelButtonText: "Cancelar",
           showLoaderOnConfirm: true,
+          allowEscapeKey: true,
 
           preConfirm: () => {
             let array = [];
@@ -335,35 +346,46 @@ export class InvestmentProposalsComponent implements OnInit {
             }
 
             this.reviewProposal["notificar"] = array.toString();
+          }
+        }).then(result1 => {
+          if (result1.dismiss) {
+            return false;
+          }
 
-            this.investmentsService
-              .sendReviewProposalInvestment(this.reviewProposal)
-              .subscribe(
-                success => {
-                  if (success) {
-                    Swal.fire({
-                      allowOutsideClick: false,
-                      icon: "success",
-                      showCancelButton: false,
-                      title: "Exito",
-                      confirmButtonText:
-                        "La propuesta ha sido enviada a revisión"
-                    }).then(result => {
-                      Swal.close();
-                      window.location.reload();
-                    });
-                  }
-                },
-                err => {
+          Swal.fire({
+            allowOutsideClick: false,
+            title: "Espere por favor...",
+            icon: "info"
+          });
+          Swal.showLoading();
+
+          this.investmentsService
+            .sendReviewProposalInvestment(this.reviewProposal)
+            .subscribe(
+              success => {
+                if (success) {
                   Swal.fire({
-                    icon: "error",
-                    title: "Error al guardar",
-                    text: err.message
+                    allowOutsideClick: false,
+                    icon: "success",
+                    showCancelButton: false,
+                    title: "Exito",
+                    confirmButtonText: "La propuesta ha sido enviada a revisión"
+                  }).then(result => {
+                    Swal.close();
+                    window.location.reload();
                   });
                 }
-              );
-          }
+              },
+              err => {
+                Swal.fire({
+                  icon: "error",
+                  title: "Error al guardar",
+                  text: err.message
+                });
+              }
+            );
         });
+
         //window.location.reload();
       });
     })();
@@ -393,11 +415,11 @@ export class InvestmentProposalsComponent implements OnInit {
         showCancelButton: true,
         confirmButtonText: "Siguiente",
         cancelButtonText: "Cancelar",
-        inputValidator: value => {
+        /*inputValidator: value => {
           if (!value) {
             return "Debe ingresar un comentario";
           }
-        },
+        },*/
         preConfirm: comentario => {
           this.reviewProposal = {
             id_inversion: investmentProposalID,
@@ -407,6 +429,9 @@ export class InvestmentProposalsComponent implements OnInit {
         },
         allowOutsideClick: () => !Swal.isLoading()
       }).then(result => {
+        if (result.dismiss) {
+          return false;
+        }
         Swal.fire({
           title: `<h3>Finalizar propuesta de inversión ${investmentCode}</h3>`,
           icon: "info",
@@ -430,34 +455,46 @@ export class InvestmentProposalsComponent implements OnInit {
             }
 
             this.reviewProposal["notificar"] = array.toString();
+          }
+        }).then(result1 => {
+          if (result1.dismiss) {
+            return false;
+          }
 
-            this.investmentsService
-              .sendReviewProposalInvestment(this.reviewProposal)
-              .subscribe(
-                success => {
-                  if (success) {
-                    Swal.fire({
-                      allowOutsideClick: false,
-                      icon: "success",
-                      showCancelButton: false,
-                      title: "Exito",
-                      confirmButtonText: "La propuesta ha sido finalizada"
-                    }).then(result => {
-                      Swal.close();
-                      window.location.reload();
-                    });
-                  }
-                },
-                err => {
+          Swal.fire({
+            allowOutsideClick: false,
+            title: "Espere por favor...",
+            icon: "info"
+          });
+          Swal.showLoading();
+
+          this.investmentsService
+            .sendReviewProposalInvestment(this.reviewProposal)
+            .subscribe(
+              success => {
+                if (success) {
                   Swal.fire({
-                    icon: "error",
-                    title: "Error al guardar",
-                    text: err.message
+                    allowOutsideClick: false,
+                    icon: "success",
+                    showCancelButton: false,
+                    title: "Exito",
+                    confirmButtonText: "La propuesta ha sido finalizada"
+                  }).then(result => {
+                    Swal.close();
+                    window.location.reload();
                   });
                 }
-              );
-          }
+              },
+              err => {
+                Swal.fire({
+                  icon: "error",
+                  title: "Error al guardar",
+                  text: err.message
+                });
+              }
+            );
         });
+
         //window.location.reload();
       });
     })();

+ 153 - 141
src/app/components/investment-proposals/payment-approval/payment-approval.component.ts

@@ -377,171 +377,183 @@ export class PaymentApprovalComponent implements OnInit {
 
   approve_proposal() {
     this.reviewProposal = undefined;
-    (async () => {
+
+    Swal.fire({
+      title: `<h3>Revisión de la información de pago de inversión</h3>`,
+      icon: "info",
+      html: `<p style="text-align:left;">Comentario:</p>`,
+      input: "textarea",
+      showCancelButton: true,
+      confirmButtonText: "Siguiente",
+      cancelButtonText: "Cancelar",
+      showLoaderOnConfirm: true,
+
+      preConfirm: comentario => {
+        this.reviewProposal = {
+          id_inversion: this.investmentProposalID,
+          step: "next",
+          comentario: comentario
+        };
+      },
+      allowOutsideClick: () => !Swal.isLoading()
+    }).then(result => {
+      if (result.dismiss) {
+        return false;
+      }
+
       Swal.fire({
-        title: `<h3>Revisión del pago de inversión</h3>`,
+        title: `<h3>Revisión de la información de pago de inversión</h3>`,
         icon: "info",
-        html: `<p style="text-align:left;">Comentario:</p>`,
-        input: "textarea",
+        html: `<div>Notificar a:</div>${this.generated_inputs_next}`,
+        confirmButtonText: "Aprobar pago",
         showCancelButton: true,
-        confirmButtonText: "Siguiente",
         cancelButtonText: "Cancelar",
         showLoaderOnConfirm: true,
-        inputValidator: value => {
-          if (!value) {
-            return "Debe ingresar un comentario";
-          }
-        },
 
-        preConfirm: comentario => {
-          this.reviewProposal = {
-            id_inversion: this.investmentProposalID,
-            step: "next",
-            comentario: comentario
-          };
-        },
-        allowOutsideClick: () => !Swal.isLoading()
-      }).then(result => {
-        if (result.value) {
-          Swal.fire({
-            title: `<h3>Revisión del pago de inversión</h3>`,
-            icon: "info",
-            html: `<div>Notificar a:</div>${this.generated_inputs_next}`,
-            confirmButtonText: "Aprobar propuesta",
-            showCancelButton: true,
-            cancelButtonText: "Cancelar",
-            showLoaderOnConfirm: true,
-
-            preConfirm: () => {
-              let array = [];
-
-              for (let i = 0; i < this.userListNext.length; i++) {
-                let html_input: HTMLInputElement = document.getElementById(
-                  "next-" + this.userListNext[i]
-                ) as HTMLInputElement;
-                let html_value: string = html_input.value;
-                if (html_input.checked == true) {
-                  array.push(html_value);
-                }
-              }
+        preConfirm: () => {
+          let array = [];
 
-              this.reviewProposal["notificar"] = array.toString();
-
-              this.investmentService
-                .sendReviewProposalInvestment(this.reviewProposal)
-                .subscribe(
-                  success => {
-                    if (success) {
-                      Swal.fire({
-                        allowOutsideClick: false,
-                        icon: "success",
-                        showCancelButton: false,
-                        title: "Exito",
-                        confirmButtonText: "La propuesta ha sido aprobada"
-                      }).then(result => {
-                        Swal.close();
-                        window.location.href = "#/investment-proposals";
-                      });
-                    }
-                  },
-                  err => {
-                    Swal.fire({
-                      icon: "error",
-                      title: "Error al guardar",
-                      text: err.message
-                    });
-                  }
-                );
+          for (let i = 0; i < this.userListNext.length; i++) {
+            let html_input: HTMLInputElement = document.getElementById(
+              "next-" + this.userListNext[i]
+            ) as HTMLInputElement;
+            let html_value: string = html_input.value;
+            if (html_input.checked == true) {
+              array.push(html_value);
             }
-          });
+          }
+          this.reviewProposal["notificar"] = array.toString();
+        }
+      }).then(result1 => {
+        if (result1.dismiss) {
+          return false;
         }
+
+        Swal.fire({
+          allowOutsideClick: false,
+          title: "Espere por favor...",
+          icon: "info"
+        });
+        Swal.showLoading();
+
+        this.investmentService
+          .sendReviewProposalInvestment(this.reviewProposal)
+          .subscribe(
+            success => {
+              if (success) {
+                Swal.fire({
+                  allowOutsideClick: false,
+                  icon: "success",
+                  showCancelButton: false,
+                  title: "Exito",
+                  confirmButtonText: "La información de pago ha sido aprobado"
+                }).then(result => {
+                  Swal.close();
+                  window.location.href = "#/investment-proposals";
+                });
+              }
+            },
+            err => {
+              Swal.fire({
+                icon: "error",
+                title: "Error al guardar",
+                text: err.message
+              });
+            }
+          );
       });
-    })();
+    });
   }
 
   dismiss_proposal() {
     this.reviewProposal = undefined;
-    (async () => {
+
+    Swal.fire({
+      title: `<h3>Rechazar información de pago</h3>`,
+      icon: "info",
+      html: `<p style="text-align:left;">Comentario:</p>`,
+      input: "textarea",
+      showCancelButton: true,
+      confirmButtonColor: "#C82333",
+      confirmButtonText: "Siguiente",
+      cancelButtonText: "Cancelar",
+      showLoaderOnConfirm: true,
+
+      preConfirm: comentario => {
+        this.reviewProposal = {
+          id_inversion: this.investmentProposalID,
+          step: "previous",
+          comentario: comentario
+        };
+      },
+      allowOutsideClick: () => !Swal.isLoading()
+    }).then(result => {
+      if (result.dismiss) {
+        return false;
+      }
+
       Swal.fire({
-        title: `<h3>Revisión propuesta de inversión</h3>`,
+        title: `<h3>Rechazar información de pago</h3>`,
         icon: "info",
-        html: `<p style="text-align:left;">Comentario:</p>`,
-        input: "textarea",
+        html: `<div>Notificar a:</div>${this.generated_inputs_previous}`,
         showCancelButton: true,
         confirmButtonColor: "#C82333",
-        confirmButtonText: "Siguiente",
+        confirmButtonText: "Rechazar pago",
         cancelButtonText: "Cancelar",
         showLoaderOnConfirm: true,
-        inputValidator: value => {
-          if (!value) {
-            return "Debe ingresar un comentario";
-          }
-        },
 
-        preConfirm: comentario => {
-          this.reviewProposal = {
-            id_inversion: this.investmentProposalID,
-            step: "previous",
-            comentario: comentario
-          };
-        },
-        allowOutsideClick: () => !Swal.isLoading()
-      }).then(result => {
-        if (result.value) {
-          Swal.fire({
-            title: `<h3>Revisión propuesta de inversión</h3>`,
-            icon: "info",
-            html: `<div>Notificar a:</div>${this.generated_inputs_previous}`,
-            confirmButtonText: "Rechazar propuesta",
-            showCancelButton: true,
-            confirmButtonColor: "#C82333",
-            cancelButtonText: "Cancelar",
-            showLoaderOnConfirm: true,
-
-            preConfirm: () => {
-              let array = [];
-
-              for (let i = 0; i < this.userListPrevious.length; i++) {
-                let html_input: HTMLInputElement = document.getElementById(
-                  "previous-" + this.userListPrevious[i]
-                ) as HTMLInputElement;
-                let html_value: string = html_input.value;
-                if (html_input.checked == true) {
-                  array.push(html_value);
-                }
-              }
+        preConfirm: () => {
+          let array = [];
 
-              this.reviewProposal["notificar"] = array.toString();
-
-              this.investmentService
-                .sendReviewProposalInvestment(this.reviewProposal)
-                .subscribe(
-                  success => {
-                    if (success) {
-                      Swal.fire({
-                        allowOutsideClick: false,
-                        icon: "success",
-                        showCancelButton: false,
-                        title: "Exito",
-                        confirmButtonText: "La propuesta ha sido rechazada"
-                      }).then(result => {
-                        Swal.close();
-                        window.location.href = "#/investment-proposals";
-                      });
-                    }
-                  },
-                  err => {
-                    Swal.fire({
-                      icon: "error",
-                      title: "Error al guardar",
-                      text: err.message
-                    });
-                  }
-                );
+          for (let i = 0; i < this.userListPrevious.length; i++) {
+            let html_input: HTMLInputElement = document.getElementById(
+              "previous-" + this.userListPrevious[i]
+            ) as HTMLInputElement;
+            let html_value: string = html_input.value;
+            if (html_input.checked == true) {
+              array.push(html_value);
             }
-          });
+          }
+          this.reviewProposal["notificar"] = array.toString();
+        }
+      }).then(result1 => {
+        if (result1.dismiss) {
+          return false;
         }
+
+        Swal.fire({
+          allowOutsideClick: false,
+          title: "Espere por favor...",
+          icon: "info"
+        });
+        Swal.showLoading();
+
+        this.investmentService
+          .sendReviewProposalInvestment(this.reviewProposal)
+          .subscribe(
+            success => {
+              if (success) {
+                Swal.fire({
+                  allowOutsideClick: false,
+                  icon: "warning",
+                  showCancelButton: false,
+                  title: "Exito",
+                  confirmButtonText: "La información de pago ha sido rechazada"
+                }).then(result => {
+                  Swal.close();
+                  window.location.href = "#/investment-proposals";
+                });
+              }
+            },
+            err => {
+              Swal.fire({
+                icon: "error",
+                title: "Error al guardar",
+                text: err.message
+              });
+            }
+          );
       });
-    })();
+    });
   }
 }

+ 102 - 87
src/app/components/investment-proposals/payment-info/payment-info.component.ts

@@ -235,11 +235,11 @@ export class PaymentInfoComponent implements OnInit {
         confirmButtonText: "Siguiente",
         cancelButtonText: "Cancelar",
         showLoaderOnConfirm: true,
-        inputValidator: value => {
-          if (!value) {
-            return "Debe ingresar un comentario";
-          }
-        },
+        //inputValidator: value => {
+        //  if (!value) {
+        //   return "Debe ingresar un comentario";
+        //}
+        //},
 
         preConfirm: comentario => {
           this.reviewProposal = {
@@ -250,96 +250,111 @@ export class PaymentInfoComponent implements OnInit {
         },
         allowOutsideClick: () => !Swal.isLoading()
       }).then(result => {
-        if (result.value) {
-          Swal.fire({
-            title: `<h3>Enviar información de pago</h3>`,
-            icon: "info",
-            html: `<div>Notificar a:</div>${this.generated_inputs_next}`,
-            confirmButtonText: "Enviar información",
-            showCancelButton: true,
-            cancelButtonText: "Cancelar",
-            showLoaderOnConfirm: true,
+        if (result.dismiss) {
+          Swal.close();
+        }
 
-            preConfirm: () => {
-              let array = [];
+        Swal.fire({
+          title: `<h3>Enviar información de pago</h3>`,
+          icon: "info",
+          html: `<div>Notificar a:</div>${this.generated_inputs_next}`,
+          confirmButtonText: "Enviar información",
+          showCancelButton: true,
+          cancelButtonText: "Cancelar",
+          showLoaderOnConfirm: true,
 
-              for (let i = 0; i < this.userListNext.length; i++) {
-                let html_input: HTMLInputElement = document.getElementById(
-                  "next-" + this.userListNext[i]
-                ) as HTMLInputElement;
-                let html_value: string = html_input.value;
-                if (html_input.checked == true) {
-                  array.push(html_value);
-                }
-              }
+          preConfirm: () => {
+            let array = [];
 
-              this.reviewProposal["notificar"] = array.toString();
-              this.paymentObject = {
-                monto: this.inversionAmount,
-                id_tipo_pago: +this.investmentProposalForm.value.tipo_pago,
-                id_cuenta_bancaria: +this.investmentProposalForm.value
-                  .cuenta_bancaria,
+            for (let i = 0; i < this.userListNext.length; i++) {
+              let html_input: HTMLInputElement = document.getElementById(
+                "next-" + this.userListNext[i]
+              ) as HTMLInputElement;
+              let html_value: string = html_input.value;
+              if (html_input.checked == true) {
+                array.push(html_value);
+              }
+            }
 
-                //fecha_pago: this.investmentProposalForm.value.fecha_pago.singleDate.formatted,
-                fecha_vencimiento: this.investmentProposalForm.value
-                  .fecha_vencimiento.singleDate.formatted,
-                id_inversion: +this.investmentProposalID
-              };
+            this.reviewProposal["notificar"] = array.toString();
+            this.paymentObject = {
+              monto: this.inversionAmount,
+              id_tipo_pago: +this.investmentProposalForm.value.tipo_pago,
+              id_cuenta_bancaria: +this.investmentProposalForm.value
+                .cuenta_bancaria,
 
-              if (+this.investmentProposalForm.value.tipo_pago == 2) {
-                this.paymentObject[
-                  "emitir_nombre"
-                ] = this.investmentProposalForm.value.emitir_nombre;
-              } else if (+this.investmentProposalForm.value.tipo_pago == 3) {
-                this.paymentObject["id_cuenta_bancaria_destino"] = +this
-                  .investmentProposalForm.value.cuenta_bancaria_destino;
-              }
+              //fecha_pago: this.investmentProposalForm.value.fecha_pago.singleDate.formatted,
+              fecha_vencimiento: this.investmentProposalForm.value
+                .fecha_vencimiento.singleDate.formatted,
+              id_inversion: +this.investmentProposalID
+            };
 
-              this.investmentsService
-                .sendPaymentInfoProposalInvestment(
-                  this.investmentProposalID,
-                  this.paymentObject
-                )
-                .subscribe(
-                  success => {
-                    this.investmentsService
-                      .sendProposalInvestmentToNextStep(this.reviewProposal)
-                      .subscribe(
-                        success => {
-                          if (success) {
-                            Swal.fire({
-                              allowOutsideClick: false,
-                              icon: "success",
-                              showCancelButton: false,
-                              title: "Exito",
-                              confirmButtonText:
-                                "La requisicion de pago ha sido generada"
-                            }).then(result => {
-                              Swal.close();
-                              window.location.href = "#/investment-proposals";
-                            });
-                          }
-                        },
-                        err => {
-                          Swal.fire({
-                            icon: "error",
-                            title: "Error al guardar",
-                            text: err.message
-                          });
-                        }
-                      );
-                  },
-                  err => {
-                    Swal.fire({
-                      icon: "error",
-                      title: "Error al guardar",
-                      text: err.message
-                    });
-                  }
-                );
+            if (+this.investmentProposalForm.value.tipo_pago == 2) {
+              this.paymentObject[
+                "emitir_nombre"
+              ] = this.investmentProposalForm.value.emitir_nombre;
+            } else if (+this.investmentProposalForm.value.tipo_pago == 3) {
+              this.paymentObject["id_cuenta_bancaria_destino"] = +this
+                .investmentProposalForm.value.cuenta_bancaria_destino;
             }
+          }
+        }).then(result1 => {
+          if (result1.dismiss) {
+            return false;
+          }
+
+          Swal.fire({
+            allowOutsideClick: false,
+            title: "Espere por favor...",
+            icon: "info"
           });
-        }
+          Swal.showLoading();
+
+          this.investmentsService
+            .sendPaymentInfoProposalInvestment(
+              this.investmentProposalID,
+              this.paymentObject
+            )
+            .subscribe(
+              success => {
+                this.investmentsService
+                  .sendProposalInvestmentToNextStep(this.reviewProposal)
+                  .subscribe(
+                    success => {
+                      if (success) {
+                        Swal.fire({
+                          allowOutsideClick: false,
+                          icon: "success",
+                          showCancelButton: false,
+                          title: "Exito",
+                          confirmButtonText:
+                            "La requisicion de pago ha sido generada"
+                        }).then(result => {
+                          Swal.close();
+                          window.location.href = "#/investment-proposals";
+                        });
+                      }
+                    },
+                    err => {
+                      Swal.fire({
+                        icon: "error",
+                        title: "Error al guardar",
+                        text: err.message
+                      });
+                    }
+                  );
+              },
+              err => {
+                Swal.fire({
+                  icon: "error",
+                  title: "Error al guardar",
+                  text: err.message
+                });
+              }
+            );
+        });
+
+        //window.location.reload();
       });
     })();
   }

+ 57 - 112
src/app/components/investment-proposals/payment-requirement/payment-requirement.component.ts

@@ -76,6 +76,7 @@ export class PaymentRequirementComponent implements OnInit {
   generated_inputs_next: string;
   cuenta_bancaria_destino: any;
   emitir_nombre: any;
+  formData: any;
 
   constructor(
     private http: HttpClient,
@@ -202,130 +203,74 @@ export class PaymentRequirementComponent implements OnInit {
               array.push(html_value);
             }
           }
-          const formData = new FormData();
-          formData.append("id_inversion", this.investmentProposalID);
-          formData.append("evidencia", this.fileData);
-          formData.append("step", "next");
-          formData.append("comentario", form.value.comentario);
-          formData.append("notificar", array.toString());
+          this.formData = new FormData();
+          this.formData.append("id_inversion", this.investmentProposalID);
+          this.formData.append("evidencia", this.fileData);
+          this.formData.append("step", "next");
+          this.formData.append("comentario", form.value.comentario);
+          this.formData.append("notificar", array.toString());
 
           this.paymentObject = {
             fecha_pago: form.value.fecha_pago.singleDate.formatted,
             id_inversion: this.investmentProposalID
             //comentario:
           };
+        }
+      }).then(result1 => {
+        if (result1.dismiss) {
+          return false;
+        }
+
+        Swal.fire({
+          allowOutsideClick: false,
+          title: "Espere por favor...",
+          icon: "info"
+        });
+        Swal.showLoading();
 
-          this.investmentsService
-            .updatePaymentInfoProposalInvestment(
-              this.investmentProposalID,
-              this.paymentObject
-            )
-            .subscribe(
-              success => {
-                this.investmentService
-                  .sendProposalInvestmentToNextStep(formData)
-                  .subscribe(
-                    success => {
-                      if (success) {
-                        Swal.fire({
-                          allowOutsideClick: false,
-                          icon: "success",
-                          showCancelButton: false,
-                          title: "Exito",
-                          confirmButtonText: "La propuesta ha sido liquidada"
-                        }).then(result => {
-                          Swal.close();
-                          window.location.href = "#/investment-proposals";
-                        });
-                      }
-                    },
-                    err => {
+        this.investmentsService
+          .updatePaymentInfoProposalInvestment(
+            this.investmentProposalID,
+            this.paymentObject
+          )
+          .subscribe(
+            success => {
+              this.investmentService
+                .sendProposalInvestmentToNextStep(this.formData)
+                .subscribe(
+                  success => {
+                    if (success) {
                       Swal.fire({
-                        icon: "error",
-                        title: "Error en el servidor",
-                        text: err.message
+                        allowOutsideClick: false,
+                        icon: "success",
+                        showCancelButton: false,
+                        title: "Exito",
+                        confirmButtonText: "La propuesta ha sido liquidada"
+                      }).then(result => {
+                        Swal.close();
+                        window.location.href = "#/investment-proposals";
                       });
                     }
-                  );
-              },
-              err => {
-                Swal.fire({
-                  icon: "error",
-                  title: "Error en el servidor",
-                  text: err.message
-                });
-              }
-            );
-        }
+                  },
+                  err => {
+                    Swal.fire({
+                      icon: "error",
+                      title: "Error en el servidor",
+                      text: err.message
+                    });
+                  }
+                );
+            },
+            err => {
+              Swal.fire({
+                icon: "error",
+                title: "Error en el servidor",
+                text: err.message
+              });
+            }
+          );
       });
     })();
-
-    /*
-    this.submitted = true;
-    if (!form.valid) {
-      return false;
-    }
-
-    this.paymentObject = {
-      fecha_pago: form.value.fecha_pago.singleDate.formatted,
-      id_inversion: this.investmentProposalID
-      //comentario:
-    };
-
-    Swal.fire({
-      allowOutsideClick: false,
-      icon: "info",
-      text: "Espere por favor..."
-    });
-    Swal.showLoading();
-
-    const formData = new FormData();
-    formData.append("id_inversion", this.investmentProposalID);
-    formData.append("evidencia", this.fileData);
-    formData.append("step", "next");
-    formData.append("comentario", form.value.comentario);
-
-    this.investmentsService
-      .updatePaymentInfoProposalInvestment(
-        this.investmentProposalID,
-        this.paymentObject
-      )
-      .subscribe(
-        success => {
-          this.investmentService
-            .sendProposalInvestmentToNextStep(formData)
-            .subscribe(
-              success => {
-                if (success) {
-                  Swal.fire({
-                    allowOutsideClick: false,
-                    icon: "success",
-                    showCancelButton: false,
-                    title: "Exito",
-                    confirmButtonText: "La propuesta ha sido liquidada"
-                  }).then(result => {
-                    Swal.close();
-                    window.location.href = "#/investment-proposals";
-                  });
-                }
-              },
-              err => {
-                Swal.fire({
-                  icon: "error",
-                  title: "Error en el servidor",
-                  text: err.message
-                });
-              }
-            );
-        },
-        err => {
-          Swal.fire({
-            icon: "error",
-            title: "Error en el servidor",
-            text: err.message
-          });
-        }
-      );*/
   }
 
   sendPaymentInfo(form: any) {}

+ 10 - 0
src/app/components/investment-proposals/proposal-detail/proposal-detail.component.html

@@ -33,6 +33,16 @@
                 Resumen de la propuesta
               </h4>
             </div>
+
+            <!--
+            <hr />
+            <div>
+              <app-investment-print
+                [investmentID]="investmentProposalID"
+              ></app-investment-print>
+            </div>
+            <hr />
+-->
             <div class="card-body">
               <div class="align-container">
                 <ul class="timeline timeline-simple">

+ 80 - 49
src/app/components/investment-proposals/result/result.component.ts

@@ -250,7 +250,9 @@ export class ResultComponent implements OnInit {
         this.inversion["codigo_instrumento"] == "EURB" ||
         this.inversion["codigo_instrumento"] == "CINV" ||
         this.inversion["codigo_instrumento"] == "FINV" ||
-        this.inversion["codigo_instrumento"] == "PBUR") &&
+        this.inversion["codigo_instrumento"] == "PBUR" ||
+        this.inversion["codigo_instrumento"] == "PPER" ||
+        this.inversion["codigo_instrumento"] == "PEMP") &&
       (this.instrument["proyecciones"] != undefined ||
         this.instrument["proyecciones"] != "")
     ) {
@@ -353,6 +355,10 @@ export class ResultComponent implements OnInit {
         },
         allowOutsideClick: () => !Swal.isLoading()
       }).then(result => {
+        if (result.dismiss) {
+          return false;
+        }
+
         Swal.fire({
           title: `<h3>Enviar a revisión propuesta de inversión</h3>`,
           icon: "info",
@@ -376,35 +382,46 @@ export class ResultComponent implements OnInit {
             }
 
             this.reviewProposal["notificar"] = array.toString();
+          }
+        }).then(result1 => {
+          if (result1.dismiss) {
+            return false;
+          }
+
+          Swal.fire({
+            allowOutsideClick: false,
+            title: "Espere por favor...",
+            icon: "info"
+          });
+          Swal.showLoading();
 
-            this.investmentService
-              .sendReviewProposalInvestment(this.reviewProposal)
-              .subscribe(
-                success => {
-                  if (success) {
-                    Swal.fire({
-                      allowOutsideClick: false,
-                      icon: "success",
-                      showCancelButton: false,
-                      title: "Exito",
-                      confirmButtonText:
-                        "La propuesta ha sido enviada a revisión"
-                    }).then(result => {
-                      Swal.close();
-                      window.location.reload();
-                    });
-                  }
-                },
-                err => {
+          this.investmentService
+            .sendReviewProposalInvestment(this.reviewProposal)
+            .subscribe(
+              success => {
+                if (success) {
                   Swal.fire({
-                    icon: "error",
-                    title: "Error al guardar",
-                    text: err.message
+                    allowOutsideClick: false,
+                    icon: "success",
+                    showCancelButton: false,
+                    title: "Exito",
+                    confirmButtonText: "La propuesta ha sido enviada a revisión"
+                  }).then(result => {
+                    Swal.close();
+                    window.location.reload();
                   });
                 }
-              );
-          }
+              },
+              err => {
+                Swal.fire({
+                  icon: "error",
+                  title: "Error al guardar",
+                  text: err.message
+                });
+              }
+            );
         });
+
         //window.location.reload();
       });
     })();
@@ -494,6 +511,9 @@ export class ResultComponent implements OnInit {
         },
         allowOutsideClick: () => !Swal.isLoading()
       }).then(result => {
+        if (result.dismiss) {
+          return false;
+        }
         Swal.fire({
           title: `<h3>Finalizar propuesta de inversión</h3>`,
           icon: "info",
@@ -517,39 +537,50 @@ export class ResultComponent implements OnInit {
             }
 
             this.reviewProposal["notificar"] = array.toString();
+          }
+        }).then(result1 => {
+          if (result1.dismiss) {
+            return false;
+          }
+
+          Swal.fire({
+            allowOutsideClick: false,
+            title: "Espere por favor...",
+            icon: "info"
+          });
+          Swal.showLoading();
 
-            this.investmentService
-              .sendReviewProposalInvestment(this.reviewProposal)
-              .subscribe(
-                success => {
-                  if (success) {
-                    Swal.fire({
-                      allowOutsideClick: false,
-                      icon: "success",
-                      showCancelButton: false,
-                      title: "Exito",
-                      confirmButtonText: "La propuesta ha sido finalizada"
-                    }).then(result => {
-                      Swal.close();
-                      window.location.reload();
-                    });
-                  }
-                },
-                err => {
+          this.investmentService
+            .sendReviewProposalInvestment(this.reviewProposal)
+            .subscribe(
+              success => {
+                if (success) {
                   Swal.fire({
-                    icon: "error",
-                    title: "Error al guardar",
-                    text: err.message
+                    allowOutsideClick: false,
+                    icon: "success",
+                    showCancelButton: false,
+                    title: "Exito",
+                    confirmButtonText: "La propuesta ha sido finalizada"
+                  }).then(result => {
+                    Swal.close();
+                    window.location.reload();
                   });
                 }
-              );
-          }
+              },
+              err => {
+                Swal.fire({
+                  icon: "error",
+                  title: "Error al guardar",
+                  text: err.message
+                });
+              }
+            );
         });
+
         //window.location.reload();
       });
     })();
   }
-
   // Verifica permisos para mostrar boton de edicion y/o envio a revision,
   // segun los permisos del usuario y el estado de la propuesta
   can_send_to_review(status: string) {

+ 153 - 141
src/app/components/investment-proposals/review/review.component.ts

@@ -352,171 +352,183 @@ export class InvestmentProposalReviewComponent implements OnInit {
 
   approve_proposal() {
     this.reviewProposal = undefined;
-    (async () => {
+
+    Swal.fire({
+      title: `<h3>Revisión de propuesta de inversión</h3>`,
+      icon: "info",
+      html: `<p style="text-align:left;">Comentario:</p>`,
+      input: "textarea",
+      showCancelButton: true,
+      confirmButtonText: "Siguiente",
+      cancelButtonText: "Cancelar",
+      showLoaderOnConfirm: true,
+
+      preConfirm: comentario => {
+        this.reviewProposal = {
+          id_inversion: this.investmentProposalID,
+          step: "next",
+          comentario: comentario
+        };
+      },
+      allowOutsideClick: () => !Swal.isLoading()
+    }).then(result => {
+      if (result.dismiss) {
+        return false;
+      }
+
       Swal.fire({
-        title: `<h3>Revisión propuesta de inversión</h3>`,
+        title: `<h3>Revisión de propuesta de inversión</h3>`,
         icon: "info",
-        html: `<p style="text-align:left;">Comentario:</p>`,
-        input: "textarea",
+        html: `<div>Notificar a:</div>${this.generated_inputs_next}`,
+        confirmButtonText: "Aprobar propuesta",
         showCancelButton: true,
-        confirmButtonText: "Siguiente",
         cancelButtonText: "Cancelar",
         showLoaderOnConfirm: true,
-        inputValidator: value => {
-          if (!value) {
-            return "Debe ingresar un comentario";
-          }
-        },
 
-        preConfirm: comentario => {
-          this.reviewProposal = {
-            id_inversion: this.investmentProposalID,
-            step: "next",
-            comentario: comentario
-          };
-        },
-        allowOutsideClick: () => !Swal.isLoading()
-      }).then(result => {
-        if (result.value) {
-          Swal.fire({
-            title: `<h3>Revisión propuesta de inversión</h3>`,
-            icon: "info",
-            html: `<div>Notificar a:</div>${this.generated_inputs_next}`,
-            confirmButtonText: "Aprobar propuesta",
-            showCancelButton: true,
-            cancelButtonText: "Cancelar",
-            showLoaderOnConfirm: true,
-
-            preConfirm: () => {
-              let array = [];
-
-              for (let i = 0; i < this.userListNext.length; i++) {
-                let html_input: HTMLInputElement = document.getElementById(
-                  "next-" + this.userListNext[i]
-                ) as HTMLInputElement;
-                let html_value: string = html_input.value;
-                if (html_input.checked == true) {
-                  array.push(html_value);
-                }
-              }
+        preConfirm: () => {
+          let array = [];
 
-              this.reviewProposal["notificar"] = array.toString();
-
-              this.investmentService
-                .sendReviewProposalInvestment(this.reviewProposal)
-                .subscribe(
-                  success => {
-                    if (success) {
-                      Swal.fire({
-                        allowOutsideClick: false,
-                        icon: "success",
-                        showCancelButton: false,
-                        title: "Exito",
-                        confirmButtonText: "La propuesta ha sido aprobada"
-                      }).then(result => {
-                        Swal.close();
-                        window.location.href = "#/investment-proposals";
-                      });
-                    }
-                  },
-                  err => {
-                    Swal.fire({
-                      icon: "error",
-                      title: "Error al guardar",
-                      text: err.message
-                    });
-                  }
-                );
+          for (let i = 0; i < this.userListNext.length; i++) {
+            let html_input: HTMLInputElement = document.getElementById(
+              "next-" + this.userListNext[i]
+            ) as HTMLInputElement;
+            let html_value: string = html_input.value;
+            if (html_input.checked == true) {
+              array.push(html_value);
             }
-          });
+          }
+          this.reviewProposal["notificar"] = array.toString();
+        }
+      }).then(result1 => {
+        if (result1.dismiss) {
+          return false;
         }
+
+        Swal.fire({
+          allowOutsideClick: false,
+          title: "Espere por favor...",
+          icon: "info"
+        });
+        Swal.showLoading();
+
+        this.investmentService
+          .sendReviewProposalInvestment(this.reviewProposal)
+          .subscribe(
+            success => {
+              if (success) {
+                Swal.fire({
+                  allowOutsideClick: false,
+                  icon: "success",
+                  showCancelButton: false,
+                  title: "Exito",
+                  confirmButtonText: "La propuesta ha sido aprobada"
+                }).then(result => {
+                  Swal.close();
+                  window.location.href = "#/investment-proposals";
+                });
+              }
+            },
+            err => {
+              Swal.fire({
+                icon: "error",
+                title: "Error al guardar",
+                text: err.message
+              });
+            }
+          );
       });
-    })();
+    });
   }
 
   dismiss_proposal() {
     this.reviewProposal = undefined;
-    (async () => {
+
+    Swal.fire({
+      title: `<h3>Revisión de propuesta de inversión</h3>`,
+      icon: "info",
+      html: `<p style="text-align:left;">Comentario:</p>`,
+      input: "textarea",
+      showCancelButton: true,
+      confirmButtonColor: "#C82333",
+      confirmButtonText: "Siguiente",
+      cancelButtonText: "Cancelar",
+      showLoaderOnConfirm: true,
+
+      preConfirm: comentario => {
+        this.reviewProposal = {
+          id_inversion: this.investmentProposalID,
+          step: "previous",
+          comentario: comentario
+        };
+      },
+      allowOutsideClick: () => !Swal.isLoading()
+    }).then(result => {
+      if (result.dismiss) {
+        return false;
+      }
+
       Swal.fire({
-        title: `<h3>Revisión propuesta de inversión</h3>`,
+        title: `<h3>Revisión de propuesta de inversión</h3>`,
         icon: "info",
-        html: `<p style="text-align:left;">Comentario:</p>`,
-        input: "textarea",
+        html: `<div>Notificar a:</div>${this.generated_inputs_previous}`,
         showCancelButton: true,
         confirmButtonColor: "#C82333",
-        confirmButtonText: "Siguiente",
+        confirmButtonText: "Rechazar propuesta",
         cancelButtonText: "Cancelar",
         showLoaderOnConfirm: true,
-        inputValidator: value => {
-          if (!value) {
-            return "Debe ingresar un comentario";
-          }
-        },
 
-        preConfirm: comentario => {
-          this.reviewProposal = {
-            id_inversion: this.investmentProposalID,
-            step: "previous",
-            comentario: comentario
-          };
-        },
-        allowOutsideClick: () => !Swal.isLoading()
-      }).then(result => {
-        if (result.value) {
-          Swal.fire({
-            title: `<h3>Revisión propuesta de inversión</h3>`,
-            icon: "info",
-            html: `<div>Notificar a:</div>${this.generated_inputs_previous}`,
-            confirmButtonText: "Rechazar propuesta",
-            showCancelButton: true,
-            confirmButtonColor: "#C82333",
-            cancelButtonText: "Cancelar",
-            showLoaderOnConfirm: true,
-
-            preConfirm: () => {
-              let array = [];
-
-              for (let i = 0; i < this.userListPrevious.length; i++) {
-                let html_input: HTMLInputElement = document.getElementById(
-                  "previous-" + this.userListPrevious[i]
-                ) as HTMLInputElement;
-                let html_value: string = html_input.value;
-                if (html_input.checked == true) {
-                  array.push(html_value);
-                }
-              }
+        preConfirm: () => {
+          let array = [];
 
-              this.reviewProposal["notificar"] = array.toString();
-
-              this.investmentService
-                .sendReviewProposalInvestment(this.reviewProposal)
-                .subscribe(
-                  success => {
-                    if (success) {
-                      Swal.fire({
-                        allowOutsideClick: false,
-                        icon: "success",
-                        showCancelButton: false,
-                        title: "Exito",
-                        confirmButtonText: "La propuesta ha sido rechazada"
-                      }).then(result => {
-                        Swal.close();
-                        window.location.href = "#/investment-proposals";
-                      });
-                    }
-                  },
-                  err => {
-                    Swal.fire({
-                      icon: "error",
-                      title: "Error al guardar",
-                      text: err.message
-                    });
-                  }
-                );
+          for (let i = 0; i < this.userListPrevious.length; i++) {
+            let html_input: HTMLInputElement = document.getElementById(
+              "previous-" + this.userListPrevious[i]
+            ) as HTMLInputElement;
+            let html_value: string = html_input.value;
+            if (html_input.checked == true) {
+              array.push(html_value);
             }
-          });
+          }
+          this.reviewProposal["notificar"] = array.toString();
+        }
+      }).then(result1 => {
+        if (result1.dismiss) {
+          return false;
         }
+
+        Swal.fire({
+          allowOutsideClick: false,
+          title: "Espere por favor...",
+          icon: "info"
+        });
+        Swal.showLoading();
+
+        this.investmentService
+          .sendReviewProposalInvestment(this.reviewProposal)
+          .subscribe(
+            success => {
+              if (success) {
+                Swal.fire({
+                  allowOutsideClick: false,
+                  icon: "warning",
+                  showCancelButton: false,
+                  title: "Exito",
+                  confirmButtonText: "La propuesta ha sido rechazada"
+                }).then(result => {
+                  Swal.close();
+                  window.location.href = "#/investment-proposals";
+                });
+              }
+            },
+            err => {
+              Swal.fire({
+                icon: "error",
+                title: "Error al guardar",
+                text: err.message
+              });
+            }
+          );
       });
-    })();
+    });
   }
 }

+ 12 - 0
src/app/components/investments/investments.component.ts

@@ -87,6 +87,18 @@ export class InvestmentsComponent implements OnInit {
 
         this.dataSource.data = this.listProposals;
         this.dataSource.paginator = this.paginator;
+        this.dataSource.sortingDataAccessor = (item, property) => {
+          switch (property) {
+            case "id_inversion_instrumento":
+              return item.id_inversion_instrumento.id_tipo_instrumento.nombre;
+            case "id_estado_inversion":
+              return item.id_estado_inversion.nombre;
+            case "id_empresa":
+              return item.id_empresa.nombre;
+            default:
+              return item[property];
+          }
+        };
         this.dataSource.sort = this.sort;
       },
       err => {

+ 6 - 0
src/app/components/plugins/investment-print/investment-print.html

@@ -0,0 +1,6 @@
+<button
+  (click)="generatePdf('download')"
+  class="btn btn-primary d-flex align-items-center justify-content-center"
+>
+  <i class="material-icons"> cloud_download </i><span>Download PDF</span>
+</button>

File diff suppressed because it is too large
+ 92 - 0
src/app/components/plugins/investment-print/investment-print.ts


+ 10 - 2
src/app/layouts/admin/admin.module.ts

@@ -77,6 +77,9 @@ import { SelectModule } from "ng-select";
 import { OPC } from "@app/components/instruments/opciones/opciones.component";
 import { FUTU } from "@app/components/instruments/futuros/futuros.component";
 import { FINVCostsComponent } from "@app/components/investments/costs/fondos/fondos.costs.component";
+import { InvestmentPrint } from "@app/components/plugins/investment-print/investment-print";
+import { PPER } from "@app/components/instruments/pper/pper.component";
+import { PEMP } from "@app/components/instruments/pemp/pemp.component";
 
 // This array defines which "componentId" maps to which lazy-loaded module.
 
@@ -145,6 +148,8 @@ import { FINVCostsComponent } from "@app/components/investments/costs/fondos/fon
     FINV,
     OPC,
     FUTU,
+    PPER,
+    PEMP,
     InstrumentDirective,
     PaymentInfoComponent,
     PaymentRequirementComponent,
@@ -156,7 +161,8 @@ import { FINVCostsComponent } from "@app/components/investments/costs/fondos/fon
     IncomesComponent,
     GeneralIncomeFormComponent,
     PaymentApprovalComponent,
-    UploadLiquidationComponent
+    UploadLiquidationComponent,
+    InvestmentPrint
   ],
   entryComponents: [
     LETE,
@@ -170,7 +176,9 @@ import { FINVCostsComponent } from "@app/components/investments/costs/fondos/fon
     CINV,
     FINV,
     OPC,
-    FUTU
+    FUTU,
+    PPER,
+    PEMP
   ]
 })
 export class AdminModule {}

+ 62 - 0
src/app/services/instrument-calculations.service.ts

@@ -325,6 +325,68 @@ export class InstrumentCalculations {
       );
   }
 
+  pempCalc(
+    codigo_instrumento: string,
+    info_inversion: {
+      id_tipo_base: number;
+      id_periodicidad: number;
+      id_formato_ingreso: number;
+    },
+    info_instrumento: {
+      monto_prestamo: number;
+      tasa_porcentaje: number;
+      iva_porcentaje: number;
+      comision_desembolso_porcentaje: number;
+      fecha_operacion: string;
+      fecha_vencimiento: string;
+    }
+  ): Observable<boolean> {
+    return this.http
+      .post<any>(`${environment.productionApiUrl}/autocomplete`, {
+        codigo_instrumento,
+        info_inversion,
+        info_instrumento
+      })
+      .pipe(
+        map(response => {
+          return response;
+        }),
+        catchError(this.errorHandl)
+      );
+  }
+
+  pperCalc(
+    codigo_instrumento: string,
+    info_inversion: {
+      id_tipo_base: number;
+      id_periodicidad: number;
+      id_formato_ingreso: number;
+    },
+    info_instrumento: {
+      monto_prestamo: number;
+      fecha_otorgamiento: string;
+      plazo_gracia: number;
+      tasa_porcentaje: number;
+      iva_porcentaje: number;
+      pago_seguro_dano: number;
+      pago_seguro_vivienda: number;
+      total_cuotas_mensuales: number;
+    }
+  ): Observable<boolean> {
+    return this.http
+      .post<any>(`${environment.productionApiUrl}/autocomplete`, {
+        codigo_instrumento,
+        info_inversion,
+        info_instrumento
+      })
+      .pipe(
+        map(response => {
+          return response;
+        }),
+        catchError(this.errorHandl)
+      );
+  }
+
   projectionCalc(id: string, proyecciones: any): Observable<boolean> {
     return this.http
       .put<any>(`${environment.productionApiUrl}/autocomplete/${id}`, {

+ 5 - 1
src/app/services/instruments.service.ts

@@ -14,6 +14,8 @@ import { TIT } from "@app/components/instruments/titulos/titulos.component";
 import { FINV } from "@app/components/instruments/fondos/fondos.component";
 import { OPC } from "@app/components/instruments/opciones/opciones.component";
 import { FUTU } from "@app/components/instruments/futuros/futuros.component";
+import { PPER } from "@app/components/instruments/pper/pper.component";
+import { PEMP } from "@app/components/instruments/pemp/pemp.component";
 
 @Injectable({
   providedIn: "root"
@@ -40,7 +42,9 @@ export class InstrumentsService {
       }),
       new Instrument(FINV, { key: "FINV", name: "Fondo de inversión" }),
       new Instrument(OPC, { key: "OPC", name: "Opciones" }),
-      new Instrument(FUTU, { key: "FINV", name: "Futuros" })
+      new Instrument(FUTU, { key: "FINV", name: "Futuros" }),
+      new Instrument(PPER, { key: "PPER", name: "Préstamos personales" }),
+      new Instrument(PEMP, { key: "PEMP", name: "Préstamos empresariales" })
     ];
   }
 }

+ 12 - 0
src/app/services/pdfmake-script.service.spec.ts

@@ -0,0 +1,12 @@
+import { TestBed } from '@angular/core/testing';
+
+import { PdfmakeScriptService } from './pdfmake-script.service';
+
+describe('PdfmakeScriptService', () => {
+  beforeEach(() => TestBed.configureTestingModule({}));
+
+  it('should be created', () => {
+    const service: PdfmakeScriptService = TestBed.get(PdfmakeScriptService);
+    expect(service).toBeTruthy();
+  });
+});

+ 60 - 0
src/app/services/pdfmake-script.service.ts

@@ -0,0 +1,60 @@
+import { Injectable } from "@angular/core";
+
+interface Scripts {
+  name: string;
+  src: string;
+}
+export const ScriptStore: Scripts[] = [
+  {
+    name: "pdfMake",
+    src: "https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.59/pdfmake.min.js"
+  },
+  {
+    name: "vfsFonts",
+    src: "https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.59/vfs_fonts.js"
+  }
+];
+
+@Injectable({
+  providedIn: "root"
+})
+export class PdfmakeScriptService {
+  private scripts: any = {};
+
+  constructor() {
+    ScriptStore.forEach((script: any) => {
+      this.scripts[script.name] = {
+        loaded: false,
+        src: script.src
+      };
+    });
+  }
+
+  load(...scripts: string[]) {
+    const promises: any[] = [];
+    scripts.forEach(script => promises.push(this.loadScript(script)));
+    return Promise.all(promises);
+  }
+
+  loadScript(name: string) {
+    return new Promise((resolve, reject) => {
+      // resolve if already loaded
+      if (this.scripts[name].loaded) {
+        resolve({ script: name, loaded: true, status: "Already Loaded" });
+      } else {
+        // load script
+        const script = document.createElement("script");
+        script.type = "text/javascript";
+        script.src = this.scripts[name].src;
+        script.onload = () => {
+          this.scripts[name].loaded = true;
+          console.log(`${name} Loaded.`);
+          resolve({ script: name, loaded: true, status: "Loaded" });
+        };
+        script.onerror = (error: any) =>
+          resolve({ script: name, loaded: false, status: "Loaded" });
+        document.getElementsByTagName("head")[0].appendChild(script);
+      }
+    });
+  }
+}

+ 17 - 1
src/styles.scss

@@ -201,7 +201,7 @@ textarea.form-control {
 .instrument-calcs,
 .instrument-calcs-summary {
   border: 1px solid #999;
-  padding: 10px;
+  padding: 15px;
   border-radius: 5px;
 
   h4 {
@@ -217,6 +217,12 @@ textarea.form-control {
   }
 }
 
+td.mat-cell,
+td.mat-footer-cell,
+th.mat-header-cell {
+  padding-right: 15px !important;
+}
+
 .badge-custom {
   font-size: 100%;
   padding: 0.5em 0.7em;
@@ -240,6 +246,16 @@ textarea.form-control {
   }
 }
 
+.custom-table-container {
+  position: relative;
+  overflow: scroll;
+  padding: 15px;
+
+  table {
+    background: none;
+  }
+}
+
 .costs-input-small-container,
 .costs-input-normal-container {
   max-width: 100%;

Some files were not shown because too many files changed in this diff