u
This commit is contained in:
@@ -82,6 +82,11 @@ export default function setPricesBySku(provider) {
|
||||
throw new Error('POS customer group required');
|
||||
}
|
||||
|
||||
const artCheck = await runner.query('SELECT is_father FROM article WHERE id = @articleId', { articleId });
|
||||
if (artCheck.rows[0]?.is_father) {
|
||||
throw new Error('A father article cannot have prices');
|
||||
}
|
||||
|
||||
const taxIds = new Map();
|
||||
for (const entry of normalized) {
|
||||
if (!taxIds.has(entry.tax)) {
|
||||
|
||||
@@ -53,6 +53,26 @@ export default function toggleFather(provider) {
|
||||
throw new Error('An article with options cannot become a father');
|
||||
}
|
||||
|
||||
const stockRes = await runner.query(
|
||||
'SELECT COALESCE(SUM(l.amount), 0) AS totalStock FROM ledger l WHERE l.article_id = @articleId',
|
||||
{ articleId },
|
||||
);
|
||||
const totalStock = Number(stockRes.rows[0]?.totalStock ?? 0);
|
||||
if (totalStock !== 0) {
|
||||
throw new Error('An article with existing stock cannot become a father article');
|
||||
}
|
||||
|
||||
const supRes = await runner.query(
|
||||
'SELECT COUNT(*) AS count FROM articlesupplier WHERE article_id = @articleId',
|
||||
{ articleId },
|
||||
);
|
||||
if ((supRes.rows[0]?.count ?? 0) > 0) {
|
||||
throw new Error('An article with assigned suppliers cannot become a father article');
|
||||
}
|
||||
|
||||
await runner.query('DELETE FROM price WHERE article_id = @articleId', { articleId });
|
||||
await runner.query('UPDATE article SET track_stock = 0 WHERE id = @articleId', { articleId });
|
||||
|
||||
// If article is a child, verify attribute is not used by father or any father up the chain
|
||||
let currentFatherId = currentArt?.fatherarticle_id;
|
||||
const visited = new Set();
|
||||
|
||||
@@ -39,9 +39,6 @@ export default function setItemsByArticleSku(provider) {
|
||||
if (article.is_father) {
|
||||
throw new Error('A father article cannot be a Stückliste');
|
||||
}
|
||||
if (article.optionslist_id != null) {
|
||||
throw new Error('An article with options cannot be a Stückliste');
|
||||
}
|
||||
|
||||
// If items is empty: clear Stückliste
|
||||
if (items.length === 0) {
|
||||
|
||||
@@ -91,6 +91,11 @@ export default function create(provider) {
|
||||
runner,
|
||||
);
|
||||
|
||||
const artCheck = await runner.query('SELECT is_father FROM article WHERE id = @articleId', { articleId });
|
||||
if (artCheck.rows[0]?.is_father) {
|
||||
throw new Error('A father article cannot have suppliers');
|
||||
}
|
||||
|
||||
await assertSupplier(runner, companyId, entityId);
|
||||
|
||||
const existingCheck = await runner.query(queries.CHECK_EXISTS, {
|
||||
|
||||
@@ -39,9 +39,6 @@ export default function setOptionsByArticleSku(provider) {
|
||||
if (article.is_father) {
|
||||
throw new Error('A father article cannot have options');
|
||||
}
|
||||
if (article.articlelist_id != null) {
|
||||
throw new Error('A Stückliste article cannot have options');
|
||||
}
|
||||
|
||||
// If options is empty: clear optionslist
|
||||
if (options.length === 0) {
|
||||
|
||||
23
src/store/posterminal/findByToken.js
Normal file
23
src/store/posterminal/findByToken.js
Normal file
@@ -0,0 +1,23 @@
|
||||
import { FIND_BY_TOKEN as MSSQL_FIND } from '../../providers/mssql/queries/posterminal.js';
|
||||
import { FIND_BY_TOKEN as SQLITE_FIND } from '../../providers/sqlite3/queries/posterminal.js';
|
||||
import makeRunner from '../runner.js';
|
||||
|
||||
export default function findByToken(provider) {
|
||||
const sql = provider?.dialect === 'sqlite3' ? SQLITE_FIND : MSSQL_FIND;
|
||||
|
||||
/**
|
||||
* Finds a posterminal by its auth token.
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
return async (token, tx) => {
|
||||
const trimmed = String(token ?? '').trim();
|
||||
if (!trimmed) return null;
|
||||
const result = await makeRunner(provider, tx).query(sql, {
|
||||
token: trimmed,
|
||||
});
|
||||
return result.rows[0] || null;
|
||||
};
|
||||
}
|
||||
30
src/store/posterminal/getCategoryCount.js
Normal file
30
src/store/posterminal/getCategoryCount.js
Normal file
@@ -0,0 +1,30 @@
|
||||
import { COUNT_CATEGORIES as MSSQL_SQL } from '../../providers/mssql/queries/posterminal.js';
|
||||
import { COUNT_CATEGORIES as SQLITE_SQL } from '../../providers/sqlite3/queries/posterminal.js';
|
||||
import makeRunner from '../runner.js';
|
||||
|
||||
function normalizeCursor(cursor) {
|
||||
const n = Number(cursor) || 0;
|
||||
if (n <= 0) return 0;
|
||||
return n >= 1e11 ? Math.floor(n / 1000) : Math.floor(n);
|
||||
}
|
||||
|
||||
export default function getCategoryCount(provider) {
|
||||
const sql = provider?.dialect === 'sqlite3' ? SQLITE_SQL : MSSQL_SQL;
|
||||
|
||||
/**
|
||||
* Counts categories assigned to the POS terminal updated after the given unix timestamp cursor.
|
||||
*
|
||||
* @param {object} input
|
||||
* @param {number} input.posterminalId - The POS terminal id.
|
||||
* @param {number} [input.cursor=0] - Unix timestamp cursor of last update.
|
||||
* @param {object} [tx] - Optional transaction to run within.
|
||||
* @returns {Promise<number>} The count of changed records.
|
||||
*/
|
||||
return async ({ posterminalId, cursor = 0 } = {}, tx) => {
|
||||
const result = await makeRunner(provider, tx).query(sql, {
|
||||
posterminalId: Number(posterminalId),
|
||||
cursor: normalizeCursor(cursor),
|
||||
});
|
||||
return Number(result.rows[0]?.count ?? 0);
|
||||
};
|
||||
}
|
||||
30
src/store/posterminal/getCompositeProductCount.js
Normal file
30
src/store/posterminal/getCompositeProductCount.js
Normal file
@@ -0,0 +1,30 @@
|
||||
import { COUNT_COMPOSITE_PRODUCTS as MSSQL_SQL } from '../../providers/mssql/queries/posterminal.js';
|
||||
import { COUNT_COMPOSITE_PRODUCTS as SQLITE_SQL } from '../../providers/sqlite3/queries/posterminal.js';
|
||||
import makeRunner from '../runner.js';
|
||||
|
||||
function normalizeCursor(cursor) {
|
||||
const n = Number(cursor) || 0;
|
||||
if (n <= 0) return 0;
|
||||
return n >= 1e11 ? Math.floor(n / 1000) : Math.floor(n);
|
||||
}
|
||||
|
||||
export default function getCompositeProductCount(provider) {
|
||||
const sql = provider?.dialect === 'sqlite3' ? SQLITE_SQL : MSSQL_SQL;
|
||||
|
||||
/**
|
||||
* Counts composite products (Stücklisten) assigned to the POS terminal updated after the given unix timestamp cursor.
|
||||
*
|
||||
* @param {object} input
|
||||
* @param {number} input.posterminalId - The POS terminal id.
|
||||
* @param {number} [input.cursor=0] - Unix timestamp cursor of last update.
|
||||
* @param {object} [tx] - Optional transaction to run within.
|
||||
* @returns {Promise<number>} The count of changed records.
|
||||
*/
|
||||
return async ({ posterminalId, cursor = 0 } = {}, tx) => {
|
||||
const result = await makeRunner(provider, tx).query(sql, {
|
||||
posterminalId: Number(posterminalId),
|
||||
cursor: normalizeCursor(cursor),
|
||||
});
|
||||
return Number(result.rows[0]?.count ?? 0);
|
||||
};
|
||||
}
|
||||
30
src/store/posterminal/getCustomerCount.js
Normal file
30
src/store/posterminal/getCustomerCount.js
Normal file
@@ -0,0 +1,30 @@
|
||||
import { COUNT_CUSTOMERS as MSSQL_SQL } from '../../providers/mssql/queries/posterminal.js';
|
||||
import { COUNT_CUSTOMERS as SQLITE_SQL } from '../../providers/sqlite3/queries/posterminal.js';
|
||||
import makeRunner from '../runner.js';
|
||||
|
||||
function normalizeCursor(cursor) {
|
||||
const n = Number(cursor) || 0;
|
||||
if (n <= 0) return 0;
|
||||
return n >= 1e11 ? Math.floor(n / 1000) : Math.floor(n);
|
||||
}
|
||||
|
||||
export default function getCustomerCount(provider) {
|
||||
const sql = provider?.dialect === 'sqlite3' ? SQLITE_SQL : MSSQL_SQL;
|
||||
|
||||
/**
|
||||
* Counts customers of the POS terminal company updated after the given unix timestamp cursor.
|
||||
*
|
||||
* @param {object} input
|
||||
* @param {number} input.posterminalId - The POS terminal id.
|
||||
* @param {number} [input.cursor=0] - Unix timestamp cursor of last update.
|
||||
* @param {object} [tx] - Optional transaction to run within.
|
||||
* @returns {Promise<number>} The count of changed records.
|
||||
*/
|
||||
return async ({ posterminalId, cursor = 0 } = {}, tx) => {
|
||||
const result = await makeRunner(provider, tx).query(sql, {
|
||||
posterminalId: Number(posterminalId),
|
||||
cursor: normalizeCursor(cursor),
|
||||
});
|
||||
return Number(result.rows[0]?.count ?? 0);
|
||||
};
|
||||
}
|
||||
30
src/store/posterminal/getCustomerGroupCount.js
Normal file
30
src/store/posterminal/getCustomerGroupCount.js
Normal file
@@ -0,0 +1,30 @@
|
||||
import { COUNT_CUSTOMER_GROUPS as MSSQL_SQL } from '../../providers/mssql/queries/posterminal.js';
|
||||
import { COUNT_CUSTOMER_GROUPS as SQLITE_SQL } from '../../providers/sqlite3/queries/posterminal.js';
|
||||
import makeRunner from '../runner.js';
|
||||
|
||||
function normalizeCursor(cursor) {
|
||||
const n = Number(cursor) || 0;
|
||||
if (n <= 0) return 0;
|
||||
return n >= 1e11 ? Math.floor(n / 1000) : Math.floor(n);
|
||||
}
|
||||
|
||||
export default function getCustomerGroupCount(provider) {
|
||||
const sql = provider?.dialect === 'sqlite3' ? SQLITE_SQL : MSSQL_SQL;
|
||||
|
||||
/**
|
||||
* Counts customer groups of the POS terminal company updated after the given unix timestamp cursor.
|
||||
*
|
||||
* @param {object} input
|
||||
* @param {number} input.posterminalId - The POS terminal id.
|
||||
* @param {number} [input.cursor=0] - Unix timestamp cursor of last update.
|
||||
* @param {object} [tx] - Optional transaction to run within.
|
||||
* @returns {Promise<number>} The count of changed records.
|
||||
*/
|
||||
return async ({ posterminalId, cursor = 0 } = {}, tx) => {
|
||||
const result = await makeRunner(provider, tx).query(sql, {
|
||||
posterminalId: Number(posterminalId),
|
||||
cursor: normalizeCursor(cursor),
|
||||
});
|
||||
return Number(result.rows[0]?.count ?? 0);
|
||||
};
|
||||
}
|
||||
11
src/store/posterminal/getDeletedEntityCount.js
Normal file
11
src/store/posterminal/getDeletedEntityCount.js
Normal file
@@ -0,0 +1,11 @@
|
||||
export default function getDeletedEntityCount() {
|
||||
/**
|
||||
* Counts deleted entities after the given cursor (currently always 0).
|
||||
*
|
||||
* @param {object} [input]
|
||||
* @param {number} [input.posterminalId] - The POS terminal id.
|
||||
* @param {number} [input.cursor=0] - Unix timestamp cursor.
|
||||
* @returns {Promise<number>} Always 0.
|
||||
*/
|
||||
return async () => 0;
|
||||
}
|
||||
22
src/store/posterminal/getMaxOrderIdCount.js
Normal file
22
src/store/posterminal/getMaxOrderIdCount.js
Normal file
@@ -0,0 +1,22 @@
|
||||
import { MAX_ORDER_ID as MSSQL_SQL } from '../../providers/mssql/queries/posterminal.js';
|
||||
import { MAX_ORDER_ID as SQLITE_SQL } from '../../providers/sqlite3/queries/posterminal.js';
|
||||
import makeRunner from '../runner.js';
|
||||
|
||||
export default function getMaxOrderIdCount(provider) {
|
||||
const sql = provider?.dialect === 'sqlite3' ? SQLITE_SQL : MSSQL_SQL;
|
||||
|
||||
/**
|
||||
* Returns the maximum order manifest id for the POS terminal company.
|
||||
*
|
||||
* @param {object} input
|
||||
* @param {number} input.posterminalId - The POS terminal id.
|
||||
* @param {object} [tx] - Optional transaction to run within.
|
||||
* @returns {Promise<number>} Maximum order id or 0.
|
||||
*/
|
||||
return async ({ posterminalId } = {}, tx) => {
|
||||
const result = await makeRunner(provider, tx).query(sql, {
|
||||
posterminalId: Number(posterminalId),
|
||||
});
|
||||
return Number(result.rows[0]?.maxOrderId ?? 0);
|
||||
};
|
||||
}
|
||||
30
src/store/posterminal/getProductCount.js
Normal file
30
src/store/posterminal/getProductCount.js
Normal file
@@ -0,0 +1,30 @@
|
||||
import { COUNT_PRODUCTS as MSSQL_SQL } from '../../providers/mssql/queries/posterminal.js';
|
||||
import { COUNT_PRODUCTS as SQLITE_SQL } from '../../providers/sqlite3/queries/posterminal.js';
|
||||
import makeRunner from '../runner.js';
|
||||
|
||||
function normalizeCursor(cursor) {
|
||||
const n = Number(cursor) || 0;
|
||||
if (n <= 0) return 0;
|
||||
return n >= 1e11 ? Math.floor(n / 1000) : Math.floor(n);
|
||||
}
|
||||
|
||||
export default function getProductCount(provider) {
|
||||
const sql = provider?.dialect === 'sqlite3' ? SQLITE_SQL : MSSQL_SQL;
|
||||
|
||||
/**
|
||||
* Counts products assigned to the POS terminal updated after the given unix timestamp cursor.
|
||||
*
|
||||
* @param {object} input
|
||||
* @param {number} input.posterminalId - The POS terminal id.
|
||||
* @param {number} [input.cursor=0] - Unix timestamp cursor of last update.
|
||||
* @param {object} [tx] - Optional transaction to run within.
|
||||
* @returns {Promise<number>} The count of changed records.
|
||||
*/
|
||||
return async ({ posterminalId, cursor = 0 } = {}, tx) => {
|
||||
const result = await makeRunner(provider, tx).query(sql, {
|
||||
posterminalId: Number(posterminalId),
|
||||
cursor: normalizeCursor(cursor),
|
||||
});
|
||||
return Number(result.rows[0]?.count ?? 0);
|
||||
};
|
||||
}
|
||||
@@ -97,6 +97,13 @@ export default function adjust(provider) {
|
||||
const resolvedArticles = [];
|
||||
for (const item of normalizedLines) {
|
||||
const resolved = await resolveArticle(googleAuthId, item.sku, activeTx);
|
||||
const artRes = await runner.query('SELECT is_father FROM article WHERE id = @articleId', {
|
||||
articleId: resolved.articleId,
|
||||
});
|
||||
if (artRes.rows[0]?.is_father) {
|
||||
throw new Error(`A father article cannot have stock (${item.sku})`);
|
||||
}
|
||||
|
||||
const nameRes = await runner.query(GET_ARTICLE_NAME_SQL, {
|
||||
articleId: resolved.articleId,
|
||||
languageId: resolved.languageId,
|
||||
|
||||
Reference in New Issue
Block a user