Password Policy/App rename/PM Scheduling Improvements
This commit is contained in:
@@ -129,11 +129,18 @@ function categoryRow(row) {
|
||||
const meta = parseJson(row.metadata, {});
|
||||
const templateId = meta.id_template_id || null;
|
||||
const template = templateId ? one('SELECT name, pattern FROM asset_id_templates WHERE id = ?', [templateId]) : null;
|
||||
// Categories link to an asset class by its unique id (class numbers are NOT unique — e.g. 00.12
|
||||
// covers both Computers and Casinos). The number/label are resolved from the linked class so the
|
||||
// right one is always shown; a manually-typed number (no id) falls back to that text.
|
||||
const classId = meta.asset_class_id || null;
|
||||
const cls = classId ? one('SELECT id, class_number, description FROM asset_classes WHERE id = ?', [classId]) : null;
|
||||
return {
|
||||
id: row.id,
|
||||
name: row.name,
|
||||
code: row.code,
|
||||
asset_class_number: meta.asset_class_number || null,
|
||||
asset_class_id: cls ? cls.id : null,
|
||||
asset_class_number: cls ? cls.class_number : (meta.asset_class_number || null),
|
||||
asset_class_label: cls ? `${cls.class_number} — ${cls.description}` : null,
|
||||
id_template_id: template ? templateId : null,
|
||||
id_template_name: template ? template.name : null,
|
||||
id_template_pattern: template ? template.pattern : null,
|
||||
@@ -141,6 +148,20 @@ function categoryRow(row) {
|
||||
};
|
||||
}
|
||||
|
||||
// Resolve the class number a category should carry: the linked class's number wins; otherwise a
|
||||
// manually-entered number. Returns { classId, classNumber }.
|
||||
function resolveCategoryClass(body, prev = {}) {
|
||||
if (body.asset_class_id !== undefined && body.asset_class_id !== null && body.asset_class_id !== '') {
|
||||
const cls = one('SELECT class_number FROM asset_classes WHERE id = ?', [body.asset_class_id]);
|
||||
if (cls) return { classId: Number(body.asset_class_id), classNumber: cls.class_number };
|
||||
}
|
||||
// Explicit null id, or a manual number with no id → manual override (clears the link).
|
||||
if (body.asset_class_id === null || body.asset_class_id === '' || body.asset_class_number !== undefined) {
|
||||
return { classId: null, classNumber: body.asset_class_number || null };
|
||||
}
|
||||
return { classId: prev.asset_class_id || null, classNumber: prev.asset_class_number || null };
|
||||
}
|
||||
|
||||
const categoryEditor = requireCapability('config.manage');
|
||||
|
||||
router.get('/asset-categories', (req, res) => {
|
||||
@@ -154,9 +175,10 @@ router.post('/asset-categories', categoryEditor, (req, res) => {
|
||||
if (one("SELECT id FROM reference_values WHERE type = 'category' AND name = ?", [name])) {
|
||||
return res.status(400).json({ error: 'That category already exists' });
|
||||
}
|
||||
const { classId, classNumber } = resolveCategoryClass(req.body);
|
||||
const result = run(
|
||||
"INSERT INTO reference_values (type, name, code, metadata) VALUES ('category', ?, ?, ?)",
|
||||
[name, req.body.code || null, json({ id_template_id: req.body.id_template_id || null, asset_class_number: req.body.asset_class_number || null })]
|
||||
[name, req.body.code || null, json({ id_template_id: req.body.id_template_id || null, asset_class_id: classId, asset_class_number: classNumber })]
|
||||
);
|
||||
audit(req.user.id, 'create', 'asset_category', result.lastInsertRowid, null, { name });
|
||||
return res.status(201).json({ category: categoryRow(one('SELECT * FROM reference_values WHERE id = ?', [result.lastInsertRowid])) });
|
||||
@@ -172,14 +194,19 @@ router.put('/asset-categories/:id', categoryEditor, (req, res) => {
|
||||
}
|
||||
const meta = parseJson(before.metadata, {});
|
||||
if (req.body.id_template_id !== undefined) meta.id_template_id = req.body.id_template_id || null;
|
||||
if (req.body.asset_class_number !== undefined) meta.asset_class_number = req.body.asset_class_number || null;
|
||||
const classChanged = req.body.asset_class_id !== undefined || req.body.asset_class_number !== undefined;
|
||||
if (classChanged) {
|
||||
const resolved = resolveCategoryClass(req.body, meta);
|
||||
meta.asset_class_id = resolved.classId;
|
||||
meta.asset_class_number = resolved.classNumber;
|
||||
}
|
||||
run('UPDATE reference_values SET name = ?, code = ?, metadata = ? WHERE id = ?', [name, req.body.code ?? before.code, json(meta), req.params.id]);
|
||||
let renamed = 0;
|
||||
if (name !== before.name) {
|
||||
renamed = run('UPDATE assets SET category = ?, updated_at = ? WHERE category = ?', [name, now(), before.name]).changes || 0;
|
||||
}
|
||||
// The class number is shared by every asset in the category — cascade any change.
|
||||
if (req.body.asset_class_number !== undefined) {
|
||||
if (classChanged) {
|
||||
run('UPDATE assets SET asset_class_number = ?, updated_at = ? WHERE category = ?', [meta.asset_class_number, now(), name]);
|
||||
}
|
||||
audit(req.user.id, 'update', 'asset_category', req.params.id, before, { name, renamed_assets: renamed });
|
||||
|
||||
Reference in New Issue
Block a user