58ca4e68db
- Go backend API with full CRUD for all modules (CRM, Sales, Finance, HR, Legal, Marketing, Support, Purchase, Inventory, Projects, Automation, Analytics) - Rust analytics service with parallel report generation - C runtime with POSIX shared memory IPC - PostgreSQL schema with 30+ tables, full migrations - Redis cache, sessions, pub/sub - Kafka event streaming with Zookeeper - WebSocket hub for real-time updates - Automation engine with cron jobs, workflows, event triggers - JWT authentication, multi-tenant from start - Docker Compose with all services - Nginx reverse proxy with rate limiting - Integration tests passing - Feature gap analysis against Fortnox/Odoo/Visma Refs: BOC-001
86 lines
2.9 KiB
JavaScript
86 lines
2.9 KiB
JavaScript
// ============================================================
|
|
// PAYOUT CRON — Veckovis utbetalning
|
|
// ============================================================
|
|
// Kör varje måndag 09:00 UTC
|
|
// Hämtar alla zoomers med payout-schema och utför utbetalning
|
|
|
|
const { Pool } = require('pg');
|
|
const axios = require('axios');
|
|
|
|
const pool = new Pool({
|
|
connectionString: process.env.DATABASE_URL
|
|
});
|
|
|
|
const API_BASE = process.env.API_BASE || 'http://localhost:8080';
|
|
|
|
async function executeWeeklyPayouts() {
|
|
console.log('💸 Startar veckovis payout...');
|
|
console.log(`📅 ${new Date().toISOString()}`);
|
|
|
|
try {
|
|
// Hämta dagens dag (1 = Måndag)
|
|
const today = new Date().getDay();
|
|
|
|
if (today !== 1) {
|
|
console.log('📅 Idag är inte måndag. Avslutar.');
|
|
return;
|
|
}
|
|
|
|
// Hämta alla aktiva payout-scheman för idag
|
|
const schedules = await pool.query(
|
|
`SELECT ps.*, zw.balance_qz_token, zw.stripe_connect_account_id, z.name as zoomer_name
|
|
FROM payout_schedules ps
|
|
JOIN zoomer_wallets zw ON zw.id = ps.wallet_id
|
|
JOIN zoomers z ON z.id = ps.zoomer_id
|
|
WHERE ps.day_of_week = $1
|
|
AND ps.status = 'active'
|
|
AND zw.stripe_connect_status = 'active'
|
|
AND zw.balance_qz_token >= ps.minimum_qz_token`,
|
|
[today]
|
|
);
|
|
|
|
console.log(`📊 Hittade ${schedules.rows.length} zoomers för payout`);
|
|
|
|
let successCount = 0;
|
|
let failCount = 0;
|
|
|
|
for (const schedule of schedules.rows) {
|
|
try {
|
|
console.log(`\n💸 Behandlar payout för ${schedule.zoomer_name}...`);
|
|
console.log(` Saldo: ${schedule.balance_qz_token} QZ TOKEN`);
|
|
|
|
// Anropa API för att utföra payout
|
|
const response = await axios.post(`${API_BASE}/api/v1/payouts/execute`, {
|
|
zoomer_id: schedule.zoomer_id
|
|
});
|
|
|
|
if (response.data.success) {
|
|
console.log(` ✅ Payout utförd: $${response.data.results[0]?.amount_usd}`);
|
|
successCount++;
|
|
}
|
|
} catch (error) {
|
|
console.error(` ❌ Payout misslyckades: ${error.message}`);
|
|
failCount++;
|
|
}
|
|
}
|
|
|
|
console.log('\n📊 Payout-sammanfattning:');
|
|
console.log(` Lyckade: ${successCount}`);
|
|
console.log(` Misslyckade: ${failCount}`);
|
|
console.log(` Totalt: ${schedules.rows.length}`);
|
|
|
|
} catch (error) {
|
|
console.error('❌ Kritiskt fel vid payout:', error);
|
|
process.exit(1);
|
|
} finally {
|
|
await pool.end();
|
|
}
|
|
}
|
|
|
|
// Kör om detta är huvudscript
|
|
if (require.main === module) {
|
|
executeWeeklyPayouts();
|
|
}
|
|
|
|
module.exports = { executeWeeklyPayouts };
|