2 Commits

10 changed files with 2177 additions and 31 deletions

View File

@@ -0,0 +1,2 @@
DROP VIEW "public"."v_training_surveys";--> statement-breakpoint
ALTER TABLE "training_surveys" ADD COLUMN "productive_activity_other" text DEFAULT '';

File diff suppressed because it is too large Load Diff

View File

@@ -183,6 +183,13 @@
"when": 1772643066120,
"tag": "0025_funny_makkari",
"breakpoints": true
},
{
"idx": 26,
"version": "7",
"when": 1774379641691,
"tag": "0026_last_vampiro",
"breakpoints": true
}
]
}

View File

@@ -76,6 +76,7 @@ export const trainingSurveys = t.pgTable(
.notNull()
.default(''),
productiveActivity: t.text('productive_activity').notNull(),
productiveActivityOther: t.text('productive_activity_other').default(''),
ospRif: t.text('osp_rif'),
ospName: t.text('osp_name'),
companyConstitutionYear: t.integer('company_constitution_year').notNull(),

View File

@@ -1,3 +1,4 @@
import { Optional } from '@nestjs/common';
import { ApiProperty } from '@nestjs/swagger';
import { Transform, Type } from 'class-transformer';
import {
@@ -42,6 +43,11 @@ export class CreateTrainingDto {
@IsString()
productiveActivity: string;
@ApiProperty()
@IsString()
@IsOptional()
productiveActivityOther: string;
@ApiProperty()
@IsString()
currentStatus: string;

View File

@@ -268,7 +268,7 @@ export class TrainingService {
// 2. Extraer solo visitDate para formatearlo.
// Ya NO extraemos state, municipality, etc. porque no vienen en el DTO.
const { visitDate, state, municipality, parish, ...rest } =
const { visitDate, state, municipality, parish, productiveActivityOther, ...rest } =
createTrainingDto;
const [newRecord] = await this.drizzle
@@ -280,6 +280,9 @@ export class TrainingService {
// Conversión de fecha
visitDate: new Date(visitDate),
// Borra las tildes y cambia el texto a mayusculas
productiveActivityOther: productiveActivityOther.toUpperCase().normalize("NFD").replace(/[\u0300-\u036f]/g, ""),
// 3. Asignar fotos de forma segura
photo1: photoPaths[0] ?? null,
photo2: photoPaths[1] ?? null,

View File

@@ -107,6 +107,7 @@ export function CreateTrainingForm({
coorPhone: defaultValues?.coorPhone || '',
visitDate: formatToLocalISO(defaultValues?.visitDate),
productiveActivity: defaultValues?.productiveActivity || undefined,
productiveActivityOther: defaultValues?.productiveActivityOther || undefined,
ecoSector: defaultValues?.ecoSector || undefined,
productiveSector: defaultValues?.productiveSector || undefined,
centralProductiveActivity:
@@ -202,6 +203,11 @@ export function CreateTrainingForm({
name: 'mainProductiveActivity',
});
const productiveActivity = useWatch({
control: form.control,
name: 'productiveActivity',
});
const productiveSectorOptions = ecoSector
? SECTOR_PRODUCTIVO_MAP[ecoSector] || []
: [];
@@ -215,6 +221,8 @@ export function CreateTrainingForm({
? ACTIVIDAD_PRODUCTIVA_MAP[mainProductiveActivity] || []
: [];
const other = productiveActivity == 'OTRO' ? true : false;
// Reset dependent fields when parent changes
React.useEffect(() => {
// This effect handles shifts in options, but react-hook-form values persist
@@ -225,6 +233,7 @@ export function CreateTrainingForm({
productiveSector,
centralProductiveActivity,
mainProductiveActivity,
productiveActivity
]);
const stateOptions = dataState?.data || [{ id: 0, name: 'Sin estados' }];
@@ -249,15 +258,6 @@ export function CreateTrainingForm({
setMunicipality(Number(defaultValues.municipality));
setDisabledParish(false);
}
// if (defaultValues.coorState) {
// setcoorState(Number(defaultValues.coorState));
// setDisabledCoorMunicipality(false);
// }
// if (defaultValues.coorMunicipality) {
// setcoorMunicipality(Number(defaultValues.coorMunicipality));
// setDisabledCoorParish(false);
// }
}
}, [defaultValues]);
@@ -292,16 +292,6 @@ export function CreateTrainingForm({
}
});
// 2. Mapeo manual y conversión a numérico
// if (formData.state) {
// data.append('state', Number(formData.state).toString());
// }
// if (formData.municipality) {
// data.append('municipality', Number(formData.municipality).toString());
// }
// if (formData.parish) {
// data.append('parish', Number(formData.parish).toString());
// }
if (defaultValues?.id) {
data.append('id', defaultValues.id.toString());
}
@@ -693,6 +683,27 @@ export function CreateTrainingForm({
)}
/>
{other && (<FormField
control={form.control}
name="productiveActivityOther"
render={({ field }) => (
<FormItem className="w-full flex flex-col space-y-3">
<FormLabel className="whitespace-normal leading-tight font-semibold">
¿Cuál otra Actividad Productiva?
</FormLabel>
<FormControl>
<Input
{...field}
value={field.value ?? ''}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>)}
<FormField
control={form.control}
name="ospRif"

View File

@@ -101,6 +101,9 @@ export function TrainingViewModal({
</Badge>
);
// console.log(data);
return (
<>
<Dialog open={isOpen} onOpenChange={onClose}>
@@ -158,12 +161,17 @@ export function TrainingViewModal({
label="Actividad Principal"
value={data.mainProductiveActivity}
/>
<div className="col-span-full">
{/* <div className="sm-col-span-full"> */}
<DetailItem
label="Actividad Específica"
value={data.productiveActivity}
/>
</div>
{data.productiveActivity == 'OTRO' && (<DetailItem
label="Otra Actividad Específica"
value={data.productiveActivityOther}
/>)}
{/* </div> */}
</Section>
{/* 3. Infraestructura y Ubicación */}

View File

@@ -107,6 +107,7 @@ export const ACTIVIDAD_PRODUCTIVA_MAP: Record<string, string[]> = {
'SIEMBRA DE ARROZ',
'SIEMBRA DE CEREALES (CEBADA, LINAZA, SOYA)',
'ELABORACION DE BIO-INSUMO (ABONO ORGANICO)',
'OTRO'
],
[ACTIVIDAD_PRINCIPAL.CRIA]: [
'BOVINO',
@@ -115,8 +116,9 @@ export const ACTIVIDAD_PRODUCTIVA_MAP: Record<string, string[]> = {
'CUNICULTURA',
'AVICOLA',
'PISCICULA',
'OTRO'
],
[ACTIVIDAD_PRINCIPAL.PATIOS_PRODUCTIVOS]: ['SIEMBRA Y CRIA'],
[ACTIVIDAD_PRINCIPAL.PATIOS_PRODUCTIVOS]: ['SIEMBRA Y CRIA', 'OTRO'],
[ACTIVIDAD_PRINCIPAL.TRANSFORMACION_MATERIA]: [
'ELABORACION DE PRODUCTOS QUIMICOS (LIMPIEZA E HIGIENE PERSONAL)',
'PANADERIAS',
@@ -131,6 +133,7 @@ export const ACTIVIDAD_PRODUCTIVA_MAP: Record<string, string[]> = {
'TORREFACTORA DE CÁFE',
'ESPULPADORA DE TOMATES Y FRUTAS',
'ARTESANIAS',
'OTRO'
],
[ACTIVIDAD_PRINCIPAL.TEXTIL]: [
'ELABORACION DE UNIFORME ESCOLARES Y PRENDA DE VESTIR',
@@ -138,12 +141,14 @@ export const ACTIVIDAD_PRODUCTIVA_MAP: Record<string, string[]> = {
'ELABORACION DE LENCERIA',
'SUBLIMACION DE TEJIDOS',
'ELABORACION DE CALZADOS',
'OTRO'
],
[ACTIVIDAD_PRINCIPAL.CONSTRUCCION]: [
'BLOQUERAS',
'PLANTA PREMEZCLADORA DE CEMENTO',
'CARPINTERIAS',
'HERRERIAS',
'OTRO'
],
[ACTIVIDAD_PRINCIPAL.BIENES_SERVICIOS]: [
'MERCADOS COMUNALES',
@@ -157,15 +162,17 @@ export const ACTIVIDAD_PRODUCTIVA_MAP: Record<string, string[]> = {
'REPARACION DE CALZADOS',
'TALLER DE MECANICA',
'TRANSPORTES',
'OTRO'
],
[ACTIVIDAD_PRINCIPAL.VISITAS_GUIADAS]: ['RUTAS TURISTICAS'],
[ACTIVIDAD_PRINCIPAL.ALOJAMIENTO]: ['POSADAS', 'HOTELES'],
[ACTIVIDAD_PRINCIPAL.TURISMO]: ['AGENCIAS DE VIAJES'],
[ACTIVIDAD_PRINCIPAL.VISITAS_GUIADAS]: ['RUTAS TURISTICAS', 'OTRO'],
[ACTIVIDAD_PRINCIPAL.ALOJAMIENTO]: ['POSADAS', 'HOTELES', 'OTRO'],
[ACTIVIDAD_PRINCIPAL.TURISMO]: ['AGENCIAS DE VIAJES', 'OTRO'],
[ACTIVIDAD_PRINCIPAL.COMERCIO]: [
'VENTA DE VIVERES',
'VENTAS DE PRENDAS DE VESTIR',
'VENTA DE PRODUCTOS QUIMICOS Y DERIVADOS',
'BODEGAS COMUNALES',
'FRIGORIFICOS Y CARNICOS',
'OTRO'
],
};

View File

@@ -46,6 +46,7 @@ export const trainingSchema = z.object({
productiveActivity: z.string({
message: 'Actividad Productiva es requerida',
}),
productiveActivityOther: z.string().min(1, { message: 'Este campo es requerido' }).optional(),
ospRif: z.string().optional().or(z.literal('')).nullable(),
ospName: z.string().optional().or(z.literal('')).nullable(),
companyConstitutionYear: z.coerce
@@ -226,6 +227,7 @@ export const getTrainingSchema = z.object({
centralProductiveActivity: z.string(),
mainProductiveActivity: z.string(),
productiveActivity: z.string(),
productiveActivityOther: z.string(),
ospRif: z.string().optional().or(z.literal('')).nullable(),
ospName: z.string().optional().or(z.literal('')).nullable(),
companyConstitutionYear: z.coerce.number(),