diff --git a/API.attributename.md b/API.attributename.md index 949e5a6..5fba52c 100644 --- a/API.attributename.md +++ b/API.attributename.md @@ -41,6 +41,10 @@ Deletes an attribute name for the user's selected company. `Promise` +**Throws** + +`Error` — If attribute name not found or in use. + ## `attributename.list` *Source: `src/store/attributename/list.js`* diff --git a/API.attributevalue.md b/API.attributevalue.md index 6fb0f37..3df3164 100644 --- a/API.attributevalue.md +++ b/API.attributevalue.md @@ -41,6 +41,10 @@ Deletes an attribute value. `Promise` +**Throws** + +`Error` — If attribute value not found or in use. + ## `attributevalue.listByAttributeId` *Source: `src/store/attributevalue/listByAttributeId.js`* diff --git a/API.propertyname.md b/API.propertyname.md index 2235771..498555e 100644 --- a/API.propertyname.md +++ b/API.propertyname.md @@ -41,6 +41,10 @@ Deletes a property name for the user's selected company. `Promise` +**Throws** + +`Error` — If property name not found or in use. + ## `propertyname.list` *Source: `src/store/propertyname/list.js`* diff --git a/package.json b/package.json index 57328f9..583a486 100644 --- a/package.json +++ b/package.json @@ -25,9 +25,9 @@ }, "dependencies": { "@clack/prompts": "^1.8.1", - "@hpcc-js/wasm-graphviz": "^1.29.1", + "@hpcc-js/wasm-graphviz": "^1.29.2", "chalk": "^6.0.1", - "dotenv": "^18.0.4", + "dotenv": "^18.0.5", "pdfconvert-wasm": "^0.3.0", "sharp": "^0.35.5", "thumbhash": "^0.1.1" diff --git a/src/providers/mssql/queries/article.js b/src/providers/mssql/queries/article.js index b4d2368..963fe68 100644 --- a/src/providers/mssql/queries/article.js +++ b/src/providers/mssql/queries/article.js @@ -32,6 +32,7 @@ export const ARTICLE_LIST_COLUMNS = ` pr.net, t.rate AS taxRate, a.track_stock, + a.is_father AS isFather, CASE WHEN a.optionslist_id IS NOT NULL THEN ( SELECT COUNT(*) diff --git a/src/providers/mssql/schema.js b/src/providers/mssql/schema.js index 63cdb94..e2aa9be 100644 --- a/src/providers/mssql/schema.js +++ b/src/providers/mssql/schema.js @@ -1029,7 +1029,7 @@ BEGIN value NVARCHAR(MAX) NOT NULL, sort INT NOT NULL CONSTRAINT DF_articleproperty_sort DEFAULT 0, CONSTRAINT FK_articleproperty_article FOREIGN KEY (article_id) REFERENCES article(id) ON DELETE CASCADE, - CONSTRAINT FK_articleproperty_property FOREIGN KEY (property_id) REFERENCES propertyname(id) ON DELETE CASCADE + CONSTRAINT FK_articleproperty_property FOREIGN KEY (property_id) REFERENCES propertyname(id) ON DELETE NO ACTION ); END `; @@ -1072,7 +1072,7 @@ BEGIN attributevalue_id INT NOT NULL, sort INT NOT NULL CONSTRAINT DF_articleattributevalue_sort DEFAULT 0, CONSTRAINT FK_articleattributevalue_article FOREIGN KEY (article_id) REFERENCES article(id) ON DELETE CASCADE, - CONSTRAINT FK_articleattributevalue_attributevalue FOREIGN KEY (attributevalue_id) REFERENCES attributevalue(id) ON DELETE CASCADE, + CONSTRAINT FK_articleattributevalue_attributevalue FOREIGN KEY (attributevalue_id) REFERENCES attributevalue(id) ON DELETE NO ACTION, CONSTRAINT UQ_articleattributevalue_article_attributevalue UNIQUE (article_id, attributevalue_id) ); END @@ -1088,7 +1088,7 @@ BEGIN value NVARCHAR(MAX) NOT NULL, sort INT NOT NULL CONSTRAINT DF_categoryproperty_sort DEFAULT 0, CONSTRAINT FK_categoryproperty_category FOREIGN KEY (category_id) REFERENCES category(id) ON DELETE CASCADE, - CONSTRAINT FK_categoryproperty_property FOREIGN KEY (property_id) REFERENCES propertyname(id) ON DELETE CASCADE + CONSTRAINT FK_categoryproperty_property FOREIGN KEY (property_id) REFERENCES propertyname(id) ON DELETE NO ACTION ); END `; diff --git a/src/providers/sqlite3/schema.js b/src/providers/sqlite3/schema.js index 2fe56c1..00bba19 100644 --- a/src/providers/sqlite3/schema.js +++ b/src/providers/sqlite3/schema.js @@ -716,7 +716,7 @@ CREATE TABLE IF NOT EXISTS articleproperty ( value TEXT NOT NULL, sort INTEGER NOT NULL DEFAULT 0, FOREIGN KEY (article_id) REFERENCES article(id) ON DELETE CASCADE, - FOREIGN KEY (property_id) REFERENCES propertyname(id) ON DELETE CASCADE + FOREIGN KEY (property_id) REFERENCES propertyname(id) ON DELETE NO ACTION ); `; @@ -750,7 +750,7 @@ CREATE TABLE IF NOT EXISTS articleattributevalue ( attributevalue_id INTEGER NOT NULL, sort INTEGER NOT NULL DEFAULT 0, FOREIGN KEY (article_id) REFERENCES article(id) ON DELETE CASCADE, - FOREIGN KEY (attributevalue_id) REFERENCES attributevalue(id) ON DELETE CASCADE, + FOREIGN KEY (attributevalue_id) REFERENCES attributevalue(id) ON DELETE NO ACTION, UNIQUE (article_id, attributevalue_id) ); `; @@ -763,7 +763,7 @@ CREATE TABLE IF NOT EXISTS categoryproperty ( value TEXT NOT NULL, sort INTEGER NOT NULL DEFAULT 0, FOREIGN KEY (category_id) REFERENCES category(id) ON DELETE CASCADE, - FOREIGN KEY (property_id) REFERENCES propertyname(id) ON DELETE CASCADE + FOREIGN KEY (property_id) REFERENCES propertyname(id) ON DELETE NO ACTION ); `; diff --git a/src/store/attributename/delete.js b/src/store/attributename/delete.js index 9278430..301c5da 100644 --- a/src/store/attributename/delete.js +++ b/src/store/attributename/delete.js @@ -6,6 +6,7 @@ import { GET_BY_COMPANY_AND_ID as SQLITE_GET, DELETE_BY_COMPANY_AND_ID as SQLITE_DELETE, } from '../../providers/sqlite3/queries/attributename.js'; +import { isForeignKeyConstraintError } from '../../providers/provider.js'; import resolveSelectedCompanyAccess from '../companyuser/resolveSelectedCompanyAccess.js'; import makeRunner from '../runner.js'; @@ -22,6 +23,7 @@ export default function deleteAttributename(provider) { * @param {number} id - The attribute name id. * @param {object} [tx] - Optional transaction. * @returns {Promise} + * @throws {Error} If attribute name not found or in use. */ return async (googleAuthId, id, tx) => { const runner = makeRunner(provider, tx); @@ -32,6 +34,13 @@ export default function deleteAttributename(provider) { throw new Error('Attribute name not found'); } - await runner.query(deleteSql, { id, companyId }); + try { + await runner.query(deleteSql, { id, companyId }); + } catch (err) { + if (isForeignKeyConstraintError(err)) { + throw new Error('Attribute name in use'); + } + throw err; + } }; } diff --git a/src/store/attributevalue/delete.js b/src/store/attributevalue/delete.js index a3206e2..6d8b631 100644 --- a/src/store/attributevalue/delete.js +++ b/src/store/attributevalue/delete.js @@ -6,6 +6,7 @@ import { GET_BY_ID_AND_COMPANY as SQLITE_GET, DELETE_BY_ID as SQLITE_DELETE, } from '../../providers/sqlite3/queries/attributevalue.js'; +import { isForeignKeyConstraintError } from '../../providers/provider.js'; import resolveSelectedCompanyAccess from '../companyuser/resolveSelectedCompanyAccess.js'; import makeRunner from '../runner.js'; @@ -22,6 +23,7 @@ export default function deleteAttributeValue(provider) { * @param {number} id - The attribute value id. * @param {object} [tx] - Optional transaction. * @returns {Promise} + * @throws {Error} If attribute value not found or in use. */ return async (googleAuthId, id, tx) => { const valId = Number(id); @@ -37,6 +39,13 @@ export default function deleteAttributeValue(provider) { throw new Error('Attribute value not found'); } - await runner.query(deleteSql, { id: valId }); + try { + await runner.query(deleteSql, { id: valId }); + } catch (err) { + if (isForeignKeyConstraintError(err)) { + throw new Error('Attribute value in use'); + } + throw err; + } }; } diff --git a/src/store/propertyname/delete.js b/src/store/propertyname/delete.js index f5417ba..d0ad7e6 100644 --- a/src/store/propertyname/delete.js +++ b/src/store/propertyname/delete.js @@ -6,6 +6,7 @@ import { GET_BY_COMPANY_AND_ID as SQLITE_GET, DELETE_BY_COMPANY_AND_ID as SQLITE_DELETE, } from '../../providers/sqlite3/queries/propertyname.js'; +import { isForeignKeyConstraintError } from '../../providers/provider.js'; import resolveSelectedCompanyAccess from '../companyuser/resolveSelectedCompanyAccess.js'; import makeRunner from '../runner.js'; @@ -22,6 +23,7 @@ export default function deletePropertyname(provider) { * @param {number} id - The property name id. * @param {object} [tx] - Optional transaction. * @returns {Promise} + * @throws {Error} If property name not found or in use. */ return async (googleAuthId, id, tx) => { const runner = makeRunner(provider, tx); @@ -32,6 +34,13 @@ export default function deletePropertyname(provider) { throw new Error('Property name not found'); } - await runner.query(deleteSql, { id, companyId }); + try { + await runner.query(deleteSql, { id, companyId }); + } catch (err) { + if (isForeignKeyConstraintError(err)) { + throw new Error('Property name in use'); + } + throw err; + } }; }