feat: implement rewards module with referral/coupon systems, update tariff seeding, and add trip distance service for improved billing accuracy.
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
import { writeFileSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
import {
|
||||
buildDefinition,
|
||||
COUNTRY_TARIFFS,
|
||||
SERVICE_CLASSES,
|
||||
} from '../../modules/tariff/default-tariffs';
|
||||
|
||||
/**
|
||||
* يولّد `tariffs.sql` لتطبيقها على قاعدة **قائمة** — للمستأجرين الموجودين
|
||||
* قبل أن يصير الزرع تلقائياً.
|
||||
*
|
||||
* التشغيل: `npx ts-node src/database/seeds/generate-tariff-sql.ts`
|
||||
*
|
||||
* مستأجر جديد لا يحتاج هذا الملف إطلاقاً: `SeedService` يزرع له التعرفة من
|
||||
* **نفس** `default-tariffs.ts` عند الإقلاع. هذا المولّد للحاق بالقائم فقط،
|
||||
* ولذلك يقرأ من مصدر الحقيقة نفسه — نسختان من أرقام التسعير كانتا ستتباعدان.
|
||||
*
|
||||
* الناتج **آمن للتكرار**: كل تشغيل يطفئ الفعّالة ويُدرج `max(version)+1`،
|
||||
* فلا يبقى صفّان فعّالان لنفس (مستأجر، مدينة، فئة) — و`getActive` ترتّب
|
||||
* `version DESC` فكان الاختيار بينهما غير محدَّد.
|
||||
*/
|
||||
function generateSql(): string {
|
||||
let sql = `-- Tripz — تعرفة الانطلاق الافتراضية لكل بلد.\n`;
|
||||
sql += `-- مولَّد من src/database/seeds/generate-tariff-sql.ts — لا يُحرَّر يدوياً.\n`;
|
||||
sql += `-- المصدر: src/modules/tariff/default-tariffs.ts\n`;
|
||||
sql += `-- آمن للتكرار: كل تشغيل يطفئ الفعّالة ويُدرج نسخة أعلى.\n\n`;
|
||||
sql += `BEGIN;\n\n`;
|
||||
|
||||
for (const country of COUNTRY_TARIFFS) {
|
||||
sql += `-- ============ ${country.countryPack.toUpperCase()} (${country.currency}) ============\n`;
|
||||
|
||||
for (const serviceClass of Object.values(SERVICE_CLASSES)) {
|
||||
const definition = buildDefinition(country, serviceClass);
|
||||
const defJson = JSON.stringify(definition).replace(/'/g, "''");
|
||||
|
||||
// يطال **كل** مستأجر في هذا البلد لا سيرو وحده: تعرفة الانطلاق عامة،
|
||||
// وربطها بمستأجر واحد كان يترك كل مستأجر آخر بلا تسعير.
|
||||
sql += `-- ${serviceClass}\n`;
|
||||
sql += `UPDATE tripz_tariffs SET active = false\n`;
|
||||
sql += ` WHERE city = 'default' AND service_class = '${serviceClass}' AND active = true\n`;
|
||||
sql += ` AND tenant_id IN (SELECT id FROM tripz_tenants WHERE country_pack = '${country.countryPack}');\n`;
|
||||
sql += `INSERT INTO tripz_tariffs (id, tenant_id, city, service_class, version, active, definition)\n`;
|
||||
sql += `SELECT uuid_generate_v4(), t.id, 'default', '${serviceClass}',\n`;
|
||||
sql += ` COALESCE((SELECT MAX(version) FROM tripz_tariffs x\n`;
|
||||
sql += ` WHERE x.tenant_id = t.id AND x.city = 'default'\n`;
|
||||
sql += ` AND x.service_class = '${serviceClass}'), 0) + 1,\n`;
|
||||
sql += ` true, '${defJson}'::jsonb\n`;
|
||||
sql += ` FROM tripz_tenants t WHERE t.country_pack = '${country.countryPack}';\n\n`;
|
||||
}
|
||||
}
|
||||
|
||||
sql += `COMMIT;\n`;
|
||||
return sql;
|
||||
}
|
||||
|
||||
const out = join(__dirname, 'tariffs.sql');
|
||||
writeFileSync(out, generateSql());
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`✅ generated ${out}`);
|
||||
Reference in New Issue
Block a user