diff --git a/src/controllers/andesStock.controller.ts b/src/controllers/andesStock.controller.ts new file mode 100644 index 0000000..a634c70 --- /dev/null +++ b/src/controllers/andesStock.controller.ts @@ -0,0 +1,33 @@ +import { Request, Response } from 'express'; +import AndesService from '../services/andesService'; + +class AndesStockController { + + public search = async (req: Request, res: Response): Promise => { + try { + const insumo = req.query.insumo as string; + const tipos = req.query.tipos as string; + + if (!insumo) { + return res.status(400).json({ mensaje: 'Missing required param: insumo' }); + } + + const result = await AndesService.searchStock({ insumo, tipos }); + return res.status(200).json(result); + } catch (e) { + return res.status(500).json({ mensaje: 'Error', error: e }); + } + }; + + public getStock = async (req: Request, res: Response): Promise => { + try { + const result = await AndesService.getAllStock(); + return res.status(200).json(result); + } catch (e) { + return res.status(500).json({ mensaje: 'Error', error: e }); + } + }; + +} + +export default new AndesStockController(); diff --git a/src/controllers/prescription.controller.ts b/src/controllers/prescription.controller.ts index 49d570b..cdd48e4 100644 --- a/src/controllers/prescription.controller.ts +++ b/src/controllers/prescription.controller.ts @@ -148,7 +148,8 @@ class PrescriptionController implements BaseController { public create = async (req: Request, res: Response): Promise => { const { professional, patient, date, supplies, trimestral, ambito } = req.body; - const myProfessional: IUser | null = await User.findOne({ _id: professional }); + const professionalId = professional.userId ? professional.userId : professional; + const myProfessional: IUser | null = await User.findOne({ _id: professionalId }); let myPatient: IPatient | null; if (ambito === 'publico') { const resp = await needle('get', `${process.env.ANDES_ENDPOINT}/core/tm/profesionales/guia?documento=${myProfessional?.username}`); @@ -248,6 +249,8 @@ class PrescriptionController implements BaseController { return res.status(200).json(allPrescription); } catch (err) { + // eslint-disable-next-line no-console + console.log(err); return res.status(500).json('Error al cargar la prescripción'); } } else { @@ -366,19 +369,24 @@ class PrescriptionController implements BaseController { public getByUserId = async (req: Request, res: Response): Promise => { try { const { id } = req.params; - const { offset = 0, limit = 10, ambito = 'privado' } = req.query; + const { offset = 0, limit = 10, ambito = 'privado', insumos = 'false' } = req.query; await this.updateStatuses(id, ''); + const query: any = { 'professional.userId': id }; + if (insumos === 'false') { + query['supplies.supply.type'] = { $exists: false }; + } + // Obtener prescripciones locales - const localPrescriptions: IPrescription[] | null = await Prescription.find({ 'professional.userId': id }) + const localPrescriptions: IPrescription[] | null = await Prescription.find(query) .sort({ date: -1 }); if (localPrescriptions) { await this.ensurePrescriptionIds(localPrescriptions); } - const localTotal = await Prescription.countDocuments({ 'professional.userId': id }); + const localTotal = await Prescription.countDocuments(query); // Combinar con prescripciones de ANDES si es necesario const { combinedPrescriptions, totalPrescriptions } = await this.combineLocalAndAndesPrescriptions( diff --git a/src/controllers/stock.controller.ts b/src/controllers/stock.controller.ts new file mode 100644 index 0000000..de37822 --- /dev/null +++ b/src/controllers/stock.controller.ts @@ -0,0 +1,17 @@ +import { Request, Response } from 'express'; +import Prescription from '../models/prescription.model'; + +class StockController { + + public getStock = async (req: Request, res: Response): Promise => { + try { + const prescriptions = await Prescription.find({ 'supplies.supply.type': { $exists: true } }).limit(100).sort({ date: -1 }); + + return res.status(200).json(prescriptions); + } catch (e) { + return res.status(500).json({ mensaje: 'Error', error: e }); + } + }; +} + +export default new StockController(); diff --git a/src/models/prescription.model.ts b/src/models/prescription.model.ts index 70e0d63..914ca2e 100644 --- a/src/models/prescription.model.ts +++ b/src/models/prescription.model.ts @@ -30,7 +30,19 @@ const prescriptionSchema = new Schema({ dispensedAt: { type: Date }, supplies: [{ _id: false, - supply: supplySchema, + supply: { + ...supplySchema.obj, + type: { + type: String, + enum: ['device', 'nutrition'] + }, + requiresSpecification: { + type: Boolean + }, + specification: { + type: String + } + }, quantity: Number, quantityPresentation: Number, diagnostic: { diff --git a/src/models/supply.model.ts b/src/models/supply.model.ts index b462694..9ea3113 100644 --- a/src/models/supply.model.ts +++ b/src/models/supply.model.ts @@ -11,7 +11,7 @@ export const supplySchema = new Schema({ activePrinciple: { type: String }, - pharmaceutical_form:{ + pharmaceutical_form: { type: String }, power: { @@ -32,7 +32,7 @@ export const supplySchema = new Schema({ fsn: String, semanticTag: String } -},{ +}, { timestamps: true }); diff --git a/src/routes/private.ts b/src/routes/private.ts index bca58d4..3ec438b 100644 --- a/src/routes/private.ts +++ b/src/routes/private.ts @@ -20,6 +20,8 @@ import snomedSupplyController from '../controllers/snomed.controller'; import andesPrescriptionController from '../controllers/andesPrescription.controller'; import certificateController from '../controllers/certificate.controller'; import practiceController from '../controllers/practice.controller'; +import andesStockController from '../controllers/andesStock.controller'; +import stockController from '../controllers/stock.controller'; class PrivateRoutes { constructor(private router: Router = Router()) { } @@ -63,6 +65,11 @@ class PrivateRoutes { this.router.patch('/andes-prescriptions/cancel-dispense', hasPermissionIn('updateAny', 'prescription'), andesPrescriptionController.cancelDispense); this.router.patch('/andes-prescriptions/suspend', hasPermissionIn('updateOwn', 'prescription'), andesPrescriptionController.suspend); + // Andes Stock + this.router.get('/stock/andes', andesStockController.getStock); + this.router.get('/stock/andes/search', andesStockController.search); + this.router.get('/stock', stockController.getStock); + // certificates this.router.get(`/certificates/`, certificateController.index); this.router.get(`/certificates/:id`, certificateController.getById); diff --git a/src/services/andesService.ts b/src/services/andesService.ts index a76186e..7f1f095 100644 --- a/src/services/andesService.ts +++ b/src/services/andesService.ts @@ -8,12 +8,6 @@ interface GetPrescriptionsParams { hasta?: string; // formato YYYY-MM-DD } -interface GetPrescriptionsByPatientParams { - documento: string; - sexo?: 'masculino' | 'femenino'; - estado?: 'vigente' | 'pendiente' | 'dispensada' | 'vencida' | 'finalizada' | 'suspendida' | 'rechazada'; -} - class AndesService { private baseURL: string; private token: string; @@ -26,6 +20,57 @@ class AndesService { } } + /** + * Busca stock de un insumo específico desde ANDES + */ + public async searchStock(params: { insumo: string, tipos?: string }): Promise { + try { + let url = `${this.baseURL}/modules/insumos?insumo=^${params.insumo}`; + + if (params.tipos) { + const tipos = params.tipos.split(','); + tipos.forEach(tipo => { + url += `&tipo=${tipo.trim()}`; + }); + } + + const response: AxiosResponse = await axios.get(url, { + headers: { + Authorization: this.token, + 'Content-Type': 'application/json' + } + }); + + return Array.isArray(response.data) ? response.data : [response.data]; + } catch (error) { + // eslint-disable-next-line no-console + console.error('Error al buscar stock desde ANDES:', error); + throw error; + } + } + + /** + * Obtiene todo el stock de insumos desde ANDES + */ + public async getAllStock(): Promise { + try { + const url = `${this.baseURL}/modules/insumos`; + + const response: AxiosResponse = await axios.get(url, { + headers: { + Authorization: this.token, + 'Content-Type': 'application/json' + } + }); + + return response.data; + } catch (error) { + // eslint-disable-next-line no-console + console.error('Error al obtener todo el stock desde ANDES:', error); + throw error; + } + } + /** * Obtiene las prescripciones de un profesional desde ANDES */ @@ -63,7 +108,7 @@ class AndesService { } } - public async suspendPrescription(prescriptions: [string] , motivo: string, observacion?: string, profesional?: any): Promise { + public async suspendPrescription(prescriptions: [string], motivo: string, observacion?: string, profesional?: any): Promise { try { const url = `${this.baseURL}/modules/recetas`; const body = {