feat: implement dispensing module with transaction-safe stock management, FEFO allocation, and H1 compliance reporting

This commit is contained in:
2026-08-19 11:05:04 +05:30
parent fd77985cf9
commit ea49fe800f
32 changed files with 1150 additions and 53 deletions
+53
View File
@@ -0,0 +1,53 @@
import { pool } from './src/db/pool';
import { DispensingService } from './src/modules/dispensing/service';
async function runTest() {
const dispensingService = new DispensingService();
const tenantId = 't1';
// 1. Create a fake product with MRP = 20, pack_size = 10
const productId = 'prd_test_' + Date.now();
await pool.query(`
INSERT INTO products (id, brand_name, mrp, pack_size, tenant_id)
VALUES ($1, 'Test Medicine Strip', 20.00, 10, $2)
`, [productId, tenantId]);
console.log(`Created product: ${productId} with MRP 20 and pack_size 10`);
// 2. Add some stock for it so it doesn't fail expiry/stock checks
const batchNo = 'B_TEST_' + Date.now();
const nextYear = new Date(Date.now() + 365*24*60*60*1000).toISOString();
await pool.query(`
INSERT INTO batches (batch_no, product_id, expiry, qty_on_hand, tenant_id)
VALUES ($1, $2, $3, 100, $4)
`, [batchNo, productId, nextYear, tenantId]);
console.log(`Added batch ${batchNo} with 100 qty`);
// 3. Test Dispensing Flow (Dispense 10 tablets)
const payload = {
subject_ref: 'Patient_123',
items: [
{ product_id: productId, qty: 10 }
]
};
try {
console.log(`\nAttempting to dispense 10 tablets...`);
const result = await dispensingService.executeDispensing(payload, 'user1', tenantId);
console.log(`\nDispensing Successful!`);
console.log(`Transaction ID: ${result.dispensing_id}`);
console.log(`Calculated Total Amount: ₹${result.total_amount}`);
if (parseFloat(result.total_amount) === 20) {
console.log('✅ TEST PASSED: 10 tablets at (20 MRP / 10 pack_size) correctly calculated as 20 rupees!');
} else {
console.log('❌ TEST FAILED: Total amount is not 20 rupees.');
}
} catch (err) {
console.error('Dispensing Error:', err);
}
process.exit(0);
}
runTest();