143 lines
5.4 KiB
JavaScript
143 lines
5.4 KiB
JavaScript
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 Quote Summary & Filtering in dashdbschema ---');
|
|
|
|
const tempDir = mkdtempSync(join(tmpdir(), 'test-quote-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('quote-summary-test@example.com');
|
|
const company = await store.company.create({
|
|
name: 'Quote Test Corp',
|
|
iso639: 'de',
|
|
taxrate: 19,
|
|
reducedtaxrate: 7,
|
|
googleAuthId,
|
|
});
|
|
await store.google_auth.setSelectedCompany(googleAuthId, company.id);
|
|
|
|
const groups = await store.customergroup.list(googleAuthId);
|
|
const customerAlice = await store.entity.create(googleAuthId, {
|
|
customergroupId: groups[0].id,
|
|
firstName: 'Alice',
|
|
name: 'Wonderland',
|
|
});
|
|
const customerBob = await store.entity.create(googleAuthId, {
|
|
customergroupId: groups[0].id,
|
|
firstName: 'Bob',
|
|
name: 'Builder',
|
|
});
|
|
|
|
const art = await store.article.createUnderParent({
|
|
googleAuthId,
|
|
parentId: company.rootCategoryId,
|
|
name: 'Gadget',
|
|
track_stock: 0,
|
|
});
|
|
|
|
// 1. Create quote 1: Alice, Q-1001, 2 items of 100 net @ 19% tax => 238 gross, 2 total quantity
|
|
const quote1 = await store.quote.create(googleAuthId, {
|
|
number: 'Q-1001',
|
|
date: '2026-08-01T10:00:00Z',
|
|
entityId: customerAlice.id,
|
|
lines: [{ sku: art.sku, name: 'Gadget', amount: 2, net: 100, taxrate: 19 }],
|
|
});
|
|
assert.equal(quote1.number, 'Q-1001');
|
|
|
|
// Verify row in quotesummary table directly
|
|
const directRows1 = provider.db.prepare('SELECT * FROM quotesummary WHERE manifest_id = ?').all(quote1.id);
|
|
assert.equal(directRows1.length, 1);
|
|
assert.equal(directRows1[0].quote_number, 'Q-1001');
|
|
assert.equal(directRows1[0].customer_name, 'Alice Wonderland');
|
|
assert.equal(directRows1[0].positions, 1);
|
|
assert.equal(directRows1[0].gross_total, 238);
|
|
assert.equal(directRows1[0].total_quantity, 2);
|
|
|
|
// 2. Create quote 2: Bob, Q-1002, 3 items of 50 net @ 19% tax => 178.50 gross, 3 total quantity
|
|
const quote2 = await store.quote.create(googleAuthId, {
|
|
number: 'Q-1002',
|
|
date: '2026-10-01T10:00:00Z',
|
|
entityId: customerBob.id,
|
|
lines: [{ sku: art.sku, name: 'Gadget', amount: 3, net: 50, taxrate: 19 }],
|
|
});
|
|
|
|
// Test quote.list unpaged
|
|
const unpaged = await store.quote.list(googleAuthId);
|
|
assert.equal(unpaged.length, 2);
|
|
const q1 = unpaged.find((q) => q.id === quote1.id);
|
|
assert.equal(q1.positions, 1);
|
|
assert.equal(q1.grossTotal, 238);
|
|
assert.equal(q1.totalQuantity, 2);
|
|
assert.equal(q1.customerName, 'Alice Wonderland');
|
|
|
|
// Test quote.list paged with search
|
|
const searchAlice = await store.quote.list(googleAuthId, { search: 'Alice' });
|
|
assert.equal(searchAlice.total, 1);
|
|
assert.equal(searchAlice.unfilteredTotal, 2);
|
|
assert.equal(searchAlice.quotes[0].number, 'Q-1001');
|
|
|
|
const searchNumber = await store.quote.list(googleAuthId, { search: '1002' });
|
|
assert.equal(searchNumber.total, 1);
|
|
assert.equal(searchNumber.quotes[0].number, 'Q-1002');
|
|
|
|
// Test quote.update updates summary
|
|
await store.quote.update(googleAuthId, quote1.id, {
|
|
lines: [
|
|
{ sku: art.sku, name: 'Gadget', amount: 5, net: 100, taxrate: 19 },
|
|
{ sku: art.sku, name: 'Gadget 2', amount: 1, net: 10, taxrate: 19 },
|
|
],
|
|
});
|
|
const updatedSummary = provider.db.prepare('SELECT * FROM quotesummary WHERE manifest_id = ?').get(quote1.id);
|
|
assert.equal(updatedSummary.positions, 2);
|
|
assert.equal(updatedSummary.total_quantity, 6);
|
|
// (5 * 100 * 1.19) + (1 * 10 * 1.19) = 595 + 11.9 = 606.90
|
|
assert.equal(updatedSummary.gross_total, 606.9);
|
|
|
|
// Test rebuildSummaries
|
|
provider.db.prepare('DELETE FROM quotesummary').run();
|
|
const countBeforeRebuild = provider.db.prepare('SELECT COUNT(*) as cnt FROM quotesummary').get().cnt;
|
|
assert.equal(countBeforeRebuild, 0);
|
|
|
|
const rebuildRes = await store.quote.rebuildSummaries(googleAuthId);
|
|
assert.equal(rebuildRes.ok, true);
|
|
const countAfterRebuild = provider.db.prepare('SELECT COUNT(*) as cnt FROM quotesummary').get().cnt;
|
|
assert.equal(countAfterRebuild, 2);
|
|
|
|
const rebuiltQ1 = provider.db.prepare('SELECT * FROM quotesummary WHERE manifest_id = ?').get(quote1.id);
|
|
assert.equal(rebuiltQ1.positions, 2);
|
|
assert.equal(rebuiltQ1.total_quantity, 6);
|
|
assert.equal(rebuiltQ1.gross_total, 606.9);
|
|
|
|
// Test delete cascade
|
|
await store.quote.delete(googleAuthId, quote1.id);
|
|
const countAfterDelete = provider.db.prepare('SELECT COUNT(*) as cnt FROM quotesummary WHERE manifest_id = ?').get(quote1.id);
|
|
assert.equal(countAfterDelete.cnt, 0);
|
|
|
|
console.log('--- ALL QUOTE SUMMARY TESTS PASSED ---');
|
|
} finally {
|
|
try {
|
|
rmSync(tempDir, { recursive: true, force: true });
|
|
} catch {}
|
|
}
|
|
}
|
|
|
|
run().catch((err) => {
|
|
console.error('Test failed:', err);
|
|
process.exit(1);
|
|
});
|