From ba03b5b00594cace86a084e12897e05b8669dbe7 Mon Sep 17 00:00:00 2001 From: GaryB93 Date: Thu, 5 Oct 2023 17:05:38 -0500 Subject: [PATCH 1/9] add material routing, inventoryItemMaterial schema --- package-lock.json | 106 +++++++++--------- .../bmdashboard/bmMaterialsController.js | 40 +++++++ src/models/inventoryItemMaterial.js | 36 ++++++ src/routes/bmdashboard/bmMaterialsRouter.js | 14 +++ src/startup/routes.js | 4 +- 5 files changed, 146 insertions(+), 54 deletions(-) create mode 100644 src/controllers/bmdashboard/bmMaterialsController.js create mode 100644 src/models/inventoryItemMaterial.js create mode 100644 src/routes/bmdashboard/bmMaterialsRouter.js diff --git a/package-lock.json b/package-lock.json index 5c6bd6db5..47eb32afb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1414,7 +1414,7 @@ "@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, "@types/mime": { @@ -1570,7 +1570,7 @@ "array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, "array-includes": { "version": "3.1.6", @@ -2631,7 +2631,7 @@ "bcryptjs": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", - "integrity": "sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms=" + "integrity": "sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==" }, "bignumber.js": { "version": "9.0.2", @@ -2727,7 +2727,7 @@ "buffer-equal-constant-time": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" }, "buffer-from": { "version": "1.1.2", @@ -2860,7 +2860,7 @@ "clone": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=" + "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==" }, "clone-deep": { "version": "4.0.1", @@ -2904,12 +2904,12 @@ "commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=" + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==" }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "concat-stream": { "version": "1.6.2", @@ -2965,7 +2965,7 @@ "cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, "core-js": { "version": "3.21.1", @@ -3118,7 +3118,7 @@ "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "electron-to-chromium": { "version": "1.4.81", @@ -3134,7 +3134,7 @@ "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" }, "es-abstract": { "version": "1.19.1", @@ -3215,7 +3215,7 @@ "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" }, "escape-string-regexp": { "version": "1.0.5", @@ -4129,7 +4129,7 @@ "etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" }, "event-target-shim": { "version": "5.0.1", @@ -4294,7 +4294,7 @@ "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, "fast-text-encoding": { @@ -4424,7 +4424,7 @@ "fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" }, "fs-readdir-recursive": { "version": "1.1.0", @@ -4434,7 +4434,7 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "fsevents": { "version": "2.3.2", @@ -4812,7 +4812,7 @@ "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true }, "indent-string": { @@ -4824,7 +4824,7 @@ "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "requires": { "once": "^1.3.0", "wrappy": "1" @@ -4930,7 +4930,7 @@ "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" }, "is-glob": { "version": "4.0.3", @@ -5032,13 +5032,13 @@ "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==" }, "js-tokens": { "version": "4.0.0", @@ -5076,7 +5076,7 @@ "json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, "json5": { @@ -5397,7 +5397,7 @@ "lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=" + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" }, "lodash.merge": { "version": "4.6.2", @@ -5574,7 +5574,7 @@ "lru_map": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz", - "integrity": "sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0=" + "integrity": "sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==" }, "make-dir": { "version": "2.1.0", @@ -5588,7 +5588,7 @@ "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" }, "memory-pager": { "version": "1.5.0", @@ -5599,7 +5599,7 @@ "merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" }, "merge-stream": { "version": "2.0.0", @@ -5610,7 +5610,7 @@ "methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" }, "micromatch": { "version": "4.0.5", @@ -5767,7 +5767,7 @@ "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, "negotiator": { @@ -5845,7 +5845,7 @@ "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" }, "object-inspect": { "version": "1.12.0", @@ -6564,7 +6564,7 @@ "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "requires": { "wrappy": "1" } @@ -6594,7 +6594,7 @@ "os-shim": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/os-shim/-/os-shim-0.1.3.tgz", - "integrity": "sha1-a2LDeRz3kJ6jXtRuF2WLtBfLORc=", + "integrity": "sha512-jd0cvB8qQ5uVt0lvCIexBaROw1KyKm5sbulg2fWOHjETisuCzWyt+eTZKEMs8v6HwzoGs8xik26jg7eCM6pS+A==", "dev": true }, "p-limit": { @@ -6639,7 +6639,7 @@ "parse-passwd": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", - "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=" + "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==" }, "parseurl": { "version": "1.3.3", @@ -6654,7 +6654,7 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" }, "path-key": { "version": "3.1.1", @@ -6670,7 +6670,7 @@ "path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" }, "picocolors": { "version": "1.0.0", @@ -6717,7 +6717,7 @@ "pre-commit": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/pre-commit/-/pre-commit-1.2.2.tgz", - "integrity": "sha1-287g7p3nI15X95xW186UZBpp7sY=", + "integrity": "sha512-qokTiqxD6GjODy5ETAIgzsRgnBWWQHQH2ghy86PU7mIn/wuWeTwF3otyNQZxWBwVn8XNr8Tdzj/QfUXpH+gRZA==", "dev": true, "requires": { "cross-spawn": "^5.0.1", @@ -6728,7 +6728,7 @@ "cross-spawn": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "integrity": "sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==", "dev": true, "requires": { "lru-cache": "^4.0.1", @@ -6739,7 +6739,7 @@ "which": { "version": "1.2.14", "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz", - "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=", + "integrity": "sha512-16uPglFkRPzgiUXYMi1Jf8Z5EzN1iB4V0ZtMXcHZnwsBtQhhHeCqoWw7tsUY42hJGNDWtUsVLTjakIa5BgAxCw==", "dev": true, "requires": { "isexe": "^2.0.0" @@ -6781,7 +6781,7 @@ "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", "dev": true }, "punycode": { @@ -7219,7 +7219,7 @@ "sparse-bitfield": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", - "integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=", + "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", "optional": true, "requires": { "memory-pager": "^1.0.2" @@ -7228,7 +7228,7 @@ "spawn-sync": { "version": "1.0.15", "resolved": "https://registry.npmjs.org/spawn-sync/-/spawn-sync-1.0.15.tgz", - "integrity": "sha1-sAeZVX63+wyDdsKdROih6mfldHY=", + "integrity": "sha512-9DWBgrgYZzNghseho0JOuh+5fg9u6QWhAWa51QC7+U5rCheZ/j1DrEZnyE0RBBRqZ9uEXGPgSSM0nky6burpVw==", "dev": true, "requires": { "concat-stream": "^1.4.7", @@ -7623,7 +7623,7 @@ "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "dev": true }, "strip-final-newline": { @@ -7654,19 +7654,19 @@ "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", "dev": true }, "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==" }, "to-regex-range": { "version": "5.0.1", @@ -7684,7 +7684,7 @@ "tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, "tsconfig-paths": { "version": "3.14.2", @@ -7802,7 +7802,7 @@ "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", "dev": true }, "unbox-primitive": { @@ -7843,7 +7843,7 @@ "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" }, "uri-js": { "version": "4.4.1", @@ -7857,17 +7857,17 @@ "url-template": { "version": "2.0.8", "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", - "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE=" + "integrity": "sha512-XdVKMF4SJ0nP/O7XIPB0JwAEuT9lDIYnNsK8yGVe43y0AWoKeJNdv3ZNWh7ksJ6KqQFjOO6ox/VEitLnaVNufw==" }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" }, "uuid": { "version": "3.4.0", @@ -7890,17 +7890,17 @@ "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" }, "webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" }, "whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", "requires": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" @@ -8018,7 +8018,7 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "ws": { "version": "8.8.1", diff --git a/src/controllers/bmdashboard/bmMaterialsController.js b/src/controllers/bmdashboard/bmMaterialsController.js new file mode 100644 index 000000000..558a0f403 --- /dev/null +++ b/src/controllers/bmdashboard/bmMaterialsController.js @@ -0,0 +1,40 @@ +const mongoose = require('mongoose'); + +const bmMaterialsController = function (ItemMaterial, ItemType) { + const bmMaterialsList = async function (req, res) { + try { + ItemMaterial.find() + .populate({ + path: 'project', + select: '_id projectName' + }) + .populate({ + path: 'inventoryItemType', + select: '_id name uom totalStock' + }) + .then(results => res.status(200).send(results)) + .catch(error => res.status(500).send(error)) + } catch (err) { + res.json(err); + } + }; + + const bmAddMaterials = async function (req, res) { + console.log(req.body); + // if new material or new measurement, add to inventoryItemType collection first + const { material, requestor } = req.body; + if (material.newMaterial || material.newMeasurement) { + const materials = await ItemMaterial.find().exec(); + console.log(materials); + + } + // then either add item material to project or update existing item material + }; + + return { + bmMaterialsList, + bmAddMaterials + }; +}; + +module.exports = bmMaterialsController; \ No newline at end of file diff --git a/src/models/inventoryItemMaterial.js b/src/models/inventoryItemMaterial.js new file mode 100644 index 000000000..0c8aed460 --- /dev/null +++ b/src/models/inventoryItemMaterial.js @@ -0,0 +1,36 @@ +const mongoose = require('mongoose'); +const { Schema } = mongoose; + +const InventoryItemMaterial = new Schema({ + inventoryItemType: { type: mongoose.SchemaTypes.ObjectId, ref: 'inventoryItemType', required: true }, + project: { type: mongoose.SchemaTypes.ObjectId, ref: 'project', required: true }, + stockBought: { type: Number, required: true }, // amount bought for project, affects total stock + stockUsed: { type: Number, required: true }, + stockAvailable: { type: Number, required: true }, + stockHeld: { type: Number, required: true }, + stockWasted: { type: Number, required: true }, + usageRecord: [{ // daily log of amount inventory item used at job site + date: { type: Date, required: true, default: Date.now() }, + createdBy: { type: mongoose.SchemaTypes.ObjectId, ref: 'userProfile', required: true }, + quantityUsed: { type: Number, required: true }, + }], + updateRecord: [{ // incident report affecting quantity/status of inventory item + date: { type: Date, required: true, default: Date.now() }, + createdBy: { type: mongoose.SchemaTypes.ObjectId, ref: 'userProfile', required: true }, + action: { type: String, required: true }, // ex: Add, Reduce, Hold (updates stock quantities) + cause: { type: String, required: true }, // ex: Used, Lost, Wasted, Transfer (reason for update) + quantity: { type: Number, required: true }, // amount of material affected + description: { type: String, required: true, maxLength: 150 }, + }], + purchaseRecord: [{ + date: { type: Date, required: true, default: Date.now() }, + createdBy: { type: mongoose.SchemaTypes.ObjectId, ref: 'userProfile', required: true }, + poId: { type: String, required: true }, + sellerId: { type: String, required: true }, + quantity: { type: Number, required: true }, // adds to stockBought + subtotal: { type: Number, required: true }, + tax: { type: Number, required: true }, + shipping: { type: Number, required: true }, + }] +}) +module.exports = mongoose.model('inventoryItemMaterial', InventoryItemMaterial, 'inventoryMaterial'); \ No newline at end of file diff --git a/src/routes/bmdashboard/bmMaterialsRouter.js b/src/routes/bmdashboard/bmMaterialsRouter.js new file mode 100644 index 000000000..aaded5587 --- /dev/null +++ b/src/routes/bmdashboard/bmMaterialsRouter.js @@ -0,0 +1,14 @@ +const express = require('express'); + +const routes = function (itemMaterial, itemType) { + const materialsRouter = express.Router(); + const controller = require('../../controllers/bmdashboard/bmMaterialsController')(itemMaterial, itemType); + + materialsRouter.route('/materials') + .get(controller.bmMaterialsList) + .post(controller.bmAddMaterials); + + return materialsRouter; +}; + +module.exports = routes; \ No newline at end of file diff --git a/src/startup/routes.js b/src/startup/routes.js index 43cd226bd..a1eed4a7a 100644 --- a/src/startup/routes.js +++ b/src/startup/routes.js @@ -20,6 +20,7 @@ const ownerStandardMessage = require('../models/ownerStandardMessage'); const profileInitialSetuptoken = require('../models/profileInitialSetupToken'); const reason = require('../models/reason'); const mouseoverText = require('../models/mouseoverText'); +const itemMaterial = require('../models/inventoryItemMaterial'); const userProfileRouter = require('../routes/userProfileRouter')(userProfile); const badgeRouter = require('../routes/badgeRouter')(badge); @@ -55,7 +56,7 @@ const mouseoverTextRouter = require('../routes/mouseoverTextRouter')(mouseoverTe // bm dashboard const bmLoginRouter = require('../routes/bmdashboard/bmLoginRouter')(); - +const bmMaterialsRouter = require('../routes/bmdashboard/bmMaterialsRouter')(itemMaterial); module.exports = function (app) { app.use('/api', forgotPwdRouter); @@ -88,4 +89,5 @@ module.exports = function (app) { app.use('/api', mouseoverTextRouter); // bm dashboard app.use('/api/bm', bmLoginRouter); + app.use('/api/bm', bmMaterialsRouter); }; From bbc244e5274541a73f198c58937eaa3ba7bc90aa Mon Sep 17 00:00:00 2001 From: GaryB93 Date: Fri, 6 Oct 2023 14:36:14 -0500 Subject: [PATCH 2/9] controller logic for adding materials, update schemas --- .../bmdashboard/bmMaterialsController.js | 58 +++++++++++++++++-- src/models/inventoryItemMaterial.js | 8 ++- src/models/inventoryItemType.js | 9 ++- src/startup/routes.js | 2 +- 4 files changed, 66 insertions(+), 11 deletions(-) diff --git a/src/controllers/bmdashboard/bmMaterialsController.js b/src/controllers/bmdashboard/bmMaterialsController.js index 558a0f403..d9d1c7780 100644 --- a/src/controllers/bmdashboard/bmMaterialsController.js +++ b/src/controllers/bmdashboard/bmMaterialsController.js @@ -21,14 +21,62 @@ const bmMaterialsController = function (ItemMaterial, ItemType) { const bmAddMaterials = async function (req, res) { console.log(req.body); - // if new material or new measurement, add to inventoryItemType collection first const { material, requestor } = req.body; + let itemTypeId = material.material; // if new material: material name / else: itemType id + + // if new material or new measurement, add new inventoryItemType if (material.newMaterial || material.newMeasurement) { - const materials = await ItemMaterial.find().exec(); - console.log(materials); - + try { + const itemType = new ItemType({ + type: 'material', + name: material.material, + description: material.description, + uom: material.measurement, + totalStock: material.quantity, + totalAvailable: material.quantity, + projectsUsing: [material.projectId], + imageUrl: '', + link: material.link, + }); + const newItemType = await itemType.save(); + itemTypeId = newItemType._id; + } catch (err) { + res.status(400).send({ error: 'Error saving new material type'}); + } + } + + try { + const invMaterial = await ItemMaterial.find({ id: material.projectId, inventoryItemType: itemTypeId }).exec(); + // if material already exists in project, add to it + // else, create new material for project + if (invMaterial) { + // TODO + console.log(invMaterial); + } else { + const itemMaterial = new ItemMaterial({ + inventoryItemType: itemTypeId, + project: material.projectId, + stockBought: material.quantity, + stockAvailable: material.quantity, + usageRecord: [], + updateRecord: [], + purchaseRecord: [{ + date: material.purchaseDate, + createdBy: req.requestor.requestorId, + poId: material.invoice, + sellerId: material.phone, + quantity: material.quantity, + unitPrice: material.unitPrice, + subTotal: material.quantity * material.unitPrice, + tax: material.taxRate, + shipping: material.shippingFee, + }], + }); + const newItemMaterial = await itemMaterial.save(); + } + } catch (err) { + res.status(400).send({ error: 'Error adding new material to project'}); } - // then either add item material to project or update existing item material }; return { diff --git a/src/models/inventoryItemMaterial.js b/src/models/inventoryItemMaterial.js index 0c8aed460..09c521e4d 100644 --- a/src/models/inventoryItemMaterial.js +++ b/src/models/inventoryItemMaterial.js @@ -5,10 +5,10 @@ const InventoryItemMaterial = new Schema({ inventoryItemType: { type: mongoose.SchemaTypes.ObjectId, ref: 'inventoryItemType', required: true }, project: { type: mongoose.SchemaTypes.ObjectId, ref: 'project', required: true }, stockBought: { type: Number, required: true }, // amount bought for project, affects total stock - stockUsed: { type: Number, required: true }, + stockUsed: { type: Number, default: 0 }, stockAvailable: { type: Number, required: true }, - stockHeld: { type: Number, required: true }, - stockWasted: { type: Number, required: true }, + stockHeld: { type: Number, default: 0 }, + stockWasted: { type: Number, default: 0 }, usageRecord: [{ // daily log of amount inventory item used at job site date: { type: Date, required: true, default: Date.now() }, createdBy: { type: mongoose.SchemaTypes.ObjectId, ref: 'userProfile', required: true }, @@ -28,6 +28,8 @@ const InventoryItemMaterial = new Schema({ poId: { type: String, required: true }, sellerId: { type: String, required: true }, quantity: { type: Number, required: true }, // adds to stockBought + unitPrice: { type: Number, required: true }, + currency: { type: String, required: true }, subtotal: { type: Number, required: true }, tax: { type: Number, required: true }, shipping: { type: Number, required: true }, diff --git a/src/models/inventoryItemType.js b/src/models/inventoryItemType.js index 80e5e0d7b..20a58c018 100644 --- a/src/models/inventoryItemType.js +++ b/src/models/inventoryItemType.js @@ -3,10 +3,15 @@ const mongoose = require('mongoose'); const { Schema } = mongoose; const InventoryItemType = new Schema({ + type: { type: String, required: true }, // ie Material, Equipment, Tool name: { type: String, required: true }, - description: { type: String }, + description: { type: String, required: true, maxLength: 150 }, + uom: { type: String, required: true }, // unit of measurement + totalStock: { type: Number, required: true }, // total amount of all stock acquired + totalAvailable: { type: Number, required: true }, + projectsUsing: [ {type: mongoose.SchemaTypes.ObjectId, ref: 'project'} ], imageUrl: { type: String }, - quantifier: { type: String, default: 'each' }, + link: { type: String }, }); module.exports = mongoose.model('inventoryItemType', InventoryItemType, 'inventoryItemType'); diff --git a/src/startup/routes.js b/src/startup/routes.js index a1eed4a7a..66f7772dd 100644 --- a/src/startup/routes.js +++ b/src/startup/routes.js @@ -56,7 +56,7 @@ const mouseoverTextRouter = require('../routes/mouseoverTextRouter')(mouseoverTe // bm dashboard const bmLoginRouter = require('../routes/bmdashboard/bmLoginRouter')(); -const bmMaterialsRouter = require('../routes/bmdashboard/bmMaterialsRouter')(itemMaterial); +const bmMaterialsRouter = require('../routes/bmdashboard/bmMaterialsRouter')(itemMaterial, inventoryItemType); module.exports = function (app) { app.use('/api', forgotPwdRouter); From e55f980bed651b15bb0fad0202113e70a5ca4214 Mon Sep 17 00:00:00 2001 From: GaryB93 Date: Tue, 10 Oct 2023 18:52:52 -0500 Subject: [PATCH 3/9] save new item type before adding material to project --- .../bmdashboard/bmMaterialsController.js | 33 ++++++++++--------- src/models/inventoryItemMaterial.js | 2 +- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/controllers/bmdashboard/bmMaterialsController.js b/src/controllers/bmdashboard/bmMaterialsController.js index d9d1c7780..8b53ab35f 100644 --- a/src/controllers/bmdashboard/bmMaterialsController.js +++ b/src/controllers/bmdashboard/bmMaterialsController.js @@ -20,9 +20,8 @@ const bmMaterialsController = function (ItemMaterial, ItemType) { }; const bmAddMaterials = async function (req, res) { - console.log(req.body); const { material, requestor } = req.body; - let itemTypeId = material.material; // if new material: material name / else: itemType id + let itemTypeId = material.material; // either new material or existing itemTypeId // if new material or new measurement, add new inventoryItemType if (material.newMaterial || material.newMeasurement) { @@ -38,20 +37,20 @@ const bmMaterialsController = function (ItemMaterial, ItemType) { imageUrl: '', link: material.link, }); - const newItemType = await itemType.save(); - itemTypeId = newItemType._id; - } catch (err) { - res.status(400).send({ error: 'Error saving new material type'}); + const result = await itemType.save(); + itemTypeId = result._id; + } catch (error) { + res.status(500).send(error); } } try { - const invMaterial = await ItemMaterial.find({ id: material.projectId, inventoryItemType: itemTypeId }).exec(); - // if material already exists in project, add to it - // else, create new material for project + const invMaterial = await ItemMaterial.findOne( + { project: material.projectId, inventoryItemType: itemTypeId }).exec(); + console.log(invMaterial); if (invMaterial) { - // TODO - console.log(invMaterial); + // TODO: update inventoryMaterial with new purchase record + // and updated quantities } else { const itemMaterial = new ItemMaterial({ inventoryItemType: itemTypeId, @@ -62,26 +61,28 @@ const bmMaterialsController = function (ItemMaterial, ItemType) { updateRecord: [], purchaseRecord: [{ date: material.purchaseDate, - createdBy: req.requestor.requestorId, + createdBy: requestor.requestorId, poId: material.invoice, sellerId: material.phone, quantity: material.quantity, unitPrice: material.unitPrice, - subTotal: material.quantity * material.unitPrice, + currency: material.currency, + subtotal: material.quantity, tax: material.taxRate, shipping: material.shippingFee, }], }); const newItemMaterial = await itemMaterial.save(); + console.log(newItemMaterial); } - } catch (err) { - res.status(400).send({ error: 'Error adding new material to project'}); + } catch (error) { + res.status(500).send(error); } }; return { bmMaterialsList, - bmAddMaterials + bmAddMaterials, }; }; diff --git a/src/models/inventoryItemMaterial.js b/src/models/inventoryItemMaterial.js index 09c521e4d..2ffa1fba2 100644 --- a/src/models/inventoryItemMaterial.js +++ b/src/models/inventoryItemMaterial.js @@ -23,7 +23,7 @@ const InventoryItemMaterial = new Schema({ description: { type: String, required: true, maxLength: 150 }, }], purchaseRecord: [{ - date: { type: Date, required: true, default: Date.now() }, + date: { type: String, required: true }, createdBy: { type: mongoose.SchemaTypes.ObjectId, ref: 'userProfile', required: true }, poId: { type: String, required: true }, sellerId: { type: String, required: true }, From 31d1e39d35cf0867ea786ef7eb2e59e294d63d4b Mon Sep 17 00:00:00 2001 From: GaryB93 Date: Wed, 11 Oct 2023 17:29:28 -0500 Subject: [PATCH 4/9] update method to add inventory types --- .../bmdashboard/bmMaterialsController.js | 31 +++---------------- src/controllers/inventoryController.js | 7 ++++- 2 files changed, 10 insertions(+), 28 deletions(-) diff --git a/src/controllers/bmdashboard/bmMaterialsController.js b/src/controllers/bmdashboard/bmMaterialsController.js index 8b53ab35f..708c4d884 100644 --- a/src/controllers/bmdashboard/bmMaterialsController.js +++ b/src/controllers/bmdashboard/bmMaterialsController.js @@ -21,39 +21,16 @@ const bmMaterialsController = function (ItemMaterial, ItemType) { const bmAddMaterials = async function (req, res) { const { material, requestor } = req.body; - let itemTypeId = material.material; // either new material or existing itemTypeId - - // if new material or new measurement, add new inventoryItemType - if (material.newMaterial || material.newMeasurement) { - try { - const itemType = new ItemType({ - type: 'material', - name: material.material, - description: material.description, - uom: material.measurement, - totalStock: material.quantity, - totalAvailable: material.quantity, - projectsUsing: [material.projectId], - imageUrl: '', - link: material.link, - }); - const result = await itemType.save(); - itemTypeId = result._id; - } catch (error) { - res.status(500).send(error); - } - } try { - const invMaterial = await ItemMaterial.findOne( - { project: material.projectId, inventoryItemType: itemTypeId }).exec(); - console.log(invMaterial); + const invMaterial = await ItemMaterial.findOne({ project: material.projectId, inventoryItemType: material.material }).exec(); if (invMaterial) { + console.log('found item material in project'); // TODO: update inventoryMaterial with new purchase record // and updated quantities } else { const itemMaterial = new ItemMaterial({ - inventoryItemType: itemTypeId, + inventoryItemType: material.material, project: material.projectId, stockBought: material.quantity, stockAvailable: material.quantity, @@ -73,7 +50,7 @@ const bmMaterialsController = function (ItemMaterial, ItemType) { }], }); const newItemMaterial = await itemMaterial.save(); - console.log(newItemMaterial); + res.status(201).send(newItemMaterial); } } catch (error) { res.status(500).send(error); diff --git a/src/controllers/inventoryController.js b/src/controllers/inventoryController.js index bc0902aeb..d4c9d5261 100644 --- a/src/controllers/inventoryController.js +++ b/src/controllers/inventoryController.js @@ -548,10 +548,15 @@ const inventoryController = function (Item, ItemType) { } const itemType = new ItemType(); + itemType.type = req.body.type; itemType.name = req.body.name; itemType.description = req.body.description; + itemType.uom = req.body.uom; + itemType.totalStock = req.body.totalStock; + itemType.totalAvailable = req.body.totalAvailable; + itemType.projectsUsing = []; itemType.imageUrl = req.body.imageUrl || req.body.imageURL; - itemType.quantifier = req.body.quantifier; + itemType.link = req.body.link; itemType.save() .then(results => res.status(201).send(results)) From 670d86fbfd149163f4ea5495e3bfc5c4ef68d27f Mon Sep 17 00:00:00 2001 From: GaryB93 Date: Thu, 12 Oct 2023 18:53:50 -0500 Subject: [PATCH 5/9] update inventory material quantities and purchase records when adding --- .../bmdashboard/bmMaterialsController.js | 44 +++++++++++-------- src/models/inventoryItemMaterial.js | 2 +- 2 files changed, 27 insertions(+), 19 deletions(-) diff --git a/src/controllers/bmdashboard/bmMaterialsController.js b/src/controllers/bmdashboard/bmMaterialsController.js index 708c4d884..0f1e8a38e 100644 --- a/src/controllers/bmdashboard/bmMaterialsController.js +++ b/src/controllers/bmdashboard/bmMaterialsController.js @@ -20,14 +20,33 @@ const bmMaterialsController = function (ItemMaterial, ItemType) { }; const bmAddMaterials = async function (req, res) { + // add permission check... + const { material, requestor } = req.body; + const purchaseRecord = { + date: material.purchaseDate, + createdBy: requestor.requestorId, + poId: material.invoice, + sellerId: material.phone, + quantity: material.quantity, + unitPrice: material.unitPrice, + currency: material.currency, + subtotal: material.quantity, + tax: material.taxRate, + shipping: material.shippingFee, + }; try { - const invMaterial = await ItemMaterial.findOne({ project: material.projectId, inventoryItemType: material.material }).exec(); - if (invMaterial) { - console.log('found item material in project'); - // TODO: update inventoryMaterial with new purchase record - // and updated quantities + const result = await ItemMaterial.findOneAndUpdate( + { project: material.projectId, inventoryItemType: material.material }, + { + $inc: { stockBought: material.quantity, stockAvailable: material.quantity }, + $push: { purchaseRecord: purchaseRecord }, + }, + { returnDocument: 'after', lean: true }).exec(); + if (result) { + console.log(result); + res.status(201).send(result); } else { const itemMaterial = new ItemMaterial({ inventoryItemType: material.material, @@ -36,18 +55,7 @@ const bmMaterialsController = function (ItemMaterial, ItemType) { stockAvailable: material.quantity, usageRecord: [], updateRecord: [], - purchaseRecord: [{ - date: material.purchaseDate, - createdBy: requestor.requestorId, - poId: material.invoice, - sellerId: material.phone, - quantity: material.quantity, - unitPrice: material.unitPrice, - currency: material.currency, - subtotal: material.quantity, - tax: material.taxRate, - shipping: material.shippingFee, - }], + purchaseRecord: [purchaseRecord], }); const newItemMaterial = await itemMaterial.save(); res.status(201).send(newItemMaterial); @@ -57,7 +65,7 @@ const bmMaterialsController = function (ItemMaterial, ItemType) { } }; - return { + return { bmMaterialsList, bmAddMaterials, }; diff --git a/src/models/inventoryItemMaterial.js b/src/models/inventoryItemMaterial.js index 2ffa1fba2..09c521e4d 100644 --- a/src/models/inventoryItemMaterial.js +++ b/src/models/inventoryItemMaterial.js @@ -23,7 +23,7 @@ const InventoryItemMaterial = new Schema({ description: { type: String, required: true, maxLength: 150 }, }], purchaseRecord: [{ - date: { type: String, required: true }, + date: { type: Date, required: true, default: Date.now() }, createdBy: { type: mongoose.SchemaTypes.ObjectId, ref: 'userProfile', required: true }, poId: { type: String, required: true }, sellerId: { type: String, required: true }, From 8a634b4dfdd9339a89d8dae939925a5ac10abb74 Mon Sep 17 00:00:00 2001 From: Tim Kent Date: Fri, 10 Nov 2023 09:31:52 -0800 Subject: [PATCH 6/9] add new inventory models, invtype router and controller --- .../bmdashboard/bmInventoryTypeController.js | 19 +++++++++++++ .../bmdashboard/buildingInventoryType.js | 13 +++++++++ src/models/bmdashboard/buildingMaterial.js | 28 +++++++++++++++++++ .../bmdashboard/bmInventoryTypeRouter.js | 13 +++++++++ 4 files changed, 73 insertions(+) create mode 100644 src/controllers/bmdashboard/bmInventoryTypeController.js create mode 100644 src/models/bmdashboard/buildingInventoryType.js create mode 100644 src/models/bmdashboard/buildingMaterial.js create mode 100644 src/routes/bmdashboard/bmInventoryTypeRouter.js diff --git a/src/controllers/bmdashboard/bmInventoryTypeController.js b/src/controllers/bmdashboard/bmInventoryTypeController.js new file mode 100644 index 000000000..b9ced243e --- /dev/null +++ b/src/controllers/bmdashboard/bmInventoryTypeController.js @@ -0,0 +1,19 @@ +const bmInventoryTypeController = function (InvType) { + const fetchMaterialTypes = async (req, res) => { + try { + InvType + .find() + .exec() + .then(result => res.status(200).send(result)) + .catch(error => res.status(500).send(error)); + } catch (err) { + res.json(err); + } + }; + + return { + fetchMaterialTypes, + }; +}; + +module.exports = bmInventoryTypeController; diff --git a/src/models/bmdashboard/buildingInventoryType.js b/src/models/bmdashboard/buildingInventoryType.js new file mode 100644 index 000000000..71285fa24 --- /dev/null +++ b/src/models/bmdashboard/buildingInventoryType.js @@ -0,0 +1,13 @@ +const mongoose = require('mongoose'); + +const { Schema } = mongoose; + +const buildingInventoryType = new Schema({ + category: String, // Consumable, Material, Tool, Equipment + name: String, + description: String, + unit: String, // unit of measurement + imageUrl: String, +}); + +module.exports = mongoose.model('buildingInventoryType', buildingInventoryType, 'buildingInventoryTypes'); diff --git a/src/models/bmdashboard/buildingMaterial.js b/src/models/bmdashboard/buildingMaterial.js new file mode 100644 index 000000000..714ba4ae7 --- /dev/null +++ b/src/models/bmdashboard/buildingMaterial.js @@ -0,0 +1,28 @@ +const mongoose = require('mongoose'); + +const { Schema } = mongoose; + +const buildingMaterial = new Schema({ + itemType: { type: mongoose.SchemaTypes.ObjectId, ref: 'buildingInventoryType' }, + project: { type: mongoose.SchemaTypes.ObjectId, ref: 'buildingProject' }, + stockBought: { type: Number, default: 0 }, // total amount of item bought for use in the project + stockUsed: { type: Number, default: 0 }, // total amount of item used successfully in the project + stockWasted: { type: Number, default: 0 }, // total amount of item wasted/ruined/lost in the project + stockAvailable: { type: Number, default: 0 }, // bought - (used + wasted) + purchaseRecord: [{ + _id: false, // do not add _id field to subdocument + date: { type: Date, default: Date.now() }, + requestedBy: { type: mongoose.SchemaTypes.ObjectId, ref: 'userProfile' }, + quantity: Number, + status: { type: String, default: 'Pending' }, // Pending, Rejected, Approved + }], + updateRecord: [{ + _id: false, + date: Date, + createdBy: { type: mongoose.SchemaTypes.ObjectId, ref: 'userProfile' }, + quantityUsed: String, // '10 cubic yards' + quantityWasted: Number, + }], +}); + +module.exports = mongoose.model('buildingMaterial', buildingMaterial, 'buildingMaterials'); diff --git a/src/routes/bmdashboard/bmInventoryTypeRouter.js b/src/routes/bmdashboard/bmInventoryTypeRouter.js new file mode 100644 index 000000000..ceae439dc --- /dev/null +++ b/src/routes/bmdashboard/bmInventoryTypeRouter.js @@ -0,0 +1,13 @@ +const express = require('express'); + +const routes = function (invType) { + const inventoryTypeRouter = express.Router(); + const controller = require('../../controllers/bmdashboard/bmInventoryTypeController')(invType); + + inventoryTypeRouter.route('/invtypes/materials') + .get(controller.fetchMaterialTypes); + + return inventoryTypeRouter; +}; + +module.exports = routes; From 0fbbe6183f908f873b7c170747997954a42e4504 Mon Sep 17 00:00:00 2001 From: Tim Kent Date: Tue, 14 Nov 2023 15:22:25 -0800 Subject: [PATCH 7/9] update to routes, router, controller --- .../bmdashboard/bmMaterialsController.js | 92 ++++++++++--------- src/routes/bmdashboard/bmMaterialsRouter.js | 8 +- src/startup/routes.js | 7 +- 3 files changed, 56 insertions(+), 51 deletions(-) diff --git a/src/controllers/bmdashboard/bmMaterialsController.js b/src/controllers/bmdashboard/bmMaterialsController.js index d8bcfe7df..a2e87eec2 100644 --- a/src/controllers/bmdashboard/bmMaterialsController.js +++ b/src/controllers/bmdashboard/bmMaterialsController.js @@ -1,6 +1,9 @@ -// const mongoose = require('mongoose') +const mongoose = require('mongoose'); -const bmMaterialsController = function (ItemMaterial) { +// use in bmPurchaseMaterials auth check (see below) +// const buildingProject = require('../../models/bmdashboard/buildingProject'); + +const bmMaterialsController = function (ItemMaterial, BuildingMaterial) { const bmMaterialsList = async function _matsList(req, res) { try { ItemMaterial.find() @@ -43,57 +46,58 @@ const bmMaterialsController = function (ItemMaterial) { } }; - const bmAddMaterials = async function (req, res) { - // add permission check... - - const { material, requestor } = req.body; - const purchaseRecord = { - date: material.purchaseDate, - createdBy: requestor.requestorId, - poId: material.invoice, - sellerId: material.phone, - quantity: material.quantity, - unitPrice: material.unitPrice, - currency: material.currency, - subtotal: material.quantity, - tax: material.taxRate, - shipping: material.shippingFee, + const bmPurchaseMaterials = async function (req, res) { + const { + projectId, + matTypeId, + quantity, + requestor: { requestorId }, + } = req.body; + const newPurchaseRecord = { + quantity, + requestedBy: requestorId, }; - try { - const result = await ItemMaterial.findOneAndUpdate( - { project: material.projectId, inventoryItemType: material.material }, - { - $inc: { stockBought: material.quantity, stockAvailable: material.quantity }, - $push: { purchaseRecord }, - }, - { returnDocument: 'after', lean: true }, - ) - .exec(); - if (result) { - console.log(result); - res.status(201).send(result); - } else { - const itemMaterial = new ItemMaterial({ - inventoryItemType: material.material, - project: material.projectId, - stockBought: material.quantity, - stockAvailable: material.quantity, - usageRecord: [], - updateRecord: [], - purchaseRecord: [purchaseRecord], - }); - const newItemMaterial = await itemMaterial.save(); - res.status(201).send(newItemMaterial); + // check if requestor has permission to make purchase request + //! Note: this code is disabled until permissions are added + // TODO: uncomment this code to execute auth check + // const { buildingManager: bmId } = await buildingProject.findById(projectId, 'buildingManager').exec(); + // if (bmId !== requestorId) { + // res.status(403).send({ message: 'You are not authorized to edit this record.' }); + // return; + // } + + // check if the material is already being used in the project + // if no, add a new document to the collection + // if yes, update the existing document + const doc = await BuildingMaterial.findOne({ project: projectId, itemType: matTypeId }); + if (!doc) { + const newDoc = { + itemType: matTypeId, + project: projectId, + purchaseRecord: [newPurchaseRecord], + }; + BuildingMaterial + .create(newDoc) + .then(() => res.status(201).send()) + .catch(error => res.status(500).send(error)); + return; } + BuildingMaterial + .findOneAndUpdate( + { _id: mongoose.Types.ObjectId(doc._id) }, + { $push: { purchaseRecord: newPurchaseRecord } }, + ) + .exec() + .then(() => res.status(201).send()) + .catch(error => res.status(500).send(error)); } catch (error) { res.status(500).send(error); } }; - return { bmMaterialsList, - bmAddMaterials, + bmPurchaseMaterials, }; }; diff --git a/src/routes/bmdashboard/bmMaterialsRouter.js b/src/routes/bmdashboard/bmMaterialsRouter.js index 66dc6c985..da29c35d7 100644 --- a/src/routes/bmdashboard/bmMaterialsRouter.js +++ b/src/routes/bmdashboard/bmMaterialsRouter.js @@ -1,13 +1,11 @@ const express = require('express'); -const routes = function (itemMaterial, itemType) { +const routes = function (itemMaterial, buildingMaterial) { const materialsRouter = express.Router(); - const controller = require('../../controllers/bmdashboard/bmMaterialsController')(itemMaterial, itemType); - + const controller = require('../../controllers/bmdashboard/bmMaterialsController')(itemMaterial, buildingMaterial); materialsRouter.route('/materials') .get(controller.bmMaterialsList) - .post(controller.bmAddMaterials); - + .post(controller.bmPurchaseMaterials); return materialsRouter; }; diff --git a/src/startup/routes.js b/src/startup/routes.js index 2c8aced29..b1989698a 100644 --- a/src/startup/routes.js +++ b/src/startup/routes.js @@ -22,7 +22,8 @@ const reason = require('../models/reason'); const mouseoverText = require('../models/mouseoverText'); const inventoryItemMaterial = require('../models/inventoryItemMaterial'); const buildingProject = require('../models/bmdashboard/buildingProject'); - +const buildingInventoryType = require('../models/bmdashboard/buildingInventoryType'); +const buildingMaterial = require('../models/bmdashboard/buildingMaterial'); const userProfileRouter = require('../routes/userProfileRouter')(userProfile); const badgeRouter = require('../routes/badgeRouter')(badge); @@ -60,8 +61,9 @@ const mouseoverTextRouter = require('../routes/mouseoverTextRouter')(mouseoverTe // bm dashboard const bmLoginRouter = require('../routes/bmdashboard/bmLoginRouter')(); -const bmMaterialsRouter = require('../routes/bmdashboard/bmMaterialsRouter')(inventoryItemMaterial, inventoryItemType); +const bmMaterialsRouter = require('../routes/bmdashboard/bmMaterialsRouter')(inventoryItemMaterial, buildingMaterial); const bmProjectRouter = require('../routes/bmdashboard/bmProjectRouter')(buildingProject); +const bmInventoryTypeRouter = require('../routes/bmdashboard/bmInventoryTypeRouter')(buildingInventoryType); module.exports = function (app) { app.use('/api', forgotPwdRouter); @@ -97,4 +99,5 @@ module.exports = function (app) { app.use('/api/bm', bmLoginRouter); app.use('/api/bm', bmMaterialsRouter); app.use('/api/bm', bmProjectRouter); + app.use('/api/bm', bmInventoryTypeRouter); }; From cec78db63afed949828395476c4d73f914e6133b Mon Sep 17 00:00:00 2001 From: Tim Kent Date: Wed, 15 Nov 2023 17:04:41 -0800 Subject: [PATCH 8/9] add priority, brand fields to controller. update material schema. --- src/controllers/bmdashboard/bmMaterialsController.js | 4 ++++ src/models/bmdashboard/buildingMaterial.js | 12 +++++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/controllers/bmdashboard/bmMaterialsController.js b/src/controllers/bmdashboard/bmMaterialsController.js index a2e87eec2..a8090ebd9 100644 --- a/src/controllers/bmdashboard/bmMaterialsController.js +++ b/src/controllers/bmdashboard/bmMaterialsController.js @@ -51,10 +51,14 @@ const bmMaterialsController = function (ItemMaterial, BuildingMaterial) { projectId, matTypeId, quantity, + priority, + brand, requestor: { requestorId }, } = req.body; const newPurchaseRecord = { quantity, + priority, + brand, requestedBy: requestorId, }; try { diff --git a/src/models/bmdashboard/buildingMaterial.js b/src/models/bmdashboard/buildingMaterial.js index 714ba4ae7..4170443e0 100644 --- a/src/models/bmdashboard/buildingMaterial.js +++ b/src/models/bmdashboard/buildingMaterial.js @@ -13,15 +13,17 @@ const buildingMaterial = new Schema({ _id: false, // do not add _id field to subdocument date: { type: Date, default: Date.now() }, requestedBy: { type: mongoose.SchemaTypes.ObjectId, ref: 'userProfile' }, - quantity: Number, - status: { type: String, default: 'Pending' }, // Pending, Rejected, Approved + quantity: { type: Number, required: true }, + priority: { type: String, enum: ['Low', 'Medium', 'High'], required: true }, + brand: String, + status: { type: String, default: 'Pending', enum: ['Approved', 'Pending', 'Rejected'] }, }], updateRecord: [{ _id: false, - date: Date, + date: { type: Date, required: true }, createdBy: { type: mongoose.SchemaTypes.ObjectId, ref: 'userProfile' }, - quantityUsed: String, // '10 cubic yards' - quantityWasted: Number, + quantityUsed: { type: Number, required: true }, + quantityWasted: { type: Number, required: true }, }], }); From 7542d5c29e6f8657e59e77af12b7b4ee15391477 Mon Sep 17 00:00:00 2001 From: Tim Kent Date: Wed, 15 Nov 2023 20:25:45 -0800 Subject: [PATCH 9/9] update inv type schema --- src/models/bmdashboard/buildingInventoryType.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/models/bmdashboard/buildingInventoryType.js b/src/models/bmdashboard/buildingInventoryType.js index 71285fa24..8d2364c64 100644 --- a/src/models/bmdashboard/buildingInventoryType.js +++ b/src/models/bmdashboard/buildingInventoryType.js @@ -3,10 +3,10 @@ const mongoose = require('mongoose'); const { Schema } = mongoose; const buildingInventoryType = new Schema({ - category: String, // Consumable, Material, Tool, Equipment - name: String, - description: String, - unit: String, // unit of measurement + category: { type: String, enum: ['Consumable', 'Material', 'Tool', 'Equipment'], required: true }, + name: { type: String, required: true }, + description: { type: String, required: true }, + unit: { type: String, required: true }, // unit of measurement imageUrl: String, });