183 lines
5.6 KiB
TypeScript
183 lines
5.6 KiB
TypeScript
import axios, {
|
|
AxiosError,
|
|
AxiosInstance,
|
|
InternalAxiosRequestConfig,
|
|
} from 'axios';
|
|
import {
|
|
getAccessToken,
|
|
handleTokenRefresh,
|
|
} from '../../login/utils/tokenRefresh';
|
|
import {
|
|
OrderFilters,
|
|
orderApiParamsSchema,
|
|
orderResponseSchema,
|
|
ordersResponseSchema,
|
|
storesResponseSchema,
|
|
customersResponseSchema,
|
|
sellersResponseSchema,
|
|
unwrapApiData,
|
|
} from '../schemas/order.schema';
|
|
import {
|
|
orderItemsResponseSchema,
|
|
OrderItem,
|
|
shipmentResponseSchema,
|
|
Shipment,
|
|
cargoMovementResponseSchema,
|
|
CargoMovement,
|
|
cuttingItemResponseSchema,
|
|
CuttingItem,
|
|
} from '../schemas/order.item.schema';
|
|
import { Store } from '../schemas/store.schema';
|
|
import { Seller } from '../schemas/seller.schema';
|
|
import { Order } from '../types';
|
|
|
|
const ORDERS_API_URL = process.env.NEXT_PUBLIC_ORDERS_API_URL;
|
|
|
|
export const ordersApi: AxiosInstance = axios.create({
|
|
baseURL: ORDERS_API_URL,
|
|
withCredentials: true,
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
});
|
|
|
|
/**
|
|
* Adiciona o token de autenticação aos cabeçalhos da requisição.
|
|
* Executa apenas no ambiente do navegador (verifica a existência do objeto window).
|
|
*
|
|
* @param {InternalAxiosRequestConfig} config - A configuração da requisição Axios
|
|
* @returns {InternalAxiosRequestConfig} A configuração modificada com o cabeçalho Authorization
|
|
*/
|
|
const addToken = (config: InternalAxiosRequestConfig) => {
|
|
if (globalThis.window !== undefined) {
|
|
const token = getAccessToken();
|
|
if (token && config.headers) {
|
|
config.headers.Authorization = `Bearer ${token}`;
|
|
}
|
|
}
|
|
return config;
|
|
};
|
|
|
|
ordersApi.interceptors.request.use(addToken);
|
|
|
|
/**
|
|
* Trata erros de resposta das requisições da API.
|
|
* Tenta atualizar o token de autenticação se a requisição falhar.
|
|
*
|
|
* @param {AxiosError} error - O objeto de erro do Axios
|
|
* @returns {Promise} Resultado da tentativa de atualização do token
|
|
* @throws {AxiosError} Se não houver configuração de requisição original disponível
|
|
*/
|
|
const handleResponseError = async (error: AxiosError) => {
|
|
const originalRequest = error.config as InternalAxiosRequestConfig & {
|
|
_retry?: boolean;
|
|
};
|
|
|
|
if (!originalRequest) {
|
|
throw error;
|
|
}
|
|
|
|
return handleTokenRefresh(error, originalRequest, ordersApi);
|
|
};
|
|
|
|
ordersApi.interceptors.response.use(
|
|
(response) => response,
|
|
handleResponseError
|
|
);
|
|
|
|
export const orderService = {
|
|
/**
|
|
* Busca pedidos com base nos filtros fornecidos.
|
|
* Utiliza Zod para limpar e transformar os parâmetros automaticamente.
|
|
*
|
|
* @param {OrderFilters} filters - Critérios de filtro para buscar pedidos
|
|
* @returns {Promise<Order[]>} Array de pedidos que correspondem aos filtros
|
|
*/
|
|
findOrders: async (filters: OrderFilters): Promise<Order[]> => {
|
|
const cleanParams = orderApiParamsSchema.parse(filters);
|
|
const response = await ordersApi.get('/api/v1/orders/find', {
|
|
params: cleanParams,
|
|
});
|
|
return unwrapApiData(response, ordersResponseSchema, []);
|
|
},
|
|
|
|
/**
|
|
* Busca um pedido específico pelo seu ID.
|
|
*
|
|
* @param {number} id - O identificador único do pedido
|
|
* @returns {Promise<Order | null>} O pedido com o ID especificado, ou null se não encontrado
|
|
*/
|
|
findById: async (id: number): Promise<Order | null> => {
|
|
const response = await ordersApi.get(`/orders/${id}`);
|
|
return unwrapApiData(response, orderResponseSchema, null);
|
|
},
|
|
|
|
/**
|
|
* Recupera todas as lojas disponíveis.
|
|
*
|
|
* @returns {Promise<Store[]>} Array de todas as lojas, ou array vazio se nenhuma for encontrada
|
|
*/
|
|
findStores: async (): Promise<Store[]> => {
|
|
const response = await ordersApi.get('/api/v1/data-consult/stores');
|
|
return unwrapApiData(response, storesResponseSchema, []);
|
|
},
|
|
|
|
/**
|
|
* Busca clientes por nome.
|
|
* Retorna array vazio se o termo de busca tiver menos de 2 caracteres.
|
|
*
|
|
* @param {string} name - O nome do cliente a ser buscado (mínimo 2 caracteres)
|
|
* @returns {Promise<Array<{id: number, name: string, estcob: string}>>} Array de clientes correspondentes com os campos id, name e estcob
|
|
*/
|
|
findCustomers: async (
|
|
name: string
|
|
): Promise<Array<{ id: number; name: string; estcob: string }>> => {
|
|
if (!name || name.trim().length < 2) return [];
|
|
|
|
const response = await ordersApi.get(
|
|
`/api/v1/clientes/${encodeURIComponent(name)}`
|
|
);
|
|
return unwrapApiData(response, customersResponseSchema, []);
|
|
},
|
|
|
|
findSellers: async (): Promise<Seller[]> => {
|
|
const response = await ordersApi.get('/api/v1/data-consult/sellers');
|
|
return unwrapApiData(response, sellersResponseSchema, []);
|
|
},
|
|
|
|
findOrderItems: async (orderId: number): Promise<OrderItem[]> => {
|
|
const response = await ordersApi.get(`/api/v1/orders/itens/${orderId}`);
|
|
return unwrapApiData(response, orderItemsResponseSchema, []);
|
|
},
|
|
|
|
|
|
findDelivery: async (
|
|
orderId: number,
|
|
includeCompletedDeliveries: boolean = true
|
|
): Promise<Shipment[]> => {
|
|
const response = await ordersApi.get(
|
|
`/api/v1/orders/delivery/${orderId}`,
|
|
{
|
|
params: { includeCompletedDeliveries },
|
|
}
|
|
);
|
|
return unwrapApiData(response, shipmentResponseSchema, []);
|
|
},
|
|
|
|
findCargoMovement: async (orderId: number): Promise<CargoMovement[]> => {
|
|
const response = await ordersApi.get(
|
|
`/api/v1/orders/transfer/${orderId}`
|
|
);
|
|
return unwrapApiData(response, cargoMovementResponseSchema, []);
|
|
},
|
|
|
|
findCuttingItems: async (orderId: number): Promise<CuttingItem[]> => {
|
|
const response = await ordersApi.get(
|
|
`/api/v1/orders/cut-itens/${orderId}`
|
|
);
|
|
return unwrapApiData(response, cuttingItemResponseSchema, []);
|
|
},
|
|
|
|
|
|
};
|