Add Kundennummer/Nummernkreise settings and settings dialog.
Add number & setting API endpoints, StorageManager caches, and a Settings dialog (tabs for settings keys and number ranges) reachable from the user menu. Show Kundennummer and creation date in the Kunde list, and refactor Neuer Kunde to show an auto-generated number with group select.
This commit is contained in:
@@ -146,6 +146,8 @@ export class ApiClient {
|
||||
update: (id, body) => this.#json('PATCH', `/api/entity/${enc(id)}`, { body }),
|
||||
/** DELETE /api/entity/{id} → 204 */
|
||||
delete: (id) => this.#empty('DELETE', `/api/entity/${enc(id)}`),
|
||||
/** GET /api/entity/next-number → { number: string } */
|
||||
nextNumber: () => this.#json('GET', '/api/entity/next-number'),
|
||||
/** GET /api/entity/{entityId}/address → { addresses } */
|
||||
listAddresses: (entityId) =>
|
||||
this.#json('GET', `/api/entity/${enc(entityId)}/address`),
|
||||
@@ -287,6 +289,23 @@ export class ApiClient {
|
||||
setOffAll: (id) => this.#json('DELETE', `/api/posterminal/${enc(id)}/all`),
|
||||
};
|
||||
|
||||
this.number = {
|
||||
/** GET /api/number → { numbers: [{ id, type, prefix, padding, next }] } */
|
||||
list: () => this.#json('GET', '/api/number'),
|
||||
/** PATCH /api/number/{id} — body: { prefix?, padding?, next? } (only present keys patched) */
|
||||
update: (id, body) => this.#json('PATCH', `/api/number/${enc(id)}`, { body }),
|
||||
};
|
||||
|
||||
this.setting = {
|
||||
/** GET /api/company/setting?frontendOnly=1 → { settings: [{ key, value, frontend }] } */
|
||||
list: (query) => this.#json('GET', '/api/company/setting', { query }),
|
||||
/** GET /api/company/setting/{key} → { setting: { key, value, frontend } } */
|
||||
get: (key) => this.#json('GET', `/api/company/setting/${enc(key)}`),
|
||||
/** PUT /api/company/setting/{key} body { value, frontend } → { setting: { key, value, frontend } } */
|
||||
upsert: (key, body) =>
|
||||
this.#json('PUT', `/api/company/setting/${enc(key)}`, { body }),
|
||||
};
|
||||
|
||||
this.image = {
|
||||
/** GET /api/image/{fullHash} → AVIF blob */
|
||||
get: (fullHash) => this.#blob('GET', `/api/image/${enc(fullHash)}`),
|
||||
|
||||
@@ -297,6 +297,7 @@ export class StorageManager extends ApiClient {
|
||||
this.#loadCustomergroups(),
|
||||
);
|
||||
const entityCache = createCache('GET /entity', () => this.#loadEntities());
|
||||
const numberCache = createCache('GET /number', () => this.#loadNumbers());
|
||||
const quoteCache = createCache('GET /quote', () => this.#loadQuotes());
|
||||
const orderCache = createCache('GET /order', () => this.#loadOrders());
|
||||
|
||||
@@ -352,6 +353,11 @@ export class StorageManager extends ApiClient {
|
||||
/** Settled GET /entity list, or undefined. */
|
||||
entities: { get: () => entityCache.value },
|
||||
|
||||
numberPromise: { get: () => numberCache.promise },
|
||||
updateNumber: { value: numberCache.update },
|
||||
/** Settled GET /number list, or undefined. */
|
||||
numbers: { get: () => numberCache.value },
|
||||
|
||||
quotePromise: { get: () => quoteCache.promise },
|
||||
updateQuote: { value: quoteCache.update },
|
||||
/** Settled GET /quote list, or undefined. */
|
||||
@@ -506,6 +512,12 @@ export class StorageManager extends ApiClient {
|
||||
return requireArray(data.entities, 'entities');
|
||||
}
|
||||
|
||||
async #loadNumbers() {
|
||||
const data = await this.number.list();
|
||||
requireObject(data, 'GET /api/number');
|
||||
return requireArray(data.numbers, 'numbers');
|
||||
}
|
||||
|
||||
async #loadQuotes() {
|
||||
const data = await this.quote.list();
|
||||
requireObject(data, 'GET /api/quote');
|
||||
|
||||
@@ -772,6 +772,11 @@ export const entity = {
|
||||
return http(`/api/entity/${id}`, { method: 'DELETE' });
|
||||
},
|
||||
|
||||
/** GET /api/entity/next-number → { number: string } */
|
||||
nextNumber() {
|
||||
return http('/api/entity/next-number');
|
||||
},
|
||||
|
||||
/** GET /api/entity/:entityId/address → { addresses: EntityAddress[] } */
|
||||
listAddresses(entityId) {
|
||||
return http(`/api/entity/${entityId}/address`);
|
||||
@@ -936,6 +941,25 @@ export const posterminal = {
|
||||
},
|
||||
};
|
||||
|
||||
export const number = {
|
||||
/**
|
||||
* GET /api/number → { numbers: [{ id, type, prefix, padding, next }] }
|
||||
* Lists the number sequences for the selected company.
|
||||
*/
|
||||
list() {
|
||||
return http('/api/number');
|
||||
},
|
||||
|
||||
/**
|
||||
* PATCH /api/number/:id
|
||||
* Body: at least one of { prefix, padding, next } — only present keys are patched.
|
||||
* → 200 { number: { id, type, prefix, padding, next } }
|
||||
*/
|
||||
update(id, body) {
|
||||
return http(`/api/number/${id}`, { method: 'PATCH', body });
|
||||
},
|
||||
};
|
||||
|
||||
export const auth = {
|
||||
async me() {
|
||||
try {
|
||||
@@ -997,6 +1021,7 @@ export default {
|
||||
customergroup,
|
||||
delivery,
|
||||
entity,
|
||||
number,
|
||||
order,
|
||||
posterminal,
|
||||
quote,
|
||||
|
||||
Reference in New Issue
Block a user