@7365admin1/core 3.76.0 → 3.77.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +45 -9
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +45 -9
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/test/e2e/dashboard-inventory-low-stock.e2e.test.mjs +59 -0
- package/test/notification-category.util.test.mjs +21 -1
package/package.json
CHANGED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// The dashboard supply tile reads Inventory where a store serves the site.
|
|
2
|
+
//
|
|
3
|
+
// With a store: the items at or below their own alert level, lowest first,
|
|
4
|
+
// basis `below-alert-level`, and nothing above its level. Without a store: the
|
|
5
|
+
// three lowest-quantity equipment supplies exactly as before, basis
|
|
6
|
+
// `lowest-quantity` with the no-threshold reason.
|
|
7
|
+
import { after, before, describe, it } from "node:test";
|
|
8
|
+
import assert from "node:assert/strict";
|
|
9
|
+
import { ObjectId } from "mongodb";
|
|
10
|
+
|
|
11
|
+
import { startHarness } from "./harness.mjs";
|
|
12
|
+
|
|
13
|
+
describe("dashboard supply tile", { concurrency: 1 }, () => {
|
|
14
|
+
let h;
|
|
15
|
+
const withStore = new ObjectId();
|
|
16
|
+
const withoutStore = new ObjectId();
|
|
17
|
+
|
|
18
|
+
before(async () => {
|
|
19
|
+
h = await startHarness();
|
|
20
|
+
const store = new ObjectId();
|
|
21
|
+
await h.db.collection("inventory.stores").insertOne({ _id: store, org: new ObjectId(), ownerType: "property", name: "Main", sites: [withStore], status: "active" });
|
|
22
|
+
await h.db.collection("inventory.items").insertMany([
|
|
23
|
+
{ store, name: "Tube 18W", onHand: 3, reorderLevel: 10, status: "active" },
|
|
24
|
+
{ store, name: "Holder", onHand: 0, reorderLevel: 5, status: "active" },
|
|
25
|
+
{ store, name: "Plenty", onHand: 500, reorderLevel: 10, status: "active" },
|
|
26
|
+
{ store, name: "No alert set", onHand: 0, reorderLevel: 0, status: "active" },
|
|
27
|
+
{ store, name: "Not in use", onHand: 0, reorderLevel: 10, status: "inactive" },
|
|
28
|
+
]);
|
|
29
|
+
await h.db.collection("site.supplies").insertMany([
|
|
30
|
+
{ site: withoutStore, serviceType: "cleaning_services", name: "Gloves", qty: 900, status: "active" },
|
|
31
|
+
{ site: withoutStore, serviceType: "cleaning_services", name: "Bleach", qty: 4, status: "active" },
|
|
32
|
+
{ site: withStore, serviceType: "cleaning_services", name: "Old equipment row", qty: 1, status: "active" },
|
|
33
|
+
]);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
after(async () => {
|
|
37
|
+
await h?.stop();
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
const tile = async (site) =>
|
|
41
|
+
(await h.core.useNewDashboardRepo().getServiceDashboard({ site, serviceType: "cleaning_services" })).supplyAlert;
|
|
42
|
+
|
|
43
|
+
it("a site with an Inventory store shows only items at or below their alert level, lowest first", async () => {
|
|
44
|
+
const supply = await tile(withStore);
|
|
45
|
+
assert.equal(supply.basis, "below-alert-level");
|
|
46
|
+
assert.deepEqual(supply.items, [
|
|
47
|
+
{ name: "Holder", qty: 0 },
|
|
48
|
+
{ name: "Tube 18W", qty: 3 },
|
|
49
|
+
]);
|
|
50
|
+
assert.equal(supply.thresholdUnavailableReason, undefined);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it("a site without a store keeps the old lowest-quantity list", async () => {
|
|
54
|
+
const supply = await tile(withoutStore);
|
|
55
|
+
assert.equal(supply.basis, "lowest-quantity");
|
|
56
|
+
assert.deepEqual(supply.items.map((i) => i.name), ["Bleach", "Gloves"]);
|
|
57
|
+
assert.ok(supply.thresholdUnavailableReason);
|
|
58
|
+
});
|
|
59
|
+
});
|
|
@@ -84,6 +84,24 @@ describe("notification categories", () => {
|
|
|
84
84
|
}
|
|
85
85
|
});
|
|
86
86
|
|
|
87
|
+
it("a role holding any inventory permission is offered the Inventory switch", () => {
|
|
88
|
+
for (const permission of [
|
|
89
|
+
"inventory:view-inventory",
|
|
90
|
+
"inventory:request-stock",
|
|
91
|
+
"inventory:approve-requests",
|
|
92
|
+
"inventory:manage-inventory",
|
|
93
|
+
]) {
|
|
94
|
+
assert.deepEqual(
|
|
95
|
+
keys(categoriesForPermissions({ permissions: [permission] })),
|
|
96
|
+
["inventory"],
|
|
97
|
+
permission,
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
const inventory = NOTIFICATION_CATEGORIES.find((c) => c.key === "inventory");
|
|
101
|
+
assert.equal(inventory.rendered, true);
|
|
102
|
+
assert.equal(inventory.safety, undefined);
|
|
103
|
+
});
|
|
104
|
+
|
|
87
105
|
it("a resident is not offered any safety switch", () => {
|
|
88
106
|
const offered = keys(
|
|
89
107
|
categoriesForPermissions({ permissions: [], isResident: true }),
|
|
@@ -360,7 +378,9 @@ describe("marketplace order categories", () => {
|
|
|
360
378
|
// ---------------------------------------------------------------------------
|
|
361
379
|
|
|
362
380
|
const NEW_KEYS = ["marketplaceOrder", "marketplaceVendorOrder"];
|
|
363
|
-
|
|
381
|
+
// Categories added after this snapshot was taken; each is pinned by its own test.
|
|
382
|
+
const LATER_KEYS = ["inventory"];
|
|
383
|
+
const withoutNew = (result) => keys(result).filter((k) => !NEW_KEYS.includes(k) && !LATER_KEYS.includes(k));
|
|
364
384
|
const onlyNew = (result) => keys(result).filter((k) => NEW_KEYS.includes(k));
|
|
365
385
|
|
|
366
386
|
const BEFORE = {
|