feat: Fase 2 — SENAE DSI, verificación bodega, fotos, notificaciones, auditoría, tarifas CRUD, páginas faltantes
API:
- PackagesService: verifyPackage (discrepancia >10%), addPhotos (multer disk), generateSenaeDeclaration (DSI stub)
- PATCH /packages/:id/verify — peso real + dimensiones + detección automática de discrepancia
- POST /packages/:id/photos — upload multipart fotos (hasta 10, 10 MB c/u)
- POST /packages/:id/senae/declare — genera DSI, N° autorización SENAE, cambia estado DECLARACION_ADUANERA
- GET /packages/pending-declaration — cola de paquetes VERIFICADO para agente aduanero
- AuditLogModule: GET /audit-logs con filtros (acción, recurso, fechas, paginación)
- NotificationsModule: notifyStatusChange → crea registros EMAIL/WHATSAPP/PUSH en DB (stub dispatch)
- TariffsModule: GET/PUT /tariffs — configuración de tarifas por tenant (pricePerLb, IVA, FODINFA…)
- ProductsModule: POST /products/scan — stub extracción de producto desde URL Amazon/eBay/Walmart
- StorageModule: saveFile/deleteFile con disco local (S3-ready)
- main.ts: NestExpressApplication + useStaticAssets('/uploads')
- Dirección bodega: de hardcoded a env vars (WAREHOUSE_ADDRESS_*)
Web:
- /bodega/verificacion — formulario real: peso real, dims, fotos, detección discrepancia, notificación
- /bodega/despacho — lista paquetes DECLARACION_ADUANERA → despacha a EN_TRANSITO_ECUADOR
- /bodega/declaraciones — cola SENAE: auto-detecta categoría 4×4, genera DSI por paquete
- /bodega/layout — agrega enlace Declaraciones SENAE, corrige ALLOWED roles
- /admin/tarifas — CRUD real: edita pricePerLb, IVA, FODINFA, límites 4×4; preview fórmulas
- /admin/auditoria — tabla paginada con filtros desde GET /audit-logs
- /portal/pre-alerta — tabs URL-scan / Manual, upload de factura, campos correctos
- /casillero/como-usar — timeline 9 pasos con dirección NJ y CTA
- /carga-pesada/como-funciona — flujo B2B 5 pasos, servicios incluidos
- /carga-pesada/inen — 6 categorías reguladas, callout de advertencia, proceso de asistencia
- api.ts: verify, uploadPhotos, senaeDeclare, pendingDeclaration, tariffs, auditLogs, products.scan
This commit is contained in:
@@ -1,50 +1,38 @@
|
||||
import { IsString, IsOptional, IsNumber, Min } from "class-validator";
|
||||
import { IsString, IsOptional, IsNumber, IsPositive, IsEnum, Min } from "class-validator";
|
||||
import { Type } from "class-transformer";
|
||||
|
||||
export class CreatePackageDto {
|
||||
@IsString()
|
||||
vendorTracking!: string;
|
||||
|
||||
@IsString()
|
||||
description!: string;
|
||||
|
||||
@IsString()
|
||||
store!: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsNumber()
|
||||
@Min(0)
|
||||
declaredValue?: number;
|
||||
|
||||
@IsOptional()
|
||||
@IsNumber()
|
||||
@Min(0)
|
||||
declaredWeightLb?: number;
|
||||
|
||||
@IsOptional()
|
||||
@IsNumber()
|
||||
@Min(0)
|
||||
lengthCm?: number;
|
||||
|
||||
@IsOptional()
|
||||
@IsNumber()
|
||||
@Min(0)
|
||||
widthCm?: number;
|
||||
|
||||
@IsOptional()
|
||||
@IsNumber()
|
||||
@Min(0)
|
||||
heightCm?: number;
|
||||
|
||||
/** userId del cliente al que pertenece este paquete */
|
||||
@IsString()
|
||||
userId!: string;
|
||||
@IsString() userId!: string;
|
||||
@IsString() description!: string;
|
||||
@IsOptional() @IsString() store?: string;
|
||||
@IsOptional() @IsString() vendorTracking?: string;
|
||||
@IsOptional() @IsString() productUrl?: string;
|
||||
@IsOptional() @Type(() => Number) @IsNumber() @Min(0) declaredValue?: number;
|
||||
@IsOptional() @Type(() => Number) @IsNumber() @IsPositive() declaredWeightLb?: number;
|
||||
@IsOptional() @Type(() => Number) @IsNumber() @IsPositive() lengthCm?: number;
|
||||
@IsOptional() @Type(() => Number) @IsNumber() @IsPositive() widthCm?: number;
|
||||
@IsOptional() @Type(() => Number) @IsNumber() @IsPositive() heightCm?: number;
|
||||
}
|
||||
|
||||
export class UpdateStatusDto {
|
||||
@IsString()
|
||||
status!: string;
|
||||
@IsEnum([
|
||||
"REGISTRADO","EN_TRANSITO_BODEGA","RECIBIDO_BODEGA","EN_VERIFICACION",
|
||||
"VERIFICADO","DECLARACION_ADUANERA","EN_TRANSITO_ECUADOR","EN_ADUANA_ECUADOR",
|
||||
"LISTO_ENTREGA","ENTREGADO","INCIDENCIA",
|
||||
]) status!: string;
|
||||
@IsOptional() @IsString() note?: string;
|
||||
}
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
note?: string;
|
||||
export class VerifyPackageDto {
|
||||
@Type(() => Number) @IsNumber() @IsPositive() actualWeightLb!: number;
|
||||
@IsOptional() @Type(() => Number) @IsNumber() @IsPositive() lengthCm?: number;
|
||||
@IsOptional() @Type(() => Number) @IsNumber() @IsPositive() widthCm?: number;
|
||||
@IsOptional() @Type(() => Number) @IsNumber() @IsPositive() heightCm?: number;
|
||||
@IsOptional() @IsString() note?: string;
|
||||
}
|
||||
|
||||
export class SenaeDeclarationDto {
|
||||
@IsEnum(["REGIMEN_4X4","CATEGORIA_B","CATEGORIA_C","CATEGORIA_D"])
|
||||
category!: string;
|
||||
@IsOptional() @IsString() agentNotes?: string;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user