diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 142c71f91ee6b299716b7fbc987849759a88bcc7..95b45b2680f090dac3a63844deef641246423a8f 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -2353,6 +2353,12 @@ "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz", "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==" }, + "@types/raf": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@types/raf/-/raf-3.4.0.tgz", + "integrity": "sha512-taW5/WYqo36N7V39oYyHP9Ipfd5pNFvGTIQsNGj86xV88YQ7GnI30/yMfKDF7Zgin0m3e+ikX88FvImnK4RjGw==", + "optional": true + }, "@types/react": { "version": "16.9.56", "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.56.tgz", @@ -3584,6 +3590,12 @@ } } }, + "base64-arraybuffer": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.2.0.tgz", + "integrity": "sha512-7emyCsu1/xiBXgQZrscw/8KPRT44I4Yq9Pe6EGs3aPRTsWuggML1/1DTuZUuIaJPIm1FTDUVXl4x/yW8s0kQDQ==", + "optional": true + }, "base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -3624,6 +3636,39 @@ "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", "optional": true }, + "bl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.0.3.tgz", + "integrity": "sha1-/FQhoo/UImA2w7OJGmaiW8ZNIm4=", + "requires": { + "readable-stream": "~2.0.5" + }, + "dependencies": { + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" + }, + "readable-stream": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", + "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "string_decoder": "~0.10.x", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, "block-stream": { "version": "0.0.9", "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", @@ -3702,6 +3747,14 @@ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" }, + "boom": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", + "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", + "requires": { + "hoek": "2.x.x" + } + }, "bootstrap": { "version": "4.5.3", "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.5.3.tgz", @@ -3838,6 +3891,11 @@ "node-int64": "^0.4.0" } }, + "btoa": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/btoa/-/btoa-1.2.1.tgz", + "integrity": "sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g==" + }, "buffer": { "version": "4.9.2", "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", @@ -4042,6 +4100,20 @@ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001165.tgz", "integrity": "sha512-8cEsSMwXfx7lWSUMA2s08z9dIgsnR5NAqjXP23stdsU3AUWkCr/rr4s4OFtHXn5XXr6+7kam3QFVoYyXNPdJPA==" }, + "canvg": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/canvg/-/canvg-3.0.7.tgz", + "integrity": "sha512-4sq6iL5Q4VOXS3PL1BapiXIZItpxYyANVzsAKpTPS5oq4u3SKbGfUcbZh2gdLCQ3jWpG/y5wRkMlBBAJhXeiZA==", + "optional": true, + "requires": { + "@babel/runtime-corejs3": "^7.9.6", + "@types/raf": "^3.4.0", + "raf": "^3.4.1", + "rgbcolor": "^1.0.1", + "stackblur-canvas": "^2.0.0", + "svg-pathdata": "^5.0.5" + } + }, "capture-exit": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", @@ -4639,6 +4711,14 @@ "which": "^1.2.9" } }, + "cryptiles": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", + "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", + "requires": { + "boom": "2.x.x" + } + }, "crypto-browserify": { "version": "3.12.0", "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", @@ -4720,6 +4800,15 @@ } } }, + "css-line-break": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-1.1.1.tgz", + "integrity": "sha512-1feNVaM4Fyzdj4mKPIQNL2n70MmuYzAXZ1aytlROFX1JsOo070OsugwGjj7nl6jnDJWHDM8zRZswkmeYVWZJQA==", + "optional": true, + "requires": { + "base64-arraybuffer": "^0.2.0" + } + }, "css-loader": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-4.3.0.tgz", @@ -5389,6 +5478,12 @@ "domelementtype": "1" } }, + "dompurify": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.2.6.tgz", + "integrity": "sha512-7b7ZArhhH0SP6W2R9cqK6RjaU82FZ2UPM7RO8qN1b1wyvC/NY1FNWcX1Pu00fFOAnzEORtwXe4bPaClg6pUybQ==", + "optional": true + }, "domutils": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", @@ -6630,6 +6725,70 @@ } } }, + "extract-zip": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.5.0.tgz", + "integrity": "sha1-ksz22B73Cp+kwXRxFMzvbYaIpsQ=", + "requires": { + "concat-stream": "1.5.0", + "debug": "0.7.4", + "mkdirp": "0.5.0", + "yauzl": "2.4.1" + }, + "dependencies": { + "concat-stream": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.5.0.tgz", + "integrity": "sha1-U/fUPFHF5D+ByP3QMyHGMb5o1hE=", + "requires": { + "inherits": "~2.0.1", + "readable-stream": "~2.0.0", + "typedarray": "~0.0.5" + } + }, + "debug": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-0.7.4.tgz", + "integrity": "sha1-BuHqgILCyxTjmAbiLi9vdX+Srzk=" + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + }, + "mkdirp": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz", + "integrity": "sha1-HXMHam35hs2TROFecfzAWkyavxI=", + "requires": { + "minimist": "0.0.8" + } + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" + }, + "readable-stream": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", + "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "string_decoder": "~0.10.x", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", @@ -6687,6 +6846,14 @@ "bser": "2.1.1" } }, + "fd-slicer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", + "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", + "requires": { + "pend": "~1.2.0" + } + }, "figgy-pudding": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", @@ -7112,6 +7279,22 @@ "globule": "^1.0.0" } }, + "generate-function": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", + "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", + "requires": { + "is-property": "^1.0.2" + } + }, + "generate-object-property": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", + "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", + "requires": { + "is-property": "^1.0.0" + } + }, "gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -7407,6 +7590,26 @@ "minimalistic-assert": "^1.0.1" } }, + "hasha": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-2.2.0.tgz", + "integrity": "sha1-eNfL/B5tZjA/55g3NlmEUXsvbuE=", + "requires": { + "is-stream": "^1.0.1", + "pinkie-promise": "^2.0.0" + } + }, + "hawk": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", + "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", + "requires": { + "boom": "2.x.x", + "cryptiles": "2.x.x", + "hoek": "2.x.x", + "sntp": "1.x.x" + } + }, "he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", @@ -7440,6 +7643,11 @@ "minimalistic-crypto-utils": "^1.0.1" } }, + "hoek": { + "version": "2.16.3", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", + "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=" + }, "hoist-non-react-statics": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", @@ -7561,6 +7769,15 @@ } } }, + "html2canvas": { + "version": "1.0.0-rc.7", + "resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.0.0-rc.7.tgz", + "integrity": "sha512-yvPNZGejB2KOyKleZspjK/NruXVQuowu8NnV2HYG7gW7ytzl+umffbtUI62v2dCHQLDdsK6HIDtyJZ0W3neerA==", + "optional": true, + "requires": { + "css-line-break": "1.1.1" + } + }, "htmlparser2": { "version": "3.10.1", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", @@ -8177,6 +8394,23 @@ "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=" }, + "is-my-ip-valid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz", + "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==" + }, + "is-my-json-valid": { + "version": "2.20.5", + "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.20.5.tgz", + "integrity": "sha512-VTPuvvGQtxvCeghwspQu1rBgjYUT6FGxPlvFKbYuFtgc4ADsX3U5ihZOYN0qyU6u+d4X9xXb0IT5O6QpXKt87A==", + "requires": { + "generate-function": "^2.0.0", + "generate-object-property": "^1.1.0", + "is-my-ip-valid": "^1.0.0", + "jsonpointer": "^4.0.0", + "xtend": "^4.0.0" + } + }, "is-negative-zero": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", @@ -8231,6 +8465,11 @@ "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz", "integrity": "sha1-DFLlS8yjkbssSUsh6GJtczbG45c=" }, + "is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=" + }, "is-regex": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", @@ -9847,6 +10086,30 @@ } } }, + "jsonpointer": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.1.0.tgz", + "integrity": "sha512-CXcRvMyTlnR53xMcKnuMzfCA5i/nfblTnnr74CZb6C4vG39eu6w51t7nKmU5MfLfbTgGItliNyjO/ciNPDqClg==" + }, + "jspdf": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/jspdf/-/jspdf-2.2.0.tgz", + "integrity": "sha512-kz6blXdM+wQ0vWMDJsa7GW9Ya79DHQBWQL14urVsbr6mk9nsJCSqZuIgE1CPZ78i5Yih2uW4tqOTiLf5xSpT9Q==", + "requires": { + "atob": "^2.1.2", + "btoa": "^1.2.1", + "canvg": "^3.0.6", + "core-js": "^3.6.0", + "dompurify": "^2.2.0", + "html2canvas": "^1.0.0-rc.5", + "pako": "^1.0.11" + } + }, + "jspdf-autotable": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/jspdf-autotable/-/jspdf-autotable-3.5.13.tgz", + "integrity": "sha512-0oF5eHefuBjlKm60tNpPMmMS2oDNhY5U7vPkMh+s4/JZbnSjsmcUcP4j2r3k0sDvQz4ysmAi3MoOii9niJn7Og==" + }, "jsprim": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", @@ -9946,6 +10209,11 @@ "object.assign": "^4.1.1" } }, + "kew": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/kew/-/kew-0.7.0.tgz", + "integrity": "sha1-edk9LTM2PW/dKXCzNdkUGtWR15s=" + }, "killable": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", @@ -9956,6 +10224,14 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" }, + "klaw": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", + "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", + "requires": { + "graceful-fs": "^4.1.9" + } + }, "kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", @@ -10763,6 +11039,29 @@ } } }, + "node-phantom-simple": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/node-phantom-simple/-/node-phantom-simple-2.2.4.tgz", + "integrity": "sha1-T8Tv+7AvJB+1CCvU+6s5jkrstk0=", + "requires": { + "debug": "^2.2.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, "node-releases": { "version": "1.1.67", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.67.tgz", @@ -11348,11 +11647,202 @@ "sha.js": "^2.4.8" } }, + "pdf-maker": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/pdf-maker/-/pdf-maker-0.0.2.tgz", + "integrity": "sha1-3PNAtCaKBSMuhx+4cN9IvoW/5pw=", + "requires": { + "ejs": "^2.5.6", + "lodash": "^4.17.4", + "node-phantom-simple": "^2.2.4", + "phantomjs": "^2.1.7" + } + }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=" + }, "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" }, + "phantomjs": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/phantomjs/-/phantomjs-2.1.7.tgz", + "integrity": "sha1-xpEPZ5NcNyhbYRQyn8LyfV8+MTQ=", + "requires": { + "extract-zip": "~1.5.0", + "fs-extra": "~0.26.4", + "hasha": "^2.2.0", + "kew": "~0.7.0", + "progress": "~1.1.8", + "request": "~2.67.0", + "request-progress": "~2.0.1", + "which": "~1.2.2" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "assert-plus": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", + "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=" + }, + "aws-sign2": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", + "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=" + }, + "caseless": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz", + "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "form-data": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-1.0.1.tgz", + "integrity": "sha1-rjFduaSQf6BlUCMEpm13M0de43w=", + "requires": { + "async": "^2.0.1", + "combined-stream": "^1.0.5", + "mime-types": "^2.1.11" + } + }, + "fs-extra": { + "version": "0.26.7", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.26.7.tgz", + "integrity": "sha1-muH92UiXeY7at20JGM9C0MMYT6k=", + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0", + "path-is-absolute": "^1.0.0", + "rimraf": "^2.2.8" + } + }, + "har-validator": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz", + "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=", + "requires": { + "chalk": "^1.1.1", + "commander": "^2.9.0", + "is-my-json-valid": "^2.12.4", + "pinkie-promise": "^2.0.0" + } + }, + "http-signature": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", + "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", + "requires": { + "assert-plus": "^0.2.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "node-uuid": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", + "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=" + }, + "oauth-sign": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", + "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=" + }, + "progress": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", + "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=" + }, + "qs": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-5.2.1.tgz", + "integrity": "sha1-gB/uAw4LlFDWOFrcSKTMVbRK7fw=" + }, + "request": { + "version": "2.67.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.67.0.tgz", + "integrity": "sha1-ivdHgOK/EeoK6aqWXBHxGv0nJ0I=", + "requires": { + "aws-sign2": "~0.6.0", + "bl": "~1.0.0", + "caseless": "~0.11.0", + "combined-stream": "~1.0.5", + "extend": "~3.0.0", + "forever-agent": "~0.6.1", + "form-data": "~1.0.0-rc3", + "har-validator": "~2.0.2", + "hawk": "~3.1.0", + "http-signature": "~1.1.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.7", + "node-uuid": "~1.4.7", + "oauth-sign": "~0.8.0", + "qs": "~5.2.0", + "stringstream": "~0.0.4", + "tough-cookie": "~2.2.0", + "tunnel-agent": "~0.4.1" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + }, + "tough-cookie": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.2.2.tgz", + "integrity": "sha1-yDoYMPTl7wuT7yo0iOck+N4Basc=" + }, + "tunnel-agent": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", + "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=" + }, + "which": { + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz", + "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=", + "requires": { + "isexe": "^2.0.0" + } + } + } + }, "picomatch": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", @@ -13430,6 +13920,14 @@ "uuid": "^3.3.2" } }, + "request-progress": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-2.0.1.tgz", + "integrity": "sha1-XTa7V5YcZzqlt4jbyBQf3yO0Tgg=", + "requires": { + "throttleit": "^1.0.0" + } + }, "request-promise-core": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", @@ -13682,6 +14180,12 @@ "resolved": "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz", "integrity": "sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=" }, + "rgbcolor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/rgbcolor/-/rgbcolor-1.0.1.tgz", + "integrity": "sha1-1lBezbMEplldom+ktDMHMGd1lF0=", + "optional": true + }, "rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", @@ -14457,6 +14961,14 @@ } } }, + "sntp": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", + "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", + "requires": { + "hoek": "2.x.x" + } + }, "sockjs": { "version": "0.3.20", "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.20.tgz", @@ -14666,6 +15178,12 @@ } } }, + "stackblur-canvas": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/stackblur-canvas/-/stackblur-canvas-2.4.0.tgz", + "integrity": "sha512-Z+HixfgYV0ss3C342DxPwc+UvN1SYWqoz7Wsi3xEDWEnaBkSCL3Ey21gF4io+WlLm8/RIrSnCrDBIEcH4O+q5Q==", + "optional": true + }, "stackframe": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.2.0.tgz", @@ -14839,6 +15357,11 @@ } } }, + "stringstream": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.6.tgz", + "integrity": "sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA==" + }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", @@ -14947,6 +15470,12 @@ "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==" }, + "svg-pathdata": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/svg-pathdata/-/svg-pathdata-5.0.5.tgz", + "integrity": "sha512-TAAvLNSE3fEhyl/Da19JWfMAdhSXTYeviXsLSoDT1UM76ADj5ndwAPX1FKQEgB/gFMPavOy6tOqfalXKUiXrow==", + "optional": true + }, "svgo": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", @@ -15276,6 +15805,11 @@ "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==" }, + "throttleit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz", + "integrity": "sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw=" + }, "through2": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", @@ -17190,6 +17724,14 @@ } } }, + "yauzl": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz", + "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=", + "requires": { + "fd-slicer": "~1.0.1" + } + }, "yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index 59c5d4bf253d8b2cca002c5816636de13cf05cd5..6765f0af627be53b340e848008578da7d38ace22 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -14,9 +14,12 @@ "@testing-library/user-event": "^12.5.0", "bootstrap": "^4.5.3", "dotenv": "^8.2.0", + "jspdf": "^2.2.0", + "jspdf-autotable": "^3.5.13", "moment": "^2.29.1", "node-sass": "^4.14.1", "notistack": "^1.0.2", + "pdf-maker": "0.0.2", "react": "^17.0.1", "react-bootstrap": "^1.4.0", "react-dom": "^17.0.1", diff --git a/frontend/src/components/btmbuch/BuchungTabelle.js b/frontend/src/components/btmbuch/BuchungTabelle.js index 6c38f7e9e97305604a459ac83e637a22706fd814..89c2e5acaadc52c4ddfbc4a0b95600503b9b9b3f 100644 --- a/frontend/src/components/btmbuch/BuchungTabelle.js +++ b/frontend/src/components/btmbuch/BuchungTabelle.js @@ -1,326 +1,382 @@ -import React, { useState, useEffect } from "react"; -import { faEdit, faTrash, faPlus } from "@fortawesome/free-solid-svg-icons"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { Table, Button, Row, Col } from "react-bootstrap"; -import { Collapse, Checkbox } from "@material-ui/core"; -import Moment from "react-moment"; -import { useSnackbar } from "notistack"; -import { useParams } from "react-router-dom"; -import TableBody from '@material-ui/core/TableBody'; -import NeueBuchungModal from "./NeueBuchungModal"; -import UpdateBuchungModal from "../../modals/UpdateBuchungModal"; -import DeleteModal from "../../modals/DeleteModal"; -import TablePagination from '@material-ui/core/TablePagination'; - -function BuchungTabelle(props) { - let { btm } = props; - const { apoId } = useParams(); - - const [page, setPage] = React.useState(0); - const [rowsPerPage, setRowsPerPage] = React.useState(10); - - const [open, setOpen] = useState(false); - const { enqueueSnackbar } = useSnackbar(); - - const [showNewBuchungModal, setShowNewBuchungModal] = useState(false); - const [showUpdateBuchungModal, setShowUpdateBuchungModal] = useState(false); - const [showDeleteModal, setShowDeleteModal] = useState(false); - - const [lieferanten, setLieferanten] = useState([]); - const [aerzte, setAerzte] = useState([]); - const [empfaenger, setEmpfaenger] = useState([]); - const [selectedBuchung, setSelectedBuchung] = useState({}); - - const handleChangePage = (event, newPage) => { - setPage(newPage); - }; - - const handleChangeRowsPerPage = (event) => { - setRowsPerPage(+event.target.value); - setPage(0); - }; - - const loadLieferanten = () => { - fetch(`http://${process.env.REACT_APP_BACKEND_URL}/apotheke/${apoId}/lieferant`, - { - method: "GET", - headers: { - "Content-Type": "application/json", - Authorization: - "Bearer " + window.sessionStorage.getItem("edbapo-jwt"), - }, - } - ).then(response => { - if (response.status === 200) { - setLieferanten(response.json()); - } else if (response.status === 403) { - // props.history.push('/forbidden'); - } else if (response.status === 400) { - // props.history.push('/badrequest'); - } - }).catch((err) => { - //SHOW ERROR - console.log(err); - }); - - - }; - - const loadAerzte = () => { - fetch(`http://${process.env.REACT_APP_BACKEND_URL}/apotheke/${apoId}/arzt`, - { - method: "GET", - headers: { - "Content-Type": "application/json", - Authorization: - "Bearer " + window.sessionStorage.getItem("edbapo-jwt"), - }, - } - ).then(response => { - if (response.status === 200) { - setAerzte(response.json()); - } else if (response.status === 403) { - // props.history.push('/forbidden'); - } else if (response.status === 400) { - // props.history.push('/badrequest'); - } - }).catch((err) => { - //SHOW ERROR - console.log(err); - }); - - - }; - - const loadEmpfaenger = () => { - fetch(`http://${process.env.REACT_APP_BACKEND_URL}/apotheke/${apoId}/empfaenger`, - { - method: "GET", - headers: { - "Content-Type": "application/json", - Authorization: - "Bearer " + window.sessionStorage.getItem("edbapo-jwt"), - }, - } - ).then(response => { - if (response.status === 200) { - setEmpfaenger(response.json()); - } else if (response.status === 403) { - // props.history.push('/forbidden'); - } else if (response.status === 400) { - // props.history.push('/badrequest'); - } - }).catch((err) => { - //SHOW ERROR - console.log(err); - }); - - - }; - - const deleteBtm = async () => { - const response = await fetch( - `http://${process.env.REACT_APP_BACKEND_URL}/apotheke/${apoId}/btmbuchung/${selectedBuchung.id}`, - { - method: "DELETE", - headers: { - Authorization: - "Bearer " + window.sessionStorage.getItem("edbapo-jwt"), - }, - } - ).catch((err) => { - //SHOW ERROR - console.log(err); - }); - - if (response && response.status === 200) { - props.apothekeRefFunctions.updateBtmList(); - enqueueSnackbar("Buchung erfolgreich gelöscht", { - variant: "success", - autoHideDuration: 3000, - }); - } else { - //SHOW ERROR - console.log(response); - } - }; - - const update = (buchung) => { - setSelectedBuchung(buchung); - setShowUpdateBuchungModal(true); - }; - - const del = (buchung) => { - setSelectedBuchung(buchung); - setShowDeleteModal(true); - }; - - const renderEditButtons = (buchung) => { - return ( - <Row style={{ display: "block" }}> - <Button onClick={() => update(buchung)} style={{ marginLeft: "0.5em" }}> - <FontAwesomeIcon icon={faEdit} /> - </Button> - <Button onClick={() => del(buchung)} style={{ marginLeft: "0.5em" }}> - <FontAwesomeIcon icon={faTrash} /> - </Button> - </Row> - ); - }; - - const renderPruefButton = (buchung) => { - return ( - <Row> - <Checkbox checked={buchung.pruefdatum} onChange={event => sendUpdateRequest(buchung)} style={{ marginLeft: "0.5em" }} ></Checkbox> - </Row> - ); - }; - - const sendUpdateRequest = async (buchung) => { - let geprueft = buchung.pruefdatum == null; - const response = await fetch(`http://${process.env.REACT_APP_BACKEND_URL}/apotheke/${apoId}/btmbuchung/${buchung.id}?setGeprueft=${geprueft}`, { - method: "PUT", - headers: { - "Content-Type": "application/json", - Authorization: "Bearer " + window.sessionStorage.getItem("edbapo-jwt"), - body: JSON.stringify(buchung) - } - }).catch((err) => { - //SHOW ERROR - console.log(err); - }); - - if (response && response.status === 200) { - enqueueSnackbar('Buchung erfolgreich aktualisiert', { variant: 'success', autoHideDuration: 3000 }); - props.apothekeRefFunctions.updateBtmList(); - } else { - //SHOW ERROR - console.log(response); - } - }; - - useEffect(loadLieferanten, [apoId, props.history]) - useEffect(loadAerzte, [apoId, props.history]) - useEffect(loadEmpfaenger, [apoId, props.history]) - - return ( - <React.Fragment> - <NeueBuchungModal - {...props} - lieferanten={lieferanten} - aerzte={aerzte} - empfaenger={empfaenger} - buchung={selectedBuchung} - show={showNewBuchungModal} - onHide={() => setShowNewBuchungModal(false)} - /> - <UpdateBuchungModal - {...props} - lieferanten={lieferanten} - aerzte={aerzte} - empfaenger={empfaenger} - buchung={selectedBuchung} - show={showUpdateBuchungModal} - onHide={() => setShowUpdateBuchungModal(false)} - /> - - <DeleteModal - {...props} - headertext={"Betäubungsmittel-Buchung löschen"} - maintext={"Möchtest du diese Buchung wirklich löschen?"} - onSubmit={deleteBtm} - subtext={"Dieser Vorgang kann nicht rückgängig gemacht werden"} - show={showDeleteModal} - onHide={() => setShowDeleteModal(false)} - /> - - <div style={{ marginBottom: "2em" }}> - <Row - onClick={() => setOpen(!open)} - className="noselect btm-table-header-name" - > - <Col sm={3}> - <p> - {btm.btm.name} ({btm.btm.menge}) - </p> - </Col> - <Col sm={9}> - <div style={{ marginLeft: "-9em" }}> - <Button - onClick={(event) => { - event.stopPropagation(); - setShowNewBuchungModal(true); - }} - > - Neue Buchung - <FontAwesomeIcon - style={{ marginLeft: "0.4em" }} - icon={faPlus} - /> - </Button> - </div> - </Col> - </Row> - <Collapse in={open}> - <Table striped bordered hover> - <thead> - <tr> - <th>Datum</th> - <th>Lieferant / Patient</th> - <th>Arztpraxis</th> - <th>Zugang</th> - <th>Abgang</th> - <th>Rezept Nr. / Lieferschein Nr.</th> - <th>Prüfdatum</th> - <th>Prüfer Kürzel</th> - {props.aktiveRolle.toLowerCase() === "admin" || props.aktiveRolle.toLowerCase() === "pruefer" ? ( - <th>Geprüft</th> - ) : null} - {props.aktiveRolle.toLowerCase() === "admin" ? ( - <th></th> - ) : null} - </tr> - </thead> - <TableBody> - {btm.buchungen.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage).map((buchung) => ( - <tr key={buchung.id}> - <td> <Moment format="DD.MM.YYYY">{buchung.datum}</Moment> </td> - <td>{buchung.typ === "ZUGANG" - ? buchung.lieferant.name - : buchung.empfaenger.vorname + " " + buchung.empfaenger.name} - </td> - <td>{buchung.typ === "ABGANG" ? buchung.arzt.name : ""}</td> - <td>{buchung.typ === "ZUGANG" ? buchung.menge : ""}</td> - <td>{buchung.typ === "ZUGANG" ? "" : buchung.menge}</td> - <td>{buchung.typ === "ZUGANG" ? buchung.anforderungsschein : buchung.rezept}</td> - <td>{buchung.pruefdatum ? <Moment format="DD.MM.YYYY">{buchung.pruefdatum}</Moment> : ""}</td> - <td>{buchung.pruefer ? buchung.pruefer.vorname + " " + buchung.pruefer.name : ""}</td> - - {props.aktiveRolle.toLowerCase() === "admin" || props.aktiveRolle.toLowerCase() === "pruefer" ? - <th>{renderPruefButton(buchung)}</th> : null} - - {props.aktiveRolle.toLowerCase() === "admin" ? - <td style={{ textAlign: "center", verticalAlign: "middle" }} > - {renderEditButtons(buchung)} - </td> : null} - - </tr> - ))} - </TableBody> - </Table> - <TablePagination - rowsPerPageOptions={[5, 10, 15]} - component="div" - count={btm.buchungen.length} - rowsPerPage={rowsPerPage} - page={page} - onChangePage={handleChangePage} - onChangeRowsPerPage={handleChangeRowsPerPage} - /> - </Collapse> - </div> - </React.Fragment> - ); -} - -export default BuchungTabelle; +import React, { useState, useEffect } from "react"; +import { faEdit, faTrash, faPlus } from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { Table, Button, Row, Col } from "react-bootstrap"; +import { Collapse, Checkbox } from "@material-ui/core"; +import Moment from "react-moment"; +import { useSnackbar } from "notistack"; +import { useParams } from "react-router-dom"; +import TableBody from '@material-ui/core/TableBody'; +import NeueBuchungModal from "./NeueBuchungModal"; +import UpdateBuchungModal from "../../modals/UpdateBuchungModal"; +import DeleteModal from "../../modals/DeleteModal"; +import { makeStyles } from '@material-ui/core/styles'; +import TablePagination from '@material-ui/core/TablePagination'; +import jsPDF from 'jspdf' +import 'jspdf-autotable' + + +const useStyles = makeStyles({ + root: { + width: '100%', + }, + container: { + maxHeight: 440, + }, +}); + +function BuchungTabelle(props) { + let { btm } = props; + const { apoId } = useParams(); + + const classes = useStyles(); + const [page, setPage] = React.useState(0); + const [rowsPerPage, setRowsPerPage] = React.useState(10); + + const [open, setOpen] = useState(false); + const { enqueueSnackbar } = useSnackbar(); + + const [showNewBuchungModal, setShowNewBuchungModal] = useState(false); + const [showUpdateBuchungModal, setShowUpdateBuchungModal] = useState(false); + const [showDeleteModal, setShowDeleteModal] = useState(false); + + const [lieferanten, setLieferanten] = useState([]); + const [aerzte, setAerzte] = useState([]); + const [empfaenger, setEmpfaenger] = useState([]); + const [selectedBuchung, setSelectedBuchung] = useState({}); + + const handleChangePage = (event, newPage) => { + setPage(newPage); + }; + + const handleChangeRowsPerPage = (event) => { + setRowsPerPage(+event.target.value); + setPage(0); + }; + + const loadLieferanten = async () => { + const response = await fetch( + `http://${process.env.REACT_APP_BACKEND_URL}/apotheke/${props.apothekeId}/lieferant`, + { + method: "GET", + headers: { + "Content-Type": "application/json", + Authorization: + "Bearer " + window.sessionStorage.getItem("edbapo-jwt"), + }, + } + ).catch((err) => { + //SHOW ERROR + console.log(err); + }); + + if (response.status === 200) { + setLieferanten(await response.json()); + } else if (response.status === 403) { + // props.history.push('/forbidden'); + } else if (response.status === 400) { + // props.history.push('/badrequest'); + } + }; + + const loadAerzte = async () => { + const response = await fetch( + `http://${process.env.REACT_APP_BACKEND_URL}/apotheke/${props.apothekeId}/arzt`, + { + method: "GET", + headers: { + "Content-Type": "application/json", + Authorization: + "Bearer " + window.sessionStorage.getItem("edbapo-jwt"), + }, + } + ).catch((err) => { + //SHOW ERROR + console.log(err); + }); + + if (response.status === 200) { + setAerzte(await response.json()); + } else if (response.status === 403) { + // props.history.push('/forbidden'); + } else if (response.status === 400) { + // props.history.push('/badrequest'); + } + }; + + const loadEmpfaenger = async () => { + const response = await fetch( + `http://${process.env.REACT_APP_BACKEND_URL}/apotheke/${props.apothekeId}/empfaenger`, + { + method: "GET", + headers: { + "Content-Type": "application/json", + Authorization: + "Bearer " + window.sessionStorage.getItem("edbapo-jwt"), + }, + } + ).catch((err) => { + //SHOW ERROR + console.log(err); + }); + + if (response.status === 200) { + setEmpfaenger(await response.json()); + } else if (response.status === 403) { + // props.history.push('/forbidden'); + } else if (response.status === 400) { + // props.history.push('/badrequest'); + } + }; + + const deleteBtm = async () => { + const response = await fetch( + `http://${process.env.REACT_APP_BACKEND_URL}/apotheke/${apoId}/btmbuchung/${selectedBuchung.id}`, + { + method: "DELETE", + headers: { + Authorization: + "Bearer " + window.sessionStorage.getItem("edbapo-jwt"), + }, + } + ).catch((err) => { + //SHOW ERROR + console.log(err); + }); + + if (response && response.status === 200) { + props.apothekeRefFunctions.updateBtmList(); + enqueueSnackbar("Buchung erfolgreich gelöscht", { + variant: "success", + autoHideDuration: 3000, + }); + } else { + //SHOW ERROR + console.log(response); + } + }; + + const update = (buchung) => { + setSelectedBuchung(buchung); + setShowUpdateBuchungModal(true); + }; + + const del = (buchung) => { + setSelectedBuchung(buchung); + setShowDeleteModal(true); + }; + + const renderEditButtons = (buchung) => { + return ( + <Row style={{ display: "block" }}> + <Button onClick={() => update(buchung)} style={{ marginLeft: "0.5em" }}> + <FontAwesomeIcon icon={faEdit} /> + </Button> + <Button onClick={() => del(buchung)} style={{ marginLeft: "0.5em" }}> + <FontAwesomeIcon icon={faTrash} /> + </Button> + </Row> + ); + }; + + const renderPruefButton = (buchung) => { + return ( + <Row> + <Checkbox checked={buchung.pruefdatum} onChange={event => sendUpdateRequest(buchung)} style={{ marginLeft: "0.5em" }} ></Checkbox> + </Row> + ); + }; + + const sendUpdateRequest = async (buchung) => { + let geprueft = buchung.pruefdatum == null; + const response = await fetch(`http://${process.env.REACT_APP_BACKEND_URL}/apotheke/${apoId}/btmbuchung/${buchung.id}?setGeprueft=${geprueft}`, { + method: "PUT", + headers: { + "Content-Type": "application/json", + Authorization: "Bearer " + window.sessionStorage.getItem("edbapo-jwt"), + body: JSON.stringify(buchung) + } + }).catch((err) => { + //SHOW ERROR + console.log(err); + }); + + if (response && response.status === 200) { + enqueueSnackbar('Buchung erfolgreich aktualisiert', { variant: 'success', autoHideDuration: 3000 }); + props.apothekeRefFunctions.updateBtmList(); + } else { + //SHOW ERROR + console.log(response); + } + }; + + const exportPdf = () => { + const unit = "pt"; + const size = "A4"; // Use A1, A2, A3 or A4 + const orientation = "portrait"; // portrait or landscape + + const marginLeft = 40; + const doc = new jsPDF(orientation, unit, size); + + doc.setFontSize(10); + console.log('print btm liste', btm.name); + + const title = [props.btm.btm.name]; + const headers = [["Datum", "Lieferant/Patient","Arztpraxis", "Zugang", "Abgang", "Rp.Nr./L.Nr.", "Prüfdatum", "Prüfer Kürzel"]]; + + const moment = require('moment'); + + const data = btm.buchungen.map(buchung => [moment(buchung.datum).format("DD.MM.YYYY"), + buchung.typ === "ZUGANG" ? buchung.lieferant.name : buchung.empfaenger.vorname + " " + buchung.empfaenger.name, + buchung.typ === "ABGANG" ? buchung.arzt.name : "", + buchung.typ === "ZUGANG" ? buchung.menge : "", + buchung.typ === "ZUGANG" ? "" : buchung.menge, + buchung.typ === "ZUGANG" ? buchung.anforderungsschein : buchung.rezept, + buchung.pruefdatum ? moment(buchung.pruefdatum).format("DD.MM.YYYY") : "", + buchung.pruefer ? buchung.pruefer.vorname+" "+buchung.pruefer.name : "", + ]); + + let content = { + startY: 50, + head: headers, + body: data + }; + + + + doc.text(title, marginLeft, 40); + doc.autoTable(content); + doc.save("BtmListe.pdf") + + } + + useEffect(() => { + loadLieferanten(); + loadAerzte(); + loadEmpfaenger(); + }, []); + + return ( + <React.Fragment> + <NeueBuchungModal + {...props} + lieferanten={lieferanten} + aerzte={aerzte} + empfaenger={empfaenger} + buchung={selectedBuchung} + show={showNewBuchungModal} + onHide={() => setShowNewBuchungModal(false)} + /> + <UpdateBuchungModal + {...props} + lieferanten={lieferanten} + aerzte={aerzte} + empfaenger={empfaenger} + buchung={selectedBuchung} + show={showUpdateBuchungModal} + onHide={() => setShowUpdateBuchungModal(false)} + /> + + <DeleteModal + {...props} + headertext={"Betäubungsmittel-Buchung löschen"} + maintext={"Möchtest du diese Buchung wirklich löschen?"} + onSubmit={deleteBtm} + subtext={"Dieser Vorgang kann nicht rückgängig gemacht werden"} + show={showDeleteModal} + onHide={() => setShowDeleteModal(false)} + /> + + <div style={{ marginBottom: "2em" }}> + <Row + onClick={() => setOpen(!open)} + className="noselect btm-table-header-name" + > + <Col sm={3}> + <p> + {btm.btm.name} ({btm.btm.menge}) + </p> + </Col> + <Col sm={9}> + <div style={{ marginLeft: "-9em" }}> + <Button style={{ marginRight: "1em" }} onClick={exportPdf}> + PDF + </Button> + <Button + onClick={(event) => { + event.stopPropagation(); + setShowNewBuchungModal(true); + }} + > + Neue Buchung + <FontAwesomeIcon + style={{ marginLeft: "0.4em" }} + icon={faPlus} + /> + </Button> + </div> + </Col> + </Row> + <Collapse in={open}> + <Table striped bordered hover id="btm-table"> + <thead> + <tr> + <th>Datum</th> + <th>Lieferant / Patient</th> + <th>Arztpraxis</th> + <th>Zugang</th> + <th>Abgang</th> + <th>Rezept Nr. / Lieferschein Nr.</th> + <th>Prüfdatum</th> + <th>Prüfer Kürzel</th> + {props.aktiveRolle.toLowerCase() === "admin" || props.aktiveRolle.toLowerCase() === "pruefer" ? ( + <th>Geprüft</th> + ) : null} + {props.aktiveRolle.toLowerCase() === "admin" ? ( + <th></th> + ) : null} + </tr> + </thead> + <TableBody> + {btm.buchungen.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage).map((buchung) => ( + <tr key={buchung.id}> + <td> <Moment format="DD.MM.YYYY">{buchung.datum}</Moment> </td> + <td>{buchung.typ === "ZUGANG" + ? buchung.lieferant.name + : buchung.empfaenger.vorname + " " + buchung.empfaenger.name} + </td> + <td>{buchung.typ === "ABGANG" ? buchung.arzt.name : ""}</td> + <td>{buchung.typ === "ZUGANG" ? buchung.menge : ""}</td> + <td>{buchung.typ === "ZUGANG" ? "" : buchung.menge}</td> + <td>{buchung.typ === "ZUGANG" ? buchung.anforderungsschein : buchung.rezept}</td> + <td>{buchung.pruefdatum ? <Moment format="DD.MM.YYYY">{buchung.pruefdatum}</Moment> : ""}</td> + <td>{buchung.pruefer ? buchung.pruefer.vorname+" "+buchung.pruefer.name : ""}</td> + + {props.aktiveRolle.toLowerCase() === "admin" || props.aktiveRolle.toLowerCase() === "pruefer" ? + <th>{renderPruefButton(buchung)}</th> : null} + + {props.aktiveRolle.toLowerCase() === "admin" ? + <td style={{ textAlign: "center", verticalAlign: "middle" }} > + {renderEditButtons(buchung)} + </td> : null} + + </tr> + ))} + </TableBody> + </Table> + <TablePagination + rowsPerPageOptions={[5, 10, 15]} + component="div" + count={btm.buchungen.length} + rowsPerPage={rowsPerPage} + page={page} + onChangePage={handleChangePage} + onChangeRowsPerPage={handleChangeRowsPerPage} + /> + </Collapse> + </div> + </React.Fragment> + ); +} + +export default BuchungTabelle;