API/src/adapter/woocommerce.adapter.ts

311 lines
9.3 KiB
TypeScript

import { ISiteAdapter } from '../interface/site-adapter.interface';
import { WPService } from '../service/wp.service';
import {
UnifiedMediaDTO,
UnifiedOrderDTO,
UnifiedPaginationDTO,
UnifiedProductDTO,
UnifiedSearchParamsDTO,
UnifiedSubscriptionDTO,
UnifiedCustomerDTO,
} from '../dto/site-api.dto';
export class WooCommerceAdapter implements ISiteAdapter {
constructor(private site: any, private wpService: WPService) {}
private mapProduct(item: any): UnifiedProductDTO {
return {
id: item.id,
name: item.name,
type: item.type,
status: item.status,
sku: item.sku,
regular_price: item.regular_price,
sale_price: item.sale_price,
price: item.price,
stock_status: item.stock_status,
stock_quantity: item.stock_quantity,
images: (item.images || []).map((img: any) => ({
id: img.id,
src: img.src,
name: img.name,
alt: img.alt,
})),
attributes: item.attributes,
variations: item.variations,
date_created: item.date_created,
date_modified: item.date_modified,
raw: item,
};
}
private mapOrder(item: any): UnifiedOrderDTO {
const formatAddress = (addr: any) => {
if (!addr) return '';
const name = addr.fullname || `${addr.first_name || ''} ${addr.last_name || ''}`.trim();
return [
name,
addr.company,
addr.address_1,
addr.address_2,
addr.city,
addr.state,
addr.postcode,
addr.country,
addr.phone
].filter(Boolean).join(', ');
};
return {
id: item.id,
number: item.number,
status: item.status,
currency: item.currency,
total: item.total,
customer_id: item.customer_id,
customer_name: `${item.billing?.first_name || ''} ${
item.billing?.last_name || ''
}`.trim(),
email: item.billing?.email || '',
line_items: item.line_items,
sales: (item.line_items || []).map((li: any) => ({
...li,
productId: li.product_id,
// Ensure other fields match frontend expectation if needed
})),
billing: item.billing,
shipping: item.shipping,
billing_full_address: formatAddress(item.billing),
shipping_full_address: formatAddress(item.shipping),
payment_method: item.payment_method_title,
date_created: item.date_created,
raw: item,
};
}
private mapSubscription(item: any): UnifiedSubscriptionDTO {
return {
id: item.id,
status: item.status,
customer_id: item.customer_id,
billing_period: item.billing_period,
billing_interval: item.billing_interval,
start_date: item.start_date,
next_payment_date: item.next_payment_date,
line_items: item.line_items,
raw: item,
};
}
private mapMedia(item: any): UnifiedMediaDTO {
return {
id: item.id,
title: item.title?.rendered || '',
media_type: item.media_type,
mime_type: item.mime_type,
source_url: item.source_url,
date_created: item.date_created,
};
}
async getProducts(
params: UnifiedSearchParamsDTO
): Promise<UnifiedPaginationDTO<UnifiedProductDTO>> {
const { items, total, totalPages, page, per_page } =
await this.wpService.fetchResourcePaged<any>(
this.site,
'products',
params
);
return {
items: items.map(this.mapProduct),
total,
totalPages,
page,
per_page,
};
}
async getProduct(id: string | number): Promise<UnifiedProductDTO> {
const api = (this.wpService as any).createApi(this.site, 'wc/v3');
const res = await api.get(`products/${id}`);
return this.mapProduct(res.data);
}
async createProduct(data: Partial<UnifiedProductDTO>): Promise<UnifiedProductDTO> {
const res = await this.wpService.createProduct(this.site, data);
return this.mapProduct(res);
}
async updateProduct(id: string | number, data: Partial<UnifiedProductDTO>): Promise<UnifiedProductDTO> {
const res = await this.wpService.updateProduct(this.site, String(id), data as any);
return this.mapProduct(res);
}
async updateVariation(productId: string | number, variationId: string | number, data: any): Promise<any> {
const res = await this.wpService.updateVariation(this.site, String(productId), String(variationId), data);
return res;
}
async getOrderNotes(orderId: string | number): Promise<any[]> {
const api = (this.wpService as any).createApi(this.site, 'wc/v3');
const res = await api.get(`orders/${orderId}/notes`);
return res.data;
}
async createOrderNote(orderId: string | number, data: any): Promise<any> {
const api = (this.wpService as any).createApi(this.site, 'wc/v3');
const res = await api.post(`orders/${orderId}/notes`, data);
return res.data;
}
async deleteProduct(id: string | number): Promise<boolean> {
const api = (this.wpService as any).createApi(this.site, 'wc/v3');
try {
await api.delete(`products/${id}`, { force: true });
return true;
} catch (e) {
return false;
}
}
async batchProcessProducts(
data: { create?: any[]; update?: any[]; delete?: Array<string | number> }
): Promise<any> {
return await this.wpService.batchProcessProducts(this.site, data);
}
async getOrders(
params: UnifiedSearchParamsDTO
): Promise<UnifiedPaginationDTO<UnifiedOrderDTO>> {
const { items, total, totalPages, page, per_page } =
await this.wpService.fetchResourcePaged<any>(this.site, 'orders', params);
return {
items: items.map(this.mapOrder),
total,
totalPages,
page,
per_page,
};
}
async getOrder(id: string | number): Promise<UnifiedOrderDTO> {
const api = (this.wpService as any).createApi(this.site, 'wc/v3');
const res = await api.get(`orders/${id}`);
return this.mapOrder(res.data);
}
async createOrder(data: Partial<UnifiedOrderDTO>): Promise<UnifiedOrderDTO> {
const api = (this.wpService as any).createApi(this.site, 'wc/v3');
const res = await api.post('orders', data);
return this.mapOrder(res.data);
}
async updateOrder(id: string | number, data: Partial<UnifiedOrderDTO>): Promise<boolean> {
return await this.wpService.updateOrder(this.site, String(id), data as any);
}
async deleteOrder(id: string | number): Promise<boolean> {
const api = (this.wpService as any).createApi(this.site, 'wc/v3');
await api.delete(`orders/${id}`, { force: true });
return true;
}
async getSubscriptions(
params: UnifiedSearchParamsDTO
): Promise<UnifiedPaginationDTO<UnifiedSubscriptionDTO>> {
const { items, total, totalPages, page, per_page } =
await this.wpService.fetchResourcePaged<any>(
this.site,
'subscriptions',
params
);
return {
items: items.map(this.mapSubscription),
total,
totalPages,
page,
per_page,
};
}
async getMedia(
params: UnifiedSearchParamsDTO
): Promise<UnifiedPaginationDTO<UnifiedMediaDTO>> {
const { items, total, totalPages } = await this.wpService.getMedia(
this.site.id,
params.page || 1,
params.per_page || 20
);
return {
items: items.map(this.mapMedia),
total,
totalPages,
page: params.page || 1,
per_page: params.per_page || 20,
};
}
async deleteMedia(id: string | number): Promise<boolean> {
await this.wpService.deleteMedia(Number(this.site.id), Number(id), true);
return true;
}
async updateMedia(id: string | number, data: any): Promise<any> {
return await this.wpService.updateMedia(Number(this.site.id), Number(id), data);
}
private mapCustomer(item: any): UnifiedCustomerDTO {
return {
id: item.id,
email: item.email,
first_name: item.first_name,
last_name: item.last_name,
username: item.username,
phone: item.billing?.phone || item.shipping?.phone,
billing: item.billing,
shipping: item.shipping,
raw: item,
};
}
async getCustomers(params: UnifiedSearchParamsDTO): Promise<UnifiedPaginationDTO<UnifiedCustomerDTO>> {
const { items, total, totalPages, page, per_page } = await this.wpService.fetchResourcePaged<any>(
this.site,
'customers',
params
);
return {
items: items.map((i: any) => this.mapCustomer(i)),
total,
totalPages,
page,
per_page,
};
}
async getCustomer(id: string | number): Promise<UnifiedCustomerDTO> {
const api = (this.wpService as any).createApi(this.site, 'wc/v3');
const res = await api.get(`customers/${id}`);
return this.mapCustomer(res.data);
}
async createCustomer(data: Partial<UnifiedCustomerDTO>): Promise<UnifiedCustomerDTO> {
const api = (this.wpService as any).createApi(this.site, 'wc/v3');
const res = await api.post('customers', data);
return this.mapCustomer(res.data);
}
async updateCustomer(id: string | number, data: Partial<UnifiedCustomerDTO>): Promise<UnifiedCustomerDTO> {
const api = (this.wpService as any).createApi(this.site, 'wc/v3');
const res = await api.put(`customers/${id}`, data);
return this.mapCustomer(res.data);
}
async deleteCustomer(id: string | number): Promise<boolean> {
const api = (this.wpService as any).createApi(this.site, 'wc/v3');
await api.delete(`customers/${id}`, { force: true });
return true;
}
}