237 lines
6.7 KiB
TypeScript
237 lines
6.7 KiB
TypeScript
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<Response | void> {
|
|
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<Response | void> {
|
|
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<Response | void> {
|
|
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<Response | void> {
|
|
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<Response | void> {
|
|
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<Response | void> {
|
|
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<Response | void> {
|
|
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<Response | void> {
|
|
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<Response | void> {
|
|
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<Response | void> {
|
|
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();
|