| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 |
- import zlib from 'node:zlib';
- import {
- activeAmazonShops, allRows, dateValue, forward, hash, log,
- shopPointer, sleep, updateObject, upsertMany,
- } from './sp-api-collector-lib.mjs';
- function parseDocument(content) {
- const trimmed = content.replace(/^\uFEFF/, '').trim();
- if (!trimmed) return [];
- const parsed = JSON.parse(trimmed);
- const rows = [];
- for (const [section, value] of Object.entries(parsed)) {
- if (!Array.isArray(value)) continue;
- for (const item of value) {
- rows.push({ _section: section, ...(item && typeof item === 'object' ? item : { value: item }) });
- }
- }
- return rows.length ? rows : [parsed];
- }
- const shops = await activeAmazonShops();
- const reports = (await allRows('Reports')).filter(report =>
- report.recordKey?.startsWith('MP:')
- && report.reportType === 'GET_SALES_AND_TRAFFIC_REPORT'
- && report.isParsed !== true
- && report.processingStatus === 'DONE'
- && report.reportDocumentId
- );
- for (const report of reports) {
- const shop = shops.find(item => item.objectId === report.shop?.objectId);
- if (!shop) {
- log('sales_report_skipped', { reportId: report.reportId, reason: 'shop not found' });
- continue;
- }
- try {
- const document = await forward(shop.objectId,
- `/reports/2021-06-30/documents/${encodeURIComponent(report.reportDocumentId)}`,
- 'GET', undefined, 5);
- if (!document.url) throw new Error('Report document returned no URL');
- const response = await fetch(document.url, { signal: AbortSignal.timeout(300000) });
- if (!response.ok) throw new Error(`Report download failed: ${response.status}`);
- let bytes = Buffer.from(await response.arrayBuffer());
- if (document.compressionAlgorithm === 'GZIP') bytes = zlib.gunzipSync(bytes);
- const rows = parseDocument(new TextDecoder('utf-8').decode(bytes));
- const marketplaceKey = [...(report.marketplaceIds || [])].sort().join(',') || shop.marketplaceId;
- const objects = rows.map(row => {
- const rowHash = hash(row);
- return {
- recordKey: `${report.region || 'UNKNOWN'}:${marketplaceKey}:${report.reportType}:${rowHash}`,
- rowHash,
- reportType: report.reportType,
- reportId: report.reportId,
- region: report.region || '',
- marketplaceIds: report.marketplaceIds || [],
- capturedAt: dateValue(new Date()),
- rowData: row,
- rawData: row,
- shop: shopPointer(shop.objectId),
- };
- });
- const saved = await upsertMany('AmazonReportRow', objects);
- await updateObject('Reports', report.objectId, {
- isParsed: true,
- parsedAt: dateValue(new Date()),
- parsedRecords: objects.length,
- });
- log('sales_report_reparsed', {
- marketplaceIds: report.marketplaceIds,
- reportId: report.reportId,
- rows: objects.length,
- ...saved,
- });
- } catch (error) {
- log('sales_report_reparse_failed', { reportId: report.reportId, error: error.message });
- }
- await sleep(1000);
- }
- log('sales_report_reparse_finished', { reports: reports.length });
|