Untitled

mail@pastecode.io avatar
unknown
plain_text
a year ago
5.1 kB
6
Indexable
Never
import { DateTime } from "luxon";
import { IsDateString, IsNotEmpty, IsNumber, IsOptional } from "class-validator";
import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger";
import { CustomValidate, FORMAT_DATES, InputBaseDto, IsValidDRDoc } from "../../common";
import { DocumentType, Encf } from "../../domain";

export class InvoiceManualInputDto extends InputBaseDto {
  /**
   * Documento del cliente cedula/rnc
   */
  @ApiProperty({ description: "Documento del cliente cédula/rnc", example: '00114905656' })
  @IsNotEmpty({ message: "Documento del cliente es requerído" })
  @IsValidDRDoc("docIdType")
  docId!: string;

  @ApiProperty({ description: "Tipo de documento del cliente", example: "cedula", default: "cedula", enum: ["cedula", "rnc"] })
  @IsNotEmpty({ message: "Tipo de documento del cliente es requerído" })
  docIdType!: DocumentType;

  /**
   * Fecha del encf
  */
  @ApiProperty({ description: "Fecha del encf", example: DateTime.local().toISODate() })
  @IsNotEmpty({ message: "Fecha del encf es requerído" })
  @IsDateString({}, { message: `Fecha del encf debe tener el formato ${FORMAT_DATES.ISO}` })
  @CustomValidate((value) => {
    const input = DateTime.fromISO(value)
    if (input.isValid == false) return false;

    const now = DateTime.local();
    // se compara si la fecha de comprobante esta en el mismo año y menor igual que el mes en curso
    return now.year == input.year && input.month <= now.month;
  }, {
    message(valArgs) {
      const input = DateTime.fromFormat(valArgs.value, FORMAT_DATES.ISO);
      if (input.isValid == false) return `Fecha del encf debe tener el formato ${FORMAT_DATES.ISO}`;

      const now = DateTime.local({ locale: 'es' });
      return `Fecha del encf debe estar en el período actual (${now.year}${now.toFormat('MM')})`
    },
  })
  issuanceDate: string = DateTime.local().toFormat(`${FORMAT_DATES.ISO}`);
  /**
   * Fecha de retención
  */
  @ApiPropertyOptional({ description: "Fecha de retención", example: DateTime.local().toISODate() })
  @IsOptional()
  @IsDateString({}, { message: `Fecha de retención debe tener el formato ${FORMAT_DATES.ISO}` })
  @CustomValidate((value, obj: InvoiceManualInputDto) => {
    if (value == undefined) return true;

    const input = DateTime.fromISO(value)
    if (input.isValid == false) return false;

    // fecha del comprobante
    const encfDate = DateTime.fromISO(obj.issuanceDate);

    // comparación del año y mes de la fecha de comprobante contra la fecha de retención
    return encfDate.year == input.year && input.month == encfDate.month;
  }, {
    message(valArgs) {
      const encfDate = DateTime.fromISO((valArgs.object as InvoiceManualInputDto).issuanceDate, { locale: 'es' });
      return `Fecha de retención debe estar comprendida en el periodo de (${encfDate.year}${encfDate.toFormat('MM')})`
    },
  })
  retentionDate?: string;
  /**
   * Tipo de documento
  */
  @ApiProperty({ description: "Tipo de documento", type: Number, example: 1 })
  @IsNotEmpty({ message: "Tipo de documento es requerído" })
  @IsNumber()
  typeTaxReceiptId: number;
  /**
   * Id de la sucursal
  */
  @ApiProperty({ description: "Id de la sucursal", type: Number, example: 1 })
  @IsNotEmpty({ message: "Id de sucursal es requerído" })
  @IsNumber()
  branchId: number;
  /**
   * Tipo de ingreso
  */
  @ApiProperty({ description: "Tipo de ingreso", type: Number, example: 1 })
  @IsNotEmpty({ message: "Tipo de ingreso es requerído" })
  @IsNumber()
  typesOfIncomeId: number;
  /**
   * Valor de comprobante
  */
  @ApiProperty({ description: "Valor de documento", type: Number, example: 10000 })
  @IsNotEmpty({ message: "Valor de documento es requerído" })
  @IsNumber()
  totalAmmount: number;
  /**
   * ITBIS retenido
  */
  @ApiPropertyOptional({ description: "ITBIS retenido", type: Number, example: 500 })
  @IsOptional()
  @IsNumber()
  @CustomValidate((_, obj: InvoiceManualInputDto) => {
    return obj.retentionDate != undefined;
  }, {
    message: "ITBIS retenido tiene valor por tanto fecha de retención es requerida"
  })
  retainedVAT?: number;
  /**
   * ITBIS facturado
  */
  @ApiProperty({ description: "ITBIS facturado", type: Number, example: 1000 })
  @IsNotEmpty({ message: "ITBIS facturado es requerído" })
  @IsNumber()
  chargedVAT: number;
  /**
   * Concepto
  */
  @ApiProperty({ description: "Concepto", example: "prueba" })
  @IsNotEmpty({ message: "Concepto es requerído" })
  concept!: string;
  /**
   * Nota
  */
  @ApiPropertyOptional({ description: "Nota" })
  @IsOptional()
  note?: string;

  /**
   * Extrae la data que pertenece al encf
   */
  getEncfData() {
    const { docId, docIdType, chargedVAT, retainedVAT, totalAmmount, issuanceDate, retentionDate } = this;
    return {
      docId,
      docIdType,
      chargedVAT,
      retainedVAT,
      totalAmmount,
      issuanceDate,
      retentionDate
    } as Encf;
  }
}