Add referral/discount code to FCC carrier page + REF-JAYK05 agent
Frontend (order/fcc-carrier-registration): - Add a referral/discount code box on the review step that validates against /api/v1/discount/:code and shows the discount line + adjusted total. Discount applies to service fee + add-ons, never state filing fees. - Prefill + auto-apply from ?code= / ?ref= query param (referral links). Backend (fcc-carrier-registration route): - Accept discount_code, validate it, store discount_code/discount_cents, and subtract from the total. Checkout already reads discount_cents to apply the Stripe coupon. - Create a pending commission when the code belongs to an active sales agent. Commission fix (agents.createCommission): - Percent-type agents now earn commission_pct on ALL order types. Previously canada_crtc/formation/bundle used flat defaults and ignored percent agents. Agent: created sales agent Jay Kordic (The Horizon Group) with custom code REF-JAYK05 -> client gets 5% off discountable services, agent earns 15%. Idempotent setup script in scripts/create_agent_jaykordic.cjs.
This commit is contained in:
parent
1584a6692b
commit
53857574d3
4 changed files with 293 additions and 8 deletions
105
scripts/create_agent_jaykordic.cjs
Normal file
105
scripts/create_agent_jaykordic.cjs
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
#!/usr/bin/env node
|
||||
/**
|
||||
* Create sales agent "Jay Kordic" with custom referral code JAYK05.
|
||||
* - Client discount: 5% off all discountable service fees (discount_type='percent', value=5)
|
||||
* - Agent commission: 15% (commission_type='percent', commission_pct=15)
|
||||
*
|
||||
* Idempotent: re-running updates the existing rows instead of duplicating.
|
||||
*
|
||||
* Usage (from api/ so it loads api/.env):
|
||||
* cd api && node ../scripts/create_agent_jaykordic.cjs
|
||||
*/
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const { Client } = require("pg");
|
||||
|
||||
// Load DATABASE_URL from api/.env if not already in env
|
||||
function loadEnv() {
|
||||
if (process.env.DATABASE_URL) return;
|
||||
const envPath = path.resolve(__dirname, "../api/.env");
|
||||
if (!fs.existsSync(envPath)) return;
|
||||
for (const line of fs.readFileSync(envPath, "utf8").split("\n")) {
|
||||
const m = line.match(/^DATABASE_URL=(.*)$/);
|
||||
if (m) { process.env.DATABASE_URL = m[1].trim(); break; }
|
||||
}
|
||||
}
|
||||
|
||||
const CODE = "REF-JAYK05";
|
||||
const AGENT_NAME = "Jay Kordic";
|
||||
const AGENT_COMPANY = "The Horizon Group";
|
||||
const AGENT_EMAIL = "jay.kordic@performancewest.net"; // placeholder; update with real payout email
|
||||
const CLIENT_DISCOUNT_PCT = 5;
|
||||
const COMMISSION_PCT = 15;
|
||||
|
||||
(async () => {
|
||||
loadEnv();
|
||||
if (!process.env.DATABASE_URL) {
|
||||
console.error("DATABASE_URL not found. Run from api/ or export DATABASE_URL.");
|
||||
process.exit(1);
|
||||
}
|
||||
const c = new Client({ connectionString: process.env.DATABASE_URL });
|
||||
await c.connect();
|
||||
try {
|
||||
await c.query("BEGIN");
|
||||
|
||||
// 1) Upsert the discount code (5% off, partner attribution to Jay Kordic)
|
||||
const dc = await c.query(
|
||||
`INSERT INTO discount_codes (code, description, discount_type, discount_value, referral_partner, referral_email, referral_pct, active)
|
||||
VALUES ($1, $2, 'percent', $3, $4, $5, $6, TRUE)
|
||||
ON CONFLICT (code) DO UPDATE SET
|
||||
description = EXCLUDED.description,
|
||||
discount_type = EXCLUDED.discount_type,
|
||||
discount_value = EXCLUDED.discount_value,
|
||||
referral_partner = EXCLUDED.referral_partner,
|
||||
referral_email = EXCLUDED.referral_email,
|
||||
referral_pct = EXCLUDED.referral_pct,
|
||||
active = TRUE,
|
||||
updated_at = now()
|
||||
RETURNING id`,
|
||||
[CODE, `Sales agent: ${AGENT_NAME} (${AGENT_COMPANY})`, CLIENT_DISCOUNT_PCT, AGENT_NAME, AGENT_EMAIL, COMMISSION_PCT],
|
||||
);
|
||||
const discountCodeId = dc.rows[0].id;
|
||||
|
||||
// 2) Upsert the sales agent (commission paid as percent of order)
|
||||
const existing = await c.query("SELECT id FROM sales_agents WHERE email = $1 OR agent_code = $2", [AGENT_EMAIL, CODE]);
|
||||
if (existing.rows.length > 0) {
|
||||
await c.query(
|
||||
`UPDATE sales_agents SET
|
||||
agent_code = $1, discount_code_id = $2, name = $3, company = $4,
|
||||
commission_type = 'percent', commission_pct = $5,
|
||||
active = TRUE, updated_at = now()
|
||||
WHERE id = $6`,
|
||||
[CODE, discountCodeId, AGENT_NAME, AGENT_COMPANY, COMMISSION_PCT, existing.rows[0].id],
|
||||
);
|
||||
console.log(`Updated existing agent id=${existing.rows[0].id}`);
|
||||
} else {
|
||||
const ag = await c.query(
|
||||
`INSERT INTO sales_agents (agent_code, discount_code_id, name, email, company, commission_type, commission_pct, active, onboarded_at)
|
||||
VALUES ($1, $2, $3, $4, $5, 'percent', $6, TRUE, now())
|
||||
RETURNING id`,
|
||||
[CODE, discountCodeId, AGENT_NAME, AGENT_EMAIL, AGENT_COMPANY, COMMISSION_PCT],
|
||||
);
|
||||
console.log(`Created agent id=${ag.rows[0].id}`);
|
||||
}
|
||||
|
||||
await c.query("COMMIT");
|
||||
|
||||
// Verify
|
||||
const v = await c.query(
|
||||
`SELECT d.code, d.discount_type, d.discount_value, d.referral_partner, d.referral_email, d.referral_pct, d.active AS code_active,
|
||||
s.agent_code, s.name, s.commission_type, s.commission_pct, s.active AS agent_active
|
||||
FROM discount_codes d
|
||||
LEFT JOIN sales_agents s ON s.discount_code_id = d.id
|
||||
WHERE d.code = $1`,
|
||||
[CODE],
|
||||
);
|
||||
console.log("\nResult:");
|
||||
console.dir(v.rows[0], { depth: null });
|
||||
} catch (e) {
|
||||
await c.query("ROLLBACK").catch(() => {});
|
||||
console.error("ERROR:", e.message);
|
||||
process.exitCode = 1;
|
||||
} finally {
|
||||
await c.end();
|
||||
}
|
||||
})();
|
||||
Loading…
Add table
Add a link
Reference in a new issue