mirror of
https://github.com/christianvidalwolf-prog/CrazeAnalytix.git
synced 2026-08-03 11:35:24 +02:00
Fix: implement definitive revenue integrity filter with ASIN validation and strict marketplace whitelist
This commit is contained in:
@@ -307,16 +307,48 @@ const isAllowedCustomer = (customer: string): boolean => {
|
||||
if (!customer) return false;
|
||||
const normCustomer = customer.trim().toLowerCase();
|
||||
|
||||
// Strict business rule: Only records from recognized Amazon marketplaces are included in Sell-Out revenue.
|
||||
// This excludes marketing spend, financial adjustments, and non-Amazon channels.
|
||||
const isAmazon = normCustomer.startsWith('amazon') || normCustomer === 'pan-eu';
|
||||
// STRICT WHITELIST: Only these Exact Names are valid for Sell-Out Revenue.
|
||||
const whitelist = [
|
||||
'amazon de', 'amazon uk', 'amazon fr', 'amazon es', 'amazon it',
|
||||
'amazon nl', 'amazon pl', 'amazon be', 'amazon se', 'amazon sc',
|
||||
'pan-eu'
|
||||
];
|
||||
|
||||
// Additional check: Ensure it's not JUST a country code (often used in ad-spend records)
|
||||
const isOnlyCountryCode = ['uk', 'de', 'it', 'fr', 'es', 'nl', 'se', 'pl', 'be'].includes(normCustomer);
|
||||
if (!whitelist.includes(normCustomer)) return false;
|
||||
return true;
|
||||
};
|
||||
|
||||
if (isOnlyCountryCode && !normCustomer.startsWith('amazon')) return false;
|
||||
/**
|
||||
* Validates if a record is a real sale or a marketing/spend entry.
|
||||
* Marketing entries often have placeholder units (1) or missing ASINs.
|
||||
*/
|
||||
export const isRealSale = (record: any): boolean => {
|
||||
const asin = String(record.asin || '').toUpperCase().trim();
|
||||
const sku = String(record.sku || '').toUpperCase().trim();
|
||||
const title = String(record.title || '').toUpperCase().trim();
|
||||
const line = String(record.line || '').toUpperCase().trim();
|
||||
|
||||
return isAmazon;
|
||||
// 1. Strict ASIN Format: Amazon ASINs are 10 letters/numbers
|
||||
if (!asin || asin.length < 5 || asin.length > 20) return false;
|
||||
|
||||
// 2. Negative Keywords: Exclude records that suggest marketing or spend instead of a product
|
||||
const negativeKeywords = [
|
||||
'SPEND', 'MARKETING', 'ADVERTISING', 'AD-SPEND', 'AD_SPEND',
|
||||
'SUMMARY', 'TOTAL', 'ADJUSTMENT', 'FINANCIAL', 'CREDIT', 'FEE'
|
||||
];
|
||||
|
||||
for (const kw of negativeKeywords) {
|
||||
if (asin.includes(kw)) return false;
|
||||
if (sku.includes(kw)) return false;
|
||||
if (title.includes(kw)) return false;
|
||||
if (line.includes(kw)) return false;
|
||||
}
|
||||
|
||||
// 3. Units check: Real sales must have units.
|
||||
// Records with 0 units or negative units (unless it's a return, but usually returns have an ASIN)
|
||||
if (!record.units || record.units <= 0) return false;
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
// --- SALES / SELL OUT MAPPING ---
|
||||
@@ -1165,7 +1197,7 @@ export const filterData = (
|
||||
// These filters ensure that only valid Amazon sales are aggregated,
|
||||
// excluding ad spend and marketing records that might be present in the raw source.
|
||||
if (!isAllowedCustomer(item.customer)) return false;
|
||||
if (item.units === 0) return false;
|
||||
if (!isRealSale(item)) return false;
|
||||
|
||||
// 1. Month Logic: Handle "Apr-23" matching "Apr" filter
|
||||
const recordMonth = item.month; // e.g. "Apr-23"
|
||||
|
||||
Reference in New Issue
Block a user