Start fixing points
This commit is contained in:
@@ -48,13 +48,13 @@ const BUCKET_CASE = (() => {
|
||||
return `CASE\n ${parts.join('\n ')}\n END`;
|
||||
})();
|
||||
|
||||
const DEFAULT_POINT_DOLLAR_VALUE = 0.005; // 1000 points = $5
|
||||
const DEFAULT_POINT_DOLLAR_VALUE = 0.005; // 1000 points = $5, so 200 points = $1
|
||||
|
||||
const DEFAULTS = {
|
||||
merchantFeePercent: 2.9,
|
||||
fixedCostPerOrder: 1.5,
|
||||
pointsPerDollar: 0,
|
||||
pointsRedemptionRate: 0,
|
||||
pointsRedemptionRate: 0, // Will be calculated from actual data
|
||||
pointDollarValue: DEFAULT_POINT_DOLLAR_VALUE,
|
||||
};
|
||||
|
||||
@@ -265,8 +265,8 @@ router.post('/simulate', async (req, res) => {
|
||||
${BUCKET_CASE} AS bucket_key
|
||||
FROM _order o
|
||||
${promoJoin}
|
||||
WHERE o.summary_total > 0
|
||||
AND o.summary_subtotal > 0
|
||||
WHERE o.summary_shipping > 0
|
||||
AND o.summary_total > 0
|
||||
AND o.order_status NOT IN (15)
|
||||
AND o.ship_method_selected <> 'holdit'
|
||||
AND o.ship_country = ?
|
||||
@@ -302,7 +302,7 @@ router.post('/simulate', async (req, res) => {
|
||||
GROUP BY order_id
|
||||
) AS c ON c.order_id = f.order_id
|
||||
LEFT JOIN (
|
||||
SELECT order_id, SUM(discount_amount_points) AS points_redeemed
|
||||
SELECT order_id, SUM(discount_amount) AS points_redeemed
|
||||
FROM order_discounts
|
||||
WHERE discount_type = 20 AND discount_active = 1
|
||||
GROUP BY order_id
|
||||
@@ -366,11 +366,54 @@ router.post('/simulate', async (req, res) => {
|
||||
? totals.pointsAwarded / totals.subtotal
|
||||
: 0;
|
||||
|
||||
const redemptionRate = config.points.redemptionRate != null
|
||||
? config.points.redemptionRate
|
||||
: totals.pointsAwarded > 0
|
||||
? Math.min(1, totals.pointsRedeemed / totals.pointsAwarded)
|
||||
: 0;
|
||||
// Calculate redemption rate with extended lookback to account for redemption lag
|
||||
let calculatedRedemptionRate = 0;
|
||||
if (config.points.redemptionRate != null) {
|
||||
calculatedRedemptionRate = config.points.redemptionRate;
|
||||
} else if (totals.pointsAwarded > 0) {
|
||||
// Use a 12-month lookback to capture more realistic redemption patterns
|
||||
const extendedStartDt = startDt.minus({ months: 12 });
|
||||
const extendedRedemptionQuery = `
|
||||
SELECT SUM(od.discount_amount) as extended_redemptions
|
||||
FROM order_discounts od
|
||||
JOIN _order o ON od.order_id = o.order_id
|
||||
WHERE od.discount_type = 20 AND od.discount_active = 1
|
||||
AND o.order_status NOT IN (15)
|
||||
AND o.ship_country = ?
|
||||
AND o.date_placed BETWEEN ? AND ?
|
||||
AND o.order_cid IN (
|
||||
SELECT DISTINCT order_cid
|
||||
FROM _order
|
||||
WHERE date_placed BETWEEN ? AND ?
|
||||
AND order_status NOT IN (15)
|
||||
AND summary_points > 0
|
||||
)
|
||||
`;
|
||||
|
||||
try {
|
||||
const [extendedRows] = await connection.execute(extendedRedemptionQuery, [
|
||||
shipCountry,
|
||||
formatDateForSql(extendedStartDt),
|
||||
formatDateForSql(endDt),
|
||||
formatDateForSql(startDt),
|
||||
formatDateForSql(endDt)
|
||||
]);
|
||||
|
||||
const extendedRedemptions = Number(extendedRows[0]?.extended_redemptions || 0);
|
||||
// Convert dollar redemptions to points using the correct conversion rate (200 points = $1)
|
||||
const extendedRedemptionsInPoints = extendedRedemptions * 200;
|
||||
if (extendedRedemptionsInPoints > 0) {
|
||||
calculatedRedemptionRate = Math.min(1, extendedRedemptionsInPoints / totals.pointsAwarded);
|
||||
} else {
|
||||
throw new Error('Unable to calculate redemption rate: no redemption data found in extended lookback period');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to calculate redemption rate:', error);
|
||||
throw error; // Let it fail instead of using fallback
|
||||
}
|
||||
}
|
||||
|
||||
const redemptionRate = calculatedRedemptionRate;
|
||||
|
||||
const pointDollarValue = config.points.pointDollarValue || DEFAULT_POINT_DOLLAR_VALUE;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user