Campos faltantes

This commit is contained in:
2025-12-04 19:02:02 -04:00
parent d3b3fa5e85
commit 01c7bd149d
9 changed files with 2012 additions and 223 deletions

View File

@@ -0,0 +1,7 @@
ALTER TABLE "training_surveys" ADD COLUMN "state" integer;--> statement-breakpoint
ALTER TABLE "training_surveys" ADD COLUMN "municipality" integer;--> statement-breakpoint
ALTER TABLE "training_surveys" ADD COLUMN "parish" integer;--> statement-breakpoint
ALTER TABLE "training_surveys" ADD COLUMN "osp_responsible_email" text NOT NULL;--> statement-breakpoint
ALTER TABLE "training_surveys" ADD CONSTRAINT "training_surveys_state_states_id_fk" FOREIGN KEY ("state") REFERENCES "public"."states"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "training_surveys" ADD CONSTRAINT "training_surveys_municipality_municipalities_id_fk" FOREIGN KEY ("municipality") REFERENCES "public"."municipalities"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "training_surveys" ADD CONSTRAINT "training_surveys_parish_parishes_id_fk" FOREIGN KEY ("parish") REFERENCES "public"."parishes"("id") ON DELETE set null ON UPDATE no action;

File diff suppressed because it is too large Load Diff

View File

@@ -64,6 +64,13 @@
"when": 1764623430844, "when": 1764623430844,
"tag": "0008_plain_scream", "tag": "0008_plain_scream",
"breakpoints": true "breakpoints": true
},
{
"idx": 9,
"version": "7",
"when": 1764883378610,
"tag": "0009_eminent_ares",
"breakpoints": true
} }
] ]
} }

View File

@@ -2,6 +2,7 @@ import * as t from 'drizzle-orm/pg-core';
import { eq, lt, gte, ne, sql } from 'drizzle-orm'; import { eq, lt, gte, ne, sql } from 'drizzle-orm';
import { timestamps } from '../timestamps'; import { timestamps } from '../timestamps';
import { users } from './auth'; import { users } from './auth';
import { states, municipalities, parishes } from './general';
// Tabla surveys // Tabla surveys
@@ -48,37 +49,47 @@ export const answersSurveys = t.pgTable(
export const trainingSurveys = t.pgTable( export const trainingSurveys = t.pgTable(
'training_surveys', 'training_surveys',
{ {
// Datos basicos
id: t.serial('id').primaryKey(), id: t.serial('id').primaryKey(),
firstname: t.text('firstname').notNull(), firstname: t.text('firstname').notNull(),
lastname: t.text('lastname').notNull(), lastname: t.text('lastname').notNull(),
visitDate: t.timestamp('visit_date').notNull(), visitDate: t.timestamp('visit_date').notNull(),
productiveActivity: t.text('productive_activity').notNull(), // ubicacion
financialRequirementDescription: t.text('financial_requirement_description').notNull(), state: t.integer('state').references(() => states.id, { onDelete: 'set null' }),
municipality: t.integer('municipality').references(() => municipalities.id, { onDelete: 'set null' }),
parish: t.integer('parish').references(() => parishes.id, { onDelete: 'set null' }),
siturCodeCommune: t.text('situr_code_commune').notNull(), siturCodeCommune: t.text('situr_code_commune').notNull(),
communalCouncil: t.text('communal_council').notNull(), communalCouncil: t.text('communal_council').notNull(),
siturCodeCommunalCouncil: t.text('situr_code_communal_council').notNull(), siturCodeCommunalCouncil: t.text('situr_code_communal_council').notNull(),
// datos del OSP (ORGANIZACIÓN SOCIOPRODUCTIVA)
ospName: t.text('osp_name').notNull(), ospName: t.text('osp_name').notNull(),
ospAddress: t.text('osp_address').notNull(), ospAddress: t.text('osp_address').notNull(),
ospRif: t.text('osp_rif').notNull(), ospRif: t.text('osp_rif').notNull(),
ospType: t.text('osp_type').notNull(), ospType: t.text('osp_type').notNull(),
productiveActivity: t.text('productive_activity').notNull(),
financialRequirementDescription: t.text('financial_requirement_description').notNull(),
currentStatus: t.text('current_status').notNull(), currentStatus: t.text('current_status').notNull(),
companyConstitutionYear: t.integer('company_constitution_year').notNull(), companyConstitutionYear: t.integer('company_constitution_year').notNull(),
producerCount: t.integer('producer_count').notNull(), producerCount: t.integer('producer_count').notNull(),
productDescription: t.text('product_description').notNull(), productDescription: t.text('product_description').notNull(),
installedCapacity: t.text('installed_capacity').notNull(), installedCapacity: t.text('installed_capacity').notNull(),
operationalCapacity: t.text('operational_capacity').notNull(), operationalCapacity: t.text('operational_capacity').notNull(),
// datos del responsable
ospResponsibleFullname: t.text('osp_responsible_fullname').notNull(), ospResponsibleFullname: t.text('osp_responsible_fullname').notNull(),
ospResponsibleCedula: t.text('osp_responsible_cedula').notNull(), ospResponsibleCedula: t.text('osp_responsible_cedula').notNull(),
ospResponsibleRif: t.text('osp_responsible_rif').notNull(), ospResponsibleRif: t.text('osp_responsible_rif').notNull(),
ospResponsiblePhone: t.text('osp_responsible_phone').notNull(), ospResponsiblePhone: t.text('osp_responsible_phone').notNull(),
ospResponsibleEmail: t.text('osp_responsible_email').notNull(),
civilState: t.text('civil_state').notNull(), civilState: t.text('civil_state').notNull(),
familyBurden: t.integer('family_burden').notNull(), familyBurden: t.integer('family_burden').notNull(),
numberOfChildren: t.integer('number_of_children').notNull(), numberOfChildren: t.integer('number_of_children').notNull(),
// datos adicionales
generalObservations: t.text('general_observations').notNull(), generalObservations: t.text('general_observations').notNull(),
paralysisReason: t.text('paralysis_reason').notNull(),
// fotos
photo1: t.text('photo1').notNull(), photo1: t.text('photo1').notNull(),
photo2: t.text('photo2').notNull(), photo2: t.text('photo2').notNull(),
photo3: t.text('photo3').notNull(), photo3: t.text('photo3').notNull(),
paralysisReason: t.text('paralysis_reason').notNull(),
...timestamps, ...timestamps,
}, },
(trainingSurveys) => ({ (trainingSurveys) => ({

View File

@@ -22,6 +22,18 @@ export class CreateTrainingDto {
@IsString() @IsString()
financialRequirementDescription: string; financialRequirementDescription: string;
@ApiProperty()
@IsInt()
state: number;
@ApiProperty()
@IsInt()
municipality: number;
@ApiProperty()
@IsInt()
parish: number;
@ApiProperty() @ApiProperty()
@IsString() @IsString()
siturCodeCommune: string; siturCodeCommune: string;
@@ -90,6 +102,10 @@ export class CreateTrainingDto {
@IsString() @IsString()
ospResponsiblePhone: string; ospResponsiblePhone: string;
@ApiProperty()
@IsString()
ospResponsibleEmail: string;
@ApiProperty() @ApiProperty()
@IsString() @IsString()
civilState: string; civilState: string;

View File

@@ -1,148 +0,0 @@
'use server';
import { safeFetchApi } from '@/lib/fetch.api';
import {
surveysApiResponseSchema,
CreateUser,
UsersMutate,
UpdateUser
} from '../schemas/users';
import { auth } from '@/lib/auth';
export const getProfileAction = async () => {
const session = await auth()
const id = session?.user?.id
const [error, response] = await safeFetchApi(
UsersMutate,
`/users/${id}`,
'GET'
);
if (error) throw new Error(error.message);
return response;
};
export const updateProfileAction = async (payload: UpdateUser) => {
const { id, ...payloadWithoutId } = payload;
const [error, data] = await safeFetchApi(
UsersMutate,
`/users/profile/${id}`,
'PATCH',
payloadWithoutId,
);
console.log(payload);
if (error) {
if (error.message === 'Email already exists') {
throw new Error('Ese correo ya está en uso');
}
// console.error('Error:', error);
throw new Error('Error al crear el usuario');
}
return data;
};
export const getUsersAction = async (params: {
page?: number;
limit?: number;
search?: string;
sortBy?: string;
sortOrder?: 'asc' | 'desc';
}) => {
const searchParams = new URLSearchParams({
page: (params.page || 1).toString(),
limit: (params.limit || 10).toString(),
...(params.search && { search: params.search }),
...(params.sortBy && { sortBy: params.sortBy }),
...(params.sortOrder && { sortOrder: params.sortOrder }),
});
const [error, response] = await safeFetchApi(
surveysApiResponseSchema,
`/users?${searchParams}`,
'GET',
);
if (error) throw new Error(error.message);
// const transformedData = response?.data ? transformSurvey(response?.data) : undefined;
return {
data: response?.data || [],
meta: response?.meta || {
page: 1,
limit: 10,
totalCount: 0,
totalPages: 1,
hasNextPage: false,
hasPreviousPage: false,
nextPage: null,
previousPage: null,
},
};
}
export const createUserAction = async (payload: CreateUser) => {
const { id, confirmPassword, ...payloadWithoutId } = payload;
const [error, data] = await safeFetchApi(
UsersMutate,
'/users',
'POST',
payloadWithoutId,
);
if (error) {
if (error.message === 'Username already exists') {
throw new Error('Ese usuario ya existe');
}
if (error.message === 'Email already exists') {
throw new Error('Ese correo ya está en uso');
}
// console.error('Error:', error);
throw new Error('Error al crear el usuario');
}
return payloadWithoutId;
};
export const updateUserAction = async (payload: UpdateUser) => {
try {
const { id, ...payloadWithoutId } = payload;
const [error, data] = await safeFetchApi(
UsersMutate,
`/users/${id}`,
'PATCH',
payloadWithoutId,
);
// console.log(data);
if (error) {
console.error(error);
throw new Error(error?.message || 'Error al actualizar el usuario');
}
return data;
} catch (error) {
console.error(error);
}
}
export const deleteUserAction = async (id: Number) => {
const [error] = await safeFetchApi(
UsersMutate,
`/users/${id}`,
'DELETE'
)
console.log(error);
// if (error) throw new Error(error.message || 'Error al eliminar el usuario')
return true;
}

View File

@@ -0,0 +1,41 @@
-- datos basicos
nombre,
apellido,
fecha de la visita,
-->Falta
hora de la visita,
-- datos de la ubicacion
estado,
municipio,
parroquia,
nombre de la comuna,
CODIGO SITUR COMUNA,
CONSEJO COMUNAL,
CODIGO SITUR CONSEJO COMUNAL,
-- datos de la osp
actividad productiva (agricola,textil,bloquera,carpinteria,unidad de suministro),
realice una breve descripcion del requerimiento financiero,
NOMBRE DE LA ORGANIZACIÓN SOCIOPRODUCTIVA,
DIRECCIÓN DE LA ORGANIZACIÓN SOCIOPRODUCTIVA,
RIF DE LA ORGANIZACIÓN SOCIOPRODUCTIVA,
TIPO DE ORGANIZACIÓN SOCIOPRODUCTIVA,
ESTATUS ACTUAL,
AÑO DE CONSTITUCIÓN DE LA EMPRESA ,
CANTIDAD DE PRODUCTORES QUE LA CONFORMAN,
BREVE DESCRIPCIÓN DEL PRODUCTO O SERVICIO QUE OFRECE,
CAPACIDAD INSTALADA,
CAPACIDAD OPERATIVA,
¿EXPLIQUE LAS RAZONES GENERALES POR LAS CUALES LA UNIDAD DE PRODUCCIÓN TUVO QUE PARALIZARSE?
-- datos del responsable
NOMBRE Y APELLIDO DEL RESPONSABLE DE LA OSP,
CÉDULA DEL RESPONSABLE (SIN PUNTOS),
RIF DEL RESPONSABLE (SIN PUNTOS),
TELÉFONOS (COLOQUE 2 NUMEROS DE TELEFONOS),
CORREO ELECTRÓNICO,
ESTADO CIVIL DEL PRODUCTOR,
CARGA FAMILIAR,
NUMERO DE HIJOS,
-- datos adicionales
OBSERVACIONES GENERALES,
-- fotos
COLOCAR TRES (3) REGISTROS FOTOGRÁFICOS VISIBLES DEL ESPACIO Y MAQUINARIAS ACTUALMENTE (OBLIGATORIO),

View File

@@ -56,19 +56,19 @@ export function CreateTrainingForm({
const [disabledMunicipality, setDisabledMunicipality] = React.useState(true); const [disabledMunicipality, setDisabledMunicipality] = React.useState(true);
const [disabledParish, setDisabledParish] = React.useState(true); const [disabledParish, setDisabledParish] = React.useState(true);
const { data : dataState } = useStateQuery() const { data: dataState } = useStateQuery()
const { data : dataMunicipality } = useMunicipalityQuery(state) const { data: dataMunicipality } = useMunicipalityQuery(state)
const { data : dataParish } = useParishQuery(municipality) const { data: dataParish } = useParishQuery(municipality)
const stateOptions = dataState?.data || [{id:0,name:'Sin estados'}] const stateOptions = dataState?.data || [{ id: 0, name: 'Sin estados' }]
const municipalityOptions = Array.isArray(dataMunicipality?.data) && dataMunicipality.data.length > 0 const municipalityOptions = Array.isArray(dataMunicipality?.data) && dataMunicipality.data.length > 0
? dataMunicipality.data ? dataMunicipality.data
: [{id:0,stateId:0,name:'Sin Municipios'}] : [{ id: 0, stateId: 0, name: 'Sin Municipios' }]
// const parishOptions = dataParish?.data || [{id:0,municipalityId:0,name:'Sin Parroquias'}] // const parishOptions = dataParish?.data || [{id:0,municipalityId:0,name:'Sin Parroquias'}]
const parishOptions = Array.isArray(dataParish?.data) && dataParish.data.length > 0 const parishOptions = Array.isArray(dataParish?.data) && dataParish.data.length > 0
? dataParish.data ? dataParish.data
: [{id:0,stateId:0,name:'Sin Parroquias'}] : [{ id: 0, stateId: 0, name: 'Sin Parroquias' }]
const form = useForm<TrainingSchema>({ const form = useForm<TrainingSchema>({
resolver: zodResolver(trainingSchema), resolver: zodResolver(trainingSchema),
@@ -99,6 +99,7 @@ export function CreateTrainingForm({
familyBurden: defaultValues?.familyBurden || 0, familyBurden: defaultValues?.familyBurden || 0,
numberOfChildren: defaultValues?.numberOfChildren || 0, numberOfChildren: defaultValues?.numberOfChildren || 0,
generalObservations: defaultValues?.generalObservations || '', generalObservations: defaultValues?.generalObservations || '',
ospResponsibleEmail: defaultValues?.ospResponsibleEmail || '',
photo1: defaultValues?.photo1 || '', photo1: defaultValues?.photo1 || '',
photo2: defaultValues?.photo2 || '', photo2: defaultValues?.photo2 || '',
photo3: defaultValues?.photo3 || '', photo3: defaultValues?.photo3 || '',
@@ -184,8 +185,7 @@ export function CreateTrainingForm({
label: item.name, label: item.name,
})) || [] })) || []
} }
onValueChange={(value : any) => onValueChange={(value: any) => { field.onChange(Number(value)); setState(value); setDisabledMunicipality(false); setDisabledParish(true) }
{field.onChange(Number(value)); setState(value); setDisabledMunicipality(false); setDisabledParish(true)}
} }
placeholder="Selecciona un estado" placeholder="Selecciona un estado"
defaultValue={field.value?.toString()} defaultValue={field.value?.toString()}
@@ -210,8 +210,7 @@ export function CreateTrainingForm({
label: item.name, label: item.name,
})) || [] })) || []
} }
onValueChange={(value : any) => onValueChange={(value: any) => { field.onChange(Number(value)); setMunicipality(value); setDisabledParish(false) }
{field.onChange(Number(value)); setMunicipality(value); setDisabledParish(false)}
} }
placeholder="Selecciona un Municipio" placeholder="Selecciona un Municipio"
defaultValue={field.value?.toString()} defaultValue={field.value?.toString()}
@@ -236,7 +235,7 @@ export function CreateTrainingForm({
label: item.name, label: item.name,
})) || [] })) || []
} }
onValueChange={(value : any) => onValueChange={(value: any) =>
field.onChange(Number(value)) field.onChange(Number(value))
} }
placeholder="Selecciona una Parroquia" placeholder="Selecciona una Parroquia"
@@ -463,6 +462,14 @@ export function CreateTrainingForm({
</FormItem> </FormItem>
)} /> )} />
<FormField control={form.control} name="ospResponsibleEmail" render={({ field }) => (
<FormItem>
<FormLabel>Correo Electrónico</FormLabel>
<FormControl><Input type="email" {...field} /></FormControl>
<FormMessage />
</FormItem>
)} />
<FormField control={form.control} name="familyBurden" render={({ field }) => ( <FormField control={form.control} name="familyBurden" render={({ field }) => (
<FormItem> <FormItem>
<FormLabel>Carga Familiar</FormLabel> <FormLabel>Carga Familiar</FormLabel>
@@ -479,6 +486,11 @@ export function CreateTrainingForm({
</FormItem> </FormItem>
)} /> )} />
{/* datos adicionales */}
<div className="col-span-2">
<h3 className="text-lg font-medium mb-2 mt-4">Datos Adicionales</h3>
</div>
<FormField control={form.control} name="generalObservations" render={({ field }) => ( <FormField control={form.control} name="generalObservations" render={({ field }) => (
<FormItem className="col-span-2"> <FormItem className="col-span-2">
<FormLabel>Observaciones Generales</FormLabel> <FormLabel>Observaciones Generales</FormLabel>

View File

@@ -27,6 +27,7 @@ export const trainingSchema = z.object({
civilState: z.string().min(1, { message: "Estado civil es requerido" }), civilState: z.string().min(1, { message: "Estado civil es requerido" }),
familyBurden: z.coerce.number().min(0, { message: "Carga familiar requerida" }), familyBurden: z.coerce.number().min(0, { message: "Carga familiar requerida" }),
numberOfChildren: z.coerce.number().min(0, { message: "Número de hijos requerido" }), numberOfChildren: z.coerce.number().min(0, { message: "Número de hijos requerido" }),
ospResponsibleEmail: z.string().email({ message: "Correo electrónico inválido" }),
generalObservations: z.string().optional().default(''), generalObservations: z.string().optional().default(''),
photo1: z.string().optional().default(''), photo1: z.string().optional().default(''),
photo2: z.string().optional().default(''), photo2: z.string().optional().default(''),