This commit is contained in:
seb
2026-10-23 02:43:35 +02:00
parent 919713fa53
commit 8a085986e5
6 changed files with 218 additions and 0 deletions

View File

@@ -0,0 +1,159 @@
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 main() {
console.log('--- Testing updated_at touch on all inventory movements ---');
const tempDir = mkdtempSync(join(tmpdir(), 'test-touch-'));
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('tester@example.com');
const company = await store.company.create({
name: 'Inventory Corp',
iso639: 'de',
taxrate: 19,
reducedtaxrate: 7,
googleAuthId,
});
await store.google_auth.setSelectedCompany(googleAuthId, company.id);
// Create warehouse
const wh = await store.warehouse.create(googleAuthId, { name: 'Hauptlager' });
const cat = await store.category.createUnderParent({
googleAuthId,
parentId: company.rootCategoryId,
name: 'Waren',
});
// Create article with past updated_at
const art = await store.article.createUnderParent({
googleAuthId,
parentId: cat.id,
sku: 'TEST-SKU',
name: 'Test Article',
track_stock: 1,
});
const oldTime = '2020-01-01T00:00:00.000Z';
await provider.query(`UPDATE article SET updated_at = @oldTime WHERE id = @id`, { oldTime, id: art.id });
const getUpdatedAt = async (articleId) => {
const res = await provider.query(`SELECT updated_at FROM article WHERE id = @articleId`, { articleId });
return res.rows[0]?.updated_at;
};
const initialUpdatedAt = await getUpdatedAt(art.id);
assert.equal(initialUpdatedAt, oldTime, 'Should start with old updated_at');
// 1. Test store.stock.adjust
console.log('1. Testing store.stock.adjust touches article.updated_at...');
await store.stock.adjust(googleAuthId, {
sku: 'TEST-SKU',
warehouseId: wh.id,
amount: 2,
// reason omitted so it defaults to "Manual stock addition (+2)"
});
const afterAdjustUpdatedAt = await getUpdatedAt(art.id);
assert.notEqual(afterAdjustUpdatedAt, oldTime, 'stock.adjust should touch updated_at');
assert.ok(new Date(afterAdjustUpdatedAt).getTime() > new Date(oldTime).getTime());
// Check history was recorded with exact text
const historyRes = await provider.query(`SELECT text FROM articlehistory WHERE article_id = @id`, { id: art.id });
const adjustmentEntry = historyRes.rows.find((h) => h.text.includes('Bestandskorrektur +2 (Manual stock addition (+2))'));
assert.ok(adjustmentEntry, 'Should have exact article history entry');
// Reset updated_at to old time
await provider.query(`UPDATE article SET updated_at = @oldTime WHERE id = @id`, { oldTime, id: art.id });
// 2. Test Stückliste component touch
console.log('2. Testing Stückliste parent is touched when component has stock adjustment...');
const bundle = await store.article.createUnderParent({
googleAuthId,
parentId: cat.id,
sku: 'BUNDLE-1',
name: 'Bundle 1',
track_stock: 0,
});
await store.articlelist.setItemsByArticleSku(googleAuthId, 'BUNDLE-1', [
{ sku: 'TEST-SKU', count: 1 },
]);
await provider.query(`UPDATE article SET updated_at = @oldTime WHERE id = @id`, { oldTime, id: bundle.id });
await store.stock.adjust(googleAuthId, {
sku: 'TEST-SKU',
warehouseId: wh.id,
amount: 5,
text: 'Restock component',
});
const bundleUpdatedAt = await getUpdatedAt(bundle.id);
assert.notEqual(bundleUpdatedAt, oldTime, 'Stückliste bundle updated_at should be touched when component changes stock');
// 3. Test delivery acceptance touches article.updated_at
console.log('3. Testing delivery touches article.updated_at...');
const supplier = await store.supplier.create(googleAuthId, { name: 'Supplier Inc' });
const delivery = await store.delivery.create(googleAuthId, {
supplierId: supplier.id,
date: new Date().toISOString(),
lines: [{ sku: 'TEST-SKU', amount: 10, net: 5, taxrate: 19 }],
});
await provider.query(`UPDATE article SET updated_at = @oldTime WHERE id = @id`, { oldTime, id: art.id });
await store.delivery.book(googleAuthId, { id: delivery.id, warehouseId: wh.id });
const deliveryUpdatedAt = await getUpdatedAt(art.id);
assert.notEqual(deliveryUpdatedAt, oldTime, 'delivery.book should touch article.updated_at');
// 4. Test customer shipment touches article.updated_at
console.log('4. Testing shipment touches article.updated_at...');
const groups = await store.customergroup.list(googleAuthId);
const customer = await store.entity.create(googleAuthId, { name: 'Customer A', customergroupId: groups[0].id });
const order = await store.order.create(googleAuthId, {
number: 'AUF-000001',
date: new Date().toISOString(),
entityId: customer.id,
lines: [{ sku: 'TEST-SKU', amount: 3, net: 10, taxrate: 19 }],
});
const carrier = await store.carrier.create(googleAuthId, { name: 'DHL' });
await provider.query(`UPDATE article SET updated_at = @oldTime WHERE id = @id`, { oldTime, id: art.id });
await store.shipment.create(googleAuthId, {
orderId: order.id,
lines: [{ sku: 'TEST-SKU', amount: 3 }],
warehouseId: wh.id,
shipping: {
carrierId: carrier.id,
type: 'standard',
state: 'shipped',
warehouseId: wh.id,
},
});
const shipmentUpdatedAt = await getUpdatedAt(art.id);
assert.notEqual(shipmentUpdatedAt, oldTime, 'shipment.create should touch article.updated_at');
console.log('✅ ALL INVENTORY TOUCH TESTS PASSED');
} finally {
try {
rmSync(tempDir, { recursive: true, force: true });
} catch {}
}
}
main().catch((err) => {
console.error('Test failed:', err);
process.exit(1);
});