284 lines
7.5 KiB
TypeScript
284 lines
7.5 KiB
TypeScript
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();
|
|
|
|
|