u
This commit is contained in:
@@ -117,6 +117,7 @@ import posterminalGetMaxOrderIdCount from './store/posterminal/getMaxOrderIdCoun
|
||||
import posterminalGetCategoryList from './store/posterminal/getCategoryList.js';
|
||||
import posterminalGetProductList from './store/posterminal/getProductList.js';
|
||||
import posterminalSetMaxKnownTombstoneId from './store/posterminal/setMaxKnownTombstoneId.js';
|
||||
import posterminalTouchLastseen from './store/posterminal/touchLastseen.js';
|
||||
import langCreate from './store/lang/create.js';
|
||||
import langDelete from './store/lang/delete.js';
|
||||
import langList from './store/lang/list.js';
|
||||
@@ -414,6 +415,7 @@ export default class LibDashStore {
|
||||
getCategoryList: posterminalGetCategoryList(provider),
|
||||
getProductList: posterminalGetProductList(provider),
|
||||
setMaxKnownTombstoneId: posterminalSetMaxKnownTombstoneId(provider),
|
||||
touchLastseen: posterminalTouchLastseen(provider),
|
||||
};
|
||||
|
||||
this.google_auth = {
|
||||
|
||||
@@ -11,7 +11,6 @@ export const TABLES = [
|
||||
'modelmessage',
|
||||
'modelconversation',
|
||||
'companyuser',
|
||||
'syncpos',
|
||||
'companysetting',
|
||||
'posterminalcategory',
|
||||
'posterminal',
|
||||
|
||||
@@ -6,7 +6,11 @@ SELECT
|
||||
pairingpin,
|
||||
paired_at AS pairedAt,
|
||||
clientserial AS clientserial,
|
||||
maxknowntombstoneid AS maxknowntombstoneid
|
||||
maxknowntombstoneid AS maxknowntombstoneid,
|
||||
root_category_id AS rootCategoryId,
|
||||
sync_root_articles AS syncRootArticles,
|
||||
lastseen_at AS lastseenAt,
|
||||
updated_at AS updatedAt
|
||||
FROM posterminal
|
||||
WHERE company_id = @companyId
|
||||
ORDER BY id
|
||||
@@ -21,7 +25,11 @@ SELECT
|
||||
pairingpin,
|
||||
paired_at AS pairedAt,
|
||||
clientserial AS clientserial,
|
||||
maxknowntombstoneid AS maxknowntombstoneid
|
||||
maxknowntombstoneid AS maxknowntombstoneid,
|
||||
root_category_id AS rootCategoryId,
|
||||
sync_root_articles AS syncRootArticles,
|
||||
lastseen_at AS lastseenAt,
|
||||
updated_at AS updatedAt
|
||||
FROM posterminal
|
||||
WHERE id = @id
|
||||
`;
|
||||
@@ -35,29 +43,39 @@ SELECT
|
||||
pairingpin,
|
||||
paired_at AS pairedAt,
|
||||
clientserial AS clientserial,
|
||||
maxknowntombstoneid AS maxknowntombstoneid
|
||||
maxknowntombstoneid AS maxknowntombstoneid,
|
||||
root_category_id AS rootCategoryId,
|
||||
sync_root_articles AS syncRootArticles,
|
||||
lastseen_at AS lastseenAt,
|
||||
updated_at AS updatedAt
|
||||
FROM posterminal
|
||||
WHERE pairingpin = @pairingpin
|
||||
`;
|
||||
|
||||
export const PAIR = `
|
||||
UPDATE posterminal
|
||||
SET token = @token, paired_at = @pairedAt, clientserial = @clientserial, pairingpin = ''
|
||||
SET token = @token, paired_at = @pairedAt, clientserial = @clientserial, pairingpin = NULL, lastseen_at = @pairedAt, updated_at = SYSUTCDATETIME()
|
||||
WHERE id = @id
|
||||
`;
|
||||
|
||||
export const CREATE = `
|
||||
INSERT INTO posterminal (company_id, name, token, pairingpin, paired_at, clientserial, maxknowntombstoneid)
|
||||
OUTPUT INSERTED.id, INSERTED.name, INSERTED.token, INSERTED.pairingpin, INSERTED.paired_at AS pairedAt, INSERTED.clientserial AS clientserial, INSERTED.maxknowntombstoneid AS maxknowntombstoneid
|
||||
VALUES (@companyId, @name, @token, @pairingpin, @pairedAt, @clientserial, @maxknowntombstoneid)
|
||||
INSERT INTO posterminal (company_id, name, token, pairingpin, paired_at, clientserial, maxknowntombstoneid, root_category_id, sync_root_articles, lastseen_at, updated_at)
|
||||
OUTPUT INSERTED.id, INSERTED.name, INSERTED.token, INSERTED.pairingpin, INSERTED.paired_at AS pairedAt, INSERTED.clientserial AS clientserial, INSERTED.maxknowntombstoneid AS maxknowntombstoneid, INSERTED.root_category_id AS rootCategoryId, INSERTED.sync_root_articles AS syncRootArticles, INSERTED.lastseen_at AS lastseenAt, INSERTED.updated_at AS updatedAt
|
||||
VALUES (@companyId, @name, @token, @pairingpin, @pairedAt, @clientserial, @maxknowntombstoneid, @rootCategoryId, @syncRootArticles, @lastseenAt, SYSUTCDATETIME())
|
||||
`;
|
||||
|
||||
export const UPDATE = `
|
||||
UPDATE posterminal
|
||||
SET name = @name, token = @token, pairingpin = @pairingpin, paired_at = @pairedAt, clientserial = @clientserial, maxknowntombstoneid = @maxknowntombstoneid
|
||||
SET name = @name, token = @token, pairingpin = @pairingpin, paired_at = @pairedAt, clientserial = @clientserial, maxknowntombstoneid = @maxknowntombstoneid, root_category_id = @rootCategoryId, sync_root_articles = @syncRootArticles, lastseen_at = @lastseenAt, updated_at = SYSUTCDATETIME()
|
||||
WHERE id = @id AND company_id = @companyId
|
||||
`;
|
||||
|
||||
export const TOUCH_LASTSEEN = `
|
||||
UPDATE posterminal
|
||||
SET lastseen_at = SYSUTCDATETIME()
|
||||
WHERE id = @id
|
||||
`;
|
||||
|
||||
export const SET_MAX_KNOWN_TOMBSTONE_ID = `
|
||||
UPDATE posterminal
|
||||
SET maxknowntombstoneid = @maxknowntombstoneid
|
||||
@@ -132,7 +150,11 @@ SELECT
|
||||
pairingpin,
|
||||
paired_at AS pairedAt,
|
||||
clientserial AS clientserial,
|
||||
maxknowntombstoneid AS maxknowntombstoneid
|
||||
maxknowntombstoneid AS maxknowntombstoneid,
|
||||
root_category_id AS rootCategoryId,
|
||||
sync_root_articles AS syncRootArticles,
|
||||
lastseen_at AS lastseenAt,
|
||||
updated_at AS updatedAt
|
||||
FROM posterminal
|
||||
WHERE token = @token
|
||||
`;
|
||||
|
||||
@@ -840,21 +840,6 @@ BEGIN
|
||||
END
|
||||
`;
|
||||
|
||||
export const INIT_SYNCPOS = `
|
||||
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'syncpos')
|
||||
BEGIN
|
||||
CREATE TABLE syncpos (
|
||||
id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
company_id INT NOT NULL,
|
||||
paircode NVARCHAR(50) NOT NULL,
|
||||
token NVARCHAR(255) NULL,
|
||||
CONSTRAINT FK_syncpos_company FOREIGN KEY (company_id) REFERENCES company(id) ON DELETE CASCADE,
|
||||
CONSTRAINT UQ_syncpos_paircode UNIQUE (paircode),
|
||||
CONSTRAINT UQ_syncpos_token UNIQUE (token)
|
||||
);
|
||||
END
|
||||
`;
|
||||
|
||||
export const INIT_COMPANYSETTING = `
|
||||
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'companysetting')
|
||||
BEGIN
|
||||
@@ -879,21 +864,19 @@ BEGIN
|
||||
company_id INT NOT NULL,
|
||||
name NVARCHAR(255) NOT NULL,
|
||||
token NVARCHAR(255) NULL,
|
||||
pairingpin NVARCHAR(50) NOT NULL,
|
||||
pairingpin NVARCHAR(50) NULL,
|
||||
paired_at DATETIME2 NULL,
|
||||
clientserial NVARCHAR(255) NULL,
|
||||
maxknowntombstoneid INT NULL,
|
||||
CONSTRAINT FK_posterminal_company FOREIGN KEY (company_id) REFERENCES company(id) ON DELETE CASCADE
|
||||
root_category_id INT NULL,
|
||||
sync_root_articles BIT NOT NULL CONSTRAINT DF_posterminal_sync_root_articles DEFAULT 1,
|
||||
lastseen_at DATETIME2 NULL,
|
||||
updated_at DATETIME2 NOT NULL CONSTRAINT DF_posterminal_updated_at DEFAULT SYSUTCDATETIME(),
|
||||
CONSTRAINT FK_posterminal_company FOREIGN KEY (company_id) REFERENCES company(id) ON DELETE CASCADE,
|
||||
CONSTRAINT FK_posterminal_root_category FOREIGN KEY (root_category_id) REFERENCES category(id) ON DELETE SET NULL
|
||||
);
|
||||
CREATE UNIQUE INDEX UQ_posterminal_token ON posterminal(token) WHERE token IS NOT NULL;
|
||||
END
|
||||
ELSE
|
||||
BEGIN
|
||||
IF NOT EXISTS (SELECT * FROM sys.columns WHERE object_id = OBJECT_ID('posterminal') AND name = 'maxknowntombstoneid')
|
||||
BEGIN
|
||||
ALTER TABLE posterminal ADD maxknowntombstoneid INT NULL;
|
||||
END
|
||||
END
|
||||
`;
|
||||
|
||||
export const INIT_POSTERMINALCATEGORY = `
|
||||
@@ -1163,7 +1146,6 @@ export const SCHEMA_SCRIPTS = [
|
||||
INIT_ARTICLETOMBSTONE,
|
||||
INIT_ENTITYHISTORY,
|
||||
INIT_COMPANYHISTORY,
|
||||
INIT_SYNCPOS,
|
||||
INIT_COMPANYSETTING,
|
||||
INIT_POSTERMINAL,
|
||||
INIT_POSTERMINALCATEGORY,
|
||||
|
||||
@@ -9,6 +9,7 @@ export const {
|
||||
FIND_BY_TOKEN, COUNT_PRODUCTS, COUNT_CATEGORIES, COUNT_CUSTOMERS,
|
||||
COUNT_CUSTOMER_GROUPS, COUNT_COMPOSITE_PRODUCTS, MAX_ORDER_ID,
|
||||
LIST_POS_PRODUCT_CATEGORIES, LIST_POS_CUSTOMER_GROUP_IDS, LIST_POS_PRODUCT_PRICES,
|
||||
TOUCH_LASTSEEN,
|
||||
} = queries;
|
||||
|
||||
export const SET_ON = `
|
||||
|
||||
@@ -578,16 +578,6 @@ CREATE TABLE IF NOT EXISTS entityhistory (
|
||||
);
|
||||
`;
|
||||
|
||||
export const INIT_SYNCPOS = `
|
||||
CREATE TABLE IF NOT EXISTS syncpos (
|
||||
id INTEGER PRIMARY KEY,
|
||||
company_id INTEGER NOT NULL,
|
||||
paircode TEXT NOT NULL UNIQUE,
|
||||
token TEXT UNIQUE,
|
||||
FOREIGN KEY (company_id) REFERENCES company(id) ON DELETE CASCADE
|
||||
);
|
||||
`;
|
||||
|
||||
export const INIT_COMPANYSETTING = `
|
||||
CREATE TABLE IF NOT EXISTS companysetting (
|
||||
id INTEGER PRIMARY KEY,
|
||||
@@ -607,11 +597,16 @@ CREATE TABLE IF NOT EXISTS posterminal (
|
||||
company_id INTEGER NOT NULL,
|
||||
name TEXT NOT NULL,
|
||||
token TEXT,
|
||||
pairingpin TEXT NOT NULL,
|
||||
pairingpin TEXT,
|
||||
paired_at TEXT,
|
||||
clientserial TEXT,
|
||||
maxknowntombstoneid INTEGER,
|
||||
FOREIGN KEY (company_id) REFERENCES company(id) ON DELETE CASCADE
|
||||
root_category_id INTEGER,
|
||||
sync_root_articles INTEGER NOT NULL DEFAULT 1,
|
||||
lastseen_at TEXT,
|
||||
updated_at TEXT NOT NULL DEFAULT (${UTC_NOW}),
|
||||
FOREIGN KEY (company_id) REFERENCES company(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (root_category_id) REFERENCES category(id) ON DELETE SET NULL
|
||||
);
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS UQ_posterminal_token
|
||||
ON posterminal(token) WHERE token IS NOT NULL;
|
||||
@@ -831,7 +826,6 @@ export const SCHEMA_SCRIPTS = [
|
||||
INIT_ARTICLETOMBSTONE,
|
||||
INIT_ENTITYHISTORY,
|
||||
INIT_COMPANYHISTORY,
|
||||
INIT_SYNCPOS,
|
||||
INIT_COMPANYSETTING,
|
||||
INIT_POSTERMINAL,
|
||||
INIT_POSTERMINALCATEGORY,
|
||||
|
||||
@@ -10,7 +10,7 @@ export default function findByPairingpin(provider) {
|
||||
*
|
||||
* @param {string} pairingpin - The pairing pin to search for.
|
||||
* @param {object} [tx] - Optional transaction to run within.
|
||||
* @returns {Promise<object|null>} The posterminal row, or null if not found.
|
||||
* @returns {Promise<{id: number, companyId: number, name: string, token: string|null, pairingpin: string|null, pairedAt: string|null, clientserial: string|null, maxknowntombstoneid: number|null, rootCategoryId: number|null, syncRootArticles: boolean|number, lastseenAt: string|null, updatedAt: string}|null>} The posterminal, or null if not found.
|
||||
*/
|
||||
return async (pairingpin, tx) => {
|
||||
if (!pairingpin) return null;
|
||||
|
||||
@@ -10,7 +10,7 @@ export default function findByToken(provider) {
|
||||
*
|
||||
* @param {string} token - The auth token to search for.
|
||||
* @param {object} [tx] - Optional transaction to run within.
|
||||
* @returns {Promise<object|null>} The posterminal row, or null if not found.
|
||||
* @returns {Promise<{id: number, companyId: number, name: string, token: string|null, pairingpin: string|null, pairedAt: string|null, clientserial: string|null, maxknowntombstoneid: number|null, rootCategoryId: number|null, syncRootArticles: boolean|number, lastseenAt: string|null, updatedAt: string}|null>} The posterminal, or null if not found.
|
||||
*/
|
||||
return async (token, tx) => {
|
||||
const trimmed = String(token ?? '').trim();
|
||||
|
||||
@@ -12,11 +12,11 @@ export default function list(provider) {
|
||||
*
|
||||
* @param {number} googleAuthId - The id of the Google auth user.
|
||||
* @param {object} [tx] - Optional transaction to run within.
|
||||
* @returns {Promise<Array<{id: number, name: string, token: string, pairingpin: string}>>} The posterminals.
|
||||
* @returns {Promise<Array<{id: number, name: string, token: string|null, pairingpin: string|null, pairedAt: string|null, clientserial: string|null, maxknowntombstoneid: number|null, rootCategoryId: number|null, syncRootArticles: boolean|number, lastseenAt: string|null, updatedAt: string}>>} The posterminals.
|
||||
*
|
||||
* @example
|
||||
* const terminals = await store.posterminal.list(42);
|
||||
* // => [{ id, name, token, pairingpin }]
|
||||
* // => [{ id, name, token, pairingpin, pairedAt, clientserial, maxknowntombstoneid, rootCategoryId, syncRootArticles, lastseenAt, updatedAt }]
|
||||
*/
|
||||
return async (googleAuthId, tx) => {
|
||||
const { companyId } = await access(googleAuthId, tx);
|
||||
|
||||
19
src/store/posterminal/touchLastseen.js
Normal file
19
src/store/posterminal/touchLastseen.js
Normal file
@@ -0,0 +1,19 @@
|
||||
import { TOUCH_LASTSEEN as MSSQL_TOUCH } from '../../providers/mssql/queries/posterminal.js';
|
||||
import { TOUCH_LASTSEEN as SQLITE_TOUCH } from '../../providers/sqlite3/queries/posterminal.js';
|
||||
import makeRunner from '../runner.js';
|
||||
|
||||
export default function touchLastseen(provider) {
|
||||
const sql = provider?.dialect === 'sqlite3' ? SQLITE_TOUCH : MSSQL_TOUCH;
|
||||
|
||||
/**
|
||||
* Updates lastseen_at for a POS terminal to the current timestamp.
|
||||
*
|
||||
* @param {number} id - The posterminal id.
|
||||
* @param {object} [tx] - Optional transaction to run within.
|
||||
* @returns {Promise<{id: number}>}
|
||||
*/
|
||||
return async (id, tx) => {
|
||||
await makeRunner(provider, tx).query(sql, { id: Number(id) });
|
||||
return { id: Number(id) };
|
||||
};
|
||||
}
|
||||
@@ -37,16 +37,12 @@ export default function upsert(provider) {
|
||||
* // => { id, name, token, pairingpin }
|
||||
*/
|
||||
return async (googleAuthId, input = {}, tx) => {
|
||||
const name = input.name?.trim();
|
||||
if (!name) {
|
||||
throw new Error('Invalid posterminal');
|
||||
}
|
||||
const pairingpin = input.pairingpin?.trim();
|
||||
if (!pairingpin) {
|
||||
const id = input.id ?? null;
|
||||
const name = input.name !== undefined ? input.name?.trim() : undefined;
|
||||
if (name === '' || (!name && !id)) {
|
||||
throw new Error('Invalid posterminal');
|
||||
}
|
||||
const token = input.token ?? null;
|
||||
const id = input.id ?? null;
|
||||
const pairedAt = input.pairedAt ?? null;
|
||||
const clientserial = input.clientserial ?? null;
|
||||
|
||||
@@ -60,26 +56,67 @@ export default function upsert(provider) {
|
||||
throw new Error('Posterminal not found');
|
||||
}
|
||||
|
||||
const nameVal = name !== undefined ? name : existing.rows[0].name;
|
||||
|
||||
const pairingpin =
|
||||
input.pairingpin !== undefined
|
||||
? (input.pairingpin ? String(input.pairingpin).trim() : null)
|
||||
: (existing.rows[0].pairingpin ?? null);
|
||||
|
||||
const maxknowntombstoneid =
|
||||
input.maxknowntombstoneid !== undefined
|
||||
? input.maxknowntombstoneid
|
||||
: (existing.rows[0].maxknowntombstoneid ?? null);
|
||||
|
||||
const rootCategoryId =
|
||||
input.rootCategoryId !== undefined
|
||||
? (input.rootCategoryId != null ? Number(input.rootCategoryId) : null)
|
||||
: (existing.rows[0].rootCategoryId ?? null);
|
||||
|
||||
const syncRootArticles =
|
||||
input.syncRootArticles !== undefined
|
||||
? (input.syncRootArticles ? 1 : 0)
|
||||
: (existing.rows[0].syncRootArticles !== undefined ? (existing.rows[0].syncRootArticles ? 1 : 0) : 1);
|
||||
|
||||
const lastseenAt =
|
||||
input.lastseenAt !== undefined
|
||||
? input.lastseenAt
|
||||
: (existing.rows[0].lastseenAt ?? null);
|
||||
|
||||
await runner.query(updateSql, {
|
||||
id,
|
||||
companyId,
|
||||
name,
|
||||
name: nameVal,
|
||||
token,
|
||||
pairingpin,
|
||||
pairedAt,
|
||||
clientserial,
|
||||
maxknowntombstoneid,
|
||||
rootCategoryId,
|
||||
syncRootArticles,
|
||||
lastseenAt,
|
||||
});
|
||||
|
||||
return { id, name, token, pairingpin, pairedAt, clientserial, maxknowntombstoneid };
|
||||
return {
|
||||
id,
|
||||
name: nameVal,
|
||||
token,
|
||||
pairingpin,
|
||||
pairedAt,
|
||||
clientserial,
|
||||
maxknowntombstoneid,
|
||||
rootCategoryId,
|
||||
syncRootArticles,
|
||||
lastseenAt,
|
||||
};
|
||||
}
|
||||
|
||||
const pairingpin = input.pairingpin ? String(input.pairingpin).trim() : null;
|
||||
const maxknowntombstoneid = input.maxknowntombstoneid ?? null;
|
||||
const rootCategoryId = input.rootCategoryId != null ? Number(input.rootCategoryId) : null;
|
||||
const syncRootArticles = input.syncRootArticles !== undefined ? (input.syncRootArticles ? 1 : 0) : 1;
|
||||
const lastseenAt = input.lastseenAt ?? null;
|
||||
|
||||
const created = await runner.query(createSql, {
|
||||
companyId,
|
||||
name,
|
||||
@@ -88,6 +125,9 @@ export default function upsert(provider) {
|
||||
pairedAt,
|
||||
clientserial,
|
||||
maxknowntombstoneid,
|
||||
rootCategoryId,
|
||||
syncRootArticles,
|
||||
lastseenAt,
|
||||
});
|
||||
|
||||
const row = created.rows[0] ?? {
|
||||
@@ -98,16 +138,23 @@ export default function upsert(provider) {
|
||||
pairedAt,
|
||||
clientserial,
|
||||
maxknowntombstoneid,
|
||||
rootCategoryId,
|
||||
syncRootArticles,
|
||||
lastseenAt,
|
||||
};
|
||||
|
||||
return {
|
||||
id: row.id,
|
||||
name: row.name,
|
||||
token: row.token,
|
||||
pairingpin: row.pairingpin,
|
||||
pairingpin: row.pairingpin ?? null,
|
||||
pairedAt: row.pairedAt ?? null,
|
||||
clientserial: row.clientserial ?? null,
|
||||
maxknowntombstoneid: row.maxknowntombstoneid ?? null,
|
||||
rootCategoryId: row.rootCategoryId ?? null,
|
||||
syncRootArticles: row.syncRootArticles !== undefined ? (row.syncRootArticles ? 1 : 0) : 1,
|
||||
lastseenAt: row.lastseenAt ?? null,
|
||||
updatedAt: row.updatedAt ?? null,
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user