- Add invoices feature: types, API service for CRUD, validation, payments, PDF - Add inventory feature: types, API service for stock, movements, warehouses, locations - Add sales feature: types, API service for orders, quotations, PDF - Add purchases feature: types, API service for orders, receipts Part of FASE 2: P0 Frontend API Services
195 lines
7.2 KiB
TypeScript
195 lines
7.2 KiB
TypeScript
import { api } from '@services/api/axios-instance';
|
|
import type {
|
|
SalesOrder,
|
|
SalesOrderLine,
|
|
CreateSalesOrderDto,
|
|
UpdateSalesOrderDto,
|
|
CreateSalesOrderLineDto,
|
|
UpdateSalesOrderLineDto,
|
|
SalesOrderFilters,
|
|
SalesOrdersResponse,
|
|
Quotation,
|
|
CreateQuotationDto,
|
|
QuotationFilters,
|
|
QuotationsResponse,
|
|
} from '../types';
|
|
|
|
const ORDERS_URL = '/api/v1/sales/orders';
|
|
const QUOTATIONS_URL = '/api/v1/sales/quotations';
|
|
|
|
export const salesApi = {
|
|
// ==================== Sales Orders ====================
|
|
|
|
// Get all sales orders with filters
|
|
getOrders: async (filters?: SalesOrderFilters): Promise<SalesOrdersResponse> => {
|
|
const params = new URLSearchParams();
|
|
if (filters?.companyId) params.append('companyId', filters.companyId);
|
|
if (filters?.partnerId) params.append('partnerId', filters.partnerId);
|
|
if (filters?.status) params.append('status', filters.status);
|
|
if (filters?.invoiceStatus) params.append('invoiceStatus', filters.invoiceStatus);
|
|
if (filters?.deliveryStatus) params.append('deliveryStatus', filters.deliveryStatus);
|
|
if (filters?.dateFrom) params.append('dateFrom', filters.dateFrom);
|
|
if (filters?.dateTo) params.append('dateTo', filters.dateTo);
|
|
if (filters?.search) params.append('search', filters.search);
|
|
if (filters?.page) params.append('page', String(filters.page));
|
|
if (filters?.limit) params.append('limit', String(filters.limit));
|
|
if (filters?.sortBy) params.append('sortBy', filters.sortBy);
|
|
if (filters?.sortOrder) params.append('sortOrder', filters.sortOrder);
|
|
|
|
const response = await api.get<SalesOrdersResponse>(`${ORDERS_URL}?${params.toString()}`);
|
|
return response.data;
|
|
},
|
|
|
|
// Get sales order by ID
|
|
getOrderById: async (id: string): Promise<SalesOrder> => {
|
|
const response = await api.get<SalesOrder>(`${ORDERS_URL}/${id}`);
|
|
return response.data;
|
|
},
|
|
|
|
// Create sales order
|
|
createOrder: async (data: CreateSalesOrderDto): Promise<SalesOrder> => {
|
|
const response = await api.post<SalesOrder>(ORDERS_URL, data);
|
|
return response.data;
|
|
},
|
|
|
|
// Update sales order
|
|
updateOrder: async (id: string, data: UpdateSalesOrderDto): Promise<SalesOrder> => {
|
|
const response = await api.patch<SalesOrder>(`${ORDERS_URL}/${id}`, data);
|
|
return response.data;
|
|
},
|
|
|
|
// Delete sales order
|
|
deleteOrder: async (id: string): Promise<void> => {
|
|
await api.delete(`${ORDERS_URL}/${id}`);
|
|
},
|
|
|
|
// ==================== Order Lines ====================
|
|
|
|
// Add line to order
|
|
addLine: async (orderId: string, data: CreateSalesOrderLineDto): Promise<SalesOrderLine> => {
|
|
const response = await api.post<SalesOrderLine>(`${ORDERS_URL}/${orderId}/lines`, data);
|
|
return response.data;
|
|
},
|
|
|
|
// Update order line
|
|
updateLine: async (orderId: string, lineId: string, data: UpdateSalesOrderLineDto): Promise<SalesOrderLine> => {
|
|
const response = await api.patch<SalesOrderLine>(`${ORDERS_URL}/${orderId}/lines/${lineId}`, data);
|
|
return response.data;
|
|
},
|
|
|
|
// Remove order line
|
|
removeLine: async (orderId: string, lineId: string): Promise<void> => {
|
|
await api.delete(`${ORDERS_URL}/${orderId}/lines/${lineId}`);
|
|
},
|
|
|
|
// ==================== Order Actions ====================
|
|
|
|
// Confirm order (send to customer)
|
|
confirmOrder: async (id: string): Promise<SalesOrder> => {
|
|
const response = await api.post<SalesOrder>(`${ORDERS_URL}/${id}/confirm`);
|
|
return response.data;
|
|
},
|
|
|
|
// Cancel order
|
|
cancelOrder: async (id: string): Promise<SalesOrder> => {
|
|
const response = await api.post<SalesOrder>(`${ORDERS_URL}/${id}/cancel`);
|
|
return response.data;
|
|
},
|
|
|
|
// Create invoice from order
|
|
createInvoice: async (id: string): Promise<{ orderId: string; invoiceId: string }> => {
|
|
const response = await api.post<{ orderId: string; invoiceId: string }>(`${ORDERS_URL}/${id}/invoice`);
|
|
return response.data;
|
|
},
|
|
|
|
// Get draft orders
|
|
getDrafts: async (filters?: Omit<SalesOrderFilters, 'status'>): Promise<SalesOrdersResponse> => {
|
|
return salesApi.getOrders({ ...filters, status: 'draft' });
|
|
},
|
|
|
|
// Get confirmed orders
|
|
getConfirmed: async (filters?: Omit<SalesOrderFilters, 'status'>): Promise<SalesOrdersResponse> => {
|
|
return salesApi.getOrders({ ...filters, status: 'sale' });
|
|
},
|
|
|
|
// Get orders by customer
|
|
getByCustomer: async (partnerId: string, filters?: Omit<SalesOrderFilters, 'partnerId'>): Promise<SalesOrdersResponse> => {
|
|
return salesApi.getOrders({ ...filters, partnerId });
|
|
},
|
|
|
|
// ==================== Quotations ====================
|
|
|
|
// Get all quotations
|
|
getQuotations: async (filters?: QuotationFilters): Promise<QuotationsResponse> => {
|
|
const params = new URLSearchParams();
|
|
if (filters?.companyId) params.append('companyId', filters.companyId);
|
|
if (filters?.partnerId) params.append('partnerId', filters.partnerId);
|
|
if (filters?.status) params.append('status', filters.status);
|
|
if (filters?.dateFrom) params.append('dateFrom', filters.dateFrom);
|
|
if (filters?.dateTo) params.append('dateTo', filters.dateTo);
|
|
if (filters?.search) params.append('search', filters.search);
|
|
if (filters?.page) params.append('page', String(filters.page));
|
|
if (filters?.limit) params.append('limit', String(filters.limit));
|
|
|
|
const response = await api.get<QuotationsResponse>(`${QUOTATIONS_URL}?${params.toString()}`);
|
|
return response.data;
|
|
},
|
|
|
|
// Get quotation by ID
|
|
getQuotationById: async (id: string): Promise<Quotation> => {
|
|
const response = await api.get<Quotation>(`${QUOTATIONS_URL}/${id}`);
|
|
return response.data;
|
|
},
|
|
|
|
// Create quotation
|
|
createQuotation: async (data: CreateQuotationDto): Promise<Quotation> => {
|
|
const response = await api.post<Quotation>(QUOTATIONS_URL, data);
|
|
return response.data;
|
|
},
|
|
|
|
// Send quotation
|
|
sendQuotation: async (id: string): Promise<Quotation> => {
|
|
const response = await api.post<Quotation>(`${QUOTATIONS_URL}/${id}/send`);
|
|
return response.data;
|
|
},
|
|
|
|
// Accept quotation
|
|
acceptQuotation: async (id: string): Promise<Quotation> => {
|
|
const response = await api.post<Quotation>(`${QUOTATIONS_URL}/${id}/accept`);
|
|
return response.data;
|
|
},
|
|
|
|
// Reject quotation
|
|
rejectQuotation: async (id: string, reason?: string): Promise<Quotation> => {
|
|
const response = await api.post<Quotation>(`${QUOTATIONS_URL}/${id}/reject`, { reason });
|
|
return response.data;
|
|
},
|
|
|
|
// Convert quotation to sales order
|
|
convertToOrder: async (id: string): Promise<SalesOrder> => {
|
|
const response = await api.post<SalesOrder>(`${QUOTATIONS_URL}/${id}/convert`);
|
|
return response.data;
|
|
},
|
|
|
|
// Generate quotation PDF
|
|
generateQuotationPdf: async (id: string): Promise<Blob> => {
|
|
const response = await api.get(`${QUOTATIONS_URL}/${id}/pdf`, {
|
|
responseType: 'blob',
|
|
});
|
|
return response.data;
|
|
},
|
|
|
|
// Download quotation PDF
|
|
downloadQuotationPdf: async (id: string, fileName?: string): Promise<void> => {
|
|
const blob = await salesApi.generateQuotationPdf(id);
|
|
const url = window.URL.createObjectURL(blob);
|
|
const link = document.createElement('a');
|
|
link.href = url;
|
|
link.download = fileName || `quotation-${id}.pdf`;
|
|
document.body.appendChild(link);
|
|
link.click();
|
|
document.body.removeChild(link);
|
|
window.URL.revokeObjectURL(url);
|
|
},
|
|
};
|