Files
Craze-Data-check/src/services/businessCentral.ts
T

108 lines
2.9 KiB
TypeScript
Raw Normal View History

const BC_PROXY_URL = '/api/bc-proxy';
const BC_EXPORT_URL = '/api/bc-export';
export interface BCUpdateResult {
success: boolean;
error?: string;
}
export interface BCDownloadResult {
success: boolean;
error?: string;
filename?: string;
}
async function readResponsePayload(res: Response): Promise<{ data: any; rawText: string }> {
const rawText = await res.text();
if (!rawText.trim()) {
return { data: null, rawText };
}
try {
return { data: JSON.parse(rawText), rawText };
} catch {
return { data: rawText, rawText };
}
}
export async function updateCpnpNoInBC(articleNo: string, cpnpNo: string): Promise<BCUpdateResult> {
try {
const res = await fetch(BC_PROXY_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ articleNo, cpnpNo }),
});
const { data, rawText } = await readResponsePayload(res);
if (!res.ok || !data?.success) {
const error =
data?.error ||
(typeof data === 'string' && data.trim()) ||
rawText ||
`HTTP ${res.status}`;
return { success: false, error };
}
return { success: true };
} catch (err: any) {
return { success: false, error: err.message };
}
}
function getFilenameFromDisposition(contentDisposition: string | null): string | null {
if (!contentDisposition) return null;
const utf8Match = contentDisposition.match(/filename\*\s*=\s*UTF-8''([^;]+)/i);
if (utf8Match?.[1]) {
try {
return decodeURIComponent(utf8Match[1].trim().replace(/^"|"$/g, ''));
} catch {
return utf8Match[1].trim().replace(/^"|"$/g, '');
}
}
const filenameMatch = contentDisposition.match(/filename\s*=\s*([^;]+)/i);
if (filenameMatch?.[1]) {
return filenameMatch[1].trim().replace(/^"|"$/g, '');
}
return null;
}
export async function downloadBusinessCentralItemsExcel(): Promise<BCDownloadResult> {
try {
const res = await fetch(BC_EXPORT_URL, {
method: 'GET',
});
if (!res.ok) {
let error = `HTTP ${res.status}`;
try {
const { data, rawText } = await readResponsePayload(res);
error = data?.error || (typeof data === 'string' && data.trim()) || rawText || error;
} catch {
error = `HTTP ${res.status}`;
}
return { success: false, error };
}
const blob = await res.blob();
const filename =
getFilenameFromDisposition(res.headers.get('content-disposition')) ||
`BusinessCentral_Items_${new Date().toISOString().split('T')[0]}.xlsx`;
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = filename;
link.rel = 'noopener';
document.body.appendChild(link);
link.click();
link.remove();
URL.revokeObjectURL(url);
return { success: true, filename };
} catch (err: any) {
return { success: false, error: err.message };
}
}