229 lines
5.1 KiB
TypeScript
229 lines
5.1 KiB
TypeScript
import { request } from "./http";
|
|
|
|
export interface ClientAddress {
|
|
line1: string | null;
|
|
line2: string | null;
|
|
postal_code: string | null;
|
|
city: string | null;
|
|
country_code: string | null;
|
|
full_address?: string;
|
|
}
|
|
|
|
export interface Client {
|
|
id: number;
|
|
client_category_id: number | null;
|
|
type_label?: string;
|
|
name: string;
|
|
vat_number: string | null;
|
|
siret: string | null;
|
|
email: string | null;
|
|
phone: string | null;
|
|
billing_address: ClientAddress;
|
|
group_id: number | null;
|
|
notes: string | null;
|
|
is_active: boolean;
|
|
default_tva_rate_id: number | null;
|
|
created_at: string;
|
|
updated_at: string;
|
|
}
|
|
|
|
export interface ClientListResponse {
|
|
data: Client[];
|
|
meta?: {
|
|
current_page: number;
|
|
last_page: number;
|
|
per_page: number;
|
|
total: number;
|
|
};
|
|
}
|
|
|
|
export interface ClientResponse {
|
|
data: Client;
|
|
}
|
|
|
|
export interface CreateClientPayload {
|
|
client_category_id?: number | null;
|
|
name: string;
|
|
vat_number?: string | null;
|
|
siret?: string | null;
|
|
email?: string | null;
|
|
phone?: string | null;
|
|
billing_address_line1?: string | null;
|
|
billing_address_line2?: string | null;
|
|
billing_postal_code?: string | null;
|
|
billing_city?: string | null;
|
|
billing_country_code?: string | null;
|
|
group_id?: number | null;
|
|
notes?: string | null;
|
|
is_active?: boolean;
|
|
default_tva_rate_id?: number | null;
|
|
}
|
|
|
|
export interface UpdateClientPayload extends Partial<CreateClientPayload> {
|
|
id: number;
|
|
}
|
|
|
|
export const ClientService = {
|
|
/**
|
|
* Get all clients with pagination
|
|
*/
|
|
async getAllClients(params?: {
|
|
page?: number;
|
|
per_page?: number;
|
|
search?: string;
|
|
is_active?: boolean;
|
|
group_id?: number;
|
|
}): Promise<ClientListResponse> {
|
|
const response = await request<ClientListResponse>({
|
|
url: "/api/clients",
|
|
method: "get",
|
|
params,
|
|
});
|
|
|
|
return response;
|
|
},
|
|
|
|
/**
|
|
* Get a specific client by ID
|
|
*/
|
|
async getClient(id: number): Promise<ClientResponse> {
|
|
const response = await request<ClientResponse>({
|
|
url: `/api/clients/${id}`,
|
|
method: "get",
|
|
});
|
|
|
|
return response;
|
|
},
|
|
|
|
/**
|
|
* Create a new client
|
|
*/
|
|
async createClient(payload: CreateClientPayload): Promise<ClientResponse> {
|
|
// Transform the payload to match Laravel form request expectations
|
|
const formattedPayload = this.transformClientPayload(payload);
|
|
|
|
const response = await request<ClientResponse>({
|
|
url: "/api/clients",
|
|
method: "post",
|
|
data: formattedPayload,
|
|
});
|
|
|
|
return response;
|
|
},
|
|
|
|
/**
|
|
* Update an existing client
|
|
*/
|
|
async updateClient(payload: UpdateClientPayload): Promise<ClientResponse> {
|
|
const { id, ...updateData } = payload;
|
|
const formattedPayload = this.transformClientPayload(updateData);
|
|
|
|
const response = await request<ClientResponse>({
|
|
url: `/api/clients/${id}`,
|
|
method: "put",
|
|
data: formattedPayload,
|
|
});
|
|
|
|
return response;
|
|
},
|
|
|
|
/**
|
|
* Delete a client
|
|
*/
|
|
async deleteClient(
|
|
id: number
|
|
): Promise<{ success: boolean; message: string }> {
|
|
const response = await request<{ success: boolean; message: string }>({
|
|
url: `/api/clients/${id}`,
|
|
method: "delete",
|
|
});
|
|
|
|
return response;
|
|
},
|
|
|
|
/**
|
|
* Transform client payload to match Laravel form request structure
|
|
*/
|
|
transformClientPayload(payload: Partial<CreateClientPayload>): any {
|
|
const transformed: any = { ...payload };
|
|
|
|
// Ensure boolean values are properly formatted
|
|
if (typeof transformed.is_active === "boolean") {
|
|
transformed.is_active = transformed.is_active ? 1 : 0;
|
|
}
|
|
|
|
// Remove undefined values to avoid sending them
|
|
Object.keys(transformed).forEach((key) => {
|
|
if (transformed[key] === undefined) {
|
|
delete transformed[key];
|
|
}
|
|
});
|
|
|
|
return transformed;
|
|
},
|
|
|
|
/**
|
|
* Search clients by name, email, or other criteria
|
|
*/
|
|
async searchClients(
|
|
query: string,
|
|
params?: {
|
|
// Remove pagination parameters since we're not using pagination
|
|
exact_match?: boolean;
|
|
}
|
|
): Promise<Client[]> {
|
|
const response = await request<{
|
|
data: Client[];
|
|
count: number;
|
|
message: string;
|
|
}>({
|
|
url: "/api/clients/searchBy",
|
|
method: "get",
|
|
params: {
|
|
name: query, // Changed from 'search' to 'name' to match your controller
|
|
exact_match: params?.exact_match || false,
|
|
},
|
|
});
|
|
return response.data; // Return just the data array
|
|
},
|
|
|
|
/**
|
|
* Get active clients only
|
|
*/
|
|
async getActiveClients(params?: {
|
|
page?: number;
|
|
per_page?: number;
|
|
}): Promise<ClientListResponse> {
|
|
const response = await request<ClientListResponse>({
|
|
url: "/api/clients",
|
|
method: "get",
|
|
params: {
|
|
is_active: true,
|
|
...params,
|
|
},
|
|
});
|
|
|
|
return response;
|
|
},
|
|
|
|
/**
|
|
* Toggle client active status
|
|
*/
|
|
async toggleClientStatus(
|
|
id: number,
|
|
isActive: boolean
|
|
): Promise<ClientResponse> {
|
|
const response = await request<ClientResponse>({
|
|
url: `/api/clients/${id}/status`,
|
|
method: "patch",
|
|
data: {
|
|
is_active: isActive,
|
|
},
|
|
});
|
|
|
|
return response;
|
|
},
|
|
};
|
|
|
|
export default ClientService;
|