refactor: introduce database provider abstraction, isolate MSSQL layer
- Add provider contract (src/providers/provider.js): query() -> {rows,
rowsAffected, insertId}, callback transaction(fn), exec() for stored
procs, initialize/purge lifecycle
- Add MssqlProvider (src/providers/mssql/index.js) wrapping an mssql
ConnectionPool with normalized results, tx commit/rollback and
constraint-error classifiers (unique 2627/2601, FK 547)
- LibDashStore constructor now takes a provider instead of a pool
(breaking); adds LibDashStore.create() async factory; keeps pool as
transitional bridge until store modules are converted (see TODO.md)
- Move MSSQL-specific code into the provider: src/sql/* ->
src/providers/mssql/queries/*, src/schema.js ->
src/providers/mssql/schema.js, purge SQL -> purgeSql.js
- Update scripts, generate-schema-graph.js and package.json exports
(./providers/mssql, ./providers/provider)
- Add TODO.md with the remaining provider/SQLite migration plan
No SQL or behavioral changes.
This commit is contained in:
126
src/providers/mssql/index.js
Normal file
126
src/providers/mssql/index.js
Normal file
@@ -0,0 +1,126 @@
|
||||
/**
|
||||
* MSSQL provider over an `mssql` ConnectionPool.
|
||||
* Normalizes mssql results into the provider contract shape:
|
||||
* { rows, rowsAffected, insertId }
|
||||
*/
|
||||
|
||||
function normalizeRows(result) {
|
||||
const recordset = result?.recordset ?? [];
|
||||
const affected = Array.isArray(result?.rowsAffected)
|
||||
? result.rowsAffected.reduce((a, b) => a + b, 0)
|
||||
: result?.rowsAffected ?? 0;
|
||||
return { rows: recordset, rowsAffected: affected, insertId: null };
|
||||
}
|
||||
|
||||
export class MssqlExecutor {
|
||||
/** @param {() => import('mssql').Request} requestFactory */
|
||||
constructor(requestFactory) {
|
||||
this.#requestFactory = requestFactory;
|
||||
}
|
||||
|
||||
#requestFactory;
|
||||
|
||||
/** @returns {Promise<import('../provider.js').QueryResult>} */
|
||||
async query(sql, params = {}) {
|
||||
const req = this.#requestFactory();
|
||||
for (const [key, value] of Object.entries(params)) {
|
||||
req.input(key, value);
|
||||
}
|
||||
return normalizeRows(await req.query(sql));
|
||||
}
|
||||
|
||||
/**
|
||||
* Stored-procedure call with input/output params.
|
||||
* Used by numbers.nextNumber / peekNumber
|
||||
* (`getnextnumberwithprefixandpadding`).
|
||||
*/
|
||||
async exec(procName, { inputs = {}, outputs = [] } = {}) {
|
||||
const req = this.#requestFactory();
|
||||
for (const [key, value] of Object.entries(inputs)) {
|
||||
req.input(key, value);
|
||||
}
|
||||
for (const out of outputs) {
|
||||
req.output(out);
|
||||
}
|
||||
const result = await req.execute(procName);
|
||||
return {
|
||||
rows: result.recordset ?? [],
|
||||
rowsAffected: Array.isArray(result.rowsAffected)
|
||||
? result.rowsAffected.reduce((a, b) => a + b, 0)
|
||||
: 0,
|
||||
insertId: null,
|
||||
outputs: result.output ?? {},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export class MssqlProvider {
|
||||
/** @param {import('mssql').ConnectionPool} pool */
|
||||
constructor(pool) {
|
||||
if (!pool || typeof pool.request !== 'function') {
|
||||
throw new TypeError('MssqlProvider requires an mssql ConnectionPool');
|
||||
}
|
||||
this.pool = pool;
|
||||
}
|
||||
|
||||
makeExecutor(requestFactory = () => this.pool.request()) {
|
||||
return new MssqlExecutor(requestFactory);
|
||||
}
|
||||
|
||||
async query(sql, params = {}) {
|
||||
return this.makeExecutor().query(sql, params);
|
||||
}
|
||||
|
||||
async exec(procName, options) {
|
||||
return this.makeExecutor().exec(procName, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs `fn(runner)` inside a transaction. Commit on success,
|
||||
* rollback on error. `runner` has query/exec like the provider.
|
||||
*
|
||||
* @template T
|
||||
* @param {(runner: MssqlExecutor) => Promise<T>} fn
|
||||
* @returns {Promise<T>}
|
||||
*/
|
||||
async transaction(fn) {
|
||||
const tx = this.pool.transaction();
|
||||
await tx.begin();
|
||||
try {
|
||||
const runner = this.makeExecutor(() => tx.request());
|
||||
const result = await fn(runner);
|
||||
await tx.commit();
|
||||
return result;
|
||||
} catch (err) {
|
||||
try {
|
||||
await tx.rollback();
|
||||
} catch {
|
||||
// ignore rollback failure after original error
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
async initialize() {
|
||||
// Implemented by store/initialize.js — no-op here (keeps parity with
|
||||
// other providers, which may run migrations internally instead).
|
||||
}
|
||||
|
||||
async purge() {
|
||||
// Implemented by store/purge.js — no-op here.
|
||||
}
|
||||
|
||||
close() {
|
||||
return this.pool.close();
|
||||
}
|
||||
}
|
||||
|
||||
/** mssql: 2627 = PK/unique violation, 2601 = unique index violation */
|
||||
export function isUniqueConstraintError(err) {
|
||||
return err?.number === 2627 || err?.number === 2601;
|
||||
}
|
||||
|
||||
/** mssql: 547 = FK conflict */
|
||||
export function isForeignKeyConstraintError(err) {
|
||||
return err?.number === 547;
|
||||
}
|
||||
74
src/providers/mssql/purgeSql.js
Normal file
74
src/providers/mssql/purgeSql.js
Normal file
@@ -0,0 +1,74 @@
|
||||
/** Drop order = reverse of schema create dependency order. */
|
||||
export const TABLES = [
|
||||
'companyuser',
|
||||
'syncpos',
|
||||
'companysetting',
|
||||
'posterminalcategory',
|
||||
'posterminal',
|
||||
'numbers',
|
||||
'ledger',
|
||||
'articlesupplier',
|
||||
'manifestarticle',
|
||||
'manifest',
|
||||
'price',
|
||||
'articletext',
|
||||
'categorytext',
|
||||
'categorypic',
|
||||
'categoryarticle',
|
||||
'optionslistarticle',
|
||||
'articlelistarticle',
|
||||
'brandpic',
|
||||
'articlepic',
|
||||
'articleean',
|
||||
'articlehistory',
|
||||
'entityhistory',
|
||||
'entityaddress',
|
||||
'entitycontact',
|
||||
'article',
|
||||
'brand',
|
||||
'articlelist',
|
||||
'optionslist',
|
||||
'unittext',
|
||||
'unit',
|
||||
'entity',
|
||||
'customergroup',
|
||||
'google_auth',
|
||||
'company',
|
||||
'pic',
|
||||
'category',
|
||||
'tax',
|
||||
'language',
|
||||
'meta',
|
||||
];
|
||||
|
||||
export const PROCEDURES = [
|
||||
'getnextnumberwithprefixandpadding',
|
||||
'peeknextnumberwithprefixandpadding',
|
||||
];
|
||||
|
||||
export const VIEWS = ['v_entity_company_number'];
|
||||
|
||||
/** Drop before tables — breaks company ↔ customergroup cycle for purge. */
|
||||
export const CONSTRAINTS = [
|
||||
`IF EXISTS (SELECT 1 FROM sys.foreign_keys WHERE name = N'FK_company_poscustomergroup')
|
||||
ALTER TABLE company DROP CONSTRAINT FK_company_poscustomergroup;`,
|
||||
];
|
||||
|
||||
export function buildPurgeSql() {
|
||||
const drops = [
|
||||
...PROCEDURES.map(
|
||||
(name) =>
|
||||
`IF OBJECT_ID(N'dbo.${name}', N'P') IS NOT NULL DROP PROCEDURE dbo.[${name}];`,
|
||||
),
|
||||
...VIEWS.map(
|
||||
(name) =>
|
||||
`IF OBJECT_ID(N'dbo.${name}', N'V') IS NOT NULL DROP VIEW dbo.[${name}];`,
|
||||
),
|
||||
...CONSTRAINTS,
|
||||
...TABLES.map(
|
||||
(name) =>
|
||||
`IF OBJECT_ID(N'dbo.${name}', N'U') IS NOT NULL DROP TABLE dbo.[${name}];`,
|
||||
),
|
||||
];
|
||||
return drops.join('\n');
|
||||
}
|
||||
506
src/providers/mssql/queries/article.js
Normal file
506
src/providers/mssql/queries/article.js
Normal file
@@ -0,0 +1,506 @@
|
||||
export const ARTICLE_LIST_JOINS = `
|
||||
LEFT JOIN articletext at
|
||||
ON at.article_id = a.id AND at.language_id = @languageId
|
||||
LEFT JOIN price pr
|
||||
ON pr.article_id = a.id
|
||||
AND pr.customergroup_id = @posCustomerGroupId
|
||||
AND pr.minmultiplier = 1
|
||||
LEFT JOIN tax t ON t.id = pr.tax_id
|
||||
OUTER APPLY (
|
||||
SELECT TOP 1 ap.pic_id
|
||||
FROM articlepic ap
|
||||
WHERE ap.article_id = a.id
|
||||
ORDER BY ap.sort ASC, ap.id ASC
|
||||
) first_pic
|
||||
LEFT JOIN pic ON pic.id = first_pic.pic_id
|
||||
LEFT JOIN article father ON father.id = a.fatherarticle_id
|
||||
`;
|
||||
|
||||
export const ARTICLE_LIST_COLUMNS = `
|
||||
a.id,
|
||||
a.sku,
|
||||
at.name,
|
||||
at.slug,
|
||||
pr.net,
|
||||
t.rate AS taxRate,
|
||||
CASE
|
||||
WHEN a.optionslist_id IS NOT NULL THEN (
|
||||
SELECT COUNT(*)
|
||||
FROM optionslistarticle ola
|
||||
WHERE ola.optionslist_id = a.optionslist_id
|
||||
)
|
||||
ELSE 0
|
||||
END AS optionsCount,
|
||||
CASE
|
||||
WHEN a.articlelist_id IS NOT NULL THEN (
|
||||
SELECT COUNT(*)
|
||||
FROM articlelistarticle ala
|
||||
WHERE ala.articlelist_id = a.articlelist_id
|
||||
)
|
||||
ELSE 0
|
||||
END AS articleListCount,
|
||||
(
|
||||
SELECT COUNT(*)
|
||||
FROM article child
|
||||
WHERE child.fatherarticle_id = a.id
|
||||
) AS childCount,
|
||||
a.fatherarticle_id AS fatherArticleId,
|
||||
father.sku AS fatherSku,
|
||||
pic.hash AS fullHash,
|
||||
pic.thumbw AS thumbW,
|
||||
pic.thumbh AS thumbH,
|
||||
pic.thumbhash AS thumbHash
|
||||
`;
|
||||
|
||||
export const GET_CATEGORY_ID_BY_SKU = `
|
||||
SELECT TOP 1 ca.category_id AS categoryId, a.id AS articleId
|
||||
FROM article a
|
||||
INNER JOIN categoryarticle ca ON ca.article_id = a.id
|
||||
WHERE a.sku = @sku
|
||||
`;
|
||||
|
||||
/** Resolve an article id by sku (used to wire father/child compound links). */
|
||||
export const GET_ID_BY_SKU = `
|
||||
SELECT TOP 1 id AS articleId
|
||||
FROM article
|
||||
WHERE sku = @sku
|
||||
`;
|
||||
|
||||
/** True if an EAN is already assigned to any article (duplicate guard). */
|
||||
export const EAN_EXISTS = `
|
||||
SELECT TOP 1 1 AS used
|
||||
FROM articleean
|
||||
WHERE ean = @ean
|
||||
`;
|
||||
|
||||
/** Link an article to its father article and mark the father. */
|
||||
export const UPDATE_FATHER_BY_SKU = `
|
||||
UPDATE article
|
||||
SET fatherarticle_id = @fatherArticleId
|
||||
WHERE sku = @sku
|
||||
`;
|
||||
|
||||
export const SET_IS_FATHER = `
|
||||
UPDATE article
|
||||
SET is_father = 1
|
||||
WHERE id = @articleId
|
||||
`;
|
||||
|
||||
export const SET_FATHER_SORT = `
|
||||
UPDATE article
|
||||
SET fathersort = @fathersort
|
||||
WHERE id = @articleId AND fatherarticle_id = @fatherArticleId
|
||||
`;
|
||||
|
||||
/** SKU → article/category + company auth in one round-trip. */
|
||||
export const RESOLVE_ARTICLE_ACCESS_BY_SKU = `
|
||||
WITH article_cat AS (
|
||||
SELECT TOP 1 a.id AS articleId, ca.category_id AS categoryId
|
||||
FROM article a
|
||||
INNER JOIN categoryarticle ca ON ca.article_id = a.id
|
||||
WHERE a.sku = @sku
|
||||
),
|
||||
ancestors AS (
|
||||
SELECT c.id, c.parent_id
|
||||
FROM category c
|
||||
INNER JOIN article_cat ac ON c.id = ac.categoryId
|
||||
|
||||
UNION ALL
|
||||
|
||||
SELECT c.id, c.parent_id
|
||||
FROM category c
|
||||
INNER JOIN ancestors a ON c.id = a.parent_id
|
||||
),
|
||||
root AS (
|
||||
SELECT TOP 1 id AS rootCategoryId
|
||||
FROM ancestors
|
||||
WHERE parent_id IS NULL
|
||||
)
|
||||
SELECT
|
||||
ac.articleId,
|
||||
ac.categoryId,
|
||||
r.rootCategoryId,
|
||||
co.id AS companyId,
|
||||
co.default_language_id AS languageId,
|
||||
co.poscustomergroup_id AS posCustomerGroupId,
|
||||
cu.id AS companyuserId
|
||||
FROM article_cat ac
|
||||
LEFT JOIN root r ON 1 = 1
|
||||
LEFT JOIN company co ON co.root_category_id = r.rootCategoryId
|
||||
LEFT JOIN companyuser cu
|
||||
ON cu.company_id = co.id AND cu.google_auth_id = @googleAuthId
|
||||
`;
|
||||
|
||||
export const UPDATE_WEIGHT = `
|
||||
UPDATE article
|
||||
SET weight = @weight
|
||||
WHERE id = @articleId
|
||||
`;
|
||||
|
||||
export const UPDATE_BRAND = `
|
||||
UPDATE article
|
||||
SET brand_id = @brandId
|
||||
WHERE id = @articleId
|
||||
`;
|
||||
|
||||
export const UPDATE_UNIT = `
|
||||
UPDATE article
|
||||
SET unit_id = @unitId
|
||||
WHERE id = @articleId
|
||||
`;
|
||||
|
||||
export const UPDATE_UNITAMOUNT = `
|
||||
UPDATE article
|
||||
SET unitamount = @unitamount
|
||||
WHERE id = @articleId
|
||||
`;
|
||||
|
||||
export const UPDATE_UNIT_AND_AMOUNT = `
|
||||
UPDATE article
|
||||
SET unit_id = @unitId, unitamount = @unitamount
|
||||
WHERE id = @articleId
|
||||
`;
|
||||
|
||||
export const CREATE = `
|
||||
INSERT INTO article (sku, unit_id, unitamount, weight)
|
||||
OUTPUT INSERTED.id
|
||||
VALUES (@sku, @unitId, @unitamount, @weight)
|
||||
`;
|
||||
|
||||
export const DELETE_EANS_BY_ARTICLE = `
|
||||
DELETE FROM articleean
|
||||
WHERE article_id = @articleId
|
||||
`;
|
||||
|
||||
export const ADD_EAN = `
|
||||
INSERT INTO articleean (article_id, ean)
|
||||
VALUES (@articleId, @ean)
|
||||
`;
|
||||
|
||||
export const DELETE_CATEGORIES_BY_ARTICLE = `
|
||||
DELETE FROM categoryarticle
|
||||
WHERE article_id = @articleId
|
||||
`;
|
||||
|
||||
export const ADD_CATEGORY = `
|
||||
INSERT INTO categoryarticle (category_id, article_id)
|
||||
VALUES (@categoryId, @articleId)
|
||||
`;
|
||||
|
||||
export const GET_BRAND_BY_COMPANY_AND_ID = `
|
||||
SELECT id
|
||||
FROM brand
|
||||
WHERE id = @brandId AND company_id = @companyId
|
||||
`;
|
||||
|
||||
/**
|
||||
* Company-wide article search index.
|
||||
* Returns one row per article with id, sku, name, and all eans as a JSON array.
|
||||
* Used by the client for local search / autocomplete.
|
||||
*/
|
||||
export const SEARCH_ARTICLES = `
|
||||
;WITH category_tree AS (
|
||||
SELECT id
|
||||
FROM category
|
||||
WHERE id = @rootCategoryId
|
||||
|
||||
UNION ALL
|
||||
|
||||
SELECT c.id
|
||||
FROM category c
|
||||
INNER JOIN category_tree ct ON c.parent_id = ct.id
|
||||
)
|
||||
SELECT
|
||||
a.id,
|
||||
a.sku,
|
||||
at.name,
|
||||
(
|
||||
SELECT ae.ean
|
||||
FROM articleean ae
|
||||
WHERE ae.article_id = a.id
|
||||
ORDER BY ae.ean
|
||||
FOR JSON PATH
|
||||
) AS eansJson,
|
||||
(
|
||||
SELECT ca2.category_id
|
||||
FROM categoryarticle ca2
|
||||
WHERE ca2.article_id = a.id
|
||||
ORDER BY ca2.category_id
|
||||
FOR JSON PATH
|
||||
) AS categoryIdsJson
|
||||
FROM article a
|
||||
LEFT JOIN articletext at
|
||||
ON at.article_id = a.id AND at.language_id = @languageId
|
||||
WHERE EXISTS (
|
||||
SELECT 1
|
||||
FROM categoryarticle ca
|
||||
INNER JOIN category_tree ct ON ct.id = ca.category_id
|
||||
WHERE ca.article_id = a.id
|
||||
)
|
||||
ORDER BY a.id
|
||||
`;
|
||||
|
||||
/**
|
||||
* Flat category tree (id, parentId, name) for a root category, used to resolve
|
||||
* breadcrumbs for the article export.
|
||||
*/
|
||||
export const GET_CATEGORY_TREE_FLAT = `
|
||||
;WITH tree AS (
|
||||
SELECT id, parent_id, sort
|
||||
FROM category
|
||||
WHERE id = @rootId
|
||||
|
||||
UNION ALL
|
||||
|
||||
SELECT c.id, c.parent_id, c.sort
|
||||
FROM category c
|
||||
INNER JOIN tree t ON c.parent_id = t.id
|
||||
)
|
||||
SELECT
|
||||
t.id,
|
||||
t.parent_id AS parentId,
|
||||
ct.name
|
||||
FROM tree t
|
||||
LEFT JOIN categorytext ct
|
||||
ON ct.category_id = t.id AND ct.language_id = @languageId
|
||||
`;
|
||||
|
||||
/**
|
||||
* Export rows for every article in a category subtree (root = @categoryId).
|
||||
* One row per article with the columns used by the export CSV, including the
|
||||
* POS price (minmultiplier = 1 for the company poscustomergroup), brand, unit,
|
||||
* eans, categoryIds and all photo hashes as JSON arrays.
|
||||
*/
|
||||
export const GET_ARTICLE_EXPORT = `
|
||||
;WITH category_tree AS (
|
||||
SELECT id
|
||||
FROM category
|
||||
WHERE id = @categoryId
|
||||
|
||||
UNION ALL
|
||||
|
||||
SELECT c.id
|
||||
FROM category c
|
||||
INNER JOIN category_tree ct ON c.parent_id = ct.id
|
||||
)
|
||||
SELECT
|
||||
a.id,
|
||||
a.sku,
|
||||
at.name,
|
||||
at.slug,
|
||||
u.si AS unitSi,
|
||||
ut.symbol AS unitSymbol,
|
||||
a.unitamount,
|
||||
b.name AS brandName,
|
||||
b.name AS brandName,
|
||||
pr.net AS net,
|
||||
t.rate AS taxRate,
|
||||
(
|
||||
SELECT ae.ean
|
||||
FROM articleean ae
|
||||
WHERE ae.article_id = a.id
|
||||
ORDER BY ae.ean
|
||||
FOR JSON PATH
|
||||
) AS eansJson,
|
||||
(
|
||||
SELECT ca2.category_id
|
||||
FROM categoryarticle ca2
|
||||
WHERE ca2.article_id = a.id
|
||||
ORDER BY ca2.category_id
|
||||
FOR JSON PATH
|
||||
) AS categoryIdsJson,
|
||||
(
|
||||
SELECT p.hash
|
||||
FROM articlepic ap
|
||||
INNER JOIN pic p ON p.id = ap.pic_id
|
||||
WHERE ap.article_id = a.id
|
||||
ORDER BY ap.sort ASC, ap.id ASC
|
||||
FOR JSON PATH
|
||||
) AS fullHashesJson
|
||||
FROM article a
|
||||
INNER JOIN categoryarticle ca ON ca.article_id = a.id
|
||||
INNER JOIN category_tree ct ON ct.id = ca.category_id
|
||||
LEFT JOIN articletext at
|
||||
ON at.article_id = a.id AND at.language_id = @languageId
|
||||
LEFT JOIN unit u ON u.id = a.unit_id
|
||||
LEFT JOIN unittext ut
|
||||
ON ut.unit_id = u.id AND ut.language_id = @languageId
|
||||
LEFT JOIN brand b ON b.id = a.brand_id
|
||||
LEFT JOIN price pr
|
||||
ON pr.article_id = a.id
|
||||
AND pr.customergroup_id = @posCustomerGroupId
|
||||
AND pr.minmultiplier = 1
|
||||
LEFT JOIN tax t ON t.id = pr.tax_id
|
||||
ORDER BY a.id
|
||||
`;
|
||||
|
||||
/**
|
||||
* Single-query replacement for resolveArticleBySku + queryBySku.
|
||||
* Resolves SKU → article + company + auth, then loads full article detail
|
||||
* including categories, photos, eans, and prices via FOR JSON sub-queries.
|
||||
* Returns one row with articleJson, or empty if not found/unauthorized.
|
||||
*/
|
||||
export const GET_ARTICLE_BY_SKU_FULL = `
|
||||
;WITH article_cat AS (
|
||||
SELECT TOP 1 a.id AS articleId, ca.category_id AS categoryId
|
||||
FROM article a
|
||||
INNER JOIN categoryarticle ca ON ca.article_id = a.id
|
||||
WHERE a.sku = @sku
|
||||
),
|
||||
ancestors AS (
|
||||
SELECT c.id, c.parent_id
|
||||
FROM category c
|
||||
INNER JOIN article_cat ac ON c.id = ac.categoryId
|
||||
|
||||
UNION ALL
|
||||
|
||||
SELECT c.id, c.parent_id
|
||||
FROM category c
|
||||
INNER JOIN ancestors a ON c.id = a.parent_id
|
||||
),
|
||||
root AS (
|
||||
SELECT TOP 1 id AS rootCategoryId
|
||||
FROM ancestors
|
||||
WHERE parent_id IS NULL
|
||||
),
|
||||
auth AS (
|
||||
SELECT
|
||||
ac.articleId,
|
||||
ac.categoryId,
|
||||
r.rootCategoryId,
|
||||
co.id AS companyId,
|
||||
co.default_language_id AS languageId,
|
||||
co.poscustomergroup_id AS posCustomerGroupId,
|
||||
cu.id AS companyuserId
|
||||
FROM article_cat ac
|
||||
LEFT JOIN root r ON 1 = 1
|
||||
LEFT JOIN company co ON co.root_category_id = r.rootCategoryId
|
||||
LEFT JOIN companyuser cu
|
||||
ON cu.company_id = co.id AND cu.google_auth_id = @googleAuthId
|
||||
)
|
||||
SELECT
|
||||
auth.articleId,
|
||||
auth.categoryId,
|
||||
auth.rootCategoryId,
|
||||
auth.companyId,
|
||||
auth.languageId,
|
||||
auth.posCustomerGroupId,
|
||||
auth.companyuserId,
|
||||
(
|
||||
SELECT
|
||||
a.id,
|
||||
a.sku,
|
||||
at.name,
|
||||
at.slug,
|
||||
a.unitamount,
|
||||
a.weight,
|
||||
u.si AS unitSi,
|
||||
u.basesi AS unitBasesi,
|
||||
u.basesifactor AS unitBasesifactor,
|
||||
ut.symbol AS unitSymbol,
|
||||
ut.name AS unitName,
|
||||
b.name AS brandName,
|
||||
bp.thumbw AS brandThumbW,
|
||||
bp.thumbh AS brandThumbH,
|
||||
bp.thumbhash AS brandThumbHash,
|
||||
(
|
||||
SELECT COUNT(*)
|
||||
FROM optionslistarticle ola
|
||||
WHERE ola.optionslist_id = a.optionslist_id
|
||||
) AS optionsCount,
|
||||
(
|
||||
SELECT COUNT(*)
|
||||
FROM articlelistarticle ala
|
||||
WHERE ala.articlelist_id = a.articlelist_id
|
||||
) AS articleListCount,
|
||||
(
|
||||
SELECT COUNT(*)
|
||||
FROM article child
|
||||
WHERE child.fatherarticle_id = a.id
|
||||
) AS childCount,
|
||||
a.fatherarticle_id AS fatherArticleId,
|
||||
fa.sku AS fatherSku,
|
||||
(
|
||||
SELECT ca2.category_id
|
||||
FROM categoryarticle ca2
|
||||
WHERE ca2.article_id = a.id
|
||||
ORDER BY ca2.category_id
|
||||
FOR JSON PATH
|
||||
) AS categoryIdsJson,
|
||||
(
|
||||
SELECT
|
||||
ap.sort,
|
||||
p.hash AS fullHash,
|
||||
p.w AS fullW,
|
||||
p.h AS fullH,
|
||||
p.size AS fullSize,
|
||||
p.thumbw AS thumbW,
|
||||
p.thumbh AS thumbH,
|
||||
p.thumbhash AS thumbHash
|
||||
FROM articlepic ap
|
||||
INNER JOIN pic p ON p.id = ap.pic_id
|
||||
WHERE ap.article_id = a.id
|
||||
ORDER BY ap.sort ASC, ap.id ASC
|
||||
FOR JSON PATH
|
||||
) AS photosJson,
|
||||
(
|
||||
SELECT ae.ean
|
||||
FROM articleean ae
|
||||
WHERE ae.article_id = a.id
|
||||
ORDER BY ae.ean
|
||||
FOR JSON PATH
|
||||
) AS eansJson,
|
||||
(
|
||||
SELECT
|
||||
pr.minmultiplier,
|
||||
pr.net,
|
||||
t.rate AS taxRate,
|
||||
pr.customergroup_id AS customergroupId
|
||||
FROM price pr
|
||||
INNER JOIN tax t ON t.id = pr.tax_id
|
||||
WHERE pr.article_id = a.id
|
||||
ORDER BY pr.customergroup_id, pr.minmultiplier
|
||||
FOR JSON PATH
|
||||
) AS pricesJson,
|
||||
(
|
||||
SELECT
|
||||
asup.id,
|
||||
asup.article_id AS articleId,
|
||||
asup.entity_id AS entityId,
|
||||
e.name AS supplierName,
|
||||
asup.sku,
|
||||
asup.pu,
|
||||
asup.stock,
|
||||
asup.sort,
|
||||
asup.price_id AS priceId,
|
||||
p.net AS [price.net],
|
||||
p.tax_id AS [price.taxId],
|
||||
t.rate AS [price.taxRate]
|
||||
FROM articlesupplier asup
|
||||
INNER JOIN entity e ON e.id = asup.entity_id
|
||||
LEFT JOIN price p ON p.id = asup.price_id
|
||||
LEFT JOIN tax t ON t.id = p.tax_id
|
||||
WHERE asup.article_id = a.id
|
||||
ORDER BY asup.sort ASC, asup.id ASC
|
||||
FOR JSON PATH
|
||||
) AS suppliersJson
|
||||
FROM article a
|
||||
LEFT JOIN articletext at
|
||||
ON at.article_id = a.id AND at.language_id = auth.languageId
|
||||
LEFT JOIN unit u ON u.id = a.unit_id
|
||||
LEFT JOIN unittext ut
|
||||
ON ut.unit_id = u.id AND ut.language_id = auth.languageId
|
||||
LEFT JOIN brand b ON b.id = a.brand_id
|
||||
OUTER APPLY (
|
||||
SELECT TOP 1 bp2.pic_id
|
||||
FROM brandpic bp2
|
||||
WHERE bp2.brand_id = b.id
|
||||
ORDER BY bp2.sort ASC, bp2.id ASC
|
||||
) first_brand_pic
|
||||
LEFT JOIN pic bp ON bp.id = first_brand_pic.pic_id
|
||||
LEFT JOIN article fa ON fa.id = a.fatherarticle_id
|
||||
WHERE a.id = auth.articleId
|
||||
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
|
||||
) AS articleJson
|
||||
FROM auth
|
||||
`;
|
||||
34
src/providers/mssql/queries/articleDelete.js
Normal file
34
src/providers/mssql/queries/articleDelete.js
Normal file
@@ -0,0 +1,34 @@
|
||||
export const GET_CHILD_COUNT = `
|
||||
SELECT COUNT(*) AS count
|
||||
FROM article
|
||||
WHERE fatherarticle_id = @articleId
|
||||
`;
|
||||
|
||||
export const GET_LIST_IDS = `
|
||||
SELECT articlelist_id AS articlelistId, optionslist_id AS optionslistId
|
||||
FROM article
|
||||
WHERE id = @articleId
|
||||
`;
|
||||
|
||||
|
||||
export const DELETE_PICS_BY_ARTICLE = `
|
||||
DELETE p
|
||||
FROM pic p
|
||||
INNER JOIN articlepic ap ON ap.pic_id = p.id
|
||||
WHERE ap.article_id = @articleId
|
||||
`;
|
||||
|
||||
export const DELETE_BY_ID = `
|
||||
DELETE FROM article
|
||||
WHERE id = @articleId
|
||||
`;
|
||||
|
||||
export const DELETE_ARTICLELIST = `
|
||||
DELETE FROM articlelist
|
||||
WHERE id = @id
|
||||
`;
|
||||
|
||||
export const DELETE_OPTIONSLIST = `
|
||||
DELETE FROM optionslist
|
||||
WHERE id = @id
|
||||
`;
|
||||
124
src/providers/mssql/queries/articleDetail.js
Normal file
124
src/providers/mssql/queries/articleDetail.js
Normal file
@@ -0,0 +1,124 @@
|
||||
export const ARTICLE_DETAIL_COLUMNS = `
|
||||
a.id,
|
||||
a.sku,
|
||||
at.name,
|
||||
at.slug,
|
||||
a.unitamount,
|
||||
a.weight,
|
||||
u.si AS unitSi,
|
||||
u.basesi AS unitBasesi,
|
||||
u.basesifactor AS unitBasesifactor,
|
||||
ut.symbol AS unitSymbol,
|
||||
ut.name AS unitName,
|
||||
b.name AS brandName,
|
||||
brand_pic.thumbw AS brandThumbW,
|
||||
brand_pic.thumbh AS brandThumbH,
|
||||
brand_pic.thumbhash AS brandThumbHash,
|
||||
CASE
|
||||
WHEN a.optionslist_id IS NOT NULL THEN (
|
||||
SELECT COUNT(*)
|
||||
FROM optionslistarticle ola
|
||||
WHERE ola.optionslist_id = a.optionslist_id
|
||||
)
|
||||
ELSE 0
|
||||
END AS optionsCount,
|
||||
CASE
|
||||
WHEN a.articlelist_id IS NOT NULL THEN (
|
||||
SELECT COUNT(*)
|
||||
FROM articlelistarticle ala
|
||||
WHERE ala.articlelist_id = a.articlelist_id
|
||||
)
|
||||
ELSE 0
|
||||
END AS articleListCount,
|
||||
(
|
||||
SELECT COUNT(*)
|
||||
FROM article child
|
||||
WHERE child.fatherarticle_id = a.id
|
||||
) AS childCount,
|
||||
a.fatherarticle_id AS fatherArticleId,
|
||||
father.sku AS fatherSku
|
||||
`;
|
||||
|
||||
export const GET_DETAIL_BY_SKU = `
|
||||
SELECT
|
||||
${ARTICLE_DETAIL_COLUMNS}
|
||||
FROM article a
|
||||
LEFT JOIN articletext at
|
||||
ON at.article_id = a.id AND at.language_id = @languageId
|
||||
LEFT JOIN unit u ON u.id = a.unit_id
|
||||
LEFT JOIN unittext ut
|
||||
ON ut.unit_id = u.id AND ut.language_id = @languageId
|
||||
LEFT JOIN brand b ON b.id = a.brand_id
|
||||
OUTER APPLY (
|
||||
SELECT TOP 1 bp.pic_id
|
||||
FROM brandpic bp
|
||||
WHERE bp.brand_id = b.id
|
||||
ORDER BY bp.sort ASC, bp.id ASC
|
||||
) first_brand_pic
|
||||
LEFT JOIN pic brand_pic ON brand_pic.id = first_brand_pic.pic_id
|
||||
LEFT JOIN article father ON father.id = a.fatherarticle_id
|
||||
WHERE a.sku = @sku
|
||||
`;
|
||||
|
||||
export const GET_DETAIL_BY_ARTICLE_ID = `
|
||||
SELECT
|
||||
${ARTICLE_DETAIL_COLUMNS}
|
||||
FROM article a
|
||||
LEFT JOIN articletext at
|
||||
ON at.article_id = a.id AND at.language_id = @languageId
|
||||
LEFT JOIN unit u ON u.id = a.unit_id
|
||||
LEFT JOIN unittext ut
|
||||
ON ut.unit_id = u.id AND ut.language_id = @languageId
|
||||
LEFT JOIN brand b ON b.id = a.brand_id
|
||||
OUTER APPLY (
|
||||
SELECT TOP 1 bp.pic_id
|
||||
FROM brandpic bp
|
||||
WHERE bp.brand_id = b.id
|
||||
ORDER BY bp.sort ASC, bp.id ASC
|
||||
) first_brand_pic
|
||||
LEFT JOIN pic brand_pic ON brand_pic.id = first_brand_pic.pic_id
|
||||
LEFT JOIN article father ON father.id = a.fatherarticle_id
|
||||
WHERE a.id = @articleId
|
||||
`;
|
||||
|
||||
export const GET_CATEGORY_IDS_BY_ARTICLE_ID = `
|
||||
SELECT ca.category_id AS categoryId
|
||||
FROM categoryarticle ca
|
||||
WHERE ca.article_id = @articleId
|
||||
ORDER BY ca.category_id
|
||||
`;
|
||||
|
||||
export const GET_PHOTOS_BY_ARTICLE_ID = `
|
||||
SELECT
|
||||
ap.sort,
|
||||
p.hash AS fullHash,
|
||||
p.w AS fullW,
|
||||
p.h AS fullH,
|
||||
p.size AS fullSize,
|
||||
p.thumbw AS thumbW,
|
||||
p.thumbh AS thumbH,
|
||||
p.thumbhash AS thumbHash
|
||||
FROM articlepic ap
|
||||
INNER JOIN pic p ON p.id = ap.pic_id
|
||||
WHERE ap.article_id = @articleId
|
||||
ORDER BY ap.sort ASC, ap.id ASC
|
||||
`;
|
||||
|
||||
export const GET_EANS_BY_ARTICLE_ID = `
|
||||
SELECT ae.ean
|
||||
FROM articleean ae
|
||||
WHERE ae.article_id = @articleId
|
||||
ORDER BY ae.ean
|
||||
`;
|
||||
|
||||
export const GET_PRICES_BY_ARTICLE_ID = `
|
||||
SELECT
|
||||
pr.minmultiplier AS minmultiplier,
|
||||
pr.net,
|
||||
t.rate AS taxRate,
|
||||
pr.customergroup_id AS customergroupId
|
||||
FROM price pr
|
||||
INNER JOIN tax t ON t.id = pr.tax_id
|
||||
WHERE pr.article_id = @articleId
|
||||
ORDER BY pr.customergroup_id, pr.minmultiplier
|
||||
`;
|
||||
11
src/providers/mssql/queries/articlehistory.js
Normal file
11
src/providers/mssql/queries/articlehistory.js
Normal file
@@ -0,0 +1,11 @@
|
||||
export const INSERT = `
|
||||
INSERT INTO articlehistory (article_id, companyuser_id, [text])
|
||||
VALUES (@articleId, @companyuserId, @text)
|
||||
`;
|
||||
|
||||
export const LIST_BY_ARTICLE_ID = `
|
||||
SELECT id, companyuser_id AS companyuserId, [date], [text]
|
||||
FROM articlehistory
|
||||
WHERE article_id = @articleId
|
||||
ORDER BY [date] DESC, id DESC
|
||||
`;
|
||||
32
src/providers/mssql/queries/articlepic.js
Normal file
32
src/providers/mssql/queries/articlepic.js
Normal file
@@ -0,0 +1,32 @@
|
||||
export const GET_NEXT_SORT = `
|
||||
SELECT ISNULL(MAX(sort), -1) + 1 AS sort
|
||||
FROM articlepic
|
||||
WHERE article_id = @articleId
|
||||
`;
|
||||
|
||||
export const ADD = `
|
||||
INSERT INTO articlepic (article_id, pic_id, sort)
|
||||
VALUES (@articleId, @picId, @sort)
|
||||
`;
|
||||
|
||||
export const LIST_HASHES_BY_ARTICLE = `
|
||||
SELECT p.hash AS fullHash
|
||||
FROM articlepic ap
|
||||
INNER JOIN pic p ON p.id = ap.pic_id
|
||||
WHERE ap.article_id = @articleId
|
||||
ORDER BY ap.sort ASC, ap.id ASC
|
||||
`;
|
||||
|
||||
export const SET_TEMP_SORTS = `
|
||||
UPDATE articlepic
|
||||
SET sort = -id
|
||||
WHERE article_id = @articleId
|
||||
`;
|
||||
|
||||
export const UPDATE_SORT_BY_HASH = `
|
||||
UPDATE ap
|
||||
SET sort = @sort
|
||||
FROM articlepic ap
|
||||
INNER JOIN pic p ON p.id = ap.pic_id
|
||||
WHERE ap.article_id = @articleId AND p.hash = @fullHash
|
||||
`;
|
||||
174
src/providers/mssql/queries/articlesupplier.js
Normal file
174
src/providers/mssql/queries/articlesupplier.js
Normal file
@@ -0,0 +1,174 @@
|
||||
export const LIST_BY_ARTICLE_ID = `
|
||||
SELECT
|
||||
asup.id,
|
||||
asup.article_id AS articleId,
|
||||
asup.entity_id AS entityId,
|
||||
e.name AS supplierName,
|
||||
asup.sku,
|
||||
asup.pu,
|
||||
asup.stock,
|
||||
asup.sort,
|
||||
asup.price_id AS priceId,
|
||||
p.net AS priceNet,
|
||||
p.tax_id AS priceTaxId,
|
||||
t.rate AS priceTaxRate
|
||||
FROM articlesupplier asup
|
||||
INNER JOIN entity e ON e.id = asup.entity_id
|
||||
INNER JOIN customergroup cg ON cg.id = e.customergroup_id
|
||||
LEFT JOIN price p ON p.id = asup.price_id
|
||||
LEFT JOIN tax t ON t.id = p.tax_id
|
||||
WHERE asup.article_id = @articleId
|
||||
AND cg.company_id = @companyId
|
||||
ORDER BY asup.sort ASC, asup.id ASC;
|
||||
`;
|
||||
|
||||
export const GET_BY_ID_AND_ARTICLE_ID = `
|
||||
SELECT
|
||||
asup.id,
|
||||
asup.article_id AS articleId,
|
||||
asup.entity_id AS entityId,
|
||||
e.name AS supplierName,
|
||||
asup.sku,
|
||||
asup.pu,
|
||||
asup.stock,
|
||||
asup.sort,
|
||||
asup.price_id AS priceId,
|
||||
p.net AS priceNet,
|
||||
p.tax_id AS priceTaxId,
|
||||
t.rate AS priceTaxRate
|
||||
FROM articlesupplier asup
|
||||
INNER JOIN entity e ON e.id = asup.entity_id
|
||||
INNER JOIN customergroup cg ON cg.id = e.customergroup_id
|
||||
LEFT JOIN price p ON p.id = asup.price_id
|
||||
LEFT JOIN tax t ON t.id = p.tax_id
|
||||
WHERE asup.id = @id
|
||||
AND asup.article_id = @articleId
|
||||
AND cg.company_id = @companyId;
|
||||
`;
|
||||
|
||||
export const CHECK_EXISTS = `
|
||||
SELECT TOP 1 id
|
||||
FROM articlesupplier
|
||||
WHERE article_id = @articleId AND entity_id = @entityId;
|
||||
`;
|
||||
|
||||
export const GET_NEXT_SORT = `
|
||||
SELECT ISNULL(MAX(sort), -1) + 1 AS sort
|
||||
FROM articlesupplier
|
||||
WHERE article_id = @articleId;
|
||||
`;
|
||||
|
||||
export const CREATE = `
|
||||
INSERT INTO articlesupplier (article_id, entity_id, price_id, sku, stock, pu, sort)
|
||||
OUTPUT INSERTED.id
|
||||
VALUES (@articleId, @entityId, @priceId, @sku, @stock, @pu, @sort);
|
||||
`;
|
||||
|
||||
export const UPDATE = `
|
||||
UPDATE articlesupplier
|
||||
SET
|
||||
sku = @sku,
|
||||
stock = @stock,
|
||||
pu = @pu,
|
||||
price_id = @priceId,
|
||||
sort = @sort
|
||||
WHERE id = @id AND article_id = @articleId;
|
||||
`;
|
||||
|
||||
export const DELETE_BY_ID_AND_ARTICLE_ID = `
|
||||
DELETE FROM articlesupplier
|
||||
WHERE id = @id AND article_id = @articleId;
|
||||
`;
|
||||
|
||||
export const LIST_IDS_BY_ARTICLE = `
|
||||
SELECT id
|
||||
FROM articlesupplier
|
||||
WHERE article_id = @articleId
|
||||
ORDER BY sort ASC, id ASC;
|
||||
`;
|
||||
|
||||
export const SET_TEMP_SORTS = `
|
||||
UPDATE articlesupplier
|
||||
SET sort = -id
|
||||
WHERE article_id = @articleId;
|
||||
`;
|
||||
|
||||
export const UPDATE_SORT = `
|
||||
UPDATE articlesupplier
|
||||
SET sort = @sort
|
||||
WHERE id = @id AND article_id = @articleId;
|
||||
`;
|
||||
|
||||
export const UPDATE_PRICE = `
|
||||
UPDATE price
|
||||
SET
|
||||
net = @net,
|
||||
tax_id = @taxId
|
||||
WHERE id = @id AND article_id = @articleId;
|
||||
`;
|
||||
|
||||
export const DELETE_PRICE = `
|
||||
DELETE FROM price
|
||||
WHERE id = @id AND article_id = @articleId;
|
||||
`;
|
||||
|
||||
export const GET_COMPANY_DEFAULT_TAX = `
|
||||
SELECT taxrate
|
||||
FROM company
|
||||
WHERE id = @companyId;
|
||||
`;
|
||||
|
||||
export const LIST_BY_ENTITY_AND_SKUS = `
|
||||
SELECT
|
||||
asup.id,
|
||||
asup.article_id AS articleId,
|
||||
asup.entity_id AS entityId,
|
||||
e.name AS supplierName,
|
||||
asup.sku,
|
||||
asup.pu,
|
||||
asup.stock,
|
||||
asup.sort,
|
||||
asup.price_id AS priceId,
|
||||
p.net AS priceNet,
|
||||
p.tax_id AS priceTaxId,
|
||||
t.rate AS priceTaxRate,
|
||||
a.id AS a_id,
|
||||
a.sku AS a_sku,
|
||||
at.name AS a_name,
|
||||
at.slug AS a_slug,
|
||||
(
|
||||
SELECT
|
||||
ap.sort,
|
||||
p.hash,
|
||||
p.thumbhash,
|
||||
p.thumbw,
|
||||
p.thumbh
|
||||
FROM articlepic ap
|
||||
INNER JOIN pic p ON p.id = ap.pic_id
|
||||
WHERE ap.article_id = a.id
|
||||
ORDER BY ap.sort ASC, ap.id ASC
|
||||
FOR JSON PATH
|
||||
) AS photosJson,
|
||||
(
|
||||
SELECT ae.ean
|
||||
FROM articleean ae
|
||||
WHERE ae.article_id = a.id
|
||||
ORDER BY ae.ean
|
||||
FOR JSON PATH
|
||||
) AS eansJson
|
||||
FROM articlesupplier asup
|
||||
INNER JOIN entity e ON e.id = asup.entity_id
|
||||
INNER JOIN customergroup cg ON cg.id = e.customergroup_id
|
||||
INNER JOIN article a ON a.id = asup.article_id
|
||||
LEFT JOIN articletext at ON at.article_id = a.id AND at.language_id = @languageId
|
||||
LEFT JOIN price p ON p.id = asup.price_id
|
||||
LEFT JOIN tax t ON t.id = p.tax_id
|
||||
WHERE asup.entity_id = @entityId
|
||||
AND cg.company_id = @companyId
|
||||
AND (
|
||||
@skusJson IS NULL
|
||||
OR a.sku IN (SELECT value FROM OPENJSON(@skusJson))
|
||||
OR asup.sku IN (SELECT value FROM OPENJSON(@skusJson))
|
||||
)
|
||||
ORDER BY asup.sort ASC, asup.id ASC;
|
||||
`;
|
||||
10
src/providers/mssql/queries/articletext.js
Normal file
10
src/providers/mssql/queries/articletext.js
Normal file
@@ -0,0 +1,10 @@
|
||||
export const CREATE = `
|
||||
INSERT INTO articletext (article_id, language_id, name, slug)
|
||||
VALUES (@articleId, @languageId, @name, @slug)
|
||||
`;
|
||||
|
||||
export const UPDATE_BY_ARTICLE_AND_LANGUAGE = `
|
||||
UPDATE articletext
|
||||
SET name = @name, slug = @slug
|
||||
WHERE article_id = @articleId AND language_id = @languageId
|
||||
`;
|
||||
36
src/providers/mssql/queries/brand.js
Normal file
36
src/providers/mssql/queries/brand.js
Normal file
@@ -0,0 +1,36 @@
|
||||
export const LIST_BY_COMPANY = `
|
||||
SELECT
|
||||
id,
|
||||
name,
|
||||
gsprpinfo
|
||||
FROM brand
|
||||
WHERE company_id = @companyId
|
||||
ORDER BY name
|
||||
`;
|
||||
|
||||
export const GET_BY_COMPANY_AND_NAME = `
|
||||
SELECT
|
||||
id,
|
||||
name,
|
||||
gsprpinfo
|
||||
FROM brand
|
||||
WHERE company_id = @companyId
|
||||
AND name = @name
|
||||
`;
|
||||
|
||||
export const CREATE = `
|
||||
INSERT INTO brand (company_id, name, gsprpinfo)
|
||||
OUTPUT INSERTED.id
|
||||
VALUES (@companyId, @name, @gsprpinfo)
|
||||
`;
|
||||
|
||||
export const UPDATE_BY_ID = `
|
||||
UPDATE brand
|
||||
SET name = @name, gsprpinfo = @gsprpinfo
|
||||
WHERE id = @id AND company_id = @companyId
|
||||
`;
|
||||
|
||||
export const DELETE_BY_COMPANY_AND_ID = `
|
||||
DELETE FROM brand
|
||||
WHERE id = @id AND company_id = @companyId
|
||||
`;
|
||||
144
src/providers/mssql/queries/category.js
Normal file
144
src/providers/mssql/queries/category.js
Normal file
@@ -0,0 +1,144 @@
|
||||
export const GET_TREE_FOR_COMPANY = `
|
||||
WITH tree AS (
|
||||
SELECT id, parent_id, sort
|
||||
FROM category
|
||||
WHERE id = @rootId
|
||||
|
||||
UNION ALL
|
||||
|
||||
SELECT c.id, c.parent_id, c.sort
|
||||
FROM category c
|
||||
INNER JOIN tree t ON c.parent_id = t.id
|
||||
)
|
||||
SELECT
|
||||
t.id,
|
||||
t.parent_id AS parentId,
|
||||
t.sort,
|
||||
ct.name,
|
||||
ct.slug,
|
||||
p.hash AS fullHash,
|
||||
p.thumbw AS thumbW,
|
||||
p.thumbh AS thumbH,
|
||||
p.thumbhash AS thumbHash
|
||||
FROM tree t
|
||||
LEFT JOIN categorytext ct
|
||||
ON ct.category_id = t.id AND ct.language_id = @languageId
|
||||
OUTER APPLY (
|
||||
SELECT TOP 1 cp.pic_id
|
||||
FROM categorypic cp
|
||||
WHERE cp.category_id = t.id
|
||||
ORDER BY cp.sort ASC, cp.id ASC
|
||||
) first_pic
|
||||
LEFT JOIN pic p ON p.id = first_pic.pic_id
|
||||
ORDER BY t.sort, t.id
|
||||
`;
|
||||
|
||||
import {
|
||||
ARTICLE_LIST_COLUMNS,
|
||||
ARTICLE_LIST_JOINS,
|
||||
} from './article.js';
|
||||
|
||||
export const GET_CATEGORY_ARTICLES = `
|
||||
SELECT
|
||||
${ARTICLE_LIST_COLUMNS}
|
||||
FROM categoryarticle ca
|
||||
INNER JOIN article a ON a.id = ca.article_id
|
||||
${ARTICLE_LIST_JOINS}
|
||||
WHERE ca.category_id = @categoryId
|
||||
ORDER BY a.id
|
||||
`;
|
||||
|
||||
export const CREATE = `
|
||||
INSERT INTO category (parent_id, sort)
|
||||
OUTPUT INSERTED.id, INSERTED.parent_id AS parentId, INSERTED.sort
|
||||
VALUES (@parentId, @sort)
|
||||
`;
|
||||
|
||||
export const RESOLVE_CATEGORY_ACCESS = `
|
||||
WITH ancestors AS (
|
||||
SELECT id, parent_id
|
||||
FROM category
|
||||
WHERE id = @categoryId
|
||||
|
||||
UNION ALL
|
||||
|
||||
SELECT c.id, c.parent_id
|
||||
FROM category c
|
||||
INNER JOIN ancestors a ON c.id = a.parent_id
|
||||
),
|
||||
root AS (
|
||||
SELECT TOP 1 id AS rootCategoryId
|
||||
FROM ancestors
|
||||
WHERE parent_id IS NULL
|
||||
)
|
||||
SELECT
|
||||
p.id AS categoryId,
|
||||
r.rootCategoryId,
|
||||
co.id AS companyId,
|
||||
co.default_language_id AS languageId,
|
||||
co.poscustomergroup_id AS posCustomerGroupId,
|
||||
cu.id AS companyuserId
|
||||
FROM category p
|
||||
LEFT JOIN root r ON 1 = 1
|
||||
LEFT JOIN company co ON co.root_category_id = r.rootCategoryId
|
||||
LEFT JOIN companyuser cu
|
||||
ON cu.company_id = co.id AND cu.google_auth_id = @googleAuthId
|
||||
WHERE p.id = @categoryId
|
||||
`;
|
||||
|
||||
export const GET_NEXT_SIBLING_SORT = `
|
||||
SELECT ISNULL(MAX(sort), -1) + 1 AS sort
|
||||
FROM category
|
||||
WHERE parent_id = @parentId
|
||||
`;
|
||||
|
||||
/** Resolve a child category by its parent id and name (language-sensitive). */
|
||||
export const GET_BY_PARENT_AND_NAME = `
|
||||
SELECT c.id
|
||||
FROM category c
|
||||
INNER JOIN categorytext ct
|
||||
ON ct.category_id = c.id AND ct.language_id = @languageId
|
||||
WHERE c.parent_id = @parentId
|
||||
AND ct.name = @name
|
||||
`;
|
||||
|
||||
export const LIST_CHILD_IDS = `
|
||||
SELECT id
|
||||
FROM category
|
||||
WHERE parent_id = @parentId
|
||||
`;
|
||||
|
||||
export const UPDATE_SORT = `
|
||||
UPDATE category
|
||||
SET sort = @sort
|
||||
WHERE id = @id AND parent_id = @parentId
|
||||
`;
|
||||
|
||||
/** True if @id is an ancestor of @parentId (would create a cycle when moving). */
|
||||
export const IS_ANCESTOR = `
|
||||
WITH ancestors AS (
|
||||
SELECT id, parent_id
|
||||
FROM category
|
||||
WHERE id = @parentId
|
||||
|
||||
UNION ALL
|
||||
|
||||
SELECT c.id, c.parent_id
|
||||
FROM category c
|
||||
INNER JOIN ancestors a ON c.id = a.parent_id
|
||||
)
|
||||
SELECT id
|
||||
FROM ancestors
|
||||
WHERE id = @id
|
||||
`;
|
||||
|
||||
export const MOVE = `
|
||||
UPDATE category
|
||||
SET parent_id = @parentId, sort = @sort
|
||||
WHERE id = @id
|
||||
`;
|
||||
|
||||
export const DELETE = `
|
||||
DELETE FROM category
|
||||
WHERE id = @id
|
||||
`;
|
||||
4
src/providers/mssql/queries/categoryarticle.js
Normal file
4
src/providers/mssql/queries/categoryarticle.js
Normal file
@@ -0,0 +1,4 @@
|
||||
export const ADD = `
|
||||
INSERT INTO categoryarticle (category_id, article_id)
|
||||
VALUES (@categoryId, @articleId)
|
||||
`;
|
||||
23
src/providers/mssql/queries/categorypic.js
Normal file
23
src/providers/mssql/queries/categorypic.js
Normal file
@@ -0,0 +1,23 @@
|
||||
export const GET_NEXT_SORT = `
|
||||
SELECT ISNULL(MAX(sort), -1) + 1 AS sort
|
||||
FROM categorypic
|
||||
WHERE category_id = @categoryId
|
||||
`;
|
||||
|
||||
export const ADD = `
|
||||
INSERT INTO categorypic (category_id, pic_id, sort)
|
||||
VALUES (@categoryId, @picId, @sort)
|
||||
`;
|
||||
|
||||
export const DELETE_BY_CATEGORY = `
|
||||
DELETE FROM categorypic
|
||||
WHERE category_id = @categoryId
|
||||
`;
|
||||
|
||||
export const GET_FIRST_PIC_BY_CATEGORY = `
|
||||
SELECT TOP 1 p.id AS picId, p.thumbw AS thumbW, p.thumbh AS thumbH, p.thumbhash AS thumbHash
|
||||
FROM categorypic cp
|
||||
INNER JOIN pic p ON p.id = cp.pic_id
|
||||
WHERE cp.category_id = @categoryId
|
||||
ORDER BY cp.sort ASC, cp.id ASC
|
||||
`;
|
||||
10
src/providers/mssql/queries/categorytext.js
Normal file
10
src/providers/mssql/queries/categorytext.js
Normal file
@@ -0,0 +1,10 @@
|
||||
export const CREATE = `
|
||||
INSERT INTO categorytext (category_id, language_id, name, slug)
|
||||
VALUES (@categoryId, @languageId, @name, @slug)
|
||||
`;
|
||||
|
||||
export const UPDATE_BY_CATEGORY_AND_LANGUAGE = `
|
||||
UPDATE categorytext
|
||||
SET name = @name, slug = @slug
|
||||
WHERE category_id = @categoryId AND language_id = @languageId
|
||||
`;
|
||||
69
src/providers/mssql/queries/company.js
Normal file
69
src/providers/mssql/queries/company.js
Normal file
@@ -0,0 +1,69 @@
|
||||
export const GET_BY_NAME = `
|
||||
SELECT id, name, root_category_id, default_language_id, taxrate, reducedtaxrate, taxfreerate
|
||||
FROM company
|
||||
WHERE name = @name
|
||||
`;
|
||||
|
||||
export const GET_BY_ID = `
|
||||
SELECT id, name, root_category_id, default_language_id, taxrate, reducedtaxrate, taxfreerate
|
||||
FROM company
|
||||
WHERE id = @id
|
||||
`;
|
||||
|
||||
export const GET_COMPANY_ROOT_CATEGORY = `
|
||||
SELECT root_category_id AS rootCategoryId FROM company WHERE id = @companyId
|
||||
`;
|
||||
|
||||
export const CREATE = `
|
||||
INSERT INTO company (
|
||||
name,
|
||||
root_category_id,
|
||||
default_language_id,
|
||||
taxrate,
|
||||
reducedtaxrate,
|
||||
taxfreerate,
|
||||
poscustomergroup_id
|
||||
)
|
||||
OUTPUT INSERTED.id
|
||||
VALUES (
|
||||
@name,
|
||||
@rootCategoryId,
|
||||
@languageId,
|
||||
@taxrate,
|
||||
@reducedtaxrate,
|
||||
@taxfreerate,
|
||||
@posCustomerGroupId
|
||||
)
|
||||
`;
|
||||
|
||||
export const UPDATE = `
|
||||
UPDATE company
|
||||
SET
|
||||
name = @name,
|
||||
default_language_id = @languageId,
|
||||
taxrate = @taxrate,
|
||||
reducedtaxrate = @reducedtaxrate
|
||||
WHERE id = @id
|
||||
`;
|
||||
|
||||
export const LIST = `
|
||||
SELECT
|
||||
c.id,
|
||||
c.name,
|
||||
c.root_category_id AS rootCategoryId,
|
||||
c.default_language_id AS languageId,
|
||||
tr.rate AS taxrate,
|
||||
rtr.rate AS reducedtaxrate,
|
||||
tfr.rate AS taxfreerate
|
||||
FROM company c
|
||||
INNER JOIN companyuser cu ON cu.company_id = c.id
|
||||
LEFT JOIN tax tr ON tr.id = c.taxrate
|
||||
LEFT JOIN tax rtr ON rtr.id = c.reducedtaxrate
|
||||
LEFT JOIN tax tfr ON tfr.id = c.taxfreerate
|
||||
WHERE cu.google_auth_id = @googleAuthId
|
||||
`;
|
||||
|
||||
export const DELETE = `
|
||||
DELETE FROM company
|
||||
WHERE id = @companyId
|
||||
`;
|
||||
44
src/providers/mssql/queries/companysetting.js
Normal file
44
src/providers/mssql/queries/companysetting.js
Normal file
@@ -0,0 +1,44 @@
|
||||
export const LIST_BY_COMPANY = `
|
||||
SELECT
|
||||
[key],
|
||||
value,
|
||||
CAST(frontend AS INT) AS frontend,
|
||||
CAST(writeonly AS INT) AS writeonly
|
||||
FROM companysetting
|
||||
WHERE company_id = @companyId
|
||||
ORDER BY [key]
|
||||
`;
|
||||
|
||||
export const LIST_BY_COMPANY_FRONTEND = `
|
||||
SELECT
|
||||
[key],
|
||||
value,
|
||||
CAST(frontend AS INT) AS frontend,
|
||||
CAST(writeonly AS INT) AS writeonly
|
||||
FROM companysetting
|
||||
WHERE company_id = @companyId
|
||||
AND frontend = 1
|
||||
ORDER BY [key]
|
||||
`;
|
||||
|
||||
export const GET_BY_COMPANY_AND_KEY = `
|
||||
SELECT
|
||||
[key],
|
||||
value,
|
||||
CAST(frontend AS INT) AS frontend,
|
||||
CAST(writeonly AS INT) AS writeonly
|
||||
FROM companysetting
|
||||
WHERE company_id = @companyId
|
||||
AND [key] = @key
|
||||
`;
|
||||
|
||||
export const UPSERT = `
|
||||
MERGE companysetting AS target
|
||||
USING (SELECT @companyId AS company_id, @key AS [key]) AS src
|
||||
ON target.company_id = src.company_id AND target.[key] = src.[key]
|
||||
WHEN MATCHED THEN
|
||||
UPDATE SET value = @value, frontend = @frontend, writeonly = @writeonly
|
||||
WHEN NOT MATCHED THEN
|
||||
INSERT (company_id, [key], value, frontend, writeonly)
|
||||
VALUES (@companyId, @key, @value, @frontend, @writeonly);
|
||||
`;
|
||||
29
src/providers/mssql/queries/companyuser.js
Normal file
29
src/providers/mssql/queries/companyuser.js
Normal file
@@ -0,0 +1,29 @@
|
||||
export const GET_BY_EMAIL = `
|
||||
SELECT cu.id
|
||||
FROM companyuser cu
|
||||
INNER JOIN google_auth ga ON ga.id = cu.google_auth_id
|
||||
WHERE ga.email = @email
|
||||
`;
|
||||
|
||||
export const GET_COMPANY_ACCESS = `
|
||||
SELECT
|
||||
c.root_category_id AS rootCategoryId,
|
||||
c.default_language_id AS languageId,
|
||||
c.poscustomergroup_id AS posCustomerGroupId,
|
||||
cu.id AS companyuserId
|
||||
FROM company c
|
||||
LEFT JOIN companyuser cu
|
||||
ON cu.company_id = c.id AND cu.google_auth_id = @googleAuthId
|
||||
WHERE c.id = @companyId
|
||||
`;
|
||||
|
||||
export const ADD = `
|
||||
INSERT INTO companyuser (google_auth_id, company_id)
|
||||
OUTPUT INSERTED.id
|
||||
VALUES (@googleAuthId, @companyId)
|
||||
`;
|
||||
|
||||
export const DELETE = `
|
||||
DELETE FROM companyuser
|
||||
WHERE id = @id
|
||||
`;
|
||||
66
src/providers/mssql/queries/customergroup.js
Normal file
66
src/providers/mssql/queries/customergroup.js
Normal file
@@ -0,0 +1,66 @@
|
||||
export const CREATE = `
|
||||
INSERT INTO customergroup (name, company_id, sort)
|
||||
OUTPUT INSERTED.id, INSERTED.name, INSERTED.sort
|
||||
VALUES (@name, @companyId, @sort)
|
||||
`;
|
||||
|
||||
export const CREATE_WITHOUT_COMPANY = `
|
||||
INSERT INTO customergroup (name, sort)
|
||||
OUTPUT INSERTED.id, INSERTED.name, INSERTED.sort
|
||||
VALUES (@name, @sort)
|
||||
`;
|
||||
|
||||
export const SET_COMPANY = `
|
||||
UPDATE customergroup
|
||||
SET company_id = @companyId
|
||||
WHERE id = @id
|
||||
`;
|
||||
|
||||
export const GET_BY_COMPANY_AND_NAME = `
|
||||
SELECT id, name, sort
|
||||
FROM customergroup
|
||||
WHERE company_id = @companyId AND name = @name
|
||||
`;
|
||||
|
||||
export const LIST_BY_COMPANY = `
|
||||
SELECT id, name, sort
|
||||
FROM customergroup
|
||||
WHERE company_id = @companyId
|
||||
ORDER BY sort ASC, name ASC, id ASC
|
||||
`;
|
||||
|
||||
export const GET_BY_COMPANY_AND_ID = `
|
||||
SELECT id, name, sort
|
||||
FROM customergroup
|
||||
WHERE id = @id AND company_id = @companyId
|
||||
`;
|
||||
|
||||
export const GET_NEXT_SORT = `
|
||||
SELECT ISNULL(MAX(sort), -1) + 1 AS sort
|
||||
FROM customergroup
|
||||
WHERE company_id = @companyId
|
||||
`;
|
||||
|
||||
export const LIST_IDS_BY_COMPANY = `
|
||||
SELECT id
|
||||
FROM customergroup
|
||||
WHERE company_id = @companyId
|
||||
`;
|
||||
|
||||
export const UPDATE = `
|
||||
UPDATE customergroup
|
||||
SET name = @name
|
||||
OUTPUT INSERTED.id, INSERTED.name, INSERTED.sort
|
||||
WHERE id = @id AND company_id = @companyId
|
||||
`;
|
||||
|
||||
export const UPDATE_SORT = `
|
||||
UPDATE customergroup
|
||||
SET sort = @sort
|
||||
WHERE id = @id AND company_id = @companyId
|
||||
`;
|
||||
|
||||
export const DELETE_BY_COMPANY_AND_ID = `
|
||||
DELETE FROM customergroup
|
||||
WHERE id = @id AND company_id = @companyId
|
||||
`;
|
||||
117
src/providers/mssql/queries/delivery.js
Normal file
117
src/providers/mssql/queries/delivery.js
Normal file
@@ -0,0 +1,117 @@
|
||||
export const DELIVERY_TYPE = 'delivery';
|
||||
|
||||
export const LIST_DELIVERIES = `
|
||||
SELECT
|
||||
m.id,
|
||||
m.[number],
|
||||
m.[type],
|
||||
m.entity_id AS supplierId,
|
||||
m.external_number AS externalNumber,
|
||||
m.[date]
|
||||
FROM manifest m
|
||||
WHERE m.company_id = @companyId
|
||||
AND m.[type] = @type
|
||||
ORDER BY m.[date] DESC, m.id DESC
|
||||
`;
|
||||
|
||||
export const GET_DELIVERY_HEADER = `
|
||||
SELECT
|
||||
m.id,
|
||||
m.[number],
|
||||
m.[type],
|
||||
m.entity_id AS supplierId,
|
||||
m.external_number AS externalNumber,
|
||||
m.[date]
|
||||
FROM manifest m
|
||||
WHERE m.id = @id
|
||||
AND m.company_id = @companyId
|
||||
AND m.[type] = @type
|
||||
`;
|
||||
|
||||
export const GET_DELIVERY_LINES = `
|
||||
SELECT
|
||||
ma.id,
|
||||
ma.sku,
|
||||
ma.name,
|
||||
ma.pu,
|
||||
ma.amount,
|
||||
ma.net,
|
||||
ma.rebate,
|
||||
ma.taxrate,
|
||||
ma.comment
|
||||
FROM manifestarticle ma
|
||||
WHERE ma.manifest_id = @manifestId
|
||||
ORDER BY ma.id
|
||||
`;
|
||||
|
||||
export const CREATE_MANIFEST = `
|
||||
INSERT INTO manifest (company_id, [number], [type], entity_id, external_number, [date])
|
||||
OUTPUT INSERTED.id
|
||||
VALUES (@companyId, @number, @type, @entityId, @externalNumber, @date)
|
||||
`;
|
||||
|
||||
export const UPDATE_MANIFEST = `
|
||||
UPDATE manifest
|
||||
SET
|
||||
[number] = @number,
|
||||
entity_id = @entityId,
|
||||
external_number = @externalNumber,
|
||||
[date] = @date
|
||||
WHERE id = @id
|
||||
AND company_id = @companyId
|
||||
AND [type] = @type
|
||||
`;
|
||||
|
||||
export const DELETE_MANIFEST = `
|
||||
DELETE FROM manifest
|
||||
WHERE id = @id
|
||||
AND company_id = @companyId
|
||||
AND [type] = @type
|
||||
`;
|
||||
|
||||
export const DELETE_LINES_BY_MANIFEST = `
|
||||
DELETE FROM manifestarticle
|
||||
WHERE manifest_id = @manifestId
|
||||
`;
|
||||
|
||||
export const GET_NEXT_ATTACHMENT_SORT = `
|
||||
SELECT ISNULL(MAX(ma.sort), -1) + 1 AS sort
|
||||
FROM manifestattachment ma
|
||||
WHERE ma.manifest_id = @manifestId
|
||||
`;
|
||||
|
||||
export const CREATE_FILE = `
|
||||
INSERT INTO [file] (hash, mimetype, name, size, created, modified, content, thumbavif, thumbx, thumby, meta)
|
||||
OUTPUT INSERTED.id
|
||||
VALUES (@hash, @mimetype, @name, @size, @created, @modified, @content, CONVERT(VARBINARY(MAX), @thumbavif), @thumbx, @thumby, @meta)
|
||||
`;
|
||||
|
||||
export const CREATE_ATTACHMENT = `
|
||||
INSERT INTO manifestattachment (manifest_id, file_id, sort)
|
||||
OUTPUT INSERTED.id
|
||||
VALUES (@manifestId, @fileId, @sort)
|
||||
`;
|
||||
|
||||
export const LIST_DELIVERY_FILES = `
|
||||
SELECT
|
||||
ma.id,
|
||||
ma.manifest_id AS manifestId,
|
||||
ma.file_id AS fileId,
|
||||
ma.sort,
|
||||
f.hash,
|
||||
f.mimetype,
|
||||
f.name,
|
||||
f.size,
|
||||
f.created,
|
||||
f.modified,
|
||||
f.thumbavif,
|
||||
f.thumbx,
|
||||
f.thumby,
|
||||
f.meta
|
||||
FROM manifestattachment ma
|
||||
INNER JOIN [file] f ON f.id = ma.file_id
|
||||
INNER JOIN manifest m ON m.id = ma.manifest_id
|
||||
WHERE m.company_id = @companyId
|
||||
AND m.[type] = @type
|
||||
ORDER BY ma.manifest_id, ma.sort ASC, ma.id ASC
|
||||
`;
|
||||
163
src/providers/mssql/queries/entity.js
Normal file
163
src/providers/mssql/queries/entity.js
Normal file
@@ -0,0 +1,163 @@
|
||||
export const SUPPLIER_GROUP_NAME = 'Lieferanten';
|
||||
export const POS_GROUP_NAME = 'POS';
|
||||
|
||||
export const ENTITY_COLUMNS = `
|
||||
e.id,
|
||||
e.customergroup_id AS customergroupId,
|
||||
e.first_name AS firstName,
|
||||
e.name,
|
||||
e.[number] AS number,
|
||||
e.created_at AS createdAt,
|
||||
e.updated_at AS updatedAt
|
||||
`;
|
||||
|
||||
export const LIST_BY_COMPANY = `
|
||||
SELECT
|
||||
${ENTITY_COLUMNS}
|
||||
FROM entity e
|
||||
INNER JOIN customergroup cg ON cg.id = e.customergroup_id
|
||||
WHERE cg.company_id = @companyId
|
||||
ORDER BY e.name, e.id
|
||||
`;
|
||||
|
||||
export const LIST_BY_COMPANY_AND_GROUP = `
|
||||
SELECT
|
||||
${ENTITY_COLUMNS}
|
||||
FROM entity e
|
||||
INNER JOIN customergroup cg ON cg.id = e.customergroup_id
|
||||
WHERE cg.company_id = @companyId
|
||||
AND e.customergroup_id = @customergroupId
|
||||
ORDER BY e.name, e.id
|
||||
`;
|
||||
|
||||
/** Entities whose group is not Lieferanten and not POS (customer picker). */
|
||||
export const LIST_CUSTOMERS_BY_COMPANY = `
|
||||
SELECT
|
||||
${ENTITY_COLUMNS}
|
||||
FROM entity e
|
||||
INNER JOIN customergroup cg ON cg.id = e.customergroup_id
|
||||
WHERE cg.company_id = @companyId
|
||||
AND cg.name NOT IN (@supplierGroupName, @posGroupName)
|
||||
ORDER BY e.name, e.id
|
||||
`;
|
||||
|
||||
export const GET_BY_COMPANY_AND_ID = `
|
||||
SELECT
|
||||
${ENTITY_COLUMNS}
|
||||
FROM entity e
|
||||
INNER JOIN customergroup cg ON cg.id = e.customergroup_id
|
||||
WHERE e.id = @id
|
||||
AND cg.company_id = @companyId
|
||||
`;
|
||||
|
||||
/** Occupied when another entity in the company already has this number. */
|
||||
export const NUMBER_TAKEN_IN_COMPANY = `
|
||||
SELECT TOP 1 e.id
|
||||
FROM entity e
|
||||
INNER JOIN customergroup cg ON cg.id = e.customergroup_id
|
||||
WHERE cg.company_id = @companyId
|
||||
AND e.[number] = @number
|
||||
AND (@excludeEntityId IS NULL OR e.id <> @excludeEntityId)
|
||||
`;
|
||||
|
||||
/** Customer entity: company-scoped and not Lieferanten/POS. */
|
||||
export const GET_CUSTOMER_BY_ID = `
|
||||
SELECT
|
||||
${ENTITY_COLUMNS}
|
||||
FROM entity e
|
||||
INNER JOIN customergroup cg ON cg.id = e.customergroup_id
|
||||
WHERE e.id = @id
|
||||
AND cg.company_id = @companyId
|
||||
AND cg.name NOT IN (@supplierGroupName, @posGroupName)
|
||||
`;
|
||||
|
||||
export const LIST_SUPPLIERS_BY_COMPANY = `
|
||||
SELECT
|
||||
e.id,
|
||||
e.name,
|
||||
e.created_at AS createdAt,
|
||||
e.updated_at AS updatedAt
|
||||
FROM entity e
|
||||
INNER JOIN customergroup cg ON cg.id = e.customergroup_id
|
||||
WHERE cg.company_id = @companyId
|
||||
AND cg.name = @groupName
|
||||
ORDER BY e.name, e.id
|
||||
`;
|
||||
|
||||
export const GET_SUPPLIER_BY_ID = `
|
||||
SELECT
|
||||
e.id,
|
||||
e.name,
|
||||
e.created_at AS createdAt,
|
||||
e.updated_at AS updatedAt
|
||||
FROM entity e
|
||||
INNER JOIN customergroup cg ON cg.id = e.customergroup_id
|
||||
WHERE e.id = @id
|
||||
AND cg.company_id = @companyId
|
||||
AND cg.name = @groupName
|
||||
`;
|
||||
|
||||
export const CREATE = `
|
||||
INSERT INTO entity (customergroup_id, first_name, name, [number])
|
||||
OUTPUT
|
||||
INSERTED.id,
|
||||
INSERTED.customergroup_id AS customergroupId,
|
||||
INSERTED.first_name AS firstName,
|
||||
INSERTED.name,
|
||||
INSERTED.[number] AS number,
|
||||
INSERTED.created_at AS createdAt,
|
||||
INSERTED.updated_at AS updatedAt
|
||||
VALUES (@customergroupId, @firstName, @name, @number)
|
||||
`;
|
||||
|
||||
export const UPDATE = `
|
||||
UPDATE entity
|
||||
SET
|
||||
first_name = @firstName,
|
||||
name = @name,
|
||||
[number] = @number,
|
||||
updated_at = SYSUTCDATETIME()
|
||||
OUTPUT
|
||||
INSERTED.id,
|
||||
INSERTED.customergroup_id AS customergroupId,
|
||||
INSERTED.first_name AS firstName,
|
||||
INSERTED.name,
|
||||
INSERTED.[number] AS number,
|
||||
INSERTED.created_at AS createdAt,
|
||||
INSERTED.updated_at AS updatedAt
|
||||
WHERE id = @id
|
||||
`;
|
||||
|
||||
export const UPDATE_NAME = `
|
||||
UPDATE entity
|
||||
SET name = @name, updated_at = SYSUTCDATETIME()
|
||||
OUTPUT INSERTED.id, INSERTED.name, INSERTED.created_at AS createdAt, INSERTED.updated_at AS updatedAt
|
||||
WHERE id = @id
|
||||
AND customergroup_id = @customergroupId
|
||||
`;
|
||||
|
||||
export const DELETE_BY_COMPANY_AND_ID = `
|
||||
DELETE e
|
||||
FROM entity e
|
||||
INNER JOIN customergroup cg ON cg.id = e.customergroup_id
|
||||
WHERE e.id = @id
|
||||
AND cg.company_id = @companyId
|
||||
`;
|
||||
|
||||
export const DELETE_BY_ID = `
|
||||
DELETE e
|
||||
FROM entity e
|
||||
INNER JOIN customergroup cg ON cg.id = e.customergroup_id
|
||||
WHERE e.id = @id
|
||||
AND cg.company_id = @companyId
|
||||
AND cg.name = @groupName
|
||||
`;
|
||||
|
||||
export const GET_GROUP_ID_FOR_SUPPLIER = `
|
||||
SELECT e.customergroup_id AS customergroupId, e.name
|
||||
FROM entity e
|
||||
INNER JOIN customergroup cg ON cg.id = e.customergroup_id
|
||||
WHERE e.id = @id
|
||||
AND cg.company_id = @companyId
|
||||
AND cg.name = @groupName
|
||||
`;
|
||||
105
src/providers/mssql/queries/entityaddress.js
Normal file
105
src/providers/mssql/queries/entityaddress.js
Normal file
@@ -0,0 +1,105 @@
|
||||
export const ADDRESS_COLUMNS = `
|
||||
id,
|
||||
entity_id AS entityId,
|
||||
first_name AS firstName,
|
||||
name,
|
||||
street,
|
||||
streetnumber AS streetNumber,
|
||||
zip,
|
||||
city,
|
||||
county,
|
||||
addresstype AS addressType,
|
||||
sort
|
||||
`;
|
||||
|
||||
export const LIST_BY_ENTITY = `
|
||||
SELECT
|
||||
${ADDRESS_COLUMNS}
|
||||
FROM entityaddress
|
||||
WHERE entity_id = @entityId
|
||||
ORDER BY sort ASC, id ASC
|
||||
`;
|
||||
|
||||
export const GET_BY_ENTITY_AND_ID = `
|
||||
SELECT
|
||||
${ADDRESS_COLUMNS}
|
||||
FROM entityaddress
|
||||
WHERE id = @id AND entity_id = @entityId
|
||||
`;
|
||||
|
||||
export const GET_NEXT_SORT = `
|
||||
SELECT ISNULL(MAX(sort), -1) + 1 AS sort
|
||||
FROM entityaddress
|
||||
WHERE entity_id = @entityId
|
||||
`;
|
||||
|
||||
export const CREATE = `
|
||||
INSERT INTO entityaddress (
|
||||
entity_id,
|
||||
first_name,
|
||||
name,
|
||||
street,
|
||||
streetnumber,
|
||||
zip,
|
||||
city,
|
||||
county,
|
||||
addresstype,
|
||||
sort
|
||||
)
|
||||
OUTPUT
|
||||
INSERTED.id,
|
||||
INSERTED.entity_id AS entityId,
|
||||
INSERTED.first_name AS firstName,
|
||||
INSERTED.name,
|
||||
INSERTED.street,
|
||||
INSERTED.streetnumber AS streetNumber,
|
||||
INSERTED.zip,
|
||||
INSERTED.city,
|
||||
INSERTED.county,
|
||||
INSERTED.addresstype AS addressType,
|
||||
INSERTED.sort
|
||||
VALUES (
|
||||
@entityId,
|
||||
@firstName,
|
||||
@name,
|
||||
@street,
|
||||
@streetNumber,
|
||||
@zip,
|
||||
@city,
|
||||
@county,
|
||||
@addressType,
|
||||
@sort
|
||||
)
|
||||
`;
|
||||
|
||||
export const UPDATE = `
|
||||
UPDATE entityaddress
|
||||
SET
|
||||
first_name = @firstName,
|
||||
name = @name,
|
||||
street = @street,
|
||||
streetnumber = @streetNumber,
|
||||
zip = @zip,
|
||||
city = @city,
|
||||
county = @county,
|
||||
addresstype = @addressType,
|
||||
sort = @sort
|
||||
OUTPUT
|
||||
INSERTED.id,
|
||||
INSERTED.entity_id AS entityId,
|
||||
INSERTED.first_name AS firstName,
|
||||
INSERTED.name,
|
||||
INSERTED.street,
|
||||
INSERTED.streetnumber AS streetNumber,
|
||||
INSERTED.zip,
|
||||
INSERTED.city,
|
||||
INSERTED.county,
|
||||
INSERTED.addresstype AS addressType,
|
||||
INSERTED.sort
|
||||
WHERE id = @id AND entity_id = @entityId
|
||||
`;
|
||||
|
||||
export const DELETE_BY_ENTITY_AND_ID = `
|
||||
DELETE FROM entityaddress
|
||||
WHERE id = @id AND entity_id = @entityId
|
||||
`;
|
||||
56
src/providers/mssql/queries/entitycontact.js
Normal file
56
src/providers/mssql/queries/entitycontact.js
Normal file
@@ -0,0 +1,56 @@
|
||||
export const CONTACT_COLUMNS = `
|
||||
id,
|
||||
entity_id AS entityId,
|
||||
contacttype AS contactType,
|
||||
contact,
|
||||
sort
|
||||
`;
|
||||
|
||||
export const LIST_BY_ENTITY = `
|
||||
SELECT
|
||||
${CONTACT_COLUMNS}
|
||||
FROM entitycontact
|
||||
WHERE entity_id = @entityId
|
||||
ORDER BY sort ASC, id ASC
|
||||
`;
|
||||
|
||||
export const GET_BY_ENTITY_AND_ID = `
|
||||
SELECT
|
||||
${CONTACT_COLUMNS}
|
||||
FROM entitycontact
|
||||
WHERE id = @id AND entity_id = @entityId
|
||||
`;
|
||||
|
||||
export const GET_NEXT_SORT = `
|
||||
SELECT ISNULL(MAX(sort), -1) + 1 AS sort
|
||||
FROM entitycontact
|
||||
WHERE entity_id = @entityId
|
||||
`;
|
||||
|
||||
export const CREATE = `
|
||||
INSERT INTO entitycontact (entity_id, contacttype, contact, sort)
|
||||
OUTPUT
|
||||
INSERTED.id,
|
||||
INSERTED.entity_id AS entityId,
|
||||
INSERTED.contacttype AS contactType,
|
||||
INSERTED.contact,
|
||||
INSERTED.sort
|
||||
VALUES (@entityId, @contactType, @contact, @sort)
|
||||
`;
|
||||
|
||||
export const UPDATE = `
|
||||
UPDATE entitycontact
|
||||
SET contacttype = @contactType, contact = @contact, sort = @sort
|
||||
OUTPUT
|
||||
INSERTED.id,
|
||||
INSERTED.entity_id AS entityId,
|
||||
INSERTED.contacttype AS contactType,
|
||||
INSERTED.contact,
|
||||
INSERTED.sort
|
||||
WHERE id = @id AND entity_id = @entityId
|
||||
`;
|
||||
|
||||
export const DELETE_BY_ENTITY_AND_ID = `
|
||||
DELETE FROM entitycontact
|
||||
WHERE id = @id AND entity_id = @entityId
|
||||
`;
|
||||
11
src/providers/mssql/queries/entityhistory.js
Normal file
11
src/providers/mssql/queries/entityhistory.js
Normal file
@@ -0,0 +1,11 @@
|
||||
export const INSERT = `
|
||||
INSERT INTO entityhistory (entity_id, companyuser_id, [text])
|
||||
VALUES (@entityId, @companyuserId, @text)
|
||||
`;
|
||||
|
||||
export const LIST_BY_ENTITY_ID = `
|
||||
SELECT id, companyuser_id AS companyuserId, [date], [text]
|
||||
FROM entityhistory
|
||||
WHERE entity_id = @entityId
|
||||
ORDER BY [date] DESC, id DESC
|
||||
`;
|
||||
58
src/providers/mssql/queries/google_auth.js
Normal file
58
src/providers/mssql/queries/google_auth.js
Normal file
@@ -0,0 +1,58 @@
|
||||
export const ADD = `
|
||||
INSERT INTO google_auth (email)
|
||||
OUTPUT INSERTED.id
|
||||
VALUES (@email)
|
||||
`;
|
||||
|
||||
export const GOOGLE_AUTH_COLUMNS = `
|
||||
id,
|
||||
email,
|
||||
picture,
|
||||
picturebinary AS pictureBinary,
|
||||
sub,
|
||||
created_at AS createdAt,
|
||||
selected_company AS selectedCompanyId
|
||||
`;
|
||||
|
||||
export const GET_BY_EMAIL = `
|
||||
SELECT
|
||||
${GOOGLE_AUTH_COLUMNS}
|
||||
FROM google_auth
|
||||
WHERE email = @email
|
||||
`;
|
||||
|
||||
export const GET_BY_ID = `
|
||||
SELECT
|
||||
${GOOGLE_AUTH_COLUMNS}
|
||||
FROM google_auth
|
||||
WHERE id = @googleAuthId
|
||||
`;
|
||||
|
||||
export const LIST_ALLOWED_EMAILS = `
|
||||
SELECT
|
||||
id,
|
||||
email,
|
||||
picture,
|
||||
sub,
|
||||
created_at AS createdAt,
|
||||
selected_company AS selectedCompanyId
|
||||
FROM google_auth
|
||||
ORDER BY email
|
||||
`;
|
||||
|
||||
export const REMOVE_ALLOWED_EMAIL = `
|
||||
DELETE FROM google_auth
|
||||
WHERE email = @email
|
||||
`;
|
||||
|
||||
export const SET_SELECTED_COMPANY = `
|
||||
UPDATE google_auth
|
||||
SET selected_company = @companyId
|
||||
WHERE id = @googleAuthId
|
||||
`;
|
||||
|
||||
export const SET_PROFILE = `
|
||||
UPDATE google_auth
|
||||
SET picture = @picture, picturebinary = @pictureBinary, sub = @sub
|
||||
WHERE id = @googleAuthId
|
||||
`;
|
||||
21
src/providers/mssql/queries/language.js
Normal file
21
src/providers/mssql/queries/language.js
Normal file
@@ -0,0 +1,21 @@
|
||||
export const CREATE = `
|
||||
INSERT INTO language (iso639)
|
||||
OUTPUT INSERTED.id
|
||||
VALUES (@iso639)
|
||||
`;
|
||||
|
||||
export const GET_BY_ISO639 = `
|
||||
SELECT id, iso639
|
||||
FROM language
|
||||
WHERE iso639 = @iso639
|
||||
`;
|
||||
|
||||
export const LIST = `
|
||||
SELECT id, iso639
|
||||
FROM language
|
||||
`;
|
||||
|
||||
export const DELETE = `
|
||||
DELETE FROM language
|
||||
WHERE id = @id
|
||||
`;
|
||||
107
src/providers/mssql/queries/manifestDoc.js
Normal file
107
src/providers/mssql/queries/manifestDoc.js
Normal file
@@ -0,0 +1,107 @@
|
||||
/**
|
||||
* Shared SQL for typed manifest documents (quote / order).
|
||||
* Delivery keeps its own SQL with supplierId naming.
|
||||
*/
|
||||
|
||||
export const QUOTE_TYPE = 'quote';
|
||||
export const ORDER_TYPE = 'order';
|
||||
|
||||
export const LIST_MANIFESTS = `
|
||||
SELECT
|
||||
m.id,
|
||||
m.[number],
|
||||
m.[type],
|
||||
m.entity_id AS entityId,
|
||||
m.external_number AS externalNumber,
|
||||
m.[date]
|
||||
FROM manifest m
|
||||
WHERE m.company_id = @companyId
|
||||
AND m.[type] = @type
|
||||
ORDER BY m.[date] DESC, m.id DESC
|
||||
`;
|
||||
|
||||
export const GET_MANIFEST_HEADER = `
|
||||
SELECT
|
||||
m.id,
|
||||
m.[number],
|
||||
m.[type],
|
||||
m.entity_id AS entityId,
|
||||
m.external_number AS externalNumber,
|
||||
m.[date]
|
||||
FROM manifest m
|
||||
WHERE m.id = @id
|
||||
AND m.company_id = @companyId
|
||||
AND m.[type] = @type
|
||||
`;
|
||||
|
||||
export const GET_MANIFEST_LINES = `
|
||||
SELECT
|
||||
ma.id,
|
||||
ma.sku,
|
||||
ma.name,
|
||||
ma.pu,
|
||||
ma.amount,
|
||||
ma.net,
|
||||
ma.rebate,
|
||||
ma.taxrate,
|
||||
ma.comment
|
||||
FROM manifestarticle ma
|
||||
WHERE ma.manifest_id = @manifestId
|
||||
ORDER BY ma.id
|
||||
`;
|
||||
|
||||
export const CREATE_MANIFEST = `
|
||||
INSERT INTO manifest (company_id, [number], [type], entity_id, external_number, [date])
|
||||
OUTPUT INSERTED.id
|
||||
VALUES (@companyId, @number, @type, @entityId, @externalNumber, @date)
|
||||
`;
|
||||
|
||||
export const UPDATE_MANIFEST = `
|
||||
UPDATE manifest
|
||||
SET
|
||||
[number] = @number,
|
||||
entity_id = @entityId,
|
||||
external_number = @externalNumber,
|
||||
[date] = @date
|
||||
WHERE id = @id
|
||||
AND company_id = @companyId
|
||||
AND [type] = @type
|
||||
`;
|
||||
|
||||
export const DELETE_MANIFEST = `
|
||||
DELETE FROM manifest
|
||||
WHERE id = @id
|
||||
AND company_id = @companyId
|
||||
AND [type] = @type
|
||||
`;
|
||||
|
||||
export const DELETE_LINES_BY_MANIFEST = `
|
||||
DELETE FROM manifestarticle
|
||||
WHERE manifest_id = @manifestId
|
||||
`;
|
||||
|
||||
export const CREATE_LINE = `
|
||||
INSERT INTO manifestarticle (
|
||||
manifest_id,
|
||||
sku,
|
||||
name,
|
||||
pu,
|
||||
amount,
|
||||
net,
|
||||
comment,
|
||||
rebate,
|
||||
taxrate
|
||||
)
|
||||
OUTPUT INSERTED.id
|
||||
VALUES (
|
||||
@manifestId,
|
||||
@sku,
|
||||
@name,
|
||||
@pu,
|
||||
@amount,
|
||||
@net,
|
||||
@comment,
|
||||
@rebate,
|
||||
@taxrate
|
||||
)
|
||||
`;
|
||||
104
src/providers/mssql/queries/manifestattachment.js
Normal file
104
src/providers/mssql/queries/manifestattachment.js
Normal file
@@ -0,0 +1,104 @@
|
||||
export const CHECK_MANIFEST_ACCESS = `
|
||||
SELECT id, company_id AS companyId
|
||||
FROM manifest
|
||||
WHERE id = @manifestId AND company_id = @companyId
|
||||
`;
|
||||
|
||||
export const CREATE_FILE = `
|
||||
INSERT INTO [file] (hash, mimetype, name, size, created, modified, content, thumbavif, thumbx, thumby, meta)
|
||||
OUTPUT INSERTED.id
|
||||
VALUES (@hash, @mimetype, @name, @size, @created, @modified, @content, CONVERT(VARBINARY(MAX), @thumbavif), @thumbx, @thumby, @meta)
|
||||
`;
|
||||
|
||||
export const GET_NEXT_SORT = `
|
||||
SELECT ISNULL(MAX(sort), -1) + 1 AS sort
|
||||
FROM manifestattachment
|
||||
WHERE manifest_id = @manifestId;
|
||||
`;
|
||||
|
||||
export const CREATE_ATTACHMENT = `
|
||||
INSERT INTO manifestattachment (manifest_id, file_id, sort)
|
||||
OUTPUT INSERTED.id
|
||||
VALUES (@manifestId, @fileId, @sort)
|
||||
`;
|
||||
|
||||
export const LIST_BY_MANIFEST = `
|
||||
SELECT
|
||||
ma.id,
|
||||
ma.manifest_id AS manifestId,
|
||||
ma.file_id AS fileId,
|
||||
ma.sort,
|
||||
f.hash,
|
||||
f.mimetype,
|
||||
f.name,
|
||||
f.size,
|
||||
f.created,
|
||||
f.modified,
|
||||
f.thumbavif,
|
||||
f.thumbx,
|
||||
f.thumby,
|
||||
f.meta
|
||||
FROM manifestattachment ma
|
||||
INNER JOIN [file] f ON f.id = ma.file_id
|
||||
WHERE ma.manifest_id = @manifestId
|
||||
ORDER BY ma.sort ASC, ma.id ASC
|
||||
`;
|
||||
|
||||
export const GET_BY_ID = `
|
||||
SELECT
|
||||
ma.id,
|
||||
ma.manifest_id AS manifestId,
|
||||
ma.file_id AS fileId,
|
||||
ma.sort,
|
||||
f.hash,
|
||||
f.mimetype,
|
||||
f.name,
|
||||
f.size,
|
||||
f.created,
|
||||
f.modified,
|
||||
f.content,
|
||||
f.thumbavif,
|
||||
f.thumbx,
|
||||
f.thumby,
|
||||
f.meta
|
||||
FROM manifestattachment ma
|
||||
INNER JOIN [file] f ON f.id = ma.file_id
|
||||
WHERE ma.manifest_id = @manifestId
|
||||
AND (ma.id = @id OR ma.file_id = @id)
|
||||
`;
|
||||
|
||||
export const FIND_ATTACHMENT = `
|
||||
SELECT ma.id, ma.file_id AS fileId
|
||||
FROM manifestattachment ma
|
||||
WHERE ma.manifest_id = @manifestId
|
||||
AND (ma.id = @id OR ma.file_id = @id)
|
||||
`;
|
||||
|
||||
export const DELETE_ATTACHMENT = `
|
||||
DELETE FROM manifestattachment
|
||||
WHERE id = @id
|
||||
`;
|
||||
|
||||
export const DELETE_FILE = `
|
||||
DELETE FROM [file]
|
||||
WHERE id = @fileId
|
||||
`;
|
||||
|
||||
export const LIST_IDS_BY_MANIFEST = `
|
||||
SELECT id
|
||||
FROM manifestattachment
|
||||
WHERE manifest_id = @manifestId
|
||||
ORDER BY sort ASC, id ASC;
|
||||
`;
|
||||
|
||||
export const SET_TEMP_SORTS = `
|
||||
UPDATE manifestattachment
|
||||
SET sort = -id
|
||||
WHERE manifest_id = @manifestId;
|
||||
`;
|
||||
|
||||
export const UPDATE_SORT = `
|
||||
UPDATE manifestattachment
|
||||
SET sort = @sort
|
||||
WHERE id = @id AND manifest_id = @manifestId;
|
||||
`;
|
||||
46
src/providers/mssql/queries/numbers.js
Normal file
46
src/providers/mssql/queries/numbers.js
Normal file
@@ -0,0 +1,46 @@
|
||||
export const ENSURE_TYPE = `
|
||||
IF NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM numbers
|
||||
WHERE company_id = @companyId AND [type] = @type
|
||||
)
|
||||
BEGIN
|
||||
INSERT INTO numbers (company_id, [type])
|
||||
VALUES (@companyId, @type);
|
||||
END
|
||||
`;
|
||||
|
||||
export const LIST_BY_COMPANY = `
|
||||
SELECT
|
||||
id,
|
||||
[type],
|
||||
prefix,
|
||||
padding,
|
||||
[next] AS [next]
|
||||
FROM numbers
|
||||
WHERE company_id = @companyId
|
||||
ORDER BY [type]
|
||||
`;
|
||||
|
||||
export const GET_BY_COMPANY_AND_ID = `
|
||||
SELECT
|
||||
id,
|
||||
[type],
|
||||
prefix,
|
||||
padding,
|
||||
[next] AS [next]
|
||||
FROM numbers
|
||||
WHERE id = @id
|
||||
AND company_id = @companyId
|
||||
`;
|
||||
|
||||
export const UPDATE_BY_COMPANY_AND_ID = `
|
||||
UPDATE numbers
|
||||
SET
|
||||
prefix = @prefix,
|
||||
padding = @padding,
|
||||
[next] = @next
|
||||
OUTPUT INSERTED.id, INSERTED.[type], INSERTED.prefix, INSERTED.padding, INSERTED.[next]
|
||||
WHERE id = @id
|
||||
AND company_id = @companyId
|
||||
`;
|
||||
46
src/providers/mssql/queries/pic.js
Normal file
46
src/providers/mssql/queries/pic.js
Normal file
@@ -0,0 +1,46 @@
|
||||
export const CREATE = `
|
||||
INSERT INTO pic (
|
||||
w, h, size, hash, thumbw, thumbh, thumbhash, source, fullbinary, thumbbinary
|
||||
)
|
||||
OUTPUT INSERTED.id
|
||||
VALUES (
|
||||
@w, @h, @size, @hash, @thumbw, @thumbh, @thumbhash, @source, @fullbinary, @thumbbinary
|
||||
)
|
||||
`;
|
||||
|
||||
export const GET_CATEGORY_ID_BY_HASH = `
|
||||
SELECT TOP 1 categoryId
|
||||
FROM (
|
||||
SELECT ca.category_id AS categoryId
|
||||
FROM pic p
|
||||
INNER JOIN articlepic ap ON ap.pic_id = p.id
|
||||
INNER JOIN categoryarticle ca ON ca.article_id = ap.article_id
|
||||
WHERE p.hash = @hash
|
||||
|
||||
UNION
|
||||
|
||||
SELECT cp.category_id AS categoryId
|
||||
FROM pic p
|
||||
INNER JOIN categorypic cp ON cp.pic_id = p.id
|
||||
WHERE p.hash = @hash
|
||||
) AS combined
|
||||
`;
|
||||
|
||||
export const GET_FULL_BY_HASH = `
|
||||
SELECT w, h, size, fullbinary AS buffer
|
||||
FROM pic
|
||||
WHERE hash = @hash
|
||||
`;
|
||||
|
||||
export const GET_THUMB_BY_HASH = `
|
||||
SELECT thumbw AS w, thumbh AS h, thumbbinary AS buffer
|
||||
FROM pic
|
||||
WHERE hash = @hash
|
||||
`;
|
||||
|
||||
export const DELETE_BY_ARTICLE_AND_HASH = `
|
||||
DELETE p
|
||||
FROM pic p
|
||||
INNER JOIN articlepic ap ON ap.pic_id = p.id AND ap.article_id = @articleId
|
||||
WHERE p.hash = @fullHash
|
||||
`;
|
||||
91
src/providers/mssql/queries/posterminal.js
Normal file
91
src/providers/mssql/queries/posterminal.js
Normal file
@@ -0,0 +1,91 @@
|
||||
export const LIST_BY_COMPANY = `
|
||||
SELECT
|
||||
id,
|
||||
name,
|
||||
token,
|
||||
pairingpin
|
||||
FROM posterminal
|
||||
WHERE company_id = @companyId
|
||||
ORDER BY id
|
||||
`;
|
||||
|
||||
export const GET_BY_ID = `
|
||||
SELECT
|
||||
id,
|
||||
company_id AS companyId,
|
||||
name,
|
||||
token,
|
||||
pairingpin
|
||||
FROM posterminal
|
||||
WHERE id = @id
|
||||
`;
|
||||
|
||||
export const CREATE = `
|
||||
INSERT INTO posterminal (company_id, name, token, pairingpin)
|
||||
OUTPUT INSERTED.id, INSERTED.name, INSERTED.token, INSERTED.pairingpin
|
||||
VALUES (@companyId, @name, @token, @pairingpin)
|
||||
`;
|
||||
|
||||
export const UPDATE = `
|
||||
UPDATE posterminal
|
||||
SET name = @name, token = @token, pairingpin = @pairingpin
|
||||
WHERE id = @id AND company_id = @companyId
|
||||
`;
|
||||
|
||||
export const DELETE_BY_COMPANY_AND_ID = `
|
||||
DELETE FROM posterminal
|
||||
WHERE id = @id AND company_id = @companyId
|
||||
`;
|
||||
|
||||
export const LIST_CATEGORY_IDS = `
|
||||
SELECT category_id AS categoryId
|
||||
FROM posterminalcategory
|
||||
WHERE posterminal_id = @posterminalId
|
||||
`;
|
||||
|
||||
/** setOn: insert if not exists (single terminal + single category). */
|
||||
export const SET_ON = `
|
||||
IF NOT EXISTS (
|
||||
SELECT 1 FROM posterminalcategory
|
||||
WHERE posterminal_id = @posterminalId AND category_id = @categoryId
|
||||
)
|
||||
INSERT INTO posterminalcategory (posterminal_id, category_id)
|
||||
VALUES (@posterminalId, @categoryId)
|
||||
`;
|
||||
|
||||
/** setOff: remove a single category from a single terminal. */
|
||||
export const SET_OFF = `
|
||||
DELETE FROM posterminalcategory
|
||||
WHERE posterminal_id = @posterminalId AND category_id = @categoryId
|
||||
`;
|
||||
|
||||
/** setOnAll: enable ALL company categories on one terminal. */
|
||||
export const SET_ON_ALL = `
|
||||
;WITH cats AS (
|
||||
SELECT id FROM category WHERE id = @rootCategoryId
|
||||
UNION ALL
|
||||
SELECT c.id FROM category c INNER JOIN cats ON c.parent_id = cats.id
|
||||
)
|
||||
INSERT INTO posterminalcategory (posterminal_id, category_id)
|
||||
SELECT @posterminalId, cats.id
|
||||
FROM cats
|
||||
WHERE NOT EXISTS (
|
||||
SELECT 1 FROM posterminalcategory pc
|
||||
WHERE pc.posterminal_id = @posterminalId AND pc.category_id = cats.id
|
||||
)
|
||||
`;
|
||||
|
||||
/** setOffAll: remove ALL category links from one terminal. */
|
||||
export const SET_OFF_ALL = `
|
||||
DELETE FROM posterminalcategory WHERE posterminal_id = @posterminalId
|
||||
`;
|
||||
|
||||
/** For category tree: map category -> posterminal ids (company-scoped). */
|
||||
export const POSTERMINAL_IDS_BY_COMPANY = `
|
||||
SELECT
|
||||
pc.category_id AS categoryId,
|
||||
pc.posterminal_id AS posterminalId
|
||||
FROM posterminalcategory pc
|
||||
INNER JOIN posterminal pt ON pt.id = pc.posterminal_id
|
||||
WHERE pt.company_id = @companyId
|
||||
`;
|
||||
11
src/providers/mssql/queries/price.js
Normal file
11
src/providers/mssql/queries/price.js
Normal file
@@ -0,0 +1,11 @@
|
||||
export const DELETE_BY_ARTICLE_AND_CUSTOMERGROUP = `
|
||||
DELETE FROM price
|
||||
WHERE article_id = @articleId
|
||||
AND customergroup_id = @customerGroupId
|
||||
`;
|
||||
|
||||
export const CREATE = `
|
||||
INSERT INTO price (tax_id, article_id, minmultiplier, customergroup_id, net)
|
||||
OUTPUT INSERTED.id
|
||||
VALUES (@taxId, @articleId, @minmultiplier, @customerGroupId, @net)
|
||||
`;
|
||||
16
src/providers/mssql/queries/tax.js
Normal file
16
src/providers/mssql/queries/tax.js
Normal file
@@ -0,0 +1,16 @@
|
||||
export const GET_BY_RATE = `
|
||||
SELECT id, rate
|
||||
FROM tax
|
||||
WHERE rate = @rate
|
||||
`;
|
||||
|
||||
export const CREATE = `
|
||||
INSERT INTO tax (rate)
|
||||
OUTPUT INSERTED.id
|
||||
VALUES (@rate)
|
||||
`;
|
||||
|
||||
export const LIST = `
|
||||
SELECT id, rate
|
||||
FROM tax
|
||||
`;
|
||||
50
src/providers/mssql/queries/unit.js
Normal file
50
src/providers/mssql/queries/unit.js
Normal file
@@ -0,0 +1,50 @@
|
||||
export const UNIT_COLUMNS = `
|
||||
u.si,
|
||||
u.basesi,
|
||||
u.basesifactor,
|
||||
ut.symbol,
|
||||
ut.name
|
||||
`;
|
||||
|
||||
export const GET_BY_SI = `
|
||||
SELECT id
|
||||
FROM unit
|
||||
WHERE company_id = @companyId AND si = @si
|
||||
`;
|
||||
|
||||
export const GET_FULL_BY_SI = `
|
||||
SELECT
|
||||
u.id,
|
||||
${UNIT_COLUMNS}
|
||||
FROM unit u
|
||||
LEFT JOIN unittext ut
|
||||
ON ut.unit_id = u.id AND ut.language_id = @languageId
|
||||
WHERE u.company_id = @companyId AND u.si = @si
|
||||
`;
|
||||
|
||||
export const LIST_BY_COMPANY = `
|
||||
SELECT
|
||||
${UNIT_COLUMNS}
|
||||
FROM unit u
|
||||
LEFT JOIN unittext ut
|
||||
ON ut.unit_id = u.id AND ut.language_id = @languageId
|
||||
WHERE u.company_id = @companyId
|
||||
ORDER BY ut.symbol, ut.name, u.si
|
||||
`;
|
||||
|
||||
export const CREATE = `
|
||||
INSERT INTO unit (company_id, si, basesi, basesifactor)
|
||||
OUTPUT INSERTED.id
|
||||
VALUES (@companyId, @si, @basesi, @basesifactor)
|
||||
`;
|
||||
|
||||
export const UPDATE_BY_SI = `
|
||||
UPDATE unit
|
||||
SET basesi = @basesi, basesifactor = @basesifactor
|
||||
WHERE company_id = @companyId AND si = @si
|
||||
`;
|
||||
|
||||
export const DELETE_BY_COMPANY_AND_SI = `
|
||||
DELETE FROM unit
|
||||
WHERE company_id = @companyId AND si = @si
|
||||
`;
|
||||
16
src/providers/mssql/queries/unittext.js
Normal file
16
src/providers/mssql/queries/unittext.js
Normal file
@@ -0,0 +1,16 @@
|
||||
export const CREATE = `
|
||||
INSERT INTO unittext (unit_id, language_id, symbol, name)
|
||||
VALUES (@unitId, @languageId, @symbol, @name)
|
||||
`;
|
||||
|
||||
export const UPDATE_BY_UNIT_AND_LANGUAGE = `
|
||||
UPDATE unittext
|
||||
SET symbol = @symbol, name = @name
|
||||
WHERE unit_id = @unitId AND language_id = @languageId
|
||||
`;
|
||||
|
||||
export const GET_BY_UNIT_AND_LANGUAGE = `
|
||||
SELECT id
|
||||
FROM unittext
|
||||
WHERE unit_id = @unitId AND language_id = @languageId
|
||||
`;
|
||||
876
src/providers/mssql/schema.js
Normal file
876
src/providers/mssql/schema.js
Normal file
@@ -0,0 +1,876 @@
|
||||
export const INIT_META = `
|
||||
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'meta')
|
||||
BEGIN
|
||||
CREATE TABLE meta (
|
||||
[key] NVARCHAR(255) NOT NULL,
|
||||
value NVARCHAR(MAX) NOT NULL,
|
||||
CONSTRAINT PK_meta PRIMARY KEY ([key])
|
||||
);
|
||||
END
|
||||
|
||||
IF NOT EXISTS (SELECT 1 FROM meta WHERE [key] = N'version')
|
||||
BEGIN
|
||||
INSERT INTO meta ([key], value)
|
||||
VALUES (N'version', N'1');
|
||||
END
|
||||
`;
|
||||
|
||||
export const INIT_GOOGLE_AUTH = `
|
||||
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'google_auth')
|
||||
BEGIN
|
||||
CREATE TABLE google_auth (
|
||||
id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
email NVARCHAR(320) NOT NULL,
|
||||
picture NVARCHAR(2048) NULL,
|
||||
picturebinary VARBINARY(MAX) NULL,
|
||||
sub NVARCHAR(255) NULL,
|
||||
created_at DATETIME2 NOT NULL CONSTRAINT DF_google_auth_created_at DEFAULT SYSUTCDATETIME(),
|
||||
selected_company INT NULL,
|
||||
CONSTRAINT UQ_google_auth_email UNIQUE (email),
|
||||
CONSTRAINT FK_google_auth_selected_company FOREIGN KEY (selected_company) REFERENCES company(id) ON DELETE SET NULL
|
||||
);
|
||||
CREATE UNIQUE INDEX UQ_google_auth_sub ON google_auth(sub) WHERE sub IS NOT NULL;
|
||||
END
|
||||
`;
|
||||
|
||||
export const INIT_LANGUAGE = `
|
||||
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'language')
|
||||
BEGIN
|
||||
CREATE TABLE language (
|
||||
id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
iso639 NVARCHAR(10) NOT NULL,
|
||||
CONSTRAINT UQ_language_iso639 UNIQUE (iso639)
|
||||
);
|
||||
END
|
||||
`;
|
||||
|
||||
export const INIT_TAX = `
|
||||
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'tax')
|
||||
BEGIN
|
||||
CREATE TABLE tax (
|
||||
id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
rate DECIMAL(18,4) NOT NULL,
|
||||
CONSTRAINT UQ_tax_rate UNIQUE (rate)
|
||||
);
|
||||
END
|
||||
|
||||
IF NOT EXISTS (SELECT 1 FROM tax WHERE rate = 0)
|
||||
BEGIN
|
||||
INSERT INTO tax (rate) VALUES (0);
|
||||
END
|
||||
|
||||
IF NOT EXISTS (SELECT 1 FROM tax WHERE rate = 7)
|
||||
BEGIN
|
||||
INSERT INTO tax (rate) VALUES (7);
|
||||
END
|
||||
|
||||
IF NOT EXISTS (SELECT 1 FROM tax WHERE rate = 19)
|
||||
BEGIN
|
||||
INSERT INTO tax (rate) VALUES (19);
|
||||
END
|
||||
`;
|
||||
|
||||
export const INIT_CATEGORY = `
|
||||
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'category')
|
||||
BEGIN
|
||||
CREATE TABLE category (
|
||||
id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
parent_id INT NULL,
|
||||
sort INT NOT NULL CONSTRAINT DF_category_sort DEFAULT 0,
|
||||
CONSTRAINT FK_category_parent FOREIGN KEY (parent_id) REFERENCES category(id) ON DELETE NO ACTION
|
||||
);
|
||||
END
|
||||
`;
|
||||
|
||||
export const INIT_PIC = `
|
||||
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'pic')
|
||||
BEGIN
|
||||
CREATE TABLE pic (
|
||||
id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
w INT NOT NULL,
|
||||
h INT NOT NULL,
|
||||
size BIGINT NOT NULL,
|
||||
hash NVARCHAR(64) NOT NULL,
|
||||
thumbw INT NOT NULL,
|
||||
thumbh INT NOT NULL,
|
||||
thumbhash NVARCHAR(64) NOT NULL,
|
||||
source NVARCHAR(MAX) NOT NULL,
|
||||
fullbinary VARBINARY(MAX) NOT NULL,
|
||||
thumbbinary VARBINARY(MAX) NOT NULL,
|
||||
CONSTRAINT UQ_pic_hash UNIQUE (hash)
|
||||
);
|
||||
END
|
||||
`;
|
||||
|
||||
export const INIT_COMPANY = `
|
||||
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'company')
|
||||
BEGIN
|
||||
CREATE TABLE company (
|
||||
id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
name NVARCHAR(255) NOT NULL,
|
||||
root_category_id INT NULL,
|
||||
default_language_id INT NULL,
|
||||
taxrate INT NULL,
|
||||
reducedtaxrate INT NULL,
|
||||
taxfreerate INT NULL,
|
||||
poscustomergroup_id INT NOT NULL,
|
||||
CONSTRAINT UQ_company_name UNIQUE (name),
|
||||
CONSTRAINT FK_company_root_category FOREIGN KEY (root_category_id) REFERENCES category(id) ON DELETE SET NULL,
|
||||
CONSTRAINT FK_company_default_language FOREIGN KEY (default_language_id) REFERENCES language(id) ON DELETE SET NULL,
|
||||
CONSTRAINT FK_company_taxrate FOREIGN KEY (taxrate) REFERENCES tax(id) ON DELETE NO ACTION,
|
||||
CONSTRAINT FK_company_reducedtaxrate FOREIGN KEY (reducedtaxrate) REFERENCES tax(id) ON DELETE NO ACTION,
|
||||
CONSTRAINT FK_company_taxfreerate FOREIGN KEY (taxfreerate) REFERENCES tax(id) ON DELETE NO ACTION
|
||||
);
|
||||
END
|
||||
`;
|
||||
|
||||
export const INIT_CUSTOMERGROUP = `
|
||||
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'customergroup')
|
||||
BEGIN
|
||||
CREATE TABLE customergroup (
|
||||
id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
name NVARCHAR(255) NOT NULL,
|
||||
sort INT NOT NULL CONSTRAINT DF_customergroup_sort DEFAULT 0,
|
||||
-- Nullable only for company-create chicken-egg (POS group first, then company, then SET).
|
||||
-- Always set before commit; never left null for live rows.
|
||||
company_id INT NULL,
|
||||
CONSTRAINT FK_customergroup_company FOREIGN KEY (company_id) REFERENCES company(id) ON DELETE CASCADE
|
||||
);
|
||||
END
|
||||
`;
|
||||
|
||||
export const INIT_COMPANY_POS_CUSTOMERGROUP_FK = `
|
||||
IF NOT EXISTS (
|
||||
SELECT 1 FROM sys.foreign_keys WHERE name = N'FK_company_poscustomergroup'
|
||||
)
|
||||
BEGIN
|
||||
ALTER TABLE company
|
||||
ADD CONSTRAINT FK_company_poscustomergroup
|
||||
FOREIGN KEY (poscustomergroup_id) REFERENCES customergroup(id) ON DELETE NO ACTION;
|
||||
END
|
||||
`;
|
||||
|
||||
export const INIT_ENTITY = `
|
||||
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'entity')
|
||||
BEGIN
|
||||
CREATE TABLE entity (
|
||||
id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
customergroup_id INT NOT NULL,
|
||||
first_name NVARCHAR(255) NULL,
|
||||
name NVARCHAR(255) NOT NULL,
|
||||
[number] NVARCHAR(100) NULL,
|
||||
created_at DATETIME2 NOT NULL CONSTRAINT DF_entity_created_at DEFAULT SYSUTCDATETIME(),
|
||||
updated_at DATETIME2 NOT NULL CONSTRAINT DF_entity_updated_at DEFAULT SYSUTCDATETIME(),
|
||||
CONSTRAINT FK_entity_customergroup FOREIGN KEY (customergroup_id) REFERENCES customergroup(id) ON DELETE CASCADE
|
||||
);
|
||||
END
|
||||
`;
|
||||
|
||||
/** Unique (company_id, number) for non-null entity numbers via customergroup. */
|
||||
export const INIT_ENTITY_COMPANY_NUMBER_UQ = `
|
||||
IF OBJECT_ID(N'dbo.v_entity_company_number', N'V') IS NULL
|
||||
BEGIN
|
||||
EXEC('
|
||||
CREATE VIEW dbo.v_entity_company_number
|
||||
WITH SCHEMABINDING
|
||||
AS
|
||||
SELECT
|
||||
e.id AS entity_id,
|
||||
cg.company_id,
|
||||
e.[number]
|
||||
FROM dbo.entity AS e
|
||||
INNER JOIN dbo.customergroup AS cg ON cg.id = e.customergroup_id
|
||||
WHERE e.[number] IS NOT NULL
|
||||
');
|
||||
END
|
||||
|
||||
IF NOT EXISTS (
|
||||
SELECT 1 FROM sys.indexes
|
||||
WHERE name = N'UQ_entity_company_number'
|
||||
AND object_id = OBJECT_ID(N'dbo.v_entity_company_number')
|
||||
)
|
||||
BEGIN
|
||||
CREATE UNIQUE CLUSTERED INDEX UQ_entity_company_number
|
||||
ON dbo.v_entity_company_number (company_id, [number]);
|
||||
END
|
||||
`;
|
||||
|
||||
export const INIT_ENTITYADDRESS = `
|
||||
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'entityaddress')
|
||||
BEGIN
|
||||
CREATE TABLE entityaddress (
|
||||
id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
entity_id INT NOT NULL,
|
||||
first_name NVARCHAR(255) NULL,
|
||||
name NVARCHAR(255) NULL,
|
||||
street NVARCHAR(255) NULL,
|
||||
streetnumber NVARCHAR(50) NULL,
|
||||
zip NVARCHAR(50) NULL,
|
||||
city NVARCHAR(255) NULL,
|
||||
county NVARCHAR(255) NULL,
|
||||
addresstype NVARCHAR(50) NOT NULL,
|
||||
sort INT NOT NULL CONSTRAINT DF_entityaddress_sort DEFAULT 0,
|
||||
CONSTRAINT FK_entityaddress_entity FOREIGN KEY (entity_id) REFERENCES entity(id) ON DELETE CASCADE
|
||||
);
|
||||
END
|
||||
`;
|
||||
|
||||
export const INIT_ENTITYCONTACT = `
|
||||
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'entitycontact')
|
||||
BEGIN
|
||||
CREATE TABLE entitycontact (
|
||||
id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
entity_id INT NOT NULL,
|
||||
contacttype NVARCHAR(50) NOT NULL,
|
||||
contact NVARCHAR(255) NOT NULL,
|
||||
sort INT NOT NULL CONSTRAINT DF_entitycontact_sort DEFAULT 0,
|
||||
CONSTRAINT FK_entitycontact_entity FOREIGN KEY (entity_id) REFERENCES entity(id) ON DELETE CASCADE
|
||||
);
|
||||
END
|
||||
`;
|
||||
|
||||
export const INIT_ENTITYHISTORY = `
|
||||
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'entityhistory')
|
||||
BEGIN
|
||||
CREATE TABLE entityhistory (
|
||||
id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
entity_id INT NOT NULL,
|
||||
companyuser_id INT NULL,
|
||||
[date] DATETIME2 NOT NULL CONSTRAINT DF_entityhistory_date DEFAULT SYSUTCDATETIME(),
|
||||
[text] NVARCHAR(MAX) NOT NULL,
|
||||
CONSTRAINT FK_entityhistory_entity FOREIGN KEY (entity_id) REFERENCES entity(id) ON DELETE CASCADE,
|
||||
CONSTRAINT FK_entityhistory_companyuser FOREIGN KEY (companyuser_id) REFERENCES companyuser(id) ON DELETE NO ACTION
|
||||
);
|
||||
END
|
||||
`;
|
||||
|
||||
export const INIT_UNIT = `
|
||||
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'unit')
|
||||
BEGIN
|
||||
CREATE TABLE unit (
|
||||
id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
company_id INT NOT NULL,
|
||||
si NVARCHAR(50) NOT NULL,
|
||||
basesi NVARCHAR(50) NOT NULL,
|
||||
basesifactor FLOAT NOT NULL,
|
||||
CONSTRAINT UQ_unit_company_si UNIQUE (company_id, si),
|
||||
CONSTRAINT FK_unit_company FOREIGN KEY (company_id) REFERENCES company(id) ON DELETE NO ACTION
|
||||
);
|
||||
END
|
||||
`;
|
||||
|
||||
export const INIT_UNITTEXT = `
|
||||
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'unittext')
|
||||
BEGIN
|
||||
CREATE TABLE unittext (
|
||||
id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
unit_id INT NOT NULL,
|
||||
language_id INT NOT NULL,
|
||||
symbol NVARCHAR(50) NOT NULL,
|
||||
name NVARCHAR(255) NOT NULL,
|
||||
CONSTRAINT FK_unittext_unit FOREIGN KEY (unit_id) REFERENCES unit(id) ON DELETE CASCADE,
|
||||
CONSTRAINT FK_unittext_language FOREIGN KEY (language_id) REFERENCES language(id) ON DELETE CASCADE,
|
||||
CONSTRAINT UQ_unittext_unit_language UNIQUE (unit_id, language_id)
|
||||
);
|
||||
END
|
||||
`;
|
||||
|
||||
export const INIT_OPTIONSLIST = `
|
||||
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'optionslist')
|
||||
BEGIN
|
||||
CREATE TABLE optionslist (
|
||||
id INT IDENTITY(1,1) PRIMARY KEY
|
||||
);
|
||||
END
|
||||
`;
|
||||
|
||||
export const INIT_ARTICLELIST = `
|
||||
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'articlelist')
|
||||
BEGIN
|
||||
CREATE TABLE articlelist (
|
||||
id INT IDENTITY(1,1) PRIMARY KEY
|
||||
);
|
||||
END
|
||||
`;
|
||||
|
||||
export const INIT_BRAND = `
|
||||
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'brand')
|
||||
BEGIN
|
||||
CREATE TABLE brand (
|
||||
id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
company_id INT NOT NULL,
|
||||
name NVARCHAR(255) NOT NULL,
|
||||
gsprpinfo NVARCHAR(MAX) NULL,
|
||||
CONSTRAINT UQ_brand_company_name UNIQUE (company_id, name),
|
||||
CONSTRAINT FK_brand_company FOREIGN KEY (company_id) REFERENCES company(id) ON DELETE NO ACTION
|
||||
);
|
||||
END
|
||||
`;
|
||||
|
||||
export const INIT_ARTICLE = `
|
||||
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'article')
|
||||
BEGIN
|
||||
CREATE TABLE article (
|
||||
id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
sku NVARCHAR(100) NULL,
|
||||
unit_id INT NOT NULL,
|
||||
unitamount FLOAT NOT NULL,
|
||||
weight FLOAT NOT NULL,
|
||||
brand_id INT NULL,
|
||||
articlelist_id INT NULL,
|
||||
optionslist_id INT NULL,
|
||||
is_father BIT NOT NULL CONSTRAINT DF_article_is_father DEFAULT 0,
|
||||
fatherarticle_id INT NULL,
|
||||
fathersort INT NOT NULL CONSTRAINT DF_article_fathersort DEFAULT 0,
|
||||
created_at DATETIME2 NOT NULL CONSTRAINT DF_article_created_at DEFAULT SYSUTCDATETIME(),
|
||||
updated_at DATETIME2 NOT NULL CONSTRAINT DF_article_updated_at DEFAULT SYSUTCDATETIME(),
|
||||
CONSTRAINT FK_article_unit FOREIGN KEY (unit_id) REFERENCES unit(id) ON DELETE NO ACTION,
|
||||
CONSTRAINT FK_article_brand FOREIGN KEY (brand_id) REFERENCES brand(id) ON DELETE SET NULL,
|
||||
CONSTRAINT FK_article_articlelist FOREIGN KEY (articlelist_id) REFERENCES articlelist(id) ON DELETE SET NULL,
|
||||
CONSTRAINT FK_article_optionslist FOREIGN KEY (optionslist_id) REFERENCES optionslist(id) ON DELETE SET NULL,
|
||||
CONSTRAINT FK_article_fatherarticle FOREIGN KEY (fatherarticle_id) REFERENCES article(id) ON DELETE NO ACTION,
|
||||
CONSTRAINT UQ_article_sku UNIQUE (sku)
|
||||
);
|
||||
|
||||
-- Only enforce sibling sort uniqueness among children of the same father.
|
||||
-- (SQL Server UNIQUE treats NULLs as equal, which would block multiple root articles.)
|
||||
CREATE UNIQUE INDEX UQ_article_fatherarticle_fathersort
|
||||
ON article (fatherarticle_id, fathersort)
|
||||
WHERE fatherarticle_id IS NOT NULL;
|
||||
END
|
||||
`;
|
||||
|
||||
export const INIT_ARTICLEHISTORY = `
|
||||
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'articlehistory')
|
||||
BEGIN
|
||||
CREATE TABLE articlehistory (
|
||||
id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
article_id INT NOT NULL,
|
||||
companyuser_id INT NULL,
|
||||
[date] DATETIME2 NOT NULL CONSTRAINT DF_articlehistory_date DEFAULT SYSUTCDATETIME(),
|
||||
[text] NVARCHAR(MAX) NOT NULL,
|
||||
CONSTRAINT FK_articlehistory_article FOREIGN KEY (article_id) REFERENCES article(id) ON DELETE CASCADE,
|
||||
CONSTRAINT FK_articlehistory_companyuser FOREIGN KEY (companyuser_id) REFERENCES companyuser(id) ON DELETE SET NULL
|
||||
);
|
||||
END
|
||||
`;
|
||||
|
||||
export const INIT_ARTICLEEAN = `
|
||||
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'articleean')
|
||||
BEGIN
|
||||
CREATE TABLE articleean (
|
||||
id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
article_id INT NOT NULL,
|
||||
ean NVARCHAR(50) NOT NULL,
|
||||
CONSTRAINT FK_articleean_article FOREIGN KEY (article_id) REFERENCES article(id) ON DELETE CASCADE,
|
||||
CONSTRAINT UQ_articleean_ean UNIQUE (ean)
|
||||
);
|
||||
-- Hot path: getBySku EANs by article (UQ is ean-leading only)
|
||||
CREATE INDEX IX_articleean_article_ean
|
||||
ON articleean (article_id, ean);
|
||||
END
|
||||
`;
|
||||
|
||||
export const INIT_ARTICLEPIC = `
|
||||
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'articlepic')
|
||||
BEGIN
|
||||
CREATE TABLE articlepic (
|
||||
id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
article_id INT NOT NULL,
|
||||
pic_id INT NOT NULL,
|
||||
sort INT NOT NULL CONSTRAINT DF_articlepic_sort DEFAULT 0,
|
||||
CONSTRAINT FK_articlepic_article FOREIGN KEY (article_id) REFERENCES article(id) ON DELETE CASCADE,
|
||||
CONSTRAINT FK_articlepic_pic FOREIGN KEY (pic_id) REFERENCES pic(id) ON DELETE CASCADE,
|
||||
CONSTRAINT UQ_articlepic_article_pic UNIQUE (article_id, pic_id),
|
||||
CONSTRAINT UQ_articlepic_article_sort UNIQUE (article_id, sort)
|
||||
);
|
||||
END
|
||||
`;
|
||||
|
||||
export const INIT_BRANDPIC = `
|
||||
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'brandpic')
|
||||
BEGIN
|
||||
CREATE TABLE brandpic (
|
||||
id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
brand_id INT NOT NULL,
|
||||
pic_id INT NOT NULL,
|
||||
sort INT NOT NULL CONSTRAINT DF_brandpic_sort DEFAULT 0,
|
||||
CONSTRAINT FK_brandpic_brand FOREIGN KEY (brand_id) REFERENCES brand(id) ON DELETE CASCADE,
|
||||
CONSTRAINT FK_brandpic_pic FOREIGN KEY (pic_id) REFERENCES pic(id) ON DELETE CASCADE,
|
||||
CONSTRAINT UQ_brandpic_brand_pic UNIQUE (brand_id, pic_id),
|
||||
CONSTRAINT UQ_brandpic_brand_sort UNIQUE (brand_id, sort)
|
||||
);
|
||||
END
|
||||
`;
|
||||
|
||||
export const INIT_ARTICLELISTARTICLE = `
|
||||
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'articlelistarticle')
|
||||
BEGIN
|
||||
CREATE TABLE articlelistarticle (
|
||||
id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
articlelist_id INT NOT NULL,
|
||||
article_id INT NOT NULL,
|
||||
count INT NOT NULL CONSTRAINT DF_articlelistarticle_count DEFAULT 1,
|
||||
sort INT NOT NULL CONSTRAINT DF_articlelistarticle_sort DEFAULT 0,
|
||||
CONSTRAINT FK_articlelistarticle_articlelist FOREIGN KEY (articlelist_id) REFERENCES articlelist(id) ON DELETE CASCADE,
|
||||
CONSTRAINT FK_articlelistarticle_article FOREIGN KEY (article_id) REFERENCES article(id) ON DELETE CASCADE,
|
||||
CONSTRAINT UQ_articlelistarticle_articlelist_article UNIQUE (articlelist_id, article_id),
|
||||
CONSTRAINT UQ_articlelistarticle_articlelist_sort UNIQUE (articlelist_id, sort)
|
||||
);
|
||||
END
|
||||
`;
|
||||
|
||||
export const INIT_OPTIONSLISTARTICLE = `
|
||||
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'optionslistarticle')
|
||||
BEGIN
|
||||
CREATE TABLE optionslistarticle (
|
||||
id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
optionslist_id INT NOT NULL,
|
||||
article_id INT NOT NULL,
|
||||
count INT NOT NULL CONSTRAINT DF_optionslistarticle_count DEFAULT 1,
|
||||
sort INT NOT NULL CONSTRAINT DF_optionslistarticle_sort DEFAULT 0,
|
||||
mandated BIT NOT NULL CONSTRAINT DF_optionslistarticle_mandated DEFAULT 0,
|
||||
CONSTRAINT FK_optionslistarticle_optionslist FOREIGN KEY (optionslist_id) REFERENCES optionslist(id) ON DELETE CASCADE,
|
||||
CONSTRAINT FK_optionslistarticle_article FOREIGN KEY (article_id) REFERENCES article(id) ON DELETE CASCADE,
|
||||
CONSTRAINT UQ_optionslistarticle_optionslist_article UNIQUE (optionslist_id, article_id),
|
||||
CONSTRAINT UQ_optionslistarticle_optionslist_sort UNIQUE (optionslist_id, sort)
|
||||
);
|
||||
END
|
||||
`;
|
||||
|
||||
export const INIT_CATEGORYARTICLE = `
|
||||
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'categoryarticle')
|
||||
BEGIN
|
||||
CREATE TABLE categoryarticle (
|
||||
id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
category_id INT NOT NULL,
|
||||
article_id INT NOT NULL,
|
||||
CONSTRAINT FK_categoryarticle_category FOREIGN KEY (category_id) REFERENCES category(id) ON DELETE NO ACTION,
|
||||
CONSTRAINT FK_categoryarticle_article FOREIGN KEY (article_id) REFERENCES article(id) ON DELETE CASCADE,
|
||||
CONSTRAINT UQ_categoryarticle_category_article UNIQUE (category_id, article_id)
|
||||
);
|
||||
-- Hot path: getBySku / resolve by article (UQ is category-leading)
|
||||
CREATE INDEX IX_categoryarticle_article_category
|
||||
ON categoryarticle (article_id, category_id);
|
||||
END
|
||||
`;
|
||||
|
||||
export const INIT_CATEGORYPIC = `
|
||||
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'categorypic')
|
||||
BEGIN
|
||||
CREATE TABLE categorypic (
|
||||
id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
category_id INT NOT NULL,
|
||||
pic_id INT NOT NULL,
|
||||
sort INT NOT NULL CONSTRAINT DF_categorypic_sort DEFAULT 0,
|
||||
CONSTRAINT FK_categorypic_category FOREIGN KEY (category_id) REFERENCES category(id) ON DELETE CASCADE,
|
||||
CONSTRAINT FK_categorypic_pic FOREIGN KEY (pic_id) REFERENCES pic(id) ON DELETE CASCADE,
|
||||
CONSTRAINT UQ_categorypic_category_pic UNIQUE (category_id, pic_id),
|
||||
CONSTRAINT UQ_categorypic_category_sort UNIQUE (category_id, sort)
|
||||
);
|
||||
END
|
||||
`;
|
||||
|
||||
export const INIT_CATEGORYTEXT = `
|
||||
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'categorytext')
|
||||
BEGIN
|
||||
CREATE TABLE categorytext (
|
||||
id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
category_id INT NOT NULL,
|
||||
language_id INT NOT NULL,
|
||||
name NVARCHAR(255) NOT NULL,
|
||||
slug NVARCHAR(255) NOT NULL,
|
||||
seo NVARCHAR(MAX) NULL,
|
||||
[desc] NVARCHAR(MAX) NULL,
|
||||
CONSTRAINT FK_categorytext_category FOREIGN KEY (category_id) REFERENCES category(id) ON DELETE CASCADE,
|
||||
CONSTRAINT FK_categorytext_language FOREIGN KEY (language_id) REFERENCES language(id) ON DELETE CASCADE,
|
||||
CONSTRAINT UQ_categorytext_category_language UNIQUE (category_id, language_id)
|
||||
);
|
||||
END
|
||||
`;
|
||||
|
||||
export const INIT_ARTICLENAME = `
|
||||
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'articletext')
|
||||
BEGIN
|
||||
CREATE TABLE articletext (
|
||||
id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
article_id INT NOT NULL,
|
||||
language_id INT NOT NULL,
|
||||
name NVARCHAR(255) NOT NULL,
|
||||
slug NVARCHAR(255) NOT NULL,
|
||||
seo NVARCHAR(MAX) NULL,
|
||||
[desc] NVARCHAR(MAX) NULL,
|
||||
CONSTRAINT FK_articletext_article FOREIGN KEY (article_id) REFERENCES article(id) ON DELETE CASCADE,
|
||||
CONSTRAINT FK_articletext_language FOREIGN KEY (language_id) REFERENCES language(id) ON DELETE CASCADE,
|
||||
CONSTRAINT UQ_articletext_article_language UNIQUE (article_id, language_id)
|
||||
);
|
||||
END
|
||||
`;
|
||||
|
||||
export const INIT_PRICE = `
|
||||
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'price')
|
||||
BEGIN
|
||||
CREATE TABLE price (
|
||||
id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
tax_id INT NOT NULL,
|
||||
article_id INT NOT NULL,
|
||||
minmultiplier DECIMAL(18,4) NOT NULL CONSTRAINT DF_price_minmultiplier DEFAULT 1,
|
||||
customergroup_id INT NOT NULL,
|
||||
net FLOAT NOT NULL,
|
||||
CONSTRAINT FK_price_tax FOREIGN KEY (tax_id) REFERENCES tax(id) ON DELETE CASCADE,
|
||||
CONSTRAINT FK_price_article FOREIGN KEY (article_id) REFERENCES article(id) ON DELETE CASCADE,
|
||||
CONSTRAINT FK_price_customergroup FOREIGN KEY (customergroup_id) REFERENCES customergroup(id) ON DELETE CASCADE
|
||||
);
|
||||
-- Hot path: getBySku prices by article (covers ORDER BY + SELECT cols)
|
||||
CREATE INDEX IX_price_article_cg_mult
|
||||
ON price (article_id, customergroup_id, minmultiplier)
|
||||
INCLUDE (net, tax_id);
|
||||
END
|
||||
`;
|
||||
|
||||
export const INIT_ARTICLE_SUPPLIER = `
|
||||
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'articlesupplier')
|
||||
BEGIN
|
||||
CREATE TABLE articlesupplier (
|
||||
id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
article_id INT NOT NULL,
|
||||
entity_id INT NOT NULL,
|
||||
price_id INT NULL,
|
||||
sku NVARCHAR(100) NULL,
|
||||
stock FLOAT NULL,
|
||||
pu FLOAT NOT NULL CONSTRAINT DF_articlesupplier_pu DEFAULT 1,
|
||||
sort INT NOT NULL CONSTRAINT DF_articlesupplier_sort DEFAULT 0,
|
||||
CONSTRAINT FK_articlesupplier_article FOREIGN KEY (article_id) REFERENCES article(id) ON DELETE CASCADE,
|
||||
CONSTRAINT FK_articlesupplier_entity FOREIGN KEY (entity_id) REFERENCES entity(id) ON DELETE CASCADE,
|
||||
CONSTRAINT FK_articlesupplier_price FOREIGN KEY (price_id) REFERENCES price(id) ON DELETE NO ACTION,
|
||||
CONSTRAINT UQ_articlesupplier_article_entity UNIQUE (article_id, entity_id),
|
||||
CONSTRAINT UQ_articlesupplier_article_sort UNIQUE (article_id, sort)
|
||||
);
|
||||
|
||||
CREATE INDEX IX_articlesupplier_article_entity
|
||||
ON articlesupplier (article_id, entity_id);
|
||||
END
|
||||
`;
|
||||
|
||||
export const INIT_MANIFEST = `
|
||||
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'manifest')
|
||||
BEGIN
|
||||
CREATE TABLE manifest (
|
||||
id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
company_id INT NOT NULL,
|
||||
[number] NVARCHAR(100) NOT NULL,
|
||||
[type] NVARCHAR(100) NOT NULL,
|
||||
entity_id INT NULL,
|
||||
external_number NVARCHAR(100) NULL,
|
||||
[date] DATETIME2 NOT NULL CONSTRAINT DF_manifest_date DEFAULT SYSUTCDATETIME(),
|
||||
CONSTRAINT FK_manifest_company FOREIGN KEY (company_id) REFERENCES company(id) ON DELETE NO ACTION,
|
||||
CONSTRAINT FK_manifest_entity FOREIGN KEY (entity_id) REFERENCES entity(id) ON DELETE SET NULL
|
||||
);
|
||||
END
|
||||
`;
|
||||
|
||||
export const INIT_MANIFESTARTICLE = `
|
||||
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'manifestarticle')
|
||||
BEGIN
|
||||
CREATE TABLE manifestarticle (
|
||||
id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
manifest_id INT NOT NULL,
|
||||
sku NVARCHAR(100) NULL,
|
||||
name NVARCHAR(255) NULL,
|
||||
pu FLOAT NOT NULL CONSTRAINT DF_manifestarticle_pu DEFAULT 1,
|
||||
amount FLOAT NOT NULL,
|
||||
net FLOAT NOT NULL,
|
||||
comment NVARCHAR(MAX) NULL,
|
||||
rebate FLOAT NOT NULL CONSTRAINT DF_manifestarticle_rebate DEFAULT 0,
|
||||
taxrate FLOAT NOT NULL CONSTRAINT DF_manifestarticle_taxrate DEFAULT 0,
|
||||
CONSTRAINT FK_manifestarticle_manifest FOREIGN KEY (manifest_id) REFERENCES manifest(id) ON DELETE CASCADE
|
||||
);
|
||||
END
|
||||
`;
|
||||
|
||||
|
||||
export const INIT_LEDGER = `
|
||||
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'ledger')
|
||||
BEGIN
|
||||
CREATE TABLE ledger (
|
||||
id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
manifestarticle_id INT NOT NULL,
|
||||
transaction_type NVARCHAR(100) NOT NULL,
|
||||
amount FLOAT NOT NULL,
|
||||
transaction_text NVARCHAR(MAX) NOT NULL,
|
||||
hash_version INT NOT NULL,
|
||||
prev_hash NVARCHAR(128) NULL,
|
||||
CONSTRAINT FK_ledger_manifestarticle FOREIGN KEY (manifestarticle_id) REFERENCES manifestarticle(id) ON DELETE NO ACTION
|
||||
) WITH (LEDGER = ON (APPEND_ONLY = ON));
|
||||
END
|
||||
`;
|
||||
|
||||
export const INIT_NUMBERS = `
|
||||
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'numbers')
|
||||
BEGIN
|
||||
CREATE TABLE numbers (
|
||||
id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
company_id INT NOT NULL,
|
||||
[type] NVARCHAR(100) NOT NULL,
|
||||
prefix NVARCHAR(50) NOT NULL CONSTRAINT DF_numbers_prefix DEFAULT '',
|
||||
padding INT NOT NULL CONSTRAINT DF_numbers_padding DEFAULT 0,
|
||||
[next] INT NOT NULL CONSTRAINT DF_numbers_next DEFAULT 1,
|
||||
CONSTRAINT FK_numbers_company FOREIGN KEY (company_id) REFERENCES company(id) ON DELETE CASCADE,
|
||||
CONSTRAINT UQ_numbers_company_type UNIQUE (company_id, [type])
|
||||
);
|
||||
END
|
||||
`;
|
||||
|
||||
// EXEC dbo.getnextnumberwithprefixandpadding
|
||||
// @company_id = 1, @type = N'articlesku', @value = @sku OUTPUT;
|
||||
export const INIT_GET_NEXT_NUMBER_WITH_PREFIX_AND_PADDING = `
|
||||
IF OBJECT_ID(N'dbo.getnextnumberwithprefixandpadding', N'P') IS NOT NULL
|
||||
DROP PROCEDURE dbo.getnextnumberwithprefixandpadding;
|
||||
|
||||
EXEC('
|
||||
CREATE PROCEDURE dbo.getnextnumberwithprefixandpadding
|
||||
@company_id INT,
|
||||
@type NVARCHAR(100),
|
||||
@value NVARCHAR(100) OUTPUT
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON;
|
||||
|
||||
DECLARE @seq TABLE (prefix NVARCHAR(50), padding INT, num INT);
|
||||
|
||||
UPDATE n
|
||||
SET [next] = [next] + 1
|
||||
OUTPUT INSERTED.prefix, INSERTED.padding, DELETED.[next]
|
||||
INTO @seq(prefix, padding, num)
|
||||
FROM numbers n WITH (UPDLOCK, ROWLOCK)
|
||||
WHERE n.company_id = @company_id AND n.[type] = @type;
|
||||
|
||||
IF @@ROWCOUNT = 0
|
||||
THROW 50000, ''Number type not found for company'', 1;
|
||||
|
||||
SELECT @value = prefix + CASE
|
||||
WHEN padding > 0 THEN RIGHT(REPLICATE(''0'', padding) + CAST(num AS NVARCHAR(20)), padding)
|
||||
ELSE CAST(num AS NVARCHAR(20))
|
||||
END
|
||||
FROM @seq;
|
||||
END
|
||||
');
|
||||
`;
|
||||
|
||||
// EXEC dbo.peeknextnumberwithprefixandpadding
|
||||
// @company_id = 1, @type = N'entity', @value = @n OUTPUT;
|
||||
export const INIT_PEEK_NEXT_NUMBER_WITH_PREFIX_AND_PADDING = `
|
||||
IF OBJECT_ID(N'dbo.peeknextnumberwithprefixandpadding', N'P') IS NOT NULL
|
||||
DROP PROCEDURE dbo.peeknextnumberwithprefixandpadding;
|
||||
|
||||
EXEC('
|
||||
CREATE PROCEDURE dbo.peeknextnumberwithprefixandpadding
|
||||
@company_id INT,
|
||||
@type NVARCHAR(100),
|
||||
@value NVARCHAR(100) OUTPUT
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON;
|
||||
|
||||
DECLARE @prefix NVARCHAR(50);
|
||||
DECLARE @padding INT;
|
||||
DECLARE @num INT;
|
||||
|
||||
SELECT
|
||||
@prefix = n.prefix,
|
||||
@padding = n.padding,
|
||||
@num = n.[next]
|
||||
FROM numbers n WITH (UPDLOCK, ROWLOCK)
|
||||
WHERE n.company_id = @company_id AND n.[type] = @type;
|
||||
|
||||
IF @@ROWCOUNT = 0
|
||||
THROW 50000, ''Number type not found for company'', 1;
|
||||
|
||||
SET @value = @prefix + CASE
|
||||
WHEN @padding > 0 THEN RIGHT(REPLICATE(''0'', @padding) + CAST(@num AS NVARCHAR(20)), @padding)
|
||||
ELSE CAST(@num AS NVARCHAR(20))
|
||||
END;
|
||||
END
|
||||
');
|
||||
`;
|
||||
|
||||
export const INIT_COMPANYUSER = `
|
||||
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'companyuser')
|
||||
BEGIN
|
||||
CREATE TABLE companyuser (
|
||||
id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
google_auth_id INT NOT NULL,
|
||||
company_id INT NOT NULL,
|
||||
CONSTRAINT UQ_companyuser_google_auth_company UNIQUE (google_auth_id, company_id),
|
||||
CONSTRAINT FK_companyuser_google_auth FOREIGN KEY (google_auth_id) REFERENCES google_auth(id) ON DELETE CASCADE,
|
||||
CONSTRAINT FK_companyuser_company FOREIGN KEY (company_id) REFERENCES company(id) ON DELETE CASCADE
|
||||
);
|
||||
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
|
||||
CREATE TABLE companysetting (
|
||||
id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
company_id INT NOT NULL,
|
||||
[key] NVARCHAR(255) NOT NULL,
|
||||
value NVARCHAR(MAX) NOT NULL,
|
||||
frontend BIT NOT NULL CONSTRAINT DF_companysetting_frontend DEFAULT 0,
|
||||
writeonly BIT NOT NULL CONSTRAINT DF_companysetting_writeonly DEFAULT 0,
|
||||
CONSTRAINT UQ_companysetting_company_key UNIQUE (company_id, [key]),
|
||||
CONSTRAINT FK_companysetting_company FOREIGN KEY (company_id) REFERENCES company(id) ON DELETE CASCADE
|
||||
);
|
||||
END
|
||||
`;
|
||||
|
||||
export const INIT_POSTERMINAL = `
|
||||
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'posterminal')
|
||||
BEGIN
|
||||
CREATE TABLE posterminal (
|
||||
id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
company_id INT NOT NULL,
|
||||
name NVARCHAR(255) NOT NULL,
|
||||
token NVARCHAR(255) NULL,
|
||||
pairingpin NVARCHAR(50) NOT NULL,
|
||||
CONSTRAINT FK_posterminal_company FOREIGN KEY (company_id) REFERENCES company(id) ON DELETE CASCADE
|
||||
);
|
||||
CREATE UNIQUE INDEX UQ_posterminal_token ON posterminal(token) WHERE token IS NOT NULL;
|
||||
END
|
||||
`;
|
||||
|
||||
export const INIT_POSTERMINALCATEGORY = `
|
||||
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'posterminalcategory')
|
||||
BEGIN
|
||||
CREATE TABLE posterminalcategory (
|
||||
id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
posterminal_id INT NOT NULL,
|
||||
category_id INT NOT NULL,
|
||||
CONSTRAINT FK_posterminalcategory_posterminal FOREIGN KEY (posterminal_id) REFERENCES posterminal(id) ON DELETE CASCADE,
|
||||
CONSTRAINT FK_posterminalcategory_category FOREIGN KEY (category_id) REFERENCES category(id) ON DELETE NO ACTION,
|
||||
CONSTRAINT UQ_posterminalcategory_posterminal_category UNIQUE (posterminal_id, category_id)
|
||||
);
|
||||
END
|
||||
`;
|
||||
|
||||
export const INIT_FILE = `
|
||||
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'file')
|
||||
BEGIN
|
||||
CREATE TABLE [file] (
|
||||
id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
hash NVARCHAR(64) NOT NULL,
|
||||
mimetype NVARCHAR(255) NOT NULL,
|
||||
name NVARCHAR(255) NOT NULL,
|
||||
size BIGINT NOT NULL,
|
||||
created DATETIME2 NOT NULL CONSTRAINT DF_file_created DEFAULT SYSUTCDATETIME(),
|
||||
modified DATETIME2 NOT NULL CONSTRAINT DF_file_modified DEFAULT SYSUTCDATETIME(),
|
||||
content VARBINARY(MAX) NOT NULL,
|
||||
thumbavif VARBINARY(MAX) NULL,
|
||||
thumbx INT NULL,
|
||||
thumby INT NULL,
|
||||
meta NVARCHAR(MAX) NULL
|
||||
);
|
||||
END
|
||||
`;
|
||||
|
||||
export const INIT_MANIFESTATTACHMENT = `
|
||||
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'manifestattachment')
|
||||
BEGIN
|
||||
CREATE TABLE manifestattachment (
|
||||
id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
manifest_id INT NOT NULL,
|
||||
file_id INT NOT NULL,
|
||||
sort INT NOT NULL CONSTRAINT DF_manifestattachment_sort DEFAULT 0,
|
||||
CONSTRAINT FK_manifestattachment_manifest FOREIGN KEY (manifest_id) REFERENCES manifest(id) ON DELETE CASCADE,
|
||||
CONSTRAINT FK_manifestattachment_file FOREIGN KEY (file_id) REFERENCES [file](id) ON DELETE CASCADE,
|
||||
CONSTRAINT UQ_manifestattachment_manifest_sort UNIQUE (manifest_id, sort)
|
||||
);
|
||||
END
|
||||
`;
|
||||
|
||||
export const INIT_MANIFESTATTACHMENT_TRIGGER = `
|
||||
IF OBJECT_ID(N'dbo.TR_manifestattachment_delete_file', N'TR') IS NOT NULL
|
||||
DROP TRIGGER dbo.TR_manifestattachment_delete_file;
|
||||
|
||||
EXEC('
|
||||
CREATE TRIGGER dbo.TR_manifestattachment_delete_file
|
||||
ON manifestattachment
|
||||
AFTER DELETE
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON;
|
||||
DELETE f
|
||||
FROM [file] f
|
||||
INNER JOIN deleted d ON f.id = d.file_id
|
||||
WHERE NOT EXISTS (
|
||||
SELECT 1 FROM manifestattachment ma WHERE ma.file_id = f.id
|
||||
);
|
||||
END
|
||||
');
|
||||
`;
|
||||
|
||||
/** DDL scripts in dependency order for schema init. */
|
||||
export const SCHEMA_SCRIPTS = [
|
||||
INIT_META,
|
||||
INIT_LANGUAGE,
|
||||
INIT_TAX,
|
||||
INIT_CATEGORY,
|
||||
INIT_PIC,
|
||||
INIT_COMPANY,
|
||||
INIT_GOOGLE_AUTH,
|
||||
INIT_CUSTOMERGROUP,
|
||||
INIT_COMPANY_POS_CUSTOMERGROUP_FK,
|
||||
INIT_ENTITY,
|
||||
INIT_ENTITY_COMPANY_NUMBER_UQ,
|
||||
INIT_ENTITYADDRESS,
|
||||
INIT_ENTITYCONTACT,
|
||||
INIT_UNIT,
|
||||
INIT_UNITTEXT,
|
||||
INIT_OPTIONSLIST,
|
||||
INIT_ARTICLELIST,
|
||||
INIT_BRAND,
|
||||
INIT_ARTICLE,
|
||||
INIT_ARTICLEEAN,
|
||||
INIT_ARTICLEPIC,
|
||||
INIT_BRANDPIC,
|
||||
INIT_ARTICLELISTARTICLE,
|
||||
INIT_OPTIONSLISTARTICLE,
|
||||
INIT_CATEGORYARTICLE,
|
||||
INIT_CATEGORYPIC,
|
||||
INIT_CATEGORYTEXT,
|
||||
INIT_ARTICLENAME,
|
||||
INIT_PRICE,
|
||||
INIT_ARTICLE_SUPPLIER,
|
||||
INIT_MANIFEST,
|
||||
INIT_MANIFESTARTICLE,
|
||||
INIT_LEDGER,
|
||||
INIT_NUMBERS,
|
||||
INIT_GET_NEXT_NUMBER_WITH_PREFIX_AND_PADDING,
|
||||
INIT_PEEK_NEXT_NUMBER_WITH_PREFIX_AND_PADDING,
|
||||
INIT_COMPANYUSER,
|
||||
INIT_ARTICLEHISTORY,
|
||||
INIT_ENTITYHISTORY,
|
||||
INIT_SYNCPOS,
|
||||
INIT_COMPANYSETTING,
|
||||
INIT_POSTERMINAL,
|
||||
INIT_POSTERMINALCATEGORY,
|
||||
INIT_FILE,
|
||||
INIT_MANIFESTATTACHMENT,
|
||||
INIT_MANIFESTATTACHMENT_TRIGGER,
|
||||
];
|
||||
|
||||
40
src/providers/provider.js
Normal file
40
src/providers/provider.js
Normal file
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* Database provider contract for LibDashStore.
|
||||
*
|
||||
* A provider wraps a concrete database driver and exposes:
|
||||
* - query(sql, params) -> { rows, rowsAffected, insertId }
|
||||
* - transaction(fn) -> runs fn(runner) in a tx, commit/rollback
|
||||
* - exec(proc, {inputs,outputs}) -> stored procedure call (optional capability)
|
||||
* - initialize() / purge() -> schema lifecycle
|
||||
* - pool -> the underlying driver handle (transitional)
|
||||
*
|
||||
* @typedef {Object} QueryResult
|
||||
* @property {Array<Object>} rows Result rows (mssql `recordset` equivalent).
|
||||
* @property {number} rowsAffected Number of affected rows (mssql `rowsAffected[0]`).
|
||||
* @property {number|null} insertId Last inserted id when applicable, else null.
|
||||
*
|
||||
* @typedef {Object} DatabaseProvider
|
||||
* @property {(sql: string, params?: Object<string, *>) => Promise<QueryResult>} query
|
||||
* @property {(fn: (runner: DatabaseProvider) => Promise<*>) => Promise<*>} transaction
|
||||
* @property {() => Promise<void>} initialize
|
||||
* @property {() => Promise<void>} purge
|
||||
* @property {*} pool
|
||||
*/
|
||||
|
||||
/**
|
||||
* Checks whether an error is a unique-constraint violation.
|
||||
* @param {unknown} err
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export function isUniqueConstraintError(err) {
|
||||
throw new Error('Not implemented: isUniqueConstraintError');
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether an error is a foreign-key-constraint violation.
|
||||
* @param {unknown} err
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export function isForeignKeyConstraintError(err) {
|
||||
throw new Error('Not implemented: isForeignKeyConstraintError');
|
||||
}
|
||||
Reference in New Issue
Block a user