Files
ERP_Distribution/distribution_fe/lib/api/master.ts
T
2026-08-31 13:00:33 +05:30

224 lines
7.2 KiB
TypeScript

import { api } from '@/lib/api'
import type {
PaginatedResponse,
RegionResponse,
RegionalTargetResponse,
RegionalBudgetResponse,
RegionAgencyMapResponse,
RegionalTaxRuleResponse,
RegionHierarchyResponse,
RegionDashboardResponse,
RouteResponse,
RouteVisitResponse,
VehicleResponse,
WarehouseResponse,
VehicleType,
WarehouseType,
} from '@/types/api'
const VEHICLE_TYPE_CODES: Record<VehicleType, number> = {
Car: 0,
Truck: 1,
Van: 2,
Motorcycle: 3,
Bicycle: 4,
}
const VEHICLE_TYPE_VALUES = ['Car', 'Truck', 'Van', 'Motorcycle', 'Bicycle'] as const
function normalizeVehicleType(type: VehicleType | number): VehicleType {
if (typeof type === 'number') {
return VEHICLE_TYPE_VALUES[type] ?? 'Car'
}
return type
}
function normalizeVehicle(
vehicle: VehicleResponse | (Omit<VehicleResponse, 'type'> & { type: VehicleType | number })
): VehicleResponse {
return {
...vehicle,
type: normalizeVehicleType(vehicle.type),
}
}
function normalizeVehicleListResponse(
response: PaginatedResponse<VehicleResponse> | (Omit<VehicleResponse, 'type'> & { type: VehicleType | number })[],
params?: VehicleListParams
): PaginatedResponse<VehicleResponse> {
if (Array.isArray(response)) {
const page = params?.page ?? 1
const pageSize = params?.pageSize ?? (response.length || 1)
const start = (page - 1) * pageSize
const items = response.slice(start, start + pageSize).map(normalizeVehicle)
return {
page,
pageSize,
total: response.length,
items,
}
}
return {
...response,
items: response.items.map(normalizeVehicle),
}
}
function serializeVehicleBody(body: VehicleBody | Partial<VehicleBody>) {
return {
...body,
...(body.type ? { type: VEHICLE_TYPE_CODES[body.type] } : {}),
}
}
// ─── Pagination ───────────────────────────────────────────────────────────────
export interface PageParams {
page?: number
pageSize?: number
}
// ─── Regions ──────────────────────────────────────────────────────────────────
export interface RegionBody {
name: string
isActive?: boolean
}
export const regions = {
list: (params?: PageParams) =>
api.get<PaginatedResponse<RegionResponse>>('/regions', { params }).then(r => r.data),
get: (id: string) =>
api.get<RegionResponse>(`/regions/${id}`).then(r => r.data),
create: (body: RegionBody) =>
api.post<RegionResponse>('/regions', body).then(r => r.data),
update: (id: string, body: Partial<RegionBody>) =>
api.put<RegionResponse>(`/regions/${id}`, body).then(r => r.data),
remove: (id: string) =>
api.delete(`/regions/${id}`),
setTarget: (id: string, period: string, targetValue: number) =>
api.put<RegionalTargetResponse>(`/regions/${id}/targets/${period}`, { targetValue }).then(r => r.data),
setBudget: (id: string, period: string, budgetAmount: number) =>
api.put<RegionalBudgetResponse>(`/regions/${id}/budgets/${period}`, { budgetAmount }).then(r => r.data),
mapAgency: (id: string, agencyUserId: string) =>
api.post<RegionAgencyMapResponse>(`/regions/${id}/agencies`, { agencyUserId }).then(r => r.data),
setTaxRule: (id: string, ruleConfig: string) =>
api.put<RegionalTaxRuleResponse>(`/regions/${id}/tax-rule`, { ruleConfig }).then(r => r.data),
hierarchy: (id: string) =>
api.get<RegionHierarchyResponse>(`/regions/${id}/hierarchy`).then(r => r.data),
dashboard: (id: string, period?: string) =>
api.get<RegionDashboardResponse>(`/regions/${id}/dashboard`, { params: { period } }).then(r => r.data),
}
// ─── Routes ───────────────────────────────────────────────────────────────────
export interface RouteBody {
regionId: string
routeName: string
startPoint: string
endPoint: string
length: number
isActive?: boolean
}
export const routes = {
list: (params?: PageParams & { regionId?: string }) =>
api.get<PaginatedResponse<RouteResponse>>('/routes', { params }).then(r => r.data),
get: (id: string) =>
api.get<RouteResponse>(`/routes/${id}`).then(r => r.data),
create: (body: RouteBody) =>
api.post<RouteResponse>('/routes', body).then(r => r.data),
update: (id: string, body: Partial<RouteBody>) =>
api.put<RouteResponse>(`/routes/${id}`, body).then(r => r.data),
remove: (id: string) =>
api.delete(`/routes/${id}`),
assignStores: (id: string, storeIds: string[]) =>
api.post<RouteResponse>(`/routes/${id}/stores`, { storeIds }).then(r => r.data),
assignOwner: (id: string, salesRepId: string) =>
api.put<RouteResponse>(`/routes/${id}/owner`, { salesRepId }).then(r => r.data),
checkIn: (id: string, body: { storeId: string; latitude: number; longitude: number }) =>
api.post<RouteVisitResponse>(`/routes/${id}/visits/check-in`, body).then(r => r.data),
checkOut: (id: string, body: { storeId: string }) =>
api.post<RouteVisitResponse>(`/routes/${id}/visits/check-out`, body).then(r => r.data),
}
// ─── Vehicles ─────────────────────────────────────────────────────────────────
export interface VehicleBody {
regNumber: string
numberPlate: string
type: VehicleType
}
export interface VehicleListParams extends PageParams {
available?: boolean
isActive?: boolean
}
export const vehicles = {
list: (params?: VehicleListParams) =>
api.get<PaginatedResponse<VehicleResponse> | VehicleResponse[]>('/vehicles', { params }).then(r =>
normalizeVehicleListResponse(r.data, params)
),
get: (id: string) =>
api.get<VehicleResponse>(`/vehicles/${id}`).then(r => normalizeVehicle(r.data)),
create: (body: VehicleBody) =>
api.post<VehicleResponse>('/vehicles', serializeVehicleBody(body)).then(r => normalizeVehicle(r.data)),
update: (id: string, body: Partial<VehicleBody>) =>
api.put<VehicleResponse>(`/vehicles/${id}`, serializeVehicleBody(body)).then(r => normalizeVehicle(r.data)),
remove: (id: string) =>
api.delete(`/vehicles/${id}`),
}
// ─── Warehouses ───────────────────────────────────────────────────────────────
export interface WarehouseBody {
name: string
location: string
type: WarehouseType
vehicleId?: string | null
isActive?: boolean
}
export const warehouses = {
list: (params?: PageParams) =>
api.get<PaginatedResponse<WarehouseResponse>>('/warehouses', { params }).then(r => r.data),
get: (id: string) =>
api.get<WarehouseResponse>(`/warehouses/${id}`).then(r => r.data),
create: (body: WarehouseBody) =>
api.post<WarehouseResponse>('/warehouses', body).then(r => r.data),
update: (id: string, body: Partial<WarehouseBody>) =>
api.put<WarehouseResponse>(`/warehouses/${id}`, body).then(r => r.data),
remove: (id: string) =>
api.delete(`/warehouses/${id}`),
}