import { TspProviderCustomerType } from '@/common/enums/enums' import { SharedCreateSalesInvoiceItemDto, SharedCreateSalesInvoicePaymentsDto, } from '@/common/services/saleInvoices/sale-invoice-create.dto' import { CustomerType, InvoiceTemplateType, PaymentMethodType, TspProviderRequestType, TspProviderResponseStatus, TspProviderType, } from '@/generated/prisma/enums' import { ApiProperty } from '@nestjs/swagger' import { Type } from 'class-transformer' import { ArrayMinSize, IsArray, IsBoolean, IsDateString, IsEnum, IsNumber, IsObject, IsOptional, IsString, Min, ValidateNested, } from 'class-validator' export class CustomerLegalInfoDto { @ApiProperty({ required: true }) @IsString() name: string @ApiProperty({ required: true }) @IsString() economic_code: string } export class CustomerIndividualInfoDto { @ApiProperty({ required: true }) @IsString() first_name: string @ApiProperty({ required: true }) @IsString() last_name: string @ApiProperty({ required: true }) @IsString() national_id: string @ApiProperty({ required: true }) @IsString() mobile_number: string } export class CustomerInfoDto { @ApiProperty({ required: true, enum: CustomerType }) @IsEnum(CustomerType) type: CustomerType @ApiProperty({}) @Type(() => CustomerLegalInfoDto) @ValidateNested({ each: true }) legal_info?: CustomerLegalInfoDto @ApiProperty({}) @Type(() => CustomerIndividualInfoDto) @ValidateNested({ each: true }) individual_info?: CustomerIndividualInfoDto } export class PaymentInfoDto { @ApiProperty({ required: true, enum: PaymentMethodType }) @IsEnum(PaymentMethodType) payment_method: PaymentMethodType @ApiProperty({ required: true }) @IsNumber({ allowInfinity: false, allowNaN: false }) @Min(10_000) amount: number @ApiProperty({ required: false }) @IsOptional() @IsString() tracking_code?: string @ApiProperty({ required: false }) @IsOptional() @IsString() card_number?: string @ApiProperty({ required: false }) @IsOptional() @IsDateString() paid_at?: Date } export class TspProviderSendItemPayloadDto { @ApiProperty({ required: true }) @IsString() sku: string @ApiProperty({ required: true }) @IsString() sku_vat: string @ApiProperty() @IsOptional() @IsString() discount: string @ApiProperty({ required: true }) @IsNumber() unit_price: number @ApiProperty() @IsString() invoice_item_id: string @ApiProperty() @IsNumber() quantity: number @ApiProperty() @IsNumber() total_amount: number @ApiProperty({ required: true }) @IsString() measure_unit: string @ApiProperty({ required: false, nullable: true }) @IsOptional() @IsString() good_id?: string | null @ApiProperty({ required: false, nullable: true }) @IsOptional() @IsString() service_id?: string | null @ApiProperty({ required: false, nullable: true, type: Object }) @IsOptional() @IsObject() payload?: unknown } export class TspProviderOriginalSendPayloadDto { @ApiProperty({ required: true, enum: TspProviderRequestType }) @IsEnum(TspProviderRequestType) type: TspProviderRequestType @ApiProperty({ required: true, enum: TspProviderCustomerType }) @IsEnum(TspProviderCustomerType) customer_type: TspProviderCustomerType @ApiProperty({ type: [TspProviderSendItemPayloadDto] }) @IsArray() @ValidateNested({ each: true }) @Type(() => TspProviderSendItemPayloadDto) items: TspProviderSendItemPayloadDto[] @ApiProperty({ required: false }) @Type(() => CustomerInfoDto) @ValidateNested({ each: true }) customer?: CustomerInfoDto @ApiProperty({ required: true, nullable: true }) @IsNumber() invoice_number: number @ApiProperty({ required: true, nullable: true }) @IsDateString() invoice_date: Date @ApiProperty({ required: true, nullable: true }) @IsString() invoice_id: string @ApiProperty() @IsNumber() total_amount: number @ApiProperty({ required: true, enum: TspProviderType }) @IsEnum(TspProviderType) tsp_provider: TspProviderType @ApiProperty({ required: true, nullable: true }) @IsString() economic_code: string @ApiProperty({ required: true, nullable: true }) @IsString() fiscal_id: string @ApiProperty({ required: true, type: [PaymentInfoDto] }) @IsArray() @ValidateNested({ each: true }) @Type(() => PaymentInfoDto) payments: PaymentInfoDto[] @ApiProperty({ required: true, enum: InvoiceTemplateType }) @IsEnum(InvoiceTemplateType) invoice_template: InvoiceTemplateType @ApiProperty({ required: true }) @IsString() tsp_token: string } export class TspProviderSendItemResultDto { @ApiProperty() @IsString() invoice_id: string @ApiProperty({ enum: TspProviderResponseStatus }) @IsEnum(TspProviderResponseStatus) status: TspProviderResponseStatus @ApiProperty({ required: false, nullable: true }) @IsOptional() @IsString() tax_id?: string | null @ApiProperty({ required: true, nullable: true, type: TspProviderOriginalSendPayloadDto, }) @IsOptional() @IsObject() request_payload: Object @ApiProperty({ required: false, nullable: true, type: Object }) @IsOptional() @IsObject() response_payload?: unknown @ApiProperty({ required: true }) @IsBoolean() hasError: boolean @ApiProperty({ required: false, nullable: true }) @IsOptional() @IsString() message?: string | null @ApiProperty({ required: true }) @IsDateString() sent_at: string @ApiProperty({ required: true }) @IsDateString() received_at: string } export class TspProviderBulkSendResultDto { @ApiProperty() @IsString() invoice_id: string @ApiProperty({ type: [TspProviderSendItemResultDto] }) @IsArray() @ValidateNested({ each: true }) @Type(() => TspProviderSendItemResultDto) items: TspProviderSendItemResultDto[] } ///////////// GET RELATED DTOs ///////////// export class TspProviderGetResultDto { @ApiProperty() @IsString() tax_id: string @ApiProperty({ enum: TspProviderResponseStatus }) @IsEnum(TspProviderResponseStatus) status: TspProviderResponseStatus @ApiProperty({ required: true }) @IsBoolean() hasError: boolean @ApiProperty({ required: false, nullable: true }) @IsOptional() @IsString() message?: string | null @ApiProperty({ required: false, nullable: true, type: Object }) @IsOptional() @IsObject() response_payload?: unknown @ApiProperty({ required: true }) @IsDateString() sent_at: string @ApiProperty({ required: true }) @IsDateString() received_at: string } ///////////// REVOKE RELATED DTOs ///////////// export class TspProviderRevokePayloadDto { @ApiProperty({ required: true, nullable: true }) @IsNumber() invoice_number: number @ApiProperty({ required: true, nullable: true }) @IsString() invoice_id: string @ApiProperty({ required: true, enum: TspProviderType }) @IsEnum(TspProviderType) tsp_provider: TspProviderType @ApiProperty({ required: true, nullable: true }) @IsString() economic_code: string @ApiProperty({ required: true, nullable: true }) @IsString() fiscal_id: string @ApiProperty({ required: true }) @IsString() tsp_token: string @ApiProperty({ required: true }) @IsString() last_tax_id: string } export class TspProviderRevokeResponseDto { @ApiProperty({ required: true, nullable: true }) @IsString() invoice_id: string @ApiProperty({ required: true }) @IsString() tax_id: string @ApiProperty({ enum: TspProviderResponseStatus }) @IsEnum(TspProviderResponseStatus) status: TspProviderResponseStatus @ApiProperty({ required: true }) @IsBoolean() hasError: boolean @ApiProperty({ required: false, nullable: true }) @IsOptional() @IsString() message?: string | null @ApiProperty({ required: false, nullable: true, type: Object }) @IsOptional() @IsObject() request_payload?: unknown @ApiProperty({ required: false, nullable: true, type: Object }) @IsOptional() @IsObject() response_payload?: unknown @ApiProperty({ required: true }) @IsDateString() sent_at: string @ApiProperty({ required: true }) @IsDateString() received_at: string } ///////////// CORRECTION RELATED DTOs ///////////// export class TspProviderCorrectionInvoicePayloadDto { @ApiProperty({ type: [SharedCreateSalesInvoiceItemDto] }) @IsArray() @ValidateNested({ each: true }) @Type(() => SharedCreateSalesInvoiceItemDto) @ArrayMinSize(1) items: SharedCreateSalesInvoiceItemDto[] @ApiProperty() @IsNumber() total_amount: number @ApiProperty({ required: true, type: SharedCreateSalesInvoicePaymentsDto }) @IsObject() @ValidateNested({ each: true }) @Type(() => SharedCreateSalesInvoicePaymentsDto) payments: SharedCreateSalesInvoicePaymentsDto } export class TspProviderCorrectionSendPayloadDto extends TspProviderOriginalSendPayloadDto { @ApiProperty({ required: true }) @IsString() last_tax_id: string } export class TspProviderCorrectionSendResponseDto {} export class TspProviderActionResponseDto { @IsObject() invoice: object @IsString() message: string @IsEnum(TspProviderResponseStatus) status: TspProviderResponseStatus } export interface IProviderSwitchAdapter { readonly code: string originalSend( payload: TspProviderOriginalSendPayloadDto, ): Promise sendBulk( payloads: TspProviderOriginalSendPayloadDto[], ): Promise correctionSend( payload: TspProviderCorrectionSendPayloadDto, ): Promise get(invoiceId: string, tsp_token: string): Promise revoke(payload: TspProviderRevokePayloadDto): Promise }