import { Response, NextFunction } from 'express'; import { BaseController } from '../../../shared/controllers/base.controller'; import { AuthenticatedRequest } from '../../../shared/types'; import { branchService } from '../services/branch.service'; import { BranchStatus, BranchType } from '../entities/branch.entity'; class BranchController extends BaseController { /** * GET /branches - List all branches */ async list(req: AuthenticatedRequest, res: Response, next: NextFunction): Promise { try { const tenantId = this.getTenantId(req); const pagination = this.parsePagination(req.query); const { status, type, search } = req.query; const result = await branchService.findAll(tenantId, { pagination, filters: [ ...(status ? [{ field: 'status', operator: 'eq' as const, value: status }] : []), ...(type ? [{ field: 'type', operator: 'eq' as const, value: type }] : []), ], search: search ? { fields: ['name', 'code', 'city'], term: search as string, } : undefined, }); return this.paginated(res, result); } catch (error) { next(error); } } /** * GET /branches/active - List active branches */ async listActive(req: AuthenticatedRequest, res: Response, next: NextFunction): Promise { try { const tenantId = this.getTenantId(req); const branches = await branchService.findActiveBranches(tenantId); return this.success(res, branches); } catch (error) { next(error); } } /** * GET /branches/:id - Get branch by ID */ async getById(req: AuthenticatedRequest, res: Response, next: NextFunction): Promise { try { const tenantId = this.getTenantId(req); const { id } = req.params; const branch = await branchService.findById(tenantId, id, ['cashRegisters']); if (!branch) { return this.notFound(res, 'Branch'); } return this.success(res, branch); } catch (error) { next(error); } } /** * GET /branches/code/:code - Get branch by code */ async getByCode(req: AuthenticatedRequest, res: Response, next: NextFunction): Promise { try { const tenantId = this.getTenantId(req); const { code } = req.params; const branch = await branchService.findByCode(tenantId, code); if (!branch) { return this.notFound(res, 'Branch'); } return this.success(res, branch); } catch (error) { next(error); } } /** * POST /branches - Create branch */ async create(req: AuthenticatedRequest, res: Response, next: NextFunction): Promise { try { const tenantId = this.getTenantId(req); const userId = this.getUserId(req); const result = await branchService.createWithRegister(tenantId, req.body, userId); if (!result.success) { if (result.error.code === 'DUPLICATE_CODE') { return this.conflict(res, result.error.message); } return this.error(res, result.error.code, result.error.message); } return this.success(res, result.data, 201); } catch (error) { next(error); } } /** * PUT /branches/:id - Update branch */ async update(req: AuthenticatedRequest, res: Response, next: NextFunction): Promise { try { const tenantId = this.getTenantId(req); const userId = this.getUserId(req); const { id } = req.params; const result = await branchService.update(tenantId, id, req.body, userId); if (!result.success) { if (result.error.code === 'NOT_FOUND') { return this.notFound(res, 'Branch'); } return this.error(res, result.error.code, result.error.message); } return this.success(res, result.data); } catch (error) { next(error); } } /** * PATCH /branches/:id/status - Update branch status */ async updateStatus(req: AuthenticatedRequest, res: Response, next: NextFunction): Promise { try { const tenantId = this.getTenantId(req); const userId = this.getUserId(req); const { id } = req.params; const { status } = req.body; if (!Object.values(BranchStatus).includes(status)) { return this.validationError(res, { status: 'Invalid status value' }); } const result = await branchService.updateStatus(tenantId, id, status, userId); if (!result.success) { if (result.error.code === 'NOT_FOUND') { return this.notFound(res, 'Branch'); } return this.error(res, result.error.code, result.error.message); } return this.success(res, result.data); } catch (error) { next(error); } } /** * DELETE /branches/:id - Delete branch */ async delete(req: AuthenticatedRequest, res: Response, next: NextFunction): Promise { try { const tenantId = this.getTenantId(req); const { id } = req.params; const result = await branchService.delete(tenantId, id); if (!result.success) { if (result.error.code === 'NOT_FOUND') { return this.notFound(res, 'Branch'); } return this.error(res, result.error.code, result.error.message); } return this.success(res, { deleted: true }); } catch (error) { next(error); } } /** * GET /branches/:id/stats - Get branch statistics */ async getStats(req: AuthenticatedRequest, res: Response, next: NextFunction): Promise { try { const tenantId = this.getTenantId(req); const { id } = req.params; const exists = await branchService.exists(tenantId, id); if (!exists) { return this.notFound(res, 'Branch'); } const stats = await branchService.getBranchStats(tenantId, id); return this.success(res, stats); } catch (error) { next(error); } } /** * GET /branches/nearby - Find nearby branches */ async findNearby(req: AuthenticatedRequest, res: Response, next: NextFunction): Promise { try { const tenantId = this.getTenantId(req); const { lat, lng, radius } = req.query; if (!lat || !lng) { return this.validationError(res, { lat: 'Required', lng: 'Required' }); } const branches = await branchService.findNearby( tenantId, parseFloat(lat as string), parseFloat(lng as string), radius ? parseFloat(radius as string) : 10 ); return this.success(res, branches); } catch (error) { next(error); } } } export const branchController = new BranchController();