fix: include ads-only ASINs in merge and use unfiltered rows for totals

1. Changed weekTotals to use 'rows' instead of 'filteredRows' so totals
   always show complete sums regardless of search/growth filters
2. Added second pass in mergeSalesAndAdsData to include ads records for
   ASINs that have ad spend but no corresponding sales data
This commit is contained in:
Christian Vidal Wolf
2026-01-22 09:24:40 +01:00
parent 8de4521fbe
commit 8b47ab844e
2 changed files with 47 additions and 3 deletions
+44
View File
@@ -541,6 +541,50 @@ export const mergeSalesAndAdsData = (salesData: SalesRecord[], adsData: AdsRecor
};
});
// 3. Include ads-only records (ASINs with ads but no sales)
const usedAdsKeys = new Set<string>();
salesData.forEach(sale => {
const weekNum = sale.week || 0;
const key = `${sale.asin.trim().toUpperCase()}|${sale.customer.trim().toUpperCase()}|${sale.year}|${weekNum}`;
usedAdsKeys.add(key);
});
adsData.forEach(ad => {
const key = `${ad.asin.trim().toUpperCase()}|${ad.country.trim().toUpperCase()}|${ad.year}|${ad.week}`;
if (!usedAdsKeys.has(key)) {
// Create a CombinedKPIs record for ads-only data
mergedData.push({
id: `ads-${key}`,
marketplace: ad.country,
customer: ad.country,
month: '',
week: ad.week,
year: ad.year,
asin: ad.asin,
title: '',
line: '',
sku: '',
salesTotal: 0,
unitsTotal: 0,
salesAds: ad.attributedSales30d,
unitsAds: ad.attributedUnits30d,
cost: ad.cost,
clicks: ad.clicks,
impressions: ad.impressions,
salesOrganic: 0,
unitsOrganic: 0,
paidSalesShare: 0,
organicSalesShare: 0,
acos: ad.attributedSales30d > 0 ? (ad.cost / ad.attributedSales30d) * 100 : 0,
tacos: 0,
roas: ad.cost > 0 ? ad.attributedSales30d / ad.cost : 0,
ctr: ad.impressions > 0 ? (ad.clicks / ad.impressions) * 100 : 0,
cpc: ad.clicks > 0 ? ad.cost / ad.clicks : 0,
cvrUnits: ad.clicks > 0 ? (ad.attributedUnits30d / ad.clicks) * 100 : 0
});
}
});
return mergedData;
};