Files
sistema_base/apps/web/feactures/training/schemas/training.ts

178 lines
6.3 KiB
TypeScript

import { z } from 'zod';
// 1. Definimos el esquema de un item individual de la lista de productos
// Basado en los campos que usaste en ProductActivityList
const productItemSchema = z.object({
productName: z.string(),
description: z.string().optional(),
dailyCount: z.coerce.string().or(z.number()).optional(), // Aceptamos string o number por los inputs
weeklyCount: z.coerce.string().or(z.number()).optional(),
monthlyCount: z.coerce.string().or(z.number()).optional(),
// Distribución Interna
internalDistributionZone: z.string().optional(),
// Distribución Externa
externalCountry: z.string().optional(),
externalState: z.number().optional(),
externalMunicipality: z.number().optional(),
externalParish: z.number().optional(),
externalCity: z.string().optional(),
externalDescription: z.string().optional(),
externalQuantity: z.coerce.string().or(z.number()).optional(),
// Mano de obra
womenCount: z.coerce.string().or(z.number()).optional(),
menCount: z.coerce.string().or(z.number()).optional(),
});
const productionItemSchema = z.object({
rawMaterial: z.string(),
supplyType: z.string().optional(),
quantity: z.coerce.string().or(z.number()).optional(), // Aceptamos string o number por los inputs
});
const equipmentItemSchema = z.object({
machine: z.string(),
quantity: z.coerce.string().or(z.number()).optional(), // Aceptamos string o number por los inputs
});
export const trainingSchema = z.object({
//Datos de la visita
id: z.number().optional(),
firstname: z.string().min(1, { message: 'Nombre es requerido' }),
lastname: z.string().min(1, { message: 'Apellido es requerido' }),
coorPhone: z.string().optional().nullable(),
visitDate: z
.string()
.min(1, { message: 'Fecha y hora de visita es requerida' }),
//Datos de la organización socioproductiva (OSP)
ospType: z.string().min(1, { message: 'Tipo de OSP es requerido' }),
ecoSector: z.string().optional().or(z.literal('')),
productiveSector: z.string().optional().or(z.literal('')),
centralProductiveActivity: z.string().optional().or(z.literal('')),
mainProductiveActivity: z.string().optional().or(z.literal('')),
productiveActivity: z
.string()
.min(1, { message: 'Actividad productiva es requerida' }),
ospRif: z.string().optional().or(z.literal('')),
ospName: z.string().optional().or(z.literal('')),
companyConstitutionYear: z.coerce
.number()
.min(1900, { message: 'Año inválido' }),
currentStatus: z
.string()
.min(1, { message: 'Estatus actual es requerido' })
.default('ACTIVA'),
infrastructureMt2: z.string().optional().or(z.literal('')),
hasTransport: z
.preprocess((val) => val === 'true' || val === true, z.boolean())
.optional(),
structureType: z.string().optional().or(z.literal('')),
isOpenSpace: z
.preprocess((val) => val === 'true' || val === true, z.boolean())
.optional(),
paralysisReason: z.string().optional().default(''),
//Datos del Equipamiento
equipmentList: z.array(equipmentItemSchema).optional().default([]),
//Datos de Producción
productionList: z.array(productionItemSchema).optional().default([]),
// Datos de Actividad Productiva
productList: z.array(productItemSchema).optional().default([]),
//Detalles de la ubicación
ospAddress: z
.string()
.min(1, { message: 'Dirección de la OSP es requerida' }),
ospGoogleMapsLink: z.string().optional().or(z.literal('')),
communeName: z.string().optional().or(z.literal('')),
siturCodeCommune: z.string().optional().or(z.literal('')),
communeRif: z.string().optional().or(z.literal('')),
communeSpokespersonName: z.string().optional().or(z.literal('')),
communeSpokespersonPhone: z.string().optional().or(z.literal('')),
communeEmail: z
.string()
.email({ message: 'Correo electrónico de la Comuna inválido' })
.optional()
.or(z.literal('')),
communalCouncil: z
.string()
.min(1, { message: 'Consejo Comunal es requerido' }),
siturCodeCommunalCouncil: z.string().optional().or(z.literal('')),
communalCouncilRif: z.string().optional().or(z.literal('')),
communalCouncilSpokespersonName: z.string().optional().or(z.literal('')),
communalCouncilSpokespersonPhone: z.string().optional().or(z.literal('')),
communalCouncilEmail: z
.string()
.email({ message: 'Correo electrónico del Consejo Comunal inválido' })
.optional()
.or(z.literal('')),
//Datos del Responsable OSP
ospResponsibleCedula: z
.string()
.min(1, { message: 'Cédula del responsable es requerida' }),
ospResponsibleFullname: z
.string()
.min(1, { message: 'Nombre del responsable es requerido' }),
ospResponsibleRif: z
.string()
.min(1, { message: 'RIF del responsable es requerido' }),
civilState: z.string().min(1, { message: 'Estado civil es requerido' }),
ospResponsiblePhone: z
.string()
.min(1, { message: 'Teléfono del responsable es requerido' }),
ospResponsibleEmail: z
.string()
.email({ message: 'Correo electrónico inválido' }),
familyBurden: z.coerce
.number()
.min(0, { message: 'Carga familiar requerida' }),
numberOfChildren: z.coerce
.number()
.min(0, { message: 'Número de hijos requerido' }),
//Datos adicionales
generalObservations: z.string().optional().default(''),
//IMAGENES
files: z.any().optional(),
//no se envia la backend al crear ni editar el formulario
state: z.number().optional().nullable(),
municipality: z.number().optional().nullable(),
parish: z.number().optional().nullable(),
coorState: z.number().optional().nullable(),
coorMunicipality: z.number().optional().nullable(),
coorParish: z.number().optional().nullable(),
photo1: z.string().optional().nullable(),
photo2: z.string().optional().nullable(),
photo3: z.string().optional().nullable(),
});
export type TrainingSchema = z.infer<typeof trainingSchema>;
export const trainingApiResponseSchema = z.object({
message: z.string(),
data: z.array(trainingSchema),
meta: z.object({
page: z.number(),
limit: z.number(),
totalCount: z.number(),
totalPages: z.number(),
hasNextPage: z.boolean(),
hasPreviousPage: z.boolean(),
nextPage: z.number().nullable(),
previousPage: z.number().nullable(),
}),
});
export const TrainingMutate = z.object({
message: z.string(),
data: trainingSchema,
});