mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-20 21:41:57 +00:00
184 lines
5.0 KiB
TypeScript
184 lines
5.0 KiB
TypeScript
import { isResponseError } from '@/lib/api-helper';
|
|
import { BaseApiService } from '@/services/api/base';
|
|
import { httpClient, httpClientFetcher } from '@/services/http/client';
|
|
import { BaseApiResponse } from '@/types/api/api-general';
|
|
import {
|
|
Marketing,
|
|
CreateSalesOrderPayload,
|
|
UpdateSalesOrderPayload,
|
|
CreateDeliveryOrderPayload,
|
|
UpdateDeliveryOrderPayload,
|
|
} from '@/types/api/marketing/marketing';
|
|
import toast from 'react-hot-toast';
|
|
import * as XLSX from 'xlsx';
|
|
import { formatCurrency, formatDate, formatTitleCase } from '@/lib/helper';
|
|
|
|
/**
|
|
* 💡 Helper untuk membuat respons dummy
|
|
* @param data Data yang akan dimasukkan ke dalam body respons
|
|
*/
|
|
const createDummyResponse = <T>(data: T): BaseApiResponse<T> => ({
|
|
code: 200,
|
|
status: 'success',
|
|
message: 'Data retrieved successfully (MOCK)',
|
|
data: data,
|
|
});
|
|
|
|
export class SalesOrderService extends BaseApiService<
|
|
Marketing,
|
|
CreateSalesOrderPayload,
|
|
UpdateSalesOrderPayload
|
|
> {
|
|
constructor(basePath: string = '/marketing') {
|
|
super(basePath);
|
|
}
|
|
|
|
/**
|
|
* Approve single marketing data
|
|
*/
|
|
async singleApproval(
|
|
id: number,
|
|
action: 'APPROVED' | 'REJECTED',
|
|
notes?: string
|
|
): Promise<BaseApiResponse<{ message: string }> | undefined> {
|
|
try {
|
|
const path = `${this.basePath}/approvals`;
|
|
return await httpClient<BaseApiResponse<{ message: string }>>(path, {
|
|
method: 'POST',
|
|
body: {
|
|
action: action,
|
|
approvable_ids: [id],
|
|
notes: notes || `${action} marketing ${id}`,
|
|
},
|
|
});
|
|
} catch (error) {
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Bulk approve
|
|
*/
|
|
async bulkApprovals(
|
|
ids: number[],
|
|
action: 'APPROVED' | 'REJECTED',
|
|
notes?: string
|
|
): Promise<BaseApiResponse<{ message: string }> | undefined> {
|
|
try {
|
|
const path = `${this.basePath}/approvals`;
|
|
return await httpClient<BaseApiResponse<{ message: string }>>(path, {
|
|
method: 'POST',
|
|
body: {
|
|
action: action,
|
|
approvable_ids: ids,
|
|
notes: notes || `${action} marketing ${ids.join(', ')}`,
|
|
},
|
|
});
|
|
} catch (error) {
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Delivery
|
|
*/
|
|
async delivery(
|
|
id: number,
|
|
notes?: string
|
|
): Promise<BaseApiResponse<{ message: string }> | undefined> {
|
|
try {
|
|
const path = `${this.basePath}/approvals`;
|
|
return await httpClient<BaseApiResponse<{ message: string }>>(path, {
|
|
method: 'POST',
|
|
body: {
|
|
action: 'APPROVED',
|
|
approvable_ids: [id],
|
|
notes: notes || `Delivery marketing ${id}`,
|
|
},
|
|
});
|
|
} catch (error) {
|
|
throw error;
|
|
}
|
|
}
|
|
}
|
|
class MarketingExportService extends BaseApiService<
|
|
Marketing,
|
|
unknown,
|
|
unknown
|
|
> {
|
|
constructor(basePath: string = '/marketing') {
|
|
super(basePath);
|
|
}
|
|
|
|
/**
|
|
* Export to Excel
|
|
*/
|
|
async exportToExcel(initialQueryString: string) {
|
|
const params = new URLSearchParams(initialQueryString);
|
|
const queryString = `?${params.toString()}`;
|
|
|
|
try {
|
|
const marketingData = await httpClientFetcher<
|
|
BaseApiResponse<Marketing[]>
|
|
>(`${this.basePath}${queryString}`);
|
|
|
|
if (isResponseError(marketingData)) {
|
|
toast.error('Gagal melakukan export marketing! Coba lagi.');
|
|
return;
|
|
}
|
|
|
|
const rows = marketingData.data;
|
|
|
|
const formattedRows = [];
|
|
|
|
for (let i = 0; i < rows.length; i++) {
|
|
const row = rows[i];
|
|
const approval = row.latest_approval;
|
|
const isRejected = approval?.action === 'REJECTED';
|
|
|
|
// Calculate grand total from sales_order products
|
|
const grandTotal =
|
|
row.sales_order
|
|
?.map((product) => product.total_price)
|
|
.reduce((a, b) => a + b, 0) ?? 0;
|
|
|
|
// Get product names
|
|
const products =
|
|
row.sales_order
|
|
?.map((product) => product.product_warehouse?.product?.name)
|
|
.filter(Boolean)
|
|
.join(', ') ?? '';
|
|
|
|
formattedRows.push({
|
|
'No. Order': row.so_number,
|
|
Tanggal: formatDate(row.so_date, 'DD-MM-YYYY'),
|
|
Status: isRejected
|
|
? 'Ditolak'
|
|
: formatTitleCase(approval?.step_name || ''),
|
|
Customer: row.customer?.name || '',
|
|
'Grand Total': formatCurrency(grandTotal),
|
|
Products: products,
|
|
Notes: row.notes || '',
|
|
});
|
|
}
|
|
|
|
const ws = XLSX.utils.json_to_sheet(formattedRows);
|
|
const wb = XLSX.utils.book_new();
|
|
XLSX.utils.book_append_sheet(wb, ws, 'marketing');
|
|
|
|
// triggers download in browser
|
|
XLSX.writeFile(wb, 'marketing.xlsx');
|
|
} catch (error) {
|
|
toast.error('Gagal melakukan export marketing! Coba lagi.');
|
|
}
|
|
}
|
|
}
|
|
|
|
export const SalesOrderApi = new SalesOrderService('/marketing/sales-orders');
|
|
export const DeliveryOrderApi = new BaseApiService<
|
|
Marketing,
|
|
CreateDeliveryOrderPayload,
|
|
UpdateDeliveryOrderPayload
|
|
>('/marketing/delivery-orders');
|
|
export const MarketingApi = new MarketingExportService('/marketing');
|