import assert from 'node:assert/strict'; import { mkdtempSync, rmSync } from 'node:fs'; import { tmpdir } from 'node:os'; import { join } from 'node:path'; import LibDashStore from '../src/index.js'; import { BetterSqlite3Provider } from '../src/providers/sqlite3/index.js'; async function run() { console.log('--- Testing Delivery Summary, Ledger Sync & Filtering in dashdbschema ---'); const tempDir = mkdtempSync(join(tmpdir(), 'test-delivery-summary-')); const dbFile = join(tempDir, 'test.db'); const storageDir = join(tempDir, 'storage'); const provider = new BetterSqlite3Provider({ filename: dbFile, storageDir, }); await provider.initialize(); const store = await new LibDashStore(provider); try { const googleAuthId = await store.google_auth.add('delivery-summary-test@example.com'); const company = await store.company.create({ name: 'Delivery Summary Corp', iso639: 'de', taxrate: 19, reducedtaxrate: 7, googleAuthId, }); await store.google_auth.setSelectedCompany(googleAuthId, company.id); const warehouse = await store.warehouse.create(googleAuthId, { name: 'Hauptlager' }); await store.unit.upsert(googleAuthId, { si: 'stk', basesi: 'stk', basesifactor: 1, symbol: 'Stk', name: 'Stück', }); const supplierAlpha = await store.supplier.create(googleAuthId, { name: 'Alpha Supplier GmbH', }); const supplierBeta = await store.supplier.create(googleAuthId, { name: 'Beta Logistics Inc', }); // 1. Create articles: // Art1: track_stock = 1 (Stock item) const artStock1 = await store.article.createUnderParent({ googleAuthId, parentId: company.rootCategoryId, name: 'Stock Item 1', track_stock: 1, }); // Art2: track_stock = 1 (Stock item) const artStock2 = await store.article.createUnderParent({ googleAuthId, parentId: company.rootCategoryId, name: 'Stock Item 2', track_stock: 1, }); // Art3: track_stock = 0 (Service / Non-stock item) const artService = await store.article.createUnderParent({ googleAuthId, parentId: company.rootCategoryId, name: 'Shipping Freight Fee', track_stock: 0, }); // 2. Create Delivery 1: // Has 2 lines: artStock1 (qty 10), artService (qty 1) const delivery1 = await store.delivery.create(googleAuthId, { date: '2026-08-01T10:00:00Z', externalNumber: 'DEL-ALPHA-1001', supplierId: supplierAlpha.id, lines: [ { sku: artStock1.sku, name: 'Stock Item 1', amount: 10, net: 50, taxrate: 19 }, { sku: artService.sku, name: 'Shipping Freight Fee', amount: 1, net: 10, taxrate: 19 }, ], }); console.log('Delivery 1 created with id:', delivery1.id); // Verify deliverysummary row for delivery 1: // positions = 2, total_quantity = 11, stock_positions = 1, booked_positions = 0, unbooked_positions = 1, is_booked = 0 let sum1 = provider.db.prepare('SELECT * FROM deliverysummary WHERE manifest_id = ?').get(delivery1.id); assert(sum1, 'deliverysummary row for delivery 1 must exist'); assert.equal(sum1.positions, 2, 'Total positions should be 2'); assert.equal(sum1.stock_positions, 1, 'Stock positions should be 1'); assert.equal(sum1.booked_positions, 0, 'Booked positions should initially be 0'); assert.equal(sum1.unbooked_positions, 1, 'Unbooked positions should initially be 1'); assert.equal(sum1.stock_quantity, 10, 'Stock quantity should be 10'); assert.equal(sum1.booked_quantity, 0, 'Booked quantity should initially be 0'); assert.equal(sum1.unbooked_quantity, 10, 'Unbooked quantity should initially be 10'); assert.equal(sum1.is_booked, 0, 'is_booked should be 0'); assert.equal(sum1.supplier_name, 'Alpha Supplier GmbH'); // 3. Create Delivery 2: // Has 1 line: artStock2 (qty 5), Supplier: Beta const delivery2 = await store.delivery.create(googleAuthId, { date: '2026-10-01T10:00:00Z', externalNumber: 'DEL-BETA-2002', supplierId: supplierBeta.id, lines: [ { sku: artStock2.sku, name: 'Stock Item 2', amount: 5, net: 20, taxrate: 19 }, ], }); let sum2 = provider.db.prepare('SELECT * FROM deliverysummary WHERE manifest_id = ?').get(delivery2.id); assert(sum2, 'deliverysummary row for delivery 2 must exist'); assert.equal(sum2.stock_positions, 1); assert.equal(sum2.unbooked_positions, 1); assert.equal(sum2.is_booked, 0); // 4. Book Delivery 1 partially: // Book 4 units of artStock1 in warehouse const lineStock1 = delivery1.lines.find((l) => l.sku === artStock1.sku); assert(lineStock1, 'lineStock1 must exist'); await store.ledger.add(googleAuthId, { manifestarticle_id: lineStock1.id, warehouse_id: warehouse.id, transaction_type: 'DELIVERY', amount: 4, transaction_text: 'Partial goods receipt', }); sum1 = provider.db.prepare('SELECT * FROM deliverysummary WHERE manifest_id = ?').get(delivery1.id); assert.equal(sum1.booked_positions, 0, 'Booked positions should still be 0 since 4 < 10'); assert.equal(sum1.unbooked_positions, 1); assert.equal(sum1.booked_quantity, 4); assert.equal(sum1.unbooked_quantity, 6); assert.equal(sum1.is_booked, 0); console.log('✓ Partial booking properly updated deliverysummary'); // 5. Book remaining 6 units of artStock1 await store.ledger.add(googleAuthId, { manifestarticle_id: lineStock1.id, warehouse_id: warehouse.id, transaction_type: 'DELIVERY', amount: 6, transaction_text: 'Final goods receipt', }); sum1 = provider.db.prepare('SELECT * FROM deliverysummary WHERE manifest_id = ?').get(delivery1.id); assert.equal(sum1.booked_positions, 1, 'Booked positions should now be 1'); assert.equal(sum1.unbooked_positions, 0, 'Unbooked positions should now be 0'); assert.equal(sum1.booked_quantity, 10); assert.equal(sum1.unbooked_quantity, 0); assert.equal(sum1.is_booked, 1, 'Delivery 1 should now be fully booked (is_booked = 1)'); console.log('✓ Full booking properly updated deliverysummary (is_booked = 1)'); // 6. Test windowed / paged list: // Both deliveries present const pagedAll = await store.delivery.list(googleAuthId, { offset: 0, limit: 10 }); assert.equal(pagedAll.total, 2); assert.equal(pagedAll.unfilteredTotal, 2); assert.equal(pagedAll.deliveries.length, 2); assert.equal(pagedAll.offset, 0); assert.equal(pagedAll.limit, 10); // Filter onlyUnbooked (Delivery 1 is fully booked, Delivery 2 is unbooked) const pagedUnbooked = await store.delivery.list(googleAuthId, { onlyUnbooked: true }); assert.equal(pagedUnbooked.total, 1, 'Only 1 delivery is unbooked'); assert.equal(pagedUnbooked.unfilteredTotal, 2, 'Unfiltered total remains 2'); assert.equal(pagedUnbooked.deliveries[0].id, delivery2.id); console.log('✓ onlyUnbooked filter returned only unbooked deliveries'); // Search filter: 'Beta' const searchBeta = await store.delivery.list(googleAuthId, { search: 'Beta' }); assert.equal(searchBeta.total, 1); assert.equal(searchBeta.unfilteredTotal, 2); assert.equal(searchBeta.deliveries[0].id, delivery2.id); // Search filter: 'ALPHA-1001' const searchNum = await store.delivery.list(googleAuthId, { search: 'ALPHA-1001' }); assert.equal(searchNum.total, 1); assert.equal(searchNum.deliveries[0].id, delivery1.id); // Test unpaged backwards compatibility const unpaged = await store.delivery.list(googleAuthId); assert(Array.isArray(unpaged), 'Unpaged list should return Array'); assert.equal(unpaged.length, 2); const d1 = unpaged.find((d) => d.id === delivery1.id); assert(d1.ledger, 'd1 should contain ledger summary object'); assert.equal(d1.ledger.totalPositions, 1); assert.equal(d1.ledger.bookedPositions, 1); assert.equal(d1.ledger.unbookedPositions, 0); assert.equal(d1.ledger.isBooked, true); const d2 = unpaged.find((d) => d.id === delivery2.id); assert.equal(d2.ledger.unbookedPositions, 1); assert.equal(d2.ledger.isBooked, false); console.log('✓ Unpaged list returns enriched deliveries with ledger summary'); // 7. Test rebuildSummaries provider.db.prepare('DELETE FROM deliverysummary').run(); const countEmpty = provider.db.prepare('SELECT COUNT(*) AS cnt FROM deliverysummary').get().cnt; assert.equal(countEmpty, 0); await store.delivery.rebuildSummaries(googleAuthId); const countRebuilt = provider.db.prepare('SELECT COUNT(*) AS cnt FROM deliverysummary').get().cnt; assert.equal(countRebuilt, 2, 'Rebuilt deliverysummary should have 2 rows'); const rebuiltD1 = provider.db.prepare('SELECT * FROM deliverysummary WHERE manifest_id = ?').get(delivery1.id); assert.equal(rebuiltD1.is_booked, 1); assert.equal(rebuiltD1.booked_quantity, 10); assert.equal(rebuiltD1.unbooked_quantity, 0); const rebuiltD2 = provider.db.prepare('SELECT * FROM deliverysummary WHERE manifest_id = ?').get(delivery2.id); assert.equal(rebuiltD2.is_booked, 0); assert.equal(rebuiltD2.unbooked_positions, 1); console.log('✓ rebuildSummaries restored all deliverysummary rows accurately'); console.log('--- ALL DELIVERY SUMMARY & FILTER TESTS PASSED ---'); } finally { try { rmSync(tempDir, { recursive: true, force: true }); } catch {} } } run().catch((err) => { console.error(err); process.exit(1); });