import { Response, NextFunction } from 'express'; import { AuthRequest } from '../../shared/middleware/auth'; import { tendersService } from './tenders.service'; import { ResponseFormatter } from '../../shared/utils/responseFormatter'; export class TendersController { async checkDuplicates(req: AuthRequest, res: Response, next: NextFunction) { try { const duplicates = await tendersService.findPossibleDuplicates(req.body); res.json(ResponseFormatter.success(duplicates)); } catch (error) { next(error); } } async create(req: AuthRequest, res: Response, next: NextFunction) { try { const result = await tendersService.create(req.body, req.user!.id); res.status(201).json( ResponseFormatter.success( result, 'تم إنشاء المناقصة بنجاح - Tender created successfully' ) ); } catch (error) { next(error); } } async delete(req: AuthRequest, res: Response, next: NextFunction) { try { await tendersService.delete(req.params.id, req.user!.id) res.json( ResponseFormatter.success( true, 'تم حذف المناقصة بنجاح - Tender deleted successfully' ) ) } catch (error) { next(error) } } async findAll(req: AuthRequest, res: Response, next: NextFunction) { try { const page = parseInt(req.query.page as string) || 1; const pageSize = parseInt(req.query.pageSize as string) || 20; const filters = { search: req.query.search, status: req.query.status, source: req.query.source, announcementType: req.query.announcementType, }; const result = await tendersService.findAll(filters, page, pageSize); res.json( ResponseFormatter.paginated( result.tenders, result.total, result.page, result.pageSize ) ); } catch (error) { next(error); } } async findById(req: AuthRequest, res: Response, next: NextFunction) { try { const tender = await tendersService.findById(req.params.id); res.json(ResponseFormatter.success(tender)); } catch (error) { next(error); } } async update(req: AuthRequest, res: Response, next: NextFunction) { try { const tender = await tendersService.update( req.params.id, req.body, req.user!.id ); res.json( ResponseFormatter.success( tender, 'تم تحديث المناقصة بنجاح - Tender updated successfully' ) ); } catch (error) { next(error); } } async createDirective(req: AuthRequest, res: Response, next: NextFunction) { try { const directive = await tendersService.createDirective( req.params.id, req.body, req.user!.id ); res.status(201).json( ResponseFormatter.success( directive, 'تم إصدار التوجيه بنجاح - Directive created successfully' ) ); } catch (error) { next(error); } } async updateDirective(req: AuthRequest, res: Response, next: NextFunction) { try { const directive = await tendersService.updateDirective( req.params.directiveId, req.body, req.user!.id ); res.json( ResponseFormatter.success( directive, 'تم تحديث التوجيه بنجاح - Directive updated successfully' ) ); } catch (error) { next(error); } } async getHistory(req: AuthRequest, res: Response, next: NextFunction) { try { const history = await tendersService.getHistory(req.params.id); res.json(ResponseFormatter.success(history)); } catch (error) { next(error); } } async convertToDeal(req: AuthRequest, res: Response, next: NextFunction) { try { const deal = await tendersService.convertToDeal( req.params.id, { contactId: req.body.contactId, pipelineId: req.body.pipelineId, ownerId: req.body.ownerId, }, req.user!.id ); res.status(201).json( ResponseFormatter.success( deal, 'تم تحويل المناقصة إلى فرصة بنجاح - Tender converted to deal successfully' ) ); } catch (error) { next(error); } } async getSourceValues(_req: AuthRequest, res: Response, next: NextFunction) { try { const values = tendersService.getSourceValues(); res.json(ResponseFormatter.success(values)); } catch (error) { next(error); } } async getAnnouncementTypeValues( _req: AuthRequest, res: Response, next: NextFunction ) { try { const values = tendersService.getAnnouncementTypeValues(); res.json(ResponseFormatter.success(values)); } catch (error) { next(error); } } async getDirectiveTypeValues( _req: AuthRequest, res: Response, next: NextFunction ) { try { const values = tendersService.getDirectiveTypeValues(); res.json(ResponseFormatter.success(values)); } catch (error) { next(error); } } async uploadTenderAttachment(req: AuthRequest, res: Response, next: NextFunction) { try { if (!req.file) { return res.status(400).json( ResponseFormatter.error('No file uploaded', 'Missing file') ); } const attachment = await tendersService.uploadTenderAttachment( req.params.id, req.file, req.user!.id, (req.body.category as string) || undefined ); res.status(201).json( ResponseFormatter.success( attachment, 'تم رفع الملف بنجاح - File uploaded successfully' ) ); } catch (error) { next(error); } } async uploadDirectiveAttachment(req: AuthRequest, res: Response, next: NextFunction) { try { if (!req.file) { return res.status(400).json( ResponseFormatter.error('No file uploaded', 'Missing file') ); } const attachment = await tendersService.uploadDirectiveAttachment( req.params.directiveId, req.file, req.user!.id, (req.body.category as string) || undefined ); res.status(201).json( ResponseFormatter.success( attachment, 'تم رفع الملف بنجاح - File uploaded successfully' ) ); } catch (error) { next(error); } } async viewAttachment(req: AuthRequest, res: Response, next: NextFunction) { try { const file = await tendersService.getAttachmentFile(req.params.attachmentId) const fs = require('fs') if (!fs.existsSync(file)) { console.error('[tenders.viewAttachment] Resolved path missing at send time', { attachmentId: req.params.attachmentId, resolvedPath: file, }) return res.status(404).json( ResponseFormatter.error('File not found - الملف غير موجود', 'FILE_NOT_FOUND') ) } const path = require('path') return res.sendFile(path.resolve(file)) } catch (error) { console.error('[tenders.viewAttachment]', error) next(error) } } async deleteAttachment(req: AuthRequest, res: Response, next: NextFunction) { try { await tendersService.deleteAttachment(req.params.attachmentId) res.json(ResponseFormatter.success(null, 'Deleted')) } catch (error) { next(error) } } } export const tendersController = new TendersController();