mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-28 22:42:11 +01:00
Compare commits
675 Commits
835-gastku
...
1.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6c04a5b3b6 | ||
|
|
d5df65ab43 | ||
|
|
195532d14b | ||
|
|
66d6ef8e40 | ||
|
|
d06512160a | ||
|
|
6f936072d0 | ||
|
|
4c67792f08 | ||
|
|
becd0a1f2c | ||
|
|
8b3213cc8c | ||
|
|
f5a614c735 | ||
|
|
bd89cfb8f1 | ||
|
|
7dbba2b5ba | ||
|
|
8c187378e0 | ||
|
|
21adae7141 | ||
|
|
64a9a457db | ||
|
|
0588612adb | ||
|
|
3bf52b7ce3 | ||
|
|
0723f80051 | ||
|
|
1eec0afa8f | ||
|
|
802b59bcd2 | ||
|
|
4d9c8c3cea | ||
|
|
bd53dcb52c | ||
|
|
608d95b77f | ||
|
|
50505f8a7b | ||
|
|
1e92e1bf20 | ||
|
|
a57109ac60 | ||
|
|
9704ecd9d2 | ||
|
|
415999bb58 | ||
|
|
6fa7f93e3d | ||
|
|
db8d209c75 | ||
|
|
92f089ccad | ||
|
|
da117e3070 | ||
|
|
acad176c8c | ||
|
|
b0a146cda3 | ||
|
|
5375862093 | ||
|
|
d6839f4884 | ||
|
|
0101ccb8f6 | ||
|
|
347a78f658 | ||
|
|
f869232f3b | ||
|
|
1758761085 | ||
|
|
1550eea5ac | ||
|
|
7e3fc0ac4d | ||
|
|
c0a475bc44 | ||
|
|
f72e9de980 | ||
|
|
51f2ec6d73 | ||
|
|
cea4dbf329 | ||
|
|
26aac3a1f5 | ||
|
|
3035175943 | ||
|
|
0c76ef6463 | ||
|
|
9e664837d9 | ||
|
|
93647dc748 | ||
|
|
89679a94b0 | ||
|
|
3be5897f5b | ||
|
|
961c69f318 | ||
|
|
865cdd8076 | ||
|
|
dba5e19b84 | ||
|
|
f4868585b5 | ||
|
|
4465bf8787 | ||
|
|
cebbd27ef6 | ||
|
|
0a9de9eaab | ||
|
|
3cdf1656d7 | ||
|
|
f85f31a46e | ||
|
|
f747b6aad7 | ||
|
|
239f940b28 | ||
|
|
b1884e4c05 | ||
|
|
6ec6d04fbc | ||
|
|
982fd1066b | ||
|
|
749e38d634 | ||
|
|
5a7d13202b | ||
|
|
52db2ba39e | ||
|
|
a8ff13dd60 | ||
|
|
078c8b74fa | ||
|
|
50b8b1e042 | ||
|
|
0a6e92075f | ||
|
|
173696f82e | ||
|
|
877a0f9f79 | ||
|
|
7b4f35caed | ||
|
|
6bee9ac8c0 | ||
|
|
c7968177e8 | ||
|
|
d8cf263bb7 | ||
|
|
85dc13771f | ||
|
|
312da5a73b | ||
|
|
23c44241ae | ||
|
|
4ab7210e26 | ||
|
|
4a8034d8fb | ||
|
|
04043e3fd8 | ||
|
|
26fd7183f7 | ||
|
|
7cfe74b84e | ||
|
|
d137d1db31 | ||
|
|
d837f90527 | ||
|
|
414328cf49 | ||
|
|
f7dddfdd80 | ||
|
|
18cc0e63ad | ||
|
|
1736fbd838 | ||
|
|
084afb6971 | ||
|
|
8a1173aaca | ||
|
|
e8c28e4728 | ||
|
|
07198b4ede | ||
|
|
2c2825a88f | ||
|
|
c70e9c4202 | ||
|
|
b19a47d044 | ||
|
|
def80dcf76 | ||
|
|
7683887387 | ||
|
|
dda86d9975 | ||
|
|
27c15fab46 | ||
|
|
5a182bf07b | ||
|
|
abf8c0b0dd | ||
|
|
0ec7e45179 | ||
|
|
a74859c2d2 | ||
|
|
dfa8e94e26 | ||
|
|
53232d4a63 | ||
|
|
b671ea0b03 | ||
|
|
92ef685474 | ||
|
|
bf25d9c716 | ||
|
|
36ae4e06b9 | ||
|
|
f9b6addafd | ||
|
|
8312942ffd | ||
|
|
8293d80004 | ||
|
|
ee365eaa1e | ||
|
|
11fa26e68a | ||
|
|
f23bb2f096 | ||
|
|
5c10d1548b | ||
|
|
4664d7d2e7 | ||
|
|
f49756f839 | ||
|
|
57aa15a710 | ||
|
|
0edd316195 | ||
|
|
a246c39be3 | ||
|
|
3d7173d50f | ||
|
|
2ed4c608a0 | ||
|
|
d4c35a255c | ||
|
|
b5b75ac967 | ||
|
|
e30d36b93a | ||
|
|
d56f3e8221 | ||
|
|
c491b47114 | ||
|
|
61ba54066c | ||
|
|
4dba96683f | ||
|
|
bb4d344737 | ||
|
|
75e6cb9d3f | ||
|
|
9b7aebd9fa | ||
|
|
63c5967b6f | ||
|
|
60b7913c7a | ||
|
|
c8a9e73b8b | ||
|
|
8a4c18df43 | ||
|
|
b15d158617 | ||
|
|
972de14e20 | ||
|
|
3332c7e23c | ||
|
|
647129bbf2 | ||
|
|
ca2f2cc24f | ||
|
|
84c68da6f6 | ||
|
|
014741e25a | ||
|
|
df4493a5c3 | ||
|
|
e59f2747b1 | ||
|
|
23c0690fd4 | ||
|
|
a508c587cb | ||
|
|
42d0bf9d99 | ||
|
|
2d4413e7c7 | ||
|
|
b8ea8ed625 | ||
|
|
602fb4fa4f | ||
|
|
e249bcca5f | ||
|
|
694779d9ff | ||
|
|
9af1bec78b | ||
|
|
3eaad281d3 | ||
|
|
808fd95783 | ||
|
|
5d4b0b684c | ||
|
|
2b5c737377 | ||
|
|
512e6fecdb | ||
|
|
9a34cb0cff | ||
|
|
7b8b3c10a6 | ||
|
|
4cab1ad4a3 | ||
|
|
e05c14a2ce | ||
|
|
68217ad2bb | ||
|
|
b86c8fc083 | ||
|
|
7bf7a0a70b | ||
|
|
6da59ab62c | ||
|
|
0a8632381d | ||
|
|
3f45c80f60 | ||
|
|
b1d7c81ee1 | ||
|
|
890e09ac69 | ||
|
|
f5e9ea81bf | ||
|
|
c97990217c | ||
|
|
7fd5eb4c8e | ||
|
|
3a4c9d7bd4 | ||
|
|
0d019d6ab7 | ||
|
|
8d0e6484b9 | ||
|
|
cfa15b59f6 | ||
|
|
fddb74ca26 | ||
|
|
d5a3fd47a7 | ||
|
|
c896d61016 | ||
|
|
5cf9eced6b | ||
|
|
749d5bba02 | ||
|
|
6f5c6fa51c | ||
|
|
d5699fdd05 | ||
|
|
395526027b | ||
|
|
a6dd070b4e | ||
|
|
7013638631 | ||
|
|
36c8d2517a | ||
|
|
a2101328e7 | ||
|
|
d96e14a154 | ||
|
|
3be12ad944 | ||
|
|
0716388141 | ||
|
|
1260a1e9f8 | ||
|
|
56ddf5b8b9 | ||
|
|
725307c022 | ||
|
|
8a94ea3d82 | ||
|
|
90d17ef359 | ||
|
|
f866db3097 | ||
|
|
7f13b79547 | ||
|
|
42d22dd514 | ||
|
|
b521e9dea0 | ||
|
|
57aa5701ad | ||
|
|
b773cb2d25 | ||
|
|
5c141d3bbe | ||
|
|
7a2a9237f7 | ||
|
|
c38c94cd36 | ||
|
|
75fb2045db | ||
|
|
1aafe81b37 | ||
|
|
ca5798e244 | ||
|
|
3458b0a642 | ||
|
|
8d905cf94d | ||
|
|
768eac723d | ||
|
|
da03e220ed | ||
|
|
1985d4df51 | ||
|
|
a28d2c05b3 | ||
|
|
7b77e8c234 | ||
|
|
cc667c13bb | ||
|
|
ca4803fda2 | ||
|
|
df058030b0 | ||
|
|
d31db9f430 | ||
|
|
6d1d7ed65c | ||
|
|
b2f3e58b59 | ||
|
|
824f3babc4 | ||
|
|
349259a3bd | ||
|
|
e2af856a24 | ||
|
|
9debb4a4e2 | ||
|
|
f68f4ae9fa | ||
|
|
c532123a2c | ||
|
|
4d196aa4eb | ||
|
|
6e76c0d48e | ||
|
|
25270474e7 | ||
|
|
97ddbac01e | ||
|
|
fd55d3a65e | ||
|
|
ca8c1b5f6b | ||
|
|
ec5f494ba5 | ||
|
|
152feb010f | ||
|
|
c93e568ea1 | ||
|
|
31b3d67974 | ||
|
|
a969ed775e | ||
|
|
3ea3f54286 | ||
|
|
c241545bd1 | ||
|
|
196a0c309a | ||
|
|
288737aed3 | ||
|
|
edc3329f5a | ||
|
|
6813eadced | ||
|
|
5a069e5fce | ||
|
|
7189cc31d1 | ||
|
|
d1570d2079 | ||
|
|
1f60ee2eb9 | ||
|
|
c9d078047e | ||
|
|
76fce84661 | ||
|
|
ecf4437cf6 | ||
|
|
c04ad8fd4d | ||
|
|
56c2b16916 | ||
|
|
e6d03dc5ea | ||
|
|
d2998d42f3 | ||
|
|
af31afac17 | ||
|
|
73fa821f19 | ||
|
|
f83e0bc88c | ||
|
|
2d1a5aad44 | ||
|
|
fdd18e656c | ||
|
|
7d2d0a1af4 | ||
|
|
77cccd225f | ||
|
|
bb591b8fca | ||
|
|
81b59440eb | ||
|
|
9809e75b33 | ||
|
|
c588ed7784 | ||
|
|
21d9b67086 | ||
|
|
774815966b | ||
|
|
f6bf2d21ee | ||
|
|
1b9f5bf0b9 | ||
|
|
39655965e8 | ||
|
|
faecc6f857 | ||
|
|
edbc5279b3 | ||
|
|
2aa7acad6a | ||
|
|
a74c05be60 | ||
|
|
038cb6c7a8 | ||
|
|
7e33832197 | ||
|
|
1e83a3efbe | ||
|
|
732bc9e4aa | ||
|
|
d05ff90031 | ||
|
|
f36050882f | ||
|
|
07bcddf7b5 | ||
|
|
efaa5d1106 | ||
|
|
2f4f8bd95c | ||
|
|
ddc92958ac | ||
|
|
c4b254b26c | ||
|
|
ce9efd3f28 | ||
|
|
e06099f1a4 | ||
|
|
3d67ebf6f1 | ||
|
|
f33bc7ee50 | ||
|
|
624eb87467 | ||
|
|
1bdbaa5c31 | ||
|
|
63d65c3679 | ||
|
|
4ef6cc7d3e | ||
|
|
7ebaf68117 | ||
|
|
0b0f0706b7 | ||
|
|
b8924fbf43 | ||
|
|
f043d9a019 | ||
|
|
038cfc6862 | ||
|
|
0e33288a2a | ||
|
|
c3682f2c05 | ||
|
|
0c5e7430f6 | ||
|
|
ae89a4e3db | ||
|
|
dffa0e3627 | ||
|
|
2d384debd6 | ||
|
|
3cc35fef03 | ||
|
|
f3c8e9024f | ||
|
|
9c175efa5f | ||
|
|
84777be5cf | ||
|
|
484ffda3ef | ||
|
|
5643da6693 | ||
|
|
5c0b057e4c | ||
|
|
6d6c3073fb | ||
|
|
fe3915be9f | ||
|
|
a1ded4ff38 | ||
|
|
2be18e4b56 | ||
|
|
91613997d3 | ||
|
|
ad9defeeb9 | ||
|
|
774ed0a30f | ||
|
|
be565cbc74 | ||
|
|
be4c91b2a7 | ||
|
|
9a3ca38b7a | ||
|
|
f3c2df64c9 | ||
|
|
3b101a9e1a | ||
|
|
e4c12f575b | ||
|
|
211fd78dc7 | ||
|
|
60971792ec | ||
|
|
77e0dad4a2 | ||
|
|
4783dfbd48 | ||
|
|
7dc22689d6 | ||
|
|
740206fd08 | ||
|
|
853e49a231 | ||
|
|
86496869c5 | ||
|
|
dfb96c735d | ||
|
|
7023635c2d | ||
|
|
90cde380d2 | ||
|
|
8c98fbb564 | ||
|
|
60a794a6ab | ||
|
|
3b23a6af7b | ||
|
|
ee4ccd9e84 | ||
|
|
4c8006c836 | ||
|
|
f4c9fe355a | ||
|
|
283803d55a | ||
|
|
a8016b0c7d | ||
|
|
bf75dc5db7 | ||
|
|
16dfcab4a7 | ||
|
|
62acbdecc5 | ||
|
|
6e2ff83336 | ||
|
|
66a2fd772a | ||
|
|
aca691fe2e | ||
|
|
9c4f2b8395 | ||
|
|
d529ed0b17 | ||
|
|
c5e73bf578 | ||
|
|
9aa9e2155b | ||
|
|
c7407c5036 | ||
|
|
7bd2e51148 | ||
|
|
8c988f0917 | ||
|
|
3b19f5c6ab | ||
|
|
79a1a5befc | ||
|
|
b2496e1c57 | ||
|
|
6a5546d0f2 | ||
|
|
c72de1f08b | ||
|
|
1ac67cf1e5 | ||
|
|
ad1cb0ff5d | ||
|
|
0270216f49 | ||
|
|
881ee9d8c7 | ||
|
|
6cd15f8eba | ||
|
|
03e4bcf760 | ||
|
|
a3c53096ad | ||
|
|
39de228eff | ||
|
|
7597832cbf | ||
|
|
cc69a0a24e | ||
|
|
29160abb97 | ||
|
|
a68d9bc906 | ||
|
|
2bf7987280 | ||
|
|
3e81c825cf | ||
|
|
342dd04452 | ||
|
|
9bc9be8538 | ||
|
|
41791981d7 | ||
|
|
3fb6cd29f7 | ||
|
|
c2d021104c | ||
|
|
4b3aedc685 | ||
|
|
0454d7e687 | ||
|
|
cfdf151b56 | ||
|
|
6cd85bcb58 | ||
|
|
be05cf7fdd | ||
|
|
e4a58baba0 | ||
|
|
1620df76b9 | ||
|
|
a1c7167e50 | ||
|
|
6e7925a18c | ||
|
|
053e28483e | ||
|
|
b5d7f084f2 | ||
|
|
1c1a6c05c2 | ||
|
|
3ebe35a0f6 | ||
|
|
bd0d9765fd | ||
|
|
b8faf2f2d6 | ||
|
|
eb280d4533 | ||
|
|
720efdb3a4 | ||
|
|
994ff7b31a | ||
|
|
cc55656b76 | ||
|
|
5f1733e147 | ||
|
|
d9c25dacf3 | ||
|
|
a762c6b1b4 | ||
|
|
570f237399 | ||
|
|
cea4d9e4fb | ||
|
|
1518c0e41b | ||
|
|
8ac66c12cb | ||
|
|
8a2df5d060 | ||
|
|
65aa27e64f | ||
|
|
6e78b4bacd | ||
|
|
b3509b510e | ||
|
|
e143067a52 | ||
|
|
b1a5e0827a | ||
|
|
ea15f1941e | ||
|
|
c7549b8594 | ||
|
|
a79e84fad8 | ||
|
|
c9d7faf9a1 | ||
|
|
d87ceb1f74 | ||
|
|
c8fa18ed29 | ||
|
|
2d5d461f02 | ||
|
|
87885cb0bd | ||
|
|
ad929324df | ||
|
|
ee2805332b | ||
|
|
c1c2f3c41f | ||
|
|
a618ff0b63 | ||
|
|
47e468b585 | ||
|
|
6729a86e02 | ||
|
|
c04f39f9df | ||
|
|
49793da5be | ||
|
|
c1b3e5f759 | ||
|
|
2a9d3419e6 | ||
|
|
b1cfa3639b | ||
|
|
891d2723c8 | ||
|
|
1b65354900 | ||
|
|
5a8c6111ff | ||
|
|
fd1e2bfd84 | ||
|
|
e388ca553e | ||
|
|
cf6fbf9799 | ||
|
|
56a2fce2b3 | ||
|
|
87397a9c1a | ||
|
|
8c2a7c0800 | ||
|
|
a177c78dda | ||
|
|
5a8b9a8c12 | ||
|
|
8859265986 | ||
|
|
eadbbff776 | ||
|
|
91541e7282 | ||
|
|
bad1a4de6a | ||
|
|
6a7cc2f5c5 | ||
|
|
fa2da7d37b | ||
|
|
442c4a7b92 | ||
|
|
ab62bc5de8 | ||
|
|
aae2039f3b | ||
|
|
607c770d7d | ||
|
|
eafff18078 | ||
|
|
66973323e9 | ||
|
|
e86c3a9355 | ||
|
|
4d2d653cfa | ||
|
|
685e401e2d | ||
|
|
6f99586bd5 | ||
|
|
918298f5fa | ||
|
|
9dd0d00cd7 | ||
|
|
c491896291 | ||
|
|
15264399d3 | ||
|
|
cb80c8d02c | ||
|
|
1b02f2a9d3 | ||
|
|
7fd7c2625b | ||
|
|
c885942690 | ||
|
|
118a987b4e | ||
|
|
6b91b232ac | ||
|
|
69556e3f06 | ||
|
|
6e435685e4 | ||
|
|
2da58b28d9 | ||
|
|
9139c5e135 | ||
|
|
b23b58925c | ||
|
|
17785bf0d4 | ||
|
|
e78c2fa8a0 | ||
|
|
ef656eef67 | ||
|
|
283f3da39d | ||
|
|
a36f0cc0a3 | ||
|
|
a2194ef191 | ||
|
|
f6f36eba23 | ||
|
|
259266d138 | ||
|
|
30eb82cca7 | ||
|
|
f87ebc2e55 | ||
|
|
23535b63aa | ||
|
|
eb80bd8447 | ||
|
|
a63fa7cebd | ||
|
|
d239ddf651 | ||
|
|
469340a305 | ||
|
|
77e771980c | ||
|
|
294712f6e0 | ||
|
|
2e6f7a828b | ||
|
|
6475f509f6 | ||
|
|
2e4ddcb958 | ||
|
|
7704a2ba97 | ||
|
|
2e3bcf3cf4 | ||
|
|
1e7ffce711 | ||
|
|
ebd0d31948 | ||
|
|
203fd91b5f | ||
|
|
386dd9263d | ||
|
|
9c779e4027 | ||
|
|
98666063ce | ||
|
|
50aa8716ae | ||
|
|
3fa8fc8fd1 | ||
|
|
407a812ce4 | ||
|
|
8ed6d60ad5 | ||
|
|
22d6cae3a6 | ||
|
|
96b9f8cf16 | ||
|
|
7647503cc6 | ||
|
|
8d3d095500 | ||
|
|
0aaf1d8f40 | ||
|
|
10cc8e75b8 | ||
|
|
2409651dc7 | ||
|
|
31a4774ba0 | ||
|
|
543cf21354 | ||
|
|
f13a3e4782 | ||
|
|
dee2f77151 | ||
|
|
72bebedd70 | ||
|
|
9c4ea77045 | ||
|
|
57be60e452 | ||
|
|
cef1fa1e6f | ||
|
|
653a0f8b51 | ||
|
|
21d91b99d5 | ||
|
|
fcaf694f0a | ||
|
|
c45344f6b2 | ||
|
|
245528a548 | ||
|
|
8a3271a3de | ||
|
|
e0115348a4 | ||
|
|
59405c41f6 | ||
|
|
f6a4e3e413 | ||
|
|
f701c7dd46 | ||
|
|
c868ccc761 | ||
|
|
d48cc25f96 | ||
|
|
9fdcc5bfad | ||
|
|
bc6e5774c6 | ||
|
|
f7d951d95e | ||
|
|
c1c51eb45c | ||
|
|
b08fab4266 | ||
|
|
7a645d3b94 | ||
|
|
fb751b0094 | ||
|
|
807928c67a | ||
|
|
b1f1fe4133 | ||
|
|
bec683c654 | ||
|
|
7885ed3207 | ||
|
|
27a3b02ae3 | ||
|
|
86817060f3 | ||
|
|
74053040bc | ||
|
|
321470797b | ||
|
|
86cde05804 | ||
|
|
d011bebba5 | ||
|
|
470c58a165 | ||
|
|
0a02bfca1d | ||
|
|
76afd571df | ||
|
|
1dbdd0b5d4 | ||
|
|
1bcbaca4bc | ||
|
|
03f77de3d7 | ||
|
|
93359a8f10 | ||
|
|
bbb476329f | ||
|
|
0c74a80c56 | ||
|
|
f588e23b7a | ||
|
|
03e46f33a7 | ||
|
|
72236cbec2 | ||
|
|
ccaefc4a03 | ||
|
|
4bdff93db9 | ||
|
|
0b706743b8 | ||
|
|
5f16f8ec64 | ||
|
|
3e6733f75b | ||
|
|
e54c842c48 | ||
|
|
2187775833 | ||
|
|
9ffe988573 | ||
|
|
a0470d24f7 | ||
|
|
c1b12297bb | ||
|
|
e96826c175 | ||
|
|
aa587de5ac | ||
|
|
47e9518353 | ||
|
|
b8c717a071 | ||
|
|
9c6e1e063c | ||
|
|
91f52b22cd | ||
|
|
f15cbbaf93 | ||
|
|
8d68647d45 | ||
|
|
6a34553c9f | ||
|
|
8df2ee5018 | ||
|
|
006a124e4b | ||
|
|
b0a42948c8 | ||
|
|
6795bc560e | ||
|
|
8c25634fd0 | ||
|
|
53d8213002 | ||
|
|
7f8b31f8f3 | ||
|
|
d8e04dd50d | ||
|
|
3f83e2c08d | ||
|
|
60c3cbc44d | ||
|
|
5d3a503d86 | ||
|
|
46f85de55c | ||
|
|
36a2770d1d | ||
|
|
fb6c69fd89 | ||
|
|
5aa9e26be7 | ||
|
|
affdf6fe05 | ||
|
|
3a571ab3f9 | ||
|
|
0bda33a327 | ||
|
|
a012599f27 | ||
|
|
e382e1a562 | ||
|
|
1fd09e5ded | ||
|
|
6930f44633 | ||
|
|
cccf7d1d70 | ||
|
|
7aa258ac9e | ||
|
|
03bb8c3484 | ||
|
|
98ccc48424 | ||
|
|
8c246803ad | ||
|
|
b0eae87a5d | ||
|
|
03e441f5af | ||
|
|
4f16bef6e3 | ||
|
|
e9061b4ef0 | ||
|
|
3e387a3390 | ||
|
|
ba7be52b85 | ||
|
|
a2c35ec67b | ||
|
|
4ab9603238 | ||
|
|
c8e22cb19c | ||
|
|
f41a7142e3 | ||
|
|
720e6c293e | ||
|
|
24c4df5b9f | ||
|
|
f23140cba5 | ||
|
|
613c928ec4 | ||
|
|
0f80935e76 | ||
|
|
ce43e0261e | ||
|
|
0dd86af01d | ||
|
|
bf8a11ea08 | ||
|
|
46cbda0357 | ||
|
|
2f42c6c8c8 | ||
|
|
923e8a1dd4 | ||
|
|
50694b1e26 | ||
|
|
1d09cf0dc2 | ||
|
|
d3e61d5ab8 | ||
|
|
4add376957 | ||
|
|
86e802f4b8 | ||
|
|
1bddf2b4f1 | ||
|
|
6b8423e5c5 | ||
|
|
3717f56665 | ||
|
|
45fca71f3b | ||
|
|
f8faffca41 | ||
|
|
93e9b232cf | ||
|
|
18df1c7a96 | ||
|
|
cdeade29d7 | ||
|
|
235023ae9f | ||
|
|
aadf5efc5e | ||
|
|
04389de476 | ||
|
|
a2da0da586 | ||
|
|
969e5d74e5 | ||
|
|
1fbbe1161b | ||
|
|
711cb2cce7 | ||
|
|
8226bd69f5 | ||
|
|
157d1f8942 | ||
|
|
e50afa3306 | ||
|
|
baa8b21a15 | ||
|
|
6ac461be61 | ||
|
|
1b46534bf0 | ||
|
|
ed59777e04 | ||
|
|
fe300effa8 | ||
|
|
489dc9a014 | ||
|
|
9c5c4b4880 | ||
|
|
3b26c27a80 | ||
|
|
e5732e70b7 | ||
|
|
91939a0fc9 | ||
|
|
91432a649b | ||
|
|
9b94d716e7 | ||
|
|
a618beb8e6 | ||
|
|
e9bef54215 |
16
.npmrc
16
.npmrc
@@ -1,13 +1,3 @@
|
||||
registry=https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel%40Local/npm/registry/
|
||||
|
||||
always-auth=true
|
||||
; Treat this auth token like a password. Do not share it with anyone, including Microsoft support. This token expires on or before 25.08.2020.
|
||||
; begin auth token
|
||||
//pkgs.dev.azure.com/hugendubel/_packaging/hugendubel%40Local/npm/registry/:username=hugendubel
|
||||
//pkgs.dev.azure.com/hugendubel/_packaging/hugendubel%40Local/npm/registry/:_password=M2JkaDdwNjIzbWVoZGlmeDU3N2Ficjc3M252NXBkaWg1M2VtaW94dXp5amwyejNkaW5yYQ==
|
||||
//pkgs.dev.azure.com/hugendubel/_packaging/hugendubel%40Local/npm/registry/:email=npm requires email to be set but doesn't use the value
|
||||
//pkgs.dev.azure.com/hugendubel/_packaging/hugendubel%40Local/npm/:username=hugendubel
|
||||
//pkgs.dev.azure.com/hugendubel/_packaging/hugendubel%40Local/npm/:_password=M2JkaDdwNjIzbWVoZGlmeDU3N2Ficjc3M252NXBkaWg1M2VtaW94dXp5amwyejNkaW5yYQ==
|
||||
//pkgs.dev.azure.com/hugendubel/_packaging/hugendubel%40Local/npm/:email=npm requires email to be set but doesn't use the value
|
||||
; end auth token
|
||||
|
||||
@isa:registry=https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel%40Local/npm/registry/
|
||||
@cmf:registry=https://pkgs.dev.azure.com/hugendubel/_packaging/hugendubel%40Local/npm/registry/
|
||||
always-auth=true
|
||||
|
||||
10
.prettierignore
Normal file
10
.prettierignore
Normal file
@@ -0,0 +1,10 @@
|
||||
# Add files here to ignore them from prettier formatting
|
||||
|
||||
/dist
|
||||
/coverage
|
||||
/helmvalues
|
||||
/apps/swagger
|
||||
/ng-swagger-gen
|
||||
|
||||
*.json
|
||||
*.yml
|
||||
5
.prettierrc.json
Normal file
5
.prettierrc.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"singleQuote": true,
|
||||
"printWidth": 140
|
||||
}
|
||||
|
||||
9
.vscode/extensions.json
vendored
Normal file
9
.vscode/extensions.json
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"recommendations": [
|
||||
"johnpapa.angular2",
|
||||
"esbenp.prettier-vscode",
|
||||
"angular.ng-template",
|
||||
"ms-vscode.vscode-typescript-tslint-plugin",
|
||||
"eg2.vscode-npm-script"
|
||||
]
|
||||
}
|
||||
@@ -1,9 +1,11 @@
|
||||
#stage 1
|
||||
FROM node:10-stretch as node
|
||||
ARG IS_PRODUCTION=false
|
||||
ARG SEMVERSION=1.0.0
|
||||
WORKDIR /app
|
||||
COPY . .
|
||||
RUN umask 0022
|
||||
RUN npm version ${SEMVERSION}
|
||||
RUN npm install --always-auth=false
|
||||
RUN if [ "${IS_PRODUCTION}" = "true" ] ; then npm run-script build-prod ; else npm run-script build ; fi
|
||||
|
||||
|
||||
4
TASKS.md
Normal file
4
TASKS.md
Normal file
@@ -0,0 +1,4 @@
|
||||
- Neue Icon Module (z.B. mit SVG sprites)
|
||||
- Breadcrumb Navigation (Neu)
|
||||
- Remissions Produkt Liste (Refactoring / Neu)
|
||||
- Angular Version (Upgrade)
|
||||
225
angular.json
225
angular.json
@@ -31,7 +31,9 @@
|
||||
"libs/ui/tsconfig.lib.json",
|
||||
"libs/ui/tsconfig.spec.json"
|
||||
],
|
||||
"exclude": ["**/node_modules/**"]
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -47,6 +49,7 @@
|
||||
"builder": "@angular-devkit/build-angular:browser",
|
||||
"options": {
|
||||
"outputPath": "dist/sales",
|
||||
"outputHashing": "all",
|
||||
"index": "apps/sales/src/index.html",
|
||||
"main": "apps/sales/src/main.ts",
|
||||
"polyfills": "apps/sales/src/polyfills.ts",
|
||||
@@ -55,11 +58,16 @@
|
||||
"apps/sales/src/favicon.ico",
|
||||
"apps/sales/src/assets",
|
||||
"apps/sales/src/manifest.webmanifest",
|
||||
"apps/sales/src/browserconfig.xml",
|
||||
"apps/sales/src/silent-refresh.html"
|
||||
],
|
||||
"styles": ["apps/sales/src/styles.scss"],
|
||||
"styles": [
|
||||
"apps/sales/src/styles.scss"
|
||||
],
|
||||
"stylePreprocessorOptions": {
|
||||
"includePaths": ["apps/sales/src/scss"]
|
||||
"includePaths": [
|
||||
"apps/sales/src/scss"
|
||||
]
|
||||
},
|
||||
"scripts": []
|
||||
},
|
||||
@@ -89,25 +97,7 @@
|
||||
],
|
||||
"serviceWorker": true
|
||||
},
|
||||
"development": {
|
||||
"optimization": true,
|
||||
"outputHashing": "all",
|
||||
"sourceMap": false,
|
||||
"extractCss": true,
|
||||
"namedChunks": false,
|
||||
"aot": true,
|
||||
"extractLicenses": true,
|
||||
"vendorChunk": false,
|
||||
"buildOptimizer": true,
|
||||
"budgets": [
|
||||
{
|
||||
"type": "initial",
|
||||
"maximumWarning": "2mb",
|
||||
"maximumError": "5mb"
|
||||
}
|
||||
],
|
||||
"serviceWorker": true
|
||||
}
|
||||
"development": {}
|
||||
}
|
||||
},
|
||||
"serve": {
|
||||
@@ -143,7 +133,14 @@
|
||||
"polyfills": "apps/sales/src/polyfills.ts",
|
||||
"tsConfig": "apps/sales/tsconfig.spec.json",
|
||||
"karmaConfig": "apps/sales/karma.conf.js",
|
||||
"styles": ["apps/sales/src/styles.scss"],
|
||||
"styles": [
|
||||
"apps/sales/src/styles.scss"
|
||||
],
|
||||
"stylePreprocessorOptions": {
|
||||
"includePaths": [
|
||||
"apps/sales/src/scss"
|
||||
]
|
||||
},
|
||||
"scripts": [],
|
||||
"assets": [
|
||||
"apps/sales/src/favicon.ico",
|
||||
@@ -159,7 +156,9 @@
|
||||
"apps/sales/tsconfig.app.json",
|
||||
"apps/sales/tsconfig.spec.json"
|
||||
],
|
||||
"exclude": ["**/node_modules/**"]
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -188,7 +187,9 @@
|
||||
"builder": "@angular-devkit/build-angular:tslint",
|
||||
"options": {
|
||||
"tsConfig": "apps/sales-e2e/tsconfig.e2e.json",
|
||||
"exclude": ["**/node_modules/**"]
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -221,7 +222,9 @@
|
||||
"libs/sso/tsconfig.lib.json",
|
||||
"libs/sso/tsconfig.spec.json"
|
||||
],
|
||||
"exclude": ["**/node_modules/**"]
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -254,7 +257,9 @@
|
||||
"apps/swagger/availability/tsconfig.lib.json",
|
||||
"apps/swagger/availability/tsconfig.spec.json"
|
||||
],
|
||||
"exclude": ["**/node_modules/**"]
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -287,7 +292,9 @@
|
||||
"apps/swagger/checkout/tsconfig.lib.json",
|
||||
"apps/swagger/checkout/tsconfig.spec.json"
|
||||
],
|
||||
"exclude": ["**/node_modules/**"]
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -320,7 +327,9 @@
|
||||
"apps/swagger/crm/tsconfig.lib.json",
|
||||
"apps/swagger/crm/tsconfig.spec.json"
|
||||
],
|
||||
"exclude": ["**/node_modules/**"]
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -353,7 +362,9 @@
|
||||
"apps/swagger/isa/tsconfig.lib.json",
|
||||
"apps/swagger/isa/tsconfig.spec.json"
|
||||
],
|
||||
"exclude": ["**/node_modules/**"]
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -386,7 +397,9 @@
|
||||
"apps/swagger/oms/tsconfig.lib.json",
|
||||
"apps/swagger/oms/tsconfig.spec.json"
|
||||
],
|
||||
"exclude": ["**/node_modules/**"]
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -419,7 +432,9 @@
|
||||
"apps/swagger/print/tsconfig.lib.json",
|
||||
"apps/swagger/print/tsconfig.spec.json"
|
||||
],
|
||||
"exclude": ["**/node_modules/**"]
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -452,7 +467,44 @@
|
||||
"apps/swagger/cat/tsconfig.lib.json",
|
||||
"apps/swagger/cat/tsconfig.spec.json"
|
||||
],
|
||||
"exclude": ["**/node_modules/**"]
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@swagger/eis": {
|
||||
"projectType": "library",
|
||||
"root": "apps/swagger/eis",
|
||||
"sourceRoot": "apps/swagger/eis/src",
|
||||
"prefix": "lib",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-ng-packagr:build",
|
||||
"options": {
|
||||
"tsConfig": "apps/swagger/eis/tsconfig.lib.json",
|
||||
"project": "apps/swagger/eis/ng-package.json"
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"builder": "@angular-devkit/build-angular:karma",
|
||||
"options": {
|
||||
"main": "apps/swagger/eis/src/test.ts",
|
||||
"tsConfig": "apps/swagger/eis/tsconfig.spec.json",
|
||||
"karmaConfig": "apps/swagger/eis/karma.conf.js"
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@angular-devkit/build-angular:tslint",
|
||||
"options": {
|
||||
"tsConfig": [
|
||||
"apps/swagger/eis/tsconfig.lib.json",
|
||||
"apps/swagger/eis/tsconfig.spec.json"
|
||||
],
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -491,7 +543,112 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@isa/remission": {
|
||||
"projectType": "library",
|
||||
"root": "apps/isa/remission",
|
||||
"sourceRoot": "apps/isa/remission/src",
|
||||
"prefix": "lib",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-ng-packagr:build",
|
||||
"options": {
|
||||
"tsConfig": "apps/isa/remission/tsconfig.lib.json",
|
||||
"project": "apps/isa/remission/ng-package.json"
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"builder": "@angular-devkit/build-angular:karma",
|
||||
"options": {
|
||||
"main": "apps/isa/remission/src/test.ts",
|
||||
"tsConfig": "apps/isa/remission/tsconfig.spec.json",
|
||||
"karmaConfig": "apps/isa/remission/karma.conf.js"
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@angular-devkit/build-angular:tslint",
|
||||
"options": {
|
||||
"tsConfig": [
|
||||
"apps/isa/remission/tsconfig.lib.json",
|
||||
"apps/isa/remission/tsconfig.spec.json"
|
||||
],
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@domain/crm": {
|
||||
"projectType": "library",
|
||||
"root": "apps/domain/crm",
|
||||
"sourceRoot": "apps/domain/crm/src",
|
||||
"prefix": "crm",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-ng-packagr:build",
|
||||
"options": {
|
||||
"tsConfig": "apps/domain/crm/tsconfig.lib.json",
|
||||
"project": "apps/domain/crm/ng-package.json"
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"builder": "@angular-devkit/build-angular:karma",
|
||||
"options": {
|
||||
"main": "apps/domain/crm/src/test.ts",
|
||||
"tsConfig": "apps/domain/crm/tsconfig.spec.json",
|
||||
"karmaConfig": "apps/domain/crm/karma.conf.js"
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@angular-devkit/build-angular:tslint",
|
||||
"options": {
|
||||
"tsConfig": [
|
||||
"apps/domain/crm/tsconfig.lib.json",
|
||||
"apps/domain/crm/tsconfig.spec.json"
|
||||
],
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@domain/checkout": {
|
||||
"projectType": "library",
|
||||
"root": "apps/domain/checkout",
|
||||
"sourceRoot": "apps/domain/checkout/src",
|
||||
"prefix": "checkout",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-ng-packagr:build",
|
||||
"options": {
|
||||
"tsConfig": "apps/domain/checkout/tsconfig.lib.json",
|
||||
"project": "apps/domain/checkout/ng-package.json"
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"builder": "@angular-devkit/build-angular:karma",
|
||||
"options": {
|
||||
"main": "apps/domain/checkout/src/test.ts",
|
||||
"tsConfig": "apps/domain/checkout/tsconfig.spec.json",
|
||||
"karmaConfig": "apps/domain/checkout/karma.conf.js"
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@angular-devkit/build-angular:tslint",
|
||||
"options": {
|
||||
"tsConfig": [
|
||||
"apps/domain/checkout/tsconfig.lib.json",
|
||||
"apps/domain/checkout/tsconfig.spec.json"
|
||||
],
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"defaultProject": "sales"
|
||||
}
|
||||
}
|
||||
25
apps/domain/checkout/README.md
Normal file
25
apps/domain/checkout/README.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# Checkout
|
||||
|
||||
This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 8.2.14.
|
||||
|
||||
## Code scaffolding
|
||||
|
||||
Run `ng generate component component-name --project checkout` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project checkout`.
|
||||
|
||||
> Note: Don't forget to add `--project checkout` or else it will be added to the default project in your `angular.json` file.
|
||||
|
||||
## Build
|
||||
|
||||
Run `ng build checkout` to build the project. The build artifacts will be stored in the `dist/` directory.
|
||||
|
||||
## Publishing
|
||||
|
||||
After building your library with `ng build checkout`, go to the dist folder `cd dist/checkout` and run `npm publish`.
|
||||
|
||||
## Running unit tests
|
||||
|
||||
Run `ng test checkout` to execute the unit tests via [Karma](https://karma-runner.github.io).
|
||||
|
||||
## Further help
|
||||
|
||||
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).
|
||||
32
apps/domain/checkout/karma.conf.js
Normal file
32
apps/domain/checkout/karma.conf.js
Normal file
@@ -0,0 +1,32 @@
|
||||
// Karma configuration file, see link for more information
|
||||
// https://karma-runner.github.io/1.0/config/configuration-file.html
|
||||
|
||||
module.exports = function (config) {
|
||||
config.set({
|
||||
basePath: '',
|
||||
frameworks: ['jasmine', '@angular-devkit/build-angular'],
|
||||
plugins: [
|
||||
require('karma-jasmine'),
|
||||
require('karma-chrome-launcher'),
|
||||
require('karma-jasmine-html-reporter'),
|
||||
require('karma-coverage-istanbul-reporter'),
|
||||
require('@angular-devkit/build-angular/plugins/karma'),
|
||||
],
|
||||
client: {
|
||||
clearContext: false, // leave Jasmine Spec Runner output visible in browser
|
||||
},
|
||||
coverageIstanbulReporter: {
|
||||
dir: require('path').join(__dirname, '../../../coverage/domain/checkout'),
|
||||
reports: ['html', 'lcovonly', 'text-summary'],
|
||||
fixWebpackSourcePaths: true,
|
||||
},
|
||||
reporters: ['progress', 'kjhtml'],
|
||||
port: 9876,
|
||||
colors: true,
|
||||
logLevel: config.LOG_INFO,
|
||||
autoWatch: true,
|
||||
browsers: ['Chrome'],
|
||||
singleRun: false,
|
||||
restartOnFileChange: true,
|
||||
});
|
||||
};
|
||||
7
apps/domain/checkout/ng-package.json
Normal file
7
apps/domain/checkout/ng-package.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"$schema": "../../../node_modules/ng-packagr/ng-package.schema.json",
|
||||
"dest": "../../../dist/domain/checkout",
|
||||
"lib": {
|
||||
"entryFile": "src/public-api.ts"
|
||||
}
|
||||
}
|
||||
8
apps/domain/checkout/package.json
Normal file
8
apps/domain/checkout/package.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "@domain/checkout",
|
||||
"version": "0.0.1",
|
||||
"peerDependencies": {
|
||||
"@angular/common": "^8.2.14",
|
||||
"@angular/core": "^8.2.14"
|
||||
}
|
||||
}
|
||||
24
apps/domain/checkout/src/lib/checkout.component.spec.ts
Normal file
24
apps/domain/checkout/src/lib/checkout.component.spec.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { CheckoutComponent } from './checkout.component';
|
||||
|
||||
describe('CheckoutComponent', () => {
|
||||
let component: CheckoutComponent;
|
||||
let fixture: ComponentFixture<CheckoutComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [CheckoutComponent],
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(CheckoutComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
16
apps/domain/checkout/src/lib/checkout.component.ts
Normal file
16
apps/domain/checkout/src/lib/checkout.component.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'checkout-checkout',
|
||||
template: `
|
||||
<p>
|
||||
checkout works!
|
||||
</p>
|
||||
`,
|
||||
styles: [],
|
||||
})
|
||||
export class CheckoutComponent implements OnInit {
|
||||
constructor() {}
|
||||
|
||||
ngOnInit() {}
|
||||
}
|
||||
9
apps/domain/checkout/src/lib/checkout.module.ts
Normal file
9
apps/domain/checkout/src/lib/checkout.module.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CheckoutComponent } from './checkout.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [CheckoutComponent],
|
||||
imports: [],
|
||||
exports: [CheckoutComponent],
|
||||
})
|
||||
export class CheckoutModule {}
|
||||
12
apps/domain/checkout/src/lib/checkout.service.spec.ts
Normal file
12
apps/domain/checkout/src/lib/checkout.service.spec.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { CheckoutService } from './checkout.service';
|
||||
|
||||
describe('CheckoutService', () => {
|
||||
beforeEach(() => TestBed.configureTestingModule({}));
|
||||
|
||||
it('should be created', () => {
|
||||
const service: CheckoutService = TestBed.get(CheckoutService);
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
||||
8
apps/domain/checkout/src/lib/checkout.service.ts
Normal file
8
apps/domain/checkout/src/lib/checkout.service.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class CheckoutService {
|
||||
constructor() {}
|
||||
}
|
||||
7
apps/domain/checkout/src/public-api.ts
Normal file
7
apps/domain/checkout/src/public-api.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
/*
|
||||
* Public API Surface of checkout
|
||||
*/
|
||||
|
||||
export * from './lib/checkout.service';
|
||||
export * from './lib/checkout.component';
|
||||
export * from './lib/checkout.module';
|
||||
15
apps/domain/checkout/src/test.ts
Normal file
15
apps/domain/checkout/src/test.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
|
||||
|
||||
import 'zone.js/dist/zone';
|
||||
import 'zone.js/dist/zone-testing';
|
||||
import { getTestBed } from '@angular/core/testing';
|
||||
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
|
||||
|
||||
declare const require: any;
|
||||
|
||||
// First, initialize the Angular testing environment.
|
||||
getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
|
||||
// Then we find all the tests.
|
||||
const context = require.context('./', true, /\.spec\.ts$/);
|
||||
// And load the modules.
|
||||
context.keys().map(context);
|
||||
26
apps/domain/checkout/tsconfig.lib.json
Normal file
26
apps/domain/checkout/tsconfig.lib.json
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"extends": "../../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../../out-tsc/lib",
|
||||
"target": "es2015",
|
||||
"declaration": true,
|
||||
"inlineSources": true,
|
||||
"types": [],
|
||||
"lib": [
|
||||
"dom",
|
||||
"es2018"
|
||||
]
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"annotateForClosureCompiler": true,
|
||||
"skipTemplateCodegen": true,
|
||||
"strictMetadataEmit": true,
|
||||
"fullTemplateTypeCheck": true,
|
||||
"strictInjectionParameters": true,
|
||||
"enableResourceInlining": true
|
||||
},
|
||||
"exclude": [
|
||||
"src/test.ts",
|
||||
"**/*.spec.ts"
|
||||
]
|
||||
}
|
||||
17
apps/domain/checkout/tsconfig.spec.json
Normal file
17
apps/domain/checkout/tsconfig.spec.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"extends": "../../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../../out-tsc/spec",
|
||||
"types": [
|
||||
"jasmine",
|
||||
"node"
|
||||
]
|
||||
},
|
||||
"files": [
|
||||
"src/test.ts"
|
||||
],
|
||||
"include": [
|
||||
"**/*.spec.ts",
|
||||
"**/*.d.ts"
|
||||
]
|
||||
}
|
||||
17
apps/domain/checkout/tslint.json
Normal file
17
apps/domain/checkout/tslint.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"extends": "../../../tslint.json",
|
||||
"rules": {
|
||||
"directive-selector": [
|
||||
true,
|
||||
"attribute",
|
||||
"checkout",
|
||||
"camelCase"
|
||||
],
|
||||
"component-selector": [
|
||||
true,
|
||||
"element",
|
||||
"checkout",
|
||||
"kebab-case"
|
||||
]
|
||||
}
|
||||
}
|
||||
25
apps/domain/crm/README.md
Normal file
25
apps/domain/crm/README.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# Crm
|
||||
|
||||
This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 8.2.14.
|
||||
|
||||
## Code scaffolding
|
||||
|
||||
Run `ng generate component component-name --project crm` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project crm`.
|
||||
|
||||
> Note: Don't forget to add `--project crm` or else it will be added to the default project in your `angular.json` file.
|
||||
|
||||
## Build
|
||||
|
||||
Run `ng build crm` to build the project. The build artifacts will be stored in the `dist/` directory.
|
||||
|
||||
## Publishing
|
||||
|
||||
After building your library with `ng build crm`, go to the dist folder `cd dist/crm` and run `npm publish`.
|
||||
|
||||
## Running unit tests
|
||||
|
||||
Run `ng test crm` to execute the unit tests via [Karma](https://karma-runner.github.io).
|
||||
|
||||
## Further help
|
||||
|
||||
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).
|
||||
32
apps/domain/crm/karma.conf.js
Normal file
32
apps/domain/crm/karma.conf.js
Normal file
@@ -0,0 +1,32 @@
|
||||
// Karma configuration file, see link for more information
|
||||
// https://karma-runner.github.io/1.0/config/configuration-file.html
|
||||
|
||||
module.exports = function (config) {
|
||||
config.set({
|
||||
basePath: '',
|
||||
frameworks: ['jasmine', '@angular-devkit/build-angular'],
|
||||
plugins: [
|
||||
require('karma-jasmine'),
|
||||
require('karma-chrome-launcher'),
|
||||
require('karma-jasmine-html-reporter'),
|
||||
require('karma-coverage-istanbul-reporter'),
|
||||
require('@angular-devkit/build-angular/plugins/karma'),
|
||||
],
|
||||
client: {
|
||||
clearContext: false, // leave Jasmine Spec Runner output visible in browser
|
||||
},
|
||||
coverageIstanbulReporter: {
|
||||
dir: require('path').join(__dirname, '../../../coverage/domain/crm'),
|
||||
reports: ['html', 'lcovonly', 'text-summary'],
|
||||
fixWebpackSourcePaths: true,
|
||||
},
|
||||
reporters: ['progress', 'kjhtml'],
|
||||
port: 9876,
|
||||
colors: true,
|
||||
logLevel: config.LOG_INFO,
|
||||
autoWatch: true,
|
||||
browsers: ['Chrome'],
|
||||
singleRun: false,
|
||||
restartOnFileChange: true,
|
||||
});
|
||||
};
|
||||
7
apps/domain/crm/ng-package.json
Normal file
7
apps/domain/crm/ng-package.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"$schema": "../../../node_modules/ng-packagr/ng-package.schema.json",
|
||||
"dest": "../../../dist/domain/crm",
|
||||
"lib": {
|
||||
"entryFile": "src/public-api.ts"
|
||||
}
|
||||
}
|
||||
8
apps/domain/crm/package.json
Normal file
8
apps/domain/crm/package.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "@domain/crm",
|
||||
"version": "0.0.1",
|
||||
"peerDependencies": {
|
||||
"@angular/common": "^8.2.14",
|
||||
"@angular/core": "^8.2.14"
|
||||
}
|
||||
}
|
||||
25
apps/domain/crm/src/lib/crm.component.spec.ts
Normal file
25
apps/domain/crm/src/lib/crm.component.spec.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { CustomerCreateComponent } from './create.component';
|
||||
|
||||
import { CrmComponent } from './crm.component';
|
||||
|
||||
describe('CrmComponent', () => {
|
||||
let component: CrmComponent;
|
||||
let fixture: ComponentFixture<CrmComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [CrmComponent],
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(CrmComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
16
apps/domain/crm/src/lib/crm.component.ts
Normal file
16
apps/domain/crm/src/lib/crm.component.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'crm-crm',
|
||||
template: `
|
||||
<p>
|
||||
crm works!
|
||||
</p>
|
||||
`,
|
||||
styles: [],
|
||||
})
|
||||
export class CrmComponent implements OnInit {
|
||||
constructor() {}
|
||||
|
||||
ngOnInit() {}
|
||||
}
|
||||
9
apps/domain/crm/src/lib/crm.module.ts
Normal file
9
apps/domain/crm/src/lib/crm.module.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CrmComponent } from './crm.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [CrmComponent],
|
||||
imports: [],
|
||||
exports: [CrmComponent],
|
||||
})
|
||||
export class CrmModule {}
|
||||
12
apps/domain/crm/src/lib/crm.service.spec.ts
Normal file
12
apps/domain/crm/src/lib/crm.service.spec.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { CrmService } from './crm.service';
|
||||
|
||||
describe('CrmService', () => {
|
||||
beforeEach(() => TestBed.configureTestingModule({}));
|
||||
|
||||
it('should be created', () => {
|
||||
const service: CrmService = TestBed.get(CrmService);
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
||||
8
apps/domain/crm/src/lib/crm.service.ts
Normal file
8
apps/domain/crm/src/lib/crm.service.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class CrmService {
|
||||
constructor() {}
|
||||
}
|
||||
7
apps/domain/crm/src/public-api.ts
Normal file
7
apps/domain/crm/src/public-api.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
/*
|
||||
* Public API Surface of crm
|
||||
*/
|
||||
|
||||
export * from './lib/crm.service';
|
||||
export * from './lib/crm.component';
|
||||
export * from './lib/crm.module';
|
||||
15
apps/domain/crm/src/test.ts
Normal file
15
apps/domain/crm/src/test.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
|
||||
|
||||
import 'zone.js/dist/zone';
|
||||
import 'zone.js/dist/zone-testing';
|
||||
import { getTestBed } from '@angular/core/testing';
|
||||
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
|
||||
|
||||
declare const require: any;
|
||||
|
||||
// First, initialize the Angular testing environment.
|
||||
getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
|
||||
// Then we find all the tests.
|
||||
const context = require.context('./', true, /\.spec\.ts$/);
|
||||
// And load the modules.
|
||||
context.keys().map(context);
|
||||
26
apps/domain/crm/tsconfig.lib.json
Normal file
26
apps/domain/crm/tsconfig.lib.json
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"extends": "../../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../../out-tsc/lib",
|
||||
"target": "es2015",
|
||||
"declaration": true,
|
||||
"inlineSources": true,
|
||||
"types": [],
|
||||
"lib": [
|
||||
"dom",
|
||||
"es2018"
|
||||
]
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"annotateForClosureCompiler": true,
|
||||
"skipTemplateCodegen": true,
|
||||
"strictMetadataEmit": true,
|
||||
"fullTemplateTypeCheck": true,
|
||||
"strictInjectionParameters": true,
|
||||
"enableResourceInlining": true
|
||||
},
|
||||
"exclude": [
|
||||
"src/test.ts",
|
||||
"**/*.spec.ts"
|
||||
]
|
||||
}
|
||||
17
apps/domain/crm/tsconfig.spec.json
Normal file
17
apps/domain/crm/tsconfig.spec.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"extends": "../../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../../out-tsc/spec",
|
||||
"types": [
|
||||
"jasmine",
|
||||
"node"
|
||||
]
|
||||
},
|
||||
"files": [
|
||||
"src/test.ts"
|
||||
],
|
||||
"include": [
|
||||
"**/*.spec.ts",
|
||||
"**/*.d.ts"
|
||||
]
|
||||
}
|
||||
17
apps/domain/crm/tslint.json
Normal file
17
apps/domain/crm/tslint.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"extends": "../../../tslint.json",
|
||||
"rules": {
|
||||
"directive-selector": [
|
||||
true,
|
||||
"attribute",
|
||||
"crm",
|
||||
"camelCase"
|
||||
],
|
||||
"component-selector": [
|
||||
true,
|
||||
"element",
|
||||
"crm",
|
||||
"kebab-case"
|
||||
]
|
||||
}
|
||||
}
|
||||
25
apps/isa/remission/README.md
Normal file
25
apps/isa/remission/README.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# Remission
|
||||
|
||||
This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 8.2.14.
|
||||
|
||||
## Code scaffolding
|
||||
|
||||
Run `ng generate component component-name --project remission` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project remission`.
|
||||
|
||||
> Note: Don't forget to add `--project remission` or else it will be added to the default project in your `angular.json` file.
|
||||
|
||||
## Build
|
||||
|
||||
Run `ng build remission` to build the project. The build artifacts will be stored in the `dist/` directory.
|
||||
|
||||
## Publishing
|
||||
|
||||
After building your library with `ng build remission`, go to the dist folder `cd dist/remission` and run `npm publish`.
|
||||
|
||||
## Running unit tests
|
||||
|
||||
Run `ng test remission` to execute the unit tests via [Karma](https://karma-runner.github.io).
|
||||
|
||||
## Further help
|
||||
|
||||
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).
|
||||
32
apps/isa/remission/karma.conf.js
Normal file
32
apps/isa/remission/karma.conf.js
Normal file
@@ -0,0 +1,32 @@
|
||||
// Karma configuration file, see link for more information
|
||||
// https://karma-runner.github.io/1.0/config/configuration-file.html
|
||||
|
||||
module.exports = function (config) {
|
||||
config.set({
|
||||
basePath: '',
|
||||
frameworks: ['jasmine', '@angular-devkit/build-angular'],
|
||||
plugins: [
|
||||
require('karma-jasmine'),
|
||||
require('karma-chrome-launcher'),
|
||||
require('karma-jasmine-html-reporter'),
|
||||
require('karma-coverage-istanbul-reporter'),
|
||||
require('@angular-devkit/build-angular/plugins/karma'),
|
||||
],
|
||||
client: {
|
||||
clearContext: false, // leave Jasmine Spec Runner output visible in browser
|
||||
},
|
||||
coverageIstanbulReporter: {
|
||||
dir: require('path').join(__dirname, '../../../coverage/isa/remission'),
|
||||
reports: ['html', 'lcovonly', 'text-summary'],
|
||||
fixWebpackSourcePaths: true,
|
||||
},
|
||||
reporters: ['progress', 'kjhtml'],
|
||||
port: 9876,
|
||||
colors: true,
|
||||
logLevel: config.LOG_INFO,
|
||||
autoWatch: true,
|
||||
browsers: ['Chrome'],
|
||||
singleRun: false,
|
||||
restartOnFileChange: true,
|
||||
});
|
||||
};
|
||||
7
apps/isa/remission/ng-package.json
Normal file
7
apps/isa/remission/ng-package.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"$schema": "../../../node_modules/ng-packagr/ng-package.schema.json",
|
||||
"dest": "../../../dist/isa/remission",
|
||||
"lib": {
|
||||
"entryFile": "src/public-api.ts"
|
||||
}
|
||||
}
|
||||
8
apps/isa/remission/package.json
Normal file
8
apps/isa/remission/package.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "@isa/remission",
|
||||
"version": "0.0.1",
|
||||
"peerDependencies": {
|
||||
"@angular/common": "^8.2.14",
|
||||
"@angular/core": "^8.2.14"
|
||||
}
|
||||
}
|
||||
3
apps/isa/remission/src/lib/generators/index.ts
Normal file
3
apps/isa/remission/src/lib/generators/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
// start:ng42.barrel
|
||||
export * from './uid-generator.service';
|
||||
// end:ng42.barrel
|
||||
@@ -0,0 +1,27 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
function* getUniqueNumber(): IterableIterator<number> {
|
||||
let timeStamp = Date.now();
|
||||
while (true) {
|
||||
yield timeStamp++;
|
||||
}
|
||||
}
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class UidGeneratorService {
|
||||
private generator = getUniqueNumber();
|
||||
|
||||
constructor() {}
|
||||
|
||||
generate(options: { type: 'string' }): string;
|
||||
generate(options: { type: 'number' }): number;
|
||||
generate(options: { type: 'string' | 'number' } = { type: 'string' }): string | number {
|
||||
const id = this.generator.next();
|
||||
|
||||
if (options.type === 'string') {
|
||||
return id.value.toString(32);
|
||||
}
|
||||
|
||||
return id.value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Mapper } from './mapper';
|
||||
|
||||
@Injectable()
|
||||
export class FeaturesToAssortmentMapping implements Mapper<{ key: string; name: string; value?: string }[], string> {
|
||||
get sourceName(): string {
|
||||
return 'Features';
|
||||
}
|
||||
|
||||
get targetName(): string {
|
||||
return 'Assortment';
|
||||
}
|
||||
|
||||
map(source: { key: string; name: string; value?: string }[]): string {
|
||||
if (!source || (!!source.length && !source.find((feat) => feat.hasOwnProperty('key')))) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return source.reduce((acc, curr) => acc + `${curr.name || ''}|${curr.key.slice(curr.key.length - 1, curr.key.length)}`, '');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Mapper } from './mapper';
|
||||
import { ItemDTO } from '@isa/catsearch-api';
|
||||
import { Product } from '../models/product';
|
||||
|
||||
@Injectable()
|
||||
export class ItemDtoToProductMapping implements Mapper<ItemDTO, Product> {
|
||||
get sourceName(): string {
|
||||
return 'ItemDTO';
|
||||
}
|
||||
|
||||
get targetName(): string {
|
||||
return 'Product';
|
||||
}
|
||||
|
||||
map(source: ItemDTO): Product {
|
||||
return {
|
||||
// tslint:disable-next-line: no-string-literal
|
||||
id: (source.ids && source.ids[0]) || source['id'],
|
||||
imageId: source.product.ean,
|
||||
contributors: source.product.contributors,
|
||||
name: source.product.name,
|
||||
format: source.product.format,
|
||||
formatDetail: source.product.formatDetail,
|
||||
ean: source.product.ean,
|
||||
productGroup: source.product.productGroup,
|
||||
productGroupName: '',
|
||||
features:
|
||||
source.features &&
|
||||
source.features.map((feature) => ({
|
||||
name: feature.value,
|
||||
key: feature.key[feature.key.length - 1],
|
||||
})),
|
||||
// tslint:disable-next-line: no-string-literal TODO update ItemDTO interface
|
||||
sourceProduct: { ...source.product, catalogProductNumber: source['id'] },
|
||||
sourcePrice:
|
||||
(source.storeAvailabilities && source.storeAvailabilities[0] && source.storeAvailabilities[0].price) ||
|
||||
(source.catalogAvailability && source.catalogAvailability.price),
|
||||
} as Product;
|
||||
}
|
||||
}
|
||||
7
apps/isa/remission/src/lib/mappings/mapper.ts
Normal file
7
apps/isa/remission/src/lib/mappings/mapper.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export abstract class Mapper<TSource = any, TTarget = any> {
|
||||
abstract get sourceName(): string;
|
||||
|
||||
abstract get targetName(): string;
|
||||
|
||||
abstract map(source: TSource): TTarget;
|
||||
}
|
||||
12
apps/isa/remission/src/lib/mappings/mapping.service.ts
Normal file
12
apps/isa/remission/src/lib/mappings/mapping.service.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { Injectable, Injector } from '@angular/core';
|
||||
import { Mapper } from './mapper';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class MappingService {
|
||||
constructor(private injector: Injector) {}
|
||||
|
||||
get<T extends Mapper>(sourceName: string, targetName: string): T {
|
||||
const mappers = this.injector.get(Mapper) as Mapper[];
|
||||
return mappers.find((f) => f.sourceName === sourceName && f.targetName === targetName) as T;
|
||||
}
|
||||
}
|
||||
28
apps/isa/remission/src/lib/mappings/product-to-price-dto.ts
Normal file
28
apps/isa/remission/src/lib/mappings/product-to-price-dto.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { PriceDTO } from '@cmf/inventory-api';
|
||||
import { Mapper } from './mapper';
|
||||
import { Product } from '../models/product';
|
||||
|
||||
@Injectable()
|
||||
export class ProductToPriceDTOMapping implements Mapper<Product, PriceDTO> {
|
||||
defaultPrice: PriceDTO = null;
|
||||
|
||||
constructor() {}
|
||||
|
||||
get sourceName(): string {
|
||||
return 'Product';
|
||||
}
|
||||
|
||||
get targetName(): string {
|
||||
return 'PriceDTO';
|
||||
}
|
||||
|
||||
map(source: Product): PriceDTO {
|
||||
if (source.sourcePrice) {
|
||||
return source.sourcePrice;
|
||||
} else {
|
||||
return this.defaultPrice;
|
||||
throw Error('Keine Preisinformationen vorhanden');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { ProductDTO } from '@cmf/inventory-api';
|
||||
import { Mapper } from './mapper';
|
||||
import { Product } from '../models/product';
|
||||
|
||||
@Injectable()
|
||||
export class ProductToProductDTOMapping implements Mapper<Product, ProductDTO> {
|
||||
constructor() {}
|
||||
|
||||
get sourceName(): string {
|
||||
return 'Product';
|
||||
}
|
||||
|
||||
get targetName(): string {
|
||||
return 'ProductDTO';
|
||||
}
|
||||
|
||||
map(source: Product): ProductDTO {
|
||||
if (source.sourceProduct) {
|
||||
return source.sourceProduct;
|
||||
} else {
|
||||
throw Error('Keine Produktinformationen vorhanden');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Mapper } from './mapper';
|
||||
import { ReceiptDTO } from '@cmf/inventory-api';
|
||||
import { ReceiptItemDtoToRemissionProductMapping } from './receipt-item-dto-to-remission-product.mapping';
|
||||
import { MappingService } from './mapping.service';
|
||||
import { ShippingDocument } from '../models/shipping-document';
|
||||
|
||||
@Injectable()
|
||||
export class ReceiptDTOToShippingDocumentMapping
|
||||
implements Mapper<ReceiptDTO, ShippingDocument> {
|
||||
constructor(private mappingService: MappingService) {}
|
||||
|
||||
get sourceName() {
|
||||
return 'ReceiptDTO';
|
||||
}
|
||||
|
||||
get targetName() {
|
||||
return 'ShippingDocument';
|
||||
}
|
||||
|
||||
map(source: ReceiptDTO): ShippingDocument {
|
||||
const productMapper = this.mappingService.get<
|
||||
ReceiptItemDtoToRemissionProductMapping
|
||||
>('ReceiptItemDTO', 'RemissionProduct');
|
||||
return {
|
||||
id: source.id,
|
||||
shippingDocumentNumber: source.receiptNumber,
|
||||
packageNumber:
|
||||
source.packages &&
|
||||
source.packages[0] &&
|
||||
source.packages[0].data &&
|
||||
source.packages[0].data.packageNumber,
|
||||
products: source.items.map((item) =>
|
||||
productMapper.map(item.data || item)
|
||||
),
|
||||
isCompleted: !!source.completed || source.status === 4 ? true : false,
|
||||
isDeleted: source.status === 4,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
import { Mapper } from './mapper';
|
||||
import { ReceiptItemDTO } from '@cmf/inventory-api';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { RemissionProduct } from '../models/remission-product';
|
||||
|
||||
@Injectable()
|
||||
export class ReceiptItemDtoToRemissionProductMapping implements Mapper<ReceiptItemDTO, RemissionProduct> {
|
||||
get sourceName() {
|
||||
return 'ReceiptItemDTO';
|
||||
}
|
||||
|
||||
get targetName() {
|
||||
return 'RemissionProduct';
|
||||
}
|
||||
|
||||
map(source: ReceiptItemDTO): RemissionProduct {
|
||||
return {
|
||||
id: source.id,
|
||||
imageId: source.product && source.product.ean,
|
||||
contributors: source.product && source.product.contributors,
|
||||
name: source.product && source.product.name,
|
||||
format: source.product && source.product.format,
|
||||
formatDetail: source.product && source.product.formatDetail,
|
||||
ean: source.product && source.product.ean,
|
||||
price: source.price && source.price.value.value,
|
||||
currency: source.price && source.price.value.currency,
|
||||
productGroup: source.product && source.product.productGroup,
|
||||
productGroupName: '',
|
||||
inStock: null,
|
||||
remainingQuantity: null,
|
||||
remissionQuantity: source.quantity,
|
||||
placementType: 'Leistung',
|
||||
remissionReason: '',
|
||||
edition: source.product && source.product.volume,
|
||||
features: [],
|
||||
} as RemissionProduct;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { ReturnItemDTO } from '@cmf/inventory-api';
|
||||
import { Mapper } from './mapper';
|
||||
import { RemissionProduct } from '../models/remission-product';
|
||||
|
||||
@Injectable()
|
||||
export class ReturnItemDtoToRemissionProductMapping implements Mapper<ReturnItemDTO, RemissionProduct> {
|
||||
get sourceName(): string {
|
||||
return 'ReturnItemDTO';
|
||||
}
|
||||
|
||||
get targetName(): string {
|
||||
return 'RemissionProduct';
|
||||
}
|
||||
|
||||
private getFeatures(assortment: string) {
|
||||
const featuresString = assortment && assortment.split('|');
|
||||
|
||||
let features = [];
|
||||
if (featuresString) {
|
||||
features = featuresString.slice(1, featuresString.length).map((str, index) => {
|
||||
return {
|
||||
[str.split(';')[0]]: assortment.split('|')[index].split(';')[1] || assortment.split('|')[index],
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
const uniqueKeys = Array.from(new Set(features.map((feature) => Object.keys(feature)).reduce((acc, curr) => acc.concat(curr), [])));
|
||||
|
||||
const result = uniqueKeys.map((key) => {
|
||||
return {
|
||||
[key]: features
|
||||
.map((feature) => {
|
||||
if (feature.hasOwnProperty(key)) {
|
||||
return feature[key];
|
||||
}
|
||||
})
|
||||
.filter((f) => !!f)
|
||||
.join(', ')
|
||||
.toString()
|
||||
.trim(),
|
||||
};
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
map(source: ReturnItemDTO): RemissionProduct {
|
||||
return {
|
||||
id: source.id,
|
||||
imageId: source.product.ean,
|
||||
contributors: source.product.contributors,
|
||||
name: source.product.name,
|
||||
format: source.product.format,
|
||||
formatDetail: source.product.formatDetail,
|
||||
ean: source.product.ean,
|
||||
price: source.retailPrice.value.value,
|
||||
currency: source.retailPrice.value.currency,
|
||||
productGroup: source.product.productGroup,
|
||||
productGroupName: '',
|
||||
inStock: null, // info retrieved separately
|
||||
remissionQuantity: source.predefinedReturnQuantity,
|
||||
remainingQuantity: source.remainingQuantityInStock,
|
||||
placementType: source.placementType,
|
||||
remissionReason: source.returnReason,
|
||||
edition: source.product.volume,
|
||||
isManuallyAdded: source.source && source.source === 'manually-added' ? true : false,
|
||||
catalogProductNumber: source.product.catalogProductNumber,
|
||||
features: this.getFeatures(source.assortment), // assortment (semicolon separiert ohne 'SO') z.B. "Wirtschaft|B"
|
||||
isResidual: source.descendantOf && source.descendantOf.enabled ? true : false || !!source.impediment,
|
||||
} as RemissionProduct;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
import { ReturnSuggestionDTO } from '@cmf/inventory-api';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Mapper } from './mapper';
|
||||
import { RemissionProduct } from '../models/remission-product';
|
||||
|
||||
@Injectable()
|
||||
export class ReturnSuggestionDtoToRemissionProductMapping implements Mapper<ReturnSuggestionDTO, RemissionProduct> {
|
||||
get sourceName(): string {
|
||||
return 'ReturnSuggestionDTO';
|
||||
}
|
||||
|
||||
get targetName(): string {
|
||||
return 'RemissionProduct';
|
||||
}
|
||||
|
||||
map(source: ReturnSuggestionDTO): RemissionProduct {
|
||||
return {
|
||||
id: source.id,
|
||||
imageId: source.product.ean,
|
||||
contributors: source.product.contributors,
|
||||
name: source.product.name,
|
||||
format: source.product.format,
|
||||
formatDetail: source.product.formatDetail,
|
||||
ean: source.product.ean,
|
||||
price: source.retailPrice.value.value,
|
||||
currency: source.retailPrice.value.currency,
|
||||
productGroup: source.product.productGroup,
|
||||
productGroupName: '',
|
||||
inStock: 0,
|
||||
remissionQuantity: source.returnItem && source.returnItem.data.predefinedReturnQuantity,
|
||||
remainingQuantity: 0,
|
||||
placementType: source.placementType,
|
||||
remissionReason: source.returnReason,
|
||||
edition: source.product.volume,
|
||||
catalogProductNumber: source.product.catalogProductNumber,
|
||||
features: [],
|
||||
isResidual:
|
||||
!!source.impediment ||
|
||||
// tslint:disable-next-line: no-string-literal
|
||||
(source['descendantOf'] && !!source['descendantOf'].enabled),
|
||||
} as RemissionProduct;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { SupplierDTO } from '@cmf/inventory-api';
|
||||
import { RemissionSupplier } from '../models';
|
||||
import { Mapper } from './mapper';
|
||||
|
||||
@Injectable()
|
||||
export class SupplierDtoToRemissionSupplier implements Mapper<SupplierDTO, RemissionSupplier> {
|
||||
get sourceName(): string {
|
||||
return 'SupplierDTO';
|
||||
}
|
||||
|
||||
get targetName(): string {
|
||||
return 'RemissionSupplier';
|
||||
}
|
||||
|
||||
map(source: SupplierDTO): RemissionSupplier {
|
||||
return {
|
||||
name: source.name || '',
|
||||
supplierNumber: source.supplierNumber || '',
|
||||
id: source.id,
|
||||
};
|
||||
}
|
||||
}
|
||||
53
apps/isa/remission/src/lib/mock/data/product.ts
Normal file
53
apps/isa/remission/src/lib/mock/data/product.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import { createRandomId } from '../util';
|
||||
import { VATType } from '@cmf/trade-api';
|
||||
import { Product } from '../../models/product';
|
||||
|
||||
export const product: Product = {
|
||||
id: createRandomId(),
|
||||
imageId: '9783836270236',
|
||||
contributors: 'Sascha Kersken',
|
||||
name: 'Remission für Fortgeschrittene',
|
||||
format: 'HC',
|
||||
formatDetail: 'Buch (Kartoniert, Paperback)',
|
||||
ean: '2638489561882',
|
||||
productGroup: '111',
|
||||
productGroupName: 'Krimi/Spannung',
|
||||
features: [
|
||||
{
|
||||
key: 'SOB',
|
||||
name: 'Basissortiment',
|
||||
},
|
||||
{
|
||||
key: 'SOE',
|
||||
name: 'Extrasortiment',
|
||||
},
|
||||
],
|
||||
sourcePrice: {
|
||||
value: {
|
||||
value: 100,
|
||||
currency: 'EUR',
|
||||
currencySymbol: '€',
|
||||
},
|
||||
vat: {
|
||||
inPercent: 7,
|
||||
vatType: VATType.MediumRate,
|
||||
},
|
||||
},
|
||||
sourceProduct: {
|
||||
name: 'Remission für Fortgeschrittene',
|
||||
ean: '2638489561882',
|
||||
contributors: 'Sascha Kersken',
|
||||
supplierProductNumber: '123ABC',
|
||||
catalogProductNumber: '123XYZ',
|
||||
manufacturer: 'Hugendubel',
|
||||
format: 'HC',
|
||||
formatDetail: 'Buch (Kartoniert, Paperback)',
|
||||
},
|
||||
};
|
||||
|
||||
export function removeSourcePriceAndProductFromProduct(prod: Product): Partial<Product> {
|
||||
delete prod.sourcePrice;
|
||||
delete prod.sourceProduct;
|
||||
|
||||
return prod;
|
||||
}
|
||||
16
apps/isa/remission/src/lib/mock/data/remission-capacities.ts
Normal file
16
apps/isa/remission/src/lib/mock/data/remission-capacities.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { CapacityType } from '../../models/capacity-type';
|
||||
|
||||
export const remissionCapacities: CapacityType[] = [
|
||||
{
|
||||
name: 'Leistunsgplätze',
|
||||
available: 100,
|
||||
utilized: Math.floor(Math.random() * 100),
|
||||
label: 'Titel',
|
||||
},
|
||||
{
|
||||
name: 'Stapelplätze',
|
||||
available: 100,
|
||||
utilized: Math.floor(Math.random() * 100),
|
||||
label: 'Exemplaren',
|
||||
},
|
||||
];
|
||||
88
apps/isa/remission/src/lib/mock/data/remission-filter.ts
Normal file
88
apps/isa/remission/src/lib/mock/data/remission-filter.ts
Normal file
@@ -0,0 +1,88 @@
|
||||
import { remissionTargets } from './remission-targets';
|
||||
import { remissionSources } from './remission-sources';
|
||||
import { Filter } from '../../models/filter';
|
||||
import { RemissionFilter } from '../../models/remission-filter';
|
||||
|
||||
export const filter: Filter[] = [
|
||||
{
|
||||
id: 'ce9ee0be',
|
||||
name: 'Aktionen',
|
||||
options: [
|
||||
{
|
||||
id: '6e99',
|
||||
name: 'Weihnachtsaktion',
|
||||
},
|
||||
{ id: 'a6a0', name: 'Osteraktion' },
|
||||
{ id: '035d', name: 'Herbstaktion' },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: '421228ce',
|
||||
name: 'Abteilung & Warengruppe',
|
||||
options: [
|
||||
{
|
||||
id: 'a7zd70',
|
||||
name: 'Romane',
|
||||
options: [
|
||||
{
|
||||
id: '111',
|
||||
name: 'Romane HC',
|
||||
},
|
||||
{
|
||||
id: '112',
|
||||
name: 'Romane TB',
|
||||
},
|
||||
|
||||
{
|
||||
id: '113',
|
||||
name: 'Historische Romane HC',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'ah55wm',
|
||||
name: 'Krimi',
|
||||
options: [
|
||||
{
|
||||
id: '120',
|
||||
name: 'Krimi HC',
|
||||
},
|
||||
{
|
||||
id: '121',
|
||||
name: 'Krimi TB',
|
||||
},
|
||||
|
||||
{
|
||||
id: '122',
|
||||
name: 'Krimi allgemein',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
export const filterUeberlauf: Filter[] = [
|
||||
{
|
||||
id: 'bi1uc0az',
|
||||
name: 'Abteilung',
|
||||
options: [
|
||||
{
|
||||
id: '6e99',
|
||||
name: 'DVD',
|
||||
},
|
||||
{ id: 'a6a0', name: 'Hörbuch' },
|
||||
{ id: '035d', name: 'Kinderwelt' },
|
||||
{ id: '6t78', name: 'Bewusster Leben' },
|
||||
{ id: '2k49', name: 'Bewusster Leben' },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
export const remissionFilter: RemissionFilter = {
|
||||
filter: {},
|
||||
skip: 0,
|
||||
take: 25,
|
||||
target: remissionTargets[1],
|
||||
source: remissionSources[0],
|
||||
};
|
||||
@@ -0,0 +1,3 @@
|
||||
import { RemissionPlacementType } from '../../types/remission-placement-types';
|
||||
|
||||
export const remissionPlacementTypes: RemissionPlacementType[] = ['Stapel', 'Leistung'];
|
||||
18
apps/isa/remission/src/lib/mock/data/remission-printers.ts
Normal file
18
apps/isa/remission/src/lib/mock/data/remission-printers.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { Printer } from '../../models/printer';
|
||||
|
||||
export const printers: Printer[] = [
|
||||
{
|
||||
enabled: true,
|
||||
key: '\\DBHPSS8301.dbh.localETI_HILBLE',
|
||||
value: 'SE Label-Drucker',
|
||||
selected: true,
|
||||
description: 'Label-Drucker in der SE',
|
||||
},
|
||||
{
|
||||
enabled: true,
|
||||
key: '\\dbhpss8301.dbh.localkkm_se_igel_01',
|
||||
value: 'SE Label-Drucker über IGEL',
|
||||
selected: false,
|
||||
description: 'Label-Drucker in der SE, am IGEL angeschlossen',
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,22 @@
|
||||
import { RemissionProcess } from '../../models/remission-process';
|
||||
import { remissionCapacities } from './remission-capacities';
|
||||
import { createRandomStringId, createRandomId } from '../util';
|
||||
import { remissionFilter } from './remission-filter';
|
||||
import { ShippingDocument } from '../../models';
|
||||
|
||||
export const remissionProcessTemplateMock: RemissionProcess = {
|
||||
id: createRandomId(),
|
||||
returnGroup: createRandomId(),
|
||||
stockId: createRandomId(),
|
||||
capacities: remissionCapacities,
|
||||
filter: remissionFilter,
|
||||
};
|
||||
|
||||
export const remissionProcessTemplates: RemissionProcess[] = [remissionProcessTemplateMock];
|
||||
|
||||
export function createRemissionProcessFromTemplate(remission: RemissionProcess): RemissionProcess {
|
||||
const shippingDocuments = [{ id: createRandomId(), shippingDocumentNumber: createRandomStringId(), products: [] } as ShippingDocument];
|
||||
const remissionId = createRandomId();
|
||||
|
||||
return { ...remission, externalId: remissionId, shippingDocuments };
|
||||
}
|
||||
490
apps/isa/remission/src/lib/mock/data/remission-products.ts
Normal file
490
apps/isa/remission/src/lib/mock/data/remission-products.ts
Normal file
@@ -0,0 +1,490 @@
|
||||
import { createRandomId } from '../util';
|
||||
import { RemissionProduct } from '../../models/remission-product';
|
||||
|
||||
export const remissionProducts: RemissionProduct[] = [
|
||||
{
|
||||
id: createRandomId(),
|
||||
imageId: '9783864906466',
|
||||
contributors: 'Max Mustermann',
|
||||
name: 'Remission für Dummies',
|
||||
format: 'HC',
|
||||
formatDetail: 'Buch (Gebunden)',
|
||||
ean: '6294261363805',
|
||||
price: 38.9,
|
||||
currency: 'EUR',
|
||||
productGroup: '121',
|
||||
productGroupName: 'Krimi/Spannung',
|
||||
inStock: 40,
|
||||
remissionQuantity: 25,
|
||||
remainingQuantity: 15,
|
||||
placementType: 'Stapel',
|
||||
remissionReason: 'Kulanz',
|
||||
edition: '1.',
|
||||
features: [
|
||||
{
|
||||
key: 'SOB',
|
||||
name: 'Basissortiment',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: createRandomId(),
|
||||
imageId: '9783836270236',
|
||||
contributors: 'Sascha Kersken',
|
||||
name: 'Remission für Fortgeschrittene',
|
||||
format: 'HC',
|
||||
formatDetail: 'Buch (Kartoniert, Paperback)',
|
||||
ean: '2638489561882',
|
||||
price: 10,
|
||||
currency: 'EUR',
|
||||
productGroup: '111',
|
||||
productGroupName: 'Krimi/Spannung',
|
||||
inStock: 10,
|
||||
remissionQuantity: 9,
|
||||
remainingQuantity: 1,
|
||||
placementType: 'Leistung',
|
||||
remissionReason: 'Falschlieferung',
|
||||
edition: '1.',
|
||||
features: [
|
||||
{
|
||||
key: 'SOB',
|
||||
name: 'Basissortiment',
|
||||
},
|
||||
{
|
||||
key: 'SOE',
|
||||
name: 'Extrasortiment',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: createRandomId(),
|
||||
imageId: '9783836270236',
|
||||
contributors: 'Hugen Dubel',
|
||||
name: 'So werden Sie zum Remissions-Experten',
|
||||
format: 'TB',
|
||||
formatDetail: 'Taschenbuch',
|
||||
ean: '4638419565833',
|
||||
price: 15.29,
|
||||
currency: 'EUR',
|
||||
productGroup: '133',
|
||||
productGroupName: 'Esoterik',
|
||||
inStock: 100,
|
||||
remissionQuantity: 1,
|
||||
remainingQuantity: 99,
|
||||
placementType: 'Leistung',
|
||||
remissionReason: 'Herstellerfehler',
|
||||
edition: '3.',
|
||||
features: [
|
||||
{
|
||||
key: 'SOB',
|
||||
name: 'Basissortiment',
|
||||
},
|
||||
{
|
||||
key: 'SOZ',
|
||||
name: 'Zentralsortiment',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: createRandomId(),
|
||||
imageId: '9783836270236',
|
||||
contributors: 'Pötzsch, Oliver',
|
||||
name: 'Der Spielmann',
|
||||
format: 'TB',
|
||||
formatDetail: 'Taschenbuch',
|
||||
ean: '4169898411136',
|
||||
price: 5.99,
|
||||
currency: 'EUR',
|
||||
productGroup: '935',
|
||||
productGroupName: 'Fantasie',
|
||||
inStock: 2,
|
||||
remissionQuantity: 1,
|
||||
remainingQuantity: 1,
|
||||
placementType: 'Leistung',
|
||||
remissionReason: 'Herstellerfehler',
|
||||
edition: '1.',
|
||||
features: [
|
||||
{
|
||||
key: 'SOB',
|
||||
name: 'Basissortiment',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: createRandomId(),
|
||||
imageId: '9783836270236',
|
||||
contributors: 'Homann, Eberhard, Homann, Klaudia',
|
||||
name: 'Individualreiseführer mit Extra-Reisekarte und Karten-Download',
|
||||
format: 'HC',
|
||||
formatDetail: 'Buch (Kartoniert, Paperback)',
|
||||
ean: '9723831038123',
|
||||
price: 19.95,
|
||||
currency: 'EUR',
|
||||
productGroup: '112',
|
||||
productGroupName: 'Krimi',
|
||||
inStock: 5,
|
||||
remissionQuantity: 5,
|
||||
remainingQuantity: 0,
|
||||
placementType: 'Leistung',
|
||||
remissionReason: 'Herstellerfehler',
|
||||
edition: '',
|
||||
features: [
|
||||
{
|
||||
key: 'SOB',
|
||||
name: 'Basissortiment',
|
||||
},
|
||||
{
|
||||
key: 'SOE',
|
||||
name: 'Extrasortiment',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: createRandomId(),
|
||||
imageId: '9783836270236',
|
||||
contributors: 'Blümm, Florian',
|
||||
name: 'Mit wenig Geld um die Welt',
|
||||
format: 'TB',
|
||||
formatDetail: 'Taschenbuch',
|
||||
ean: '6169892433336',
|
||||
price: 7,
|
||||
currency: 'EUR',
|
||||
productGroup: '312',
|
||||
productGroupName: 'Abenteuer/Reise',
|
||||
inStock: 45,
|
||||
remissionQuantity: 3,
|
||||
remainingQuantity: 42,
|
||||
placementType: 'Leistung',
|
||||
remissionReason: 'Kulanz',
|
||||
edition: '1.',
|
||||
features: [
|
||||
{
|
||||
key: 'SOB',
|
||||
name: 'Basissortiment',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: createRandomId(),
|
||||
imageId: '9783836270236',
|
||||
contributors: 'Murakami, Haruki, Gräfe, Ursula',
|
||||
name: 'Wovon ich rede, wenn ich vom Laufen rede',
|
||||
format: 'TB',
|
||||
formatDetail: 'Taschenbuch (Kartoniert, Paperback)',
|
||||
ean: '4642419565833',
|
||||
price: 11.49,
|
||||
currency: 'EUR',
|
||||
productGroup: '112',
|
||||
productGroupName: 'Krimi',
|
||||
inStock: 250,
|
||||
remissionQuantity: 10,
|
||||
remainingQuantity: 240,
|
||||
placementType: 'Leistung',
|
||||
remissionReason: 'Herstellerfehler',
|
||||
edition: '2.',
|
||||
features: [
|
||||
{
|
||||
key: 'SOB',
|
||||
name: 'Basissortiment',
|
||||
},
|
||||
{
|
||||
key: 'SOZ',
|
||||
name: 'Zentralsortiment',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: createRandomId(),
|
||||
imageId: '9783836270236',
|
||||
contributors: 'McKeown, Patrick',
|
||||
name: 'Erfolgsfaktor Sauerstoff',
|
||||
format: 'EB',
|
||||
formatDetail: 'E-Book (E-Book)',
|
||||
ean: '4638419765833',
|
||||
price: 15.99,
|
||||
currency: 'EUR',
|
||||
productGroup: '973',
|
||||
productGroupName: 'Wissenschaft',
|
||||
inStock: 12,
|
||||
remissionQuantity: 8,
|
||||
remainingQuantity: 4,
|
||||
placementType: 'Stapel',
|
||||
remissionReason: 'Kulanz',
|
||||
edition: '1.',
|
||||
features: [
|
||||
{
|
||||
key: 'SOB',
|
||||
name: 'Basissortiment',
|
||||
},
|
||||
{
|
||||
key: 'SOZ',
|
||||
name: 'Zentralsortiment',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: createRandomId(),
|
||||
imageId: '9783864906466',
|
||||
contributors: 'Lobrecht, Felix',
|
||||
name: 'Sonne und Beton',
|
||||
format: 'HC',
|
||||
formatDetail: 'Buch (Gebunden)',
|
||||
ean: '6294261363805',
|
||||
price: 3.9,
|
||||
currency: 'EUR',
|
||||
productGroup: '112',
|
||||
productGroupName: 'Krimi/Spannung',
|
||||
inStock: 33,
|
||||
remissionQuantity: 11,
|
||||
remainingQuantity: 22,
|
||||
placementType: 'Stapel',
|
||||
remissionReason: 'Kulanz',
|
||||
edition: '4.',
|
||||
features: [
|
||||
{
|
||||
key: 'SOB',
|
||||
name: 'Basissortiment',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: createRandomId(),
|
||||
imageId: '9783836270236',
|
||||
contributors: 'Dorléans, Marie',
|
||||
name: 'Auf leisen Sohlen durch die Nacht',
|
||||
format: 'TB',
|
||||
formatDetail: 'Taschenbuch',
|
||||
ean: '4638529565833',
|
||||
price: 15.29,
|
||||
currency: 'EUR',
|
||||
productGroup: '133',
|
||||
productGroupName: 'Esoterik',
|
||||
inStock: 100,
|
||||
remissionQuantity: 1,
|
||||
remainingQuantity: 99,
|
||||
placementType: 'Leistung',
|
||||
remissionReason: 'Herstellerfehler',
|
||||
edition: '6.',
|
||||
features: [
|
||||
{
|
||||
key: 'SOB',
|
||||
name: 'Basissortiment',
|
||||
},
|
||||
{
|
||||
key: 'SOZ',
|
||||
name: 'Zentralsortiment',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: createRandomId(),
|
||||
imageId: '9783864906466',
|
||||
contributors: 'May, Sabine',
|
||||
name: 'ADAC Reiseführer Algarve',
|
||||
format: 'HC',
|
||||
formatDetail: 'Buch (Gebunden)',
|
||||
ean: '6294261363305',
|
||||
price: 6.95,
|
||||
currency: 'EUR',
|
||||
productGroup: '312',
|
||||
productGroupName: 'Abenteuer/Reise',
|
||||
inStock: 30,
|
||||
remissionQuantity: 10,
|
||||
remainingQuantity: 20,
|
||||
placementType: 'Stapel',
|
||||
remissionReason: 'Kulanz',
|
||||
edition: '1.',
|
||||
features: [
|
||||
{
|
||||
key: 'SOB',
|
||||
name: 'Basissortiment',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: createRandomId(),
|
||||
imageId: '9783864906466',
|
||||
contributors: 'Schützsack, Lara',
|
||||
name: 'Sonne, Moon und Sterne',
|
||||
format: 'HC',
|
||||
formatDetail: 'Buch (Gebunden)',
|
||||
ean: '6374261363305',
|
||||
price: 6.95,
|
||||
currency: 'EUR',
|
||||
productGroup: '312',
|
||||
productGroupName: 'Abenteuer/Reise',
|
||||
inStock: 30,
|
||||
remissionQuantity: 10,
|
||||
remainingQuantity: 20,
|
||||
placementType: 'Stapel',
|
||||
remissionReason: 'Kulanz',
|
||||
edition: '2.',
|
||||
features: [
|
||||
{
|
||||
key: 'SOB',
|
||||
name: 'Basissortiment',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: createRandomId(),
|
||||
imageId: '9783864906466',
|
||||
contributors: 'Taleb, Nassim Nicholas',
|
||||
name: 'Skin in the Game',
|
||||
format: 'HC',
|
||||
formatDetail: 'Buch (Kartoniert, Paperback)',
|
||||
ean: '6294266323805',
|
||||
price: 14.49,
|
||||
currency: 'EUR',
|
||||
productGroup: '112',
|
||||
productGroupName: 'Krimi/Spannung',
|
||||
inStock: 10,
|
||||
remissionQuantity: 3,
|
||||
remainingQuantity: 7,
|
||||
placementType: 'Stapel',
|
||||
remissionReason: 'Herstellerfehler',
|
||||
edition: '4.',
|
||||
features: [
|
||||
{
|
||||
key: 'SOB',
|
||||
name: 'Basissortiment',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: createRandomId(),
|
||||
imageId: '9783864906466',
|
||||
contributors: 'Gehrmann, Markus Don Alfred',
|
||||
name: 'Fraktale',
|
||||
format: 'HC',
|
||||
formatDetail: 'Buch (Kartoniert, Paperback)',
|
||||
ean: '6294261363805',
|
||||
price: 208.99,
|
||||
currency: 'EUR',
|
||||
productGroup: '111',
|
||||
productGroupName: 'Krimi/Spannung',
|
||||
inStock: 2,
|
||||
remissionQuantity: 2,
|
||||
remainingQuantity: 0,
|
||||
placementType: 'Stapel',
|
||||
remissionReason: 'Herstellerfehler',
|
||||
edition: '1.',
|
||||
features: [
|
||||
{
|
||||
key: 'SOB',
|
||||
name: 'Basissortiment',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: createRandomId(),
|
||||
imageId: '9783864906466',
|
||||
contributors: 'Fowler, Martin',
|
||||
name: 'Refactoring',
|
||||
format: 'EB',
|
||||
formatDetail: 'E-Book (E-Book)',
|
||||
ean: '3214231363805',
|
||||
price: 42,
|
||||
currency: 'EUR',
|
||||
productGroup: '113',
|
||||
productGroupName: 'Krimi/Spannung',
|
||||
inStock: 3,
|
||||
remissionQuantity: 2,
|
||||
remainingQuantity: 1,
|
||||
placementType: 'Stapel',
|
||||
remissionReason: 'Herstellerfehler',
|
||||
edition: '10.',
|
||||
features: [
|
||||
{
|
||||
key: 'SOB',
|
||||
name: 'Basissortiment',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: createRandomId(),
|
||||
imageId: '9783836270236',
|
||||
contributors: 'Frankl, Viktor E.',
|
||||
name: "Man's Search for Meaning",
|
||||
format: 'TB',
|
||||
formatDetail: 'Taschenbuch (Kartoniert, Paperback)',
|
||||
ean: '7638229565833',
|
||||
price: 12.9,
|
||||
currency: 'EUR',
|
||||
productGroup: '133',
|
||||
productGroupName: 'Esoterik',
|
||||
inStock: 5,
|
||||
remissionQuantity: 1,
|
||||
remainingQuantity: 4,
|
||||
placementType: 'Leistung',
|
||||
remissionReason: 'Herstellerfehler',
|
||||
edition: '6.',
|
||||
features: [
|
||||
{
|
||||
key: 'SOB',
|
||||
name: 'Basissortiment',
|
||||
},
|
||||
{
|
||||
key: 'SOZ',
|
||||
name: 'Zentralsortiment',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: createRandomId(),
|
||||
imageId: '9783864906466',
|
||||
contributors: 'Heinemeyer, Christoph',
|
||||
name: 'Brandsicherheit durch Konstruktion und Stahlsortenwahl',
|
||||
format: 'EB',
|
||||
formatDetail: 'E-Book (E-Book)',
|
||||
ean: '4212431233805',
|
||||
price: 16.99,
|
||||
currency: 'EUR',
|
||||
productGroup: '113',
|
||||
productGroupName: 'Krimi/Spannung',
|
||||
inStock: 49,
|
||||
remissionQuantity: 4,
|
||||
remainingQuantity: 45,
|
||||
placementType: 'Stapel',
|
||||
remissionReason: 'Herstellerfehler',
|
||||
edition: '1.',
|
||||
features: [
|
||||
{
|
||||
key: 'SOB',
|
||||
name: 'Basissortiment',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: createRandomId(),
|
||||
imageId: '9783864906466',
|
||||
contributors: 'Heinemeyer, Elfriede; Ottenjann, Helmut',
|
||||
name: 'Alte Bauernmöbel aus dem nordwestlichen Niedersachsen',
|
||||
format: 'EB',
|
||||
formatDetail: 'E-Book (E-Book)',
|
||||
ean: '4212477733805',
|
||||
price: 16.99,
|
||||
currency: 'EUR',
|
||||
productGroup: '113',
|
||||
productGroupName: 'Krimi/Spannung',
|
||||
inStock: 28,
|
||||
remissionQuantity: 14,
|
||||
remainingQuantity: 14,
|
||||
placementType: 'Stapel',
|
||||
remissionReason: 'Herstellerfehler',
|
||||
edition: '1.',
|
||||
features: [
|
||||
{
|
||||
key: 'SOB',
|
||||
name: 'Basissortiment',
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
export function createRemissionProduct(product: Partial<RemissionProduct>): RemissionProduct {
|
||||
const baseProduct = remissionProducts[0];
|
||||
const newProduct = { ...baseProduct, ...product };
|
||||
|
||||
return newProduct;
|
||||
}
|
||||
11
apps/isa/remission/src/lib/mock/data/remission-reasons.ts
Normal file
11
apps/isa/remission/src/lib/mock/data/remission-reasons.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
export const remissionReasons = [
|
||||
'Beschädigtes Exemplar',
|
||||
'Kulanz',
|
||||
'Falschlieferung',
|
||||
'Zu spät geliefert',
|
||||
'Alte oder falsche Auflage geliefert',
|
||||
'Herstellerfehler',
|
||||
'LFA',
|
||||
'Veranstaltungsüberhang',
|
||||
'Anderer Remigrund',
|
||||
];
|
||||
@@ -0,0 +1,3 @@
|
||||
import { RemissionSourceType } from '../../types/remission-source.type';
|
||||
|
||||
export const remissionSources: RemissionSourceType[] = ['zentral', 'ueberlauf'];
|
||||
14
apps/isa/remission/src/lib/mock/data/remission-targets.ts
Normal file
14
apps/isa/remission/src/lib/mock/data/remission-targets.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { RemissionSupplier } from '../../models/remission-supplier';
|
||||
|
||||
export const remissionTargets: RemissionSupplier[] = [
|
||||
{
|
||||
id: 123,
|
||||
name: 'Libri',
|
||||
supplierNumber: 'abc-yyz',
|
||||
},
|
||||
{
|
||||
id: 456,
|
||||
name: 'Blank',
|
||||
supplierNumber: '123-890',
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,9 @@
|
||||
import { createRandomStringId, createRandomId } from '../util';
|
||||
import { ShippingDocument } from '../../models/shipping-document';
|
||||
|
||||
export const shippingDocument: ShippingDocument = {
|
||||
id: createRandomId(),
|
||||
shippingDocumentNumber: createRandomStringId(),
|
||||
products: [],
|
||||
isCompleted: false,
|
||||
};
|
||||
4
apps/isa/remission/src/lib/mock/index.ts
Normal file
4
apps/isa/remission/src/lib/mock/index.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
// start:ng42.barrel
|
||||
export * from './mock-remission.service';
|
||||
export * from './util';
|
||||
// end:ng42.barrel
|
||||
629
apps/isa/remission/src/lib/mock/mock-remission.service.ts
Normal file
629
apps/isa/remission/src/lib/mock/mock-remission.service.ts
Normal file
@@ -0,0 +1,629 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import {
|
||||
Observable,
|
||||
of,
|
||||
BehaviorSubject,
|
||||
Subject,
|
||||
merge,
|
||||
combineLatest,
|
||||
} from 'rxjs';
|
||||
import { delay, distinctUntilChanged, map } from 'rxjs/operators';
|
||||
import { createRandomStringId, createRandomId } from './util';
|
||||
import {
|
||||
product,
|
||||
removeSourcePriceAndProductFromProduct,
|
||||
} from './data/product';
|
||||
import { RemissionService } from '../services/remission.service';
|
||||
import { RemissionProcess } from '../models/remission-process';
|
||||
import { RemissionProduct } from '../models/remission-product';
|
||||
import {
|
||||
remissionProducts,
|
||||
createRemissionProduct,
|
||||
} from './data/remission-products';
|
||||
import { remissionProcessTemplateMock } from './data/remission-process-template';
|
||||
import { ShippingDocument } from '../models/shipping-document';
|
||||
import { shippingDocument } from './data/shipping-document';
|
||||
import { RemissionFilter } from '../models/remission-filter';
|
||||
import { Printer } from '../models/printer';
|
||||
import { printers } from './data/remission-printers';
|
||||
import { Product } from '../models/product';
|
||||
import { RemissionSourceType } from '../types/remission-source.type';
|
||||
import { Filter } from '../models/filter';
|
||||
import { filterUeberlauf, filter } from './data/remission-filter';
|
||||
import { RemissionPlacementType } from '../types/remission-placement-types';
|
||||
import { remissionPlacementTypes } from './data/remission-placement-types';
|
||||
import { remissionReasons } from './data/remission-reasons';
|
||||
import { RemissionSupplier } from '../models/remission-supplier';
|
||||
import { remissionTargets } from './data/remission-targets';
|
||||
import { remissionSources } from './data/remission-sources';
|
||||
import { ActionResult, CapacityType } from '../models';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class MockRemissionService extends RemissionService {
|
||||
private delayInMs = 100;
|
||||
private remissionSubjectStore = new Map<
|
||||
number,
|
||||
BehaviorSubject<RemissionProcess>
|
||||
>();
|
||||
private remissionSubjectIdRef = new Map<number, number>();
|
||||
|
||||
private reloadProductsSubject = new Subject();
|
||||
private productSubject = new BehaviorSubject<RemissionProduct[]>(
|
||||
remissionProducts
|
||||
);
|
||||
|
||||
private getRemissionFromStore = (
|
||||
remissionProcessId: number
|
||||
): BehaviorSubject<RemissionProcess> => {
|
||||
const remission =
|
||||
this.remissionSubjectStore.get(remissionProcessId) ||
|
||||
this.remissionSubjectStore.get(
|
||||
this.remissionSubjectIdRef.get(remissionProcessId)
|
||||
);
|
||||
|
||||
return remission;
|
||||
};
|
||||
|
||||
private saveRemissionInStore = (
|
||||
remissionProcessId: number,
|
||||
remissionSubject: BehaviorSubject<RemissionProcess>
|
||||
) => {
|
||||
this.remissionSubjectStore.set(remissionProcessId, remissionSubject);
|
||||
};
|
||||
|
||||
createProcess(source?: RemissionProcess): Observable<RemissionProcess> {
|
||||
const process = { ...remissionProcessTemplateMock, ...source };
|
||||
const processSubject = new BehaviorSubject<RemissionProcess>(process);
|
||||
|
||||
this.saveRemissionInStore(process.id, processSubject);
|
||||
|
||||
return processSubject.pipe(distinctUntilChanged(), delay(this.delayInMs));
|
||||
}
|
||||
|
||||
getRemissionProducts(params: {
|
||||
remissionProcessId: number;
|
||||
}): Observable<{
|
||||
skip?: number;
|
||||
take?: number;
|
||||
hits?: number;
|
||||
items: RemissionProduct[];
|
||||
completed: boolean;
|
||||
}> {
|
||||
const processSubject = this.getRemissionFromStore(
|
||||
params.remissionProcessId
|
||||
);
|
||||
|
||||
if (!processSubject) {
|
||||
throw new Error('Prozess nicht gefunden');
|
||||
}
|
||||
|
||||
const process$ = merge(
|
||||
processSubject,
|
||||
this.reloadProductsSubject.pipe(map((_) => processSubject.value))
|
||||
);
|
||||
|
||||
const products$ = this.productSubject.asObservable();
|
||||
|
||||
return combineLatest(process$, products$).pipe(
|
||||
map(([process, products]) => {
|
||||
// tslint:disable-next-line: no-shadowed-variable
|
||||
const filter = process.filter;
|
||||
|
||||
const result: {
|
||||
skip?: number;
|
||||
take?: number;
|
||||
hits?: number;
|
||||
items: RemissionProduct[];
|
||||
completed: boolean;
|
||||
} = {
|
||||
skip: filter.skip,
|
||||
take: filter.take,
|
||||
hits: 0,
|
||||
items: [...products],
|
||||
completed: false,
|
||||
};
|
||||
|
||||
const productGroupFilter = filter.filter['421228ce'] || [];
|
||||
|
||||
if (productGroupFilter.length > 0) {
|
||||
result.items = result.items.filter((product) =>
|
||||
productGroupFilter.some((s) => product.productGroup === s)
|
||||
);
|
||||
}
|
||||
|
||||
const actionFilter = filter.filter['ce9ee0be'] || [];
|
||||
|
||||
result.hits = result.items.length;
|
||||
|
||||
result.items = result.items.slice(
|
||||
result.skip,
|
||||
result.skip + result.take
|
||||
);
|
||||
|
||||
result.completed = result.skip + result.take >= result.hits;
|
||||
|
||||
return result;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
startRemission(params: {
|
||||
remissionProcessId: number;
|
||||
config?: {
|
||||
createShippingDocument?: boolean;
|
||||
};
|
||||
}): Observable<RemissionProcess> {
|
||||
const processSubject = this.remissionSubjectStore.get(
|
||||
params.remissionProcessId
|
||||
);
|
||||
|
||||
if (!processSubject) {
|
||||
throw new Error('Prozess nicht gefunden');
|
||||
}
|
||||
|
||||
const process = processSubject.value;
|
||||
const id = createRandomId();
|
||||
const doc: ShippingDocument = shippingDocument;
|
||||
|
||||
this.remissionSubjectIdRef.set(id, process.id);
|
||||
processSubject.next({
|
||||
...process,
|
||||
id,
|
||||
shippingDocuments: [doc],
|
||||
});
|
||||
|
||||
return of(processSubject.value).pipe(delay(this.delayInMs));
|
||||
}
|
||||
|
||||
continueProcess(source: RemissionProcess): Observable<RemissionProcess> {
|
||||
let processSubject = this.getRemissionFromStore(source.id);
|
||||
|
||||
if (!processSubject) {
|
||||
processSubject = new BehaviorSubject<RemissionProcess>(source);
|
||||
}
|
||||
|
||||
this.saveRemissionInStore(processSubject.value.id, processSubject);
|
||||
|
||||
return processSubject.pipe(distinctUntilChanged(), delay(this.delayInMs));
|
||||
}
|
||||
|
||||
continueProcessFromScan(containerId: string): Observable<RemissionProcess> {
|
||||
return of();
|
||||
}
|
||||
|
||||
updateRemissionFilter({
|
||||
remissionProcessId,
|
||||
changes,
|
||||
}: {
|
||||
remissionProcessId: number;
|
||||
changes: Partial<RemissionFilter>;
|
||||
}): Observable<RemissionFilter> {
|
||||
const processSubject = this.getRemissionFromStore(remissionProcessId);
|
||||
|
||||
if (!!processSubject) {
|
||||
const process = processSubject.value;
|
||||
const nextProcess = {
|
||||
...process,
|
||||
filter: { ...process.filter, ...changes },
|
||||
};
|
||||
|
||||
processSubject.next(nextProcess);
|
||||
return of(nextProcess.filter).pipe(delay(this.delayInMs));
|
||||
} else {
|
||||
throw new Error('Prozess nicht gefunden');
|
||||
}
|
||||
}
|
||||
|
||||
completeRemission(params: {
|
||||
remissionProcessId: number;
|
||||
}): Observable<boolean> {
|
||||
let processSubject = this.remissionSubjectStore.get(
|
||||
params.remissionProcessId
|
||||
);
|
||||
|
||||
if (!processSubject) {
|
||||
const refId = this.remissionSubjectIdRef.get(params.remissionProcessId);
|
||||
if (!!refId) {
|
||||
processSubject = this.remissionSubjectStore.get(refId);
|
||||
}
|
||||
|
||||
processSubject.next(processSubject.value);
|
||||
processSubject.complete();
|
||||
|
||||
return of(false).pipe(delay(this.delayInMs));
|
||||
} else {
|
||||
return of(true).pipe(delay(this.delayInMs));
|
||||
}
|
||||
}
|
||||
|
||||
getRemission(params: {
|
||||
remissionProcessId: number;
|
||||
}): Observable<RemissionProcess> {
|
||||
const remission = this.getRemissionFromStore(params.remissionProcessId);
|
||||
|
||||
if (!remission) {
|
||||
throw new Error('Prozess nicht gefunden');
|
||||
}
|
||||
|
||||
return remission.pipe(distinctUntilChanged(), delay(this.delayInMs));
|
||||
}
|
||||
|
||||
isPrintingRequired({
|
||||
remissionProcessId,
|
||||
}: {
|
||||
remissionProcessId: number;
|
||||
}): Observable<boolean> {
|
||||
const remission = this.getRemissionFromStore(remissionProcessId);
|
||||
|
||||
if (!remission) {
|
||||
return of(false).pipe(delay(this.delayInMs));
|
||||
}
|
||||
|
||||
switch (remission.value.filter.target.name) {
|
||||
case 'Libri':
|
||||
return of(true).pipe(delay(this.delayInMs));
|
||||
|
||||
case 'Blank':
|
||||
return of(false).pipe(delay(this.delayInMs));
|
||||
}
|
||||
}
|
||||
|
||||
getPrinters(): Observable<Printer[]> {
|
||||
return of(printers).pipe(delay(this.delayInMs));
|
||||
}
|
||||
|
||||
printRemissionList(params: {
|
||||
remissionProcessId: number;
|
||||
printerKey: string;
|
||||
}): Observable<boolean> {
|
||||
const remission = this.getRemissionFromStore(params.remissionProcessId);
|
||||
|
||||
if (!remission) {
|
||||
return of(false).pipe(delay(this.delayInMs));
|
||||
}
|
||||
|
||||
return of(true).pipe(delay(this.delayInMs));
|
||||
}
|
||||
|
||||
printShippingDocument(params: {
|
||||
remissionProcessId: number;
|
||||
shippingDocumentId?: number;
|
||||
printerKey: string;
|
||||
}): Observable<boolean> {
|
||||
const remission = this.getRemissionFromStore(params.remissionProcessId);
|
||||
|
||||
if (!remission || !params.printerKey) {
|
||||
return of(false).pipe(delay(this.delayInMs));
|
||||
}
|
||||
return of(true).pipe(delay(this.delayInMs));
|
||||
}
|
||||
|
||||
searchProduct({ ean }: { ean: string }): Observable<Product> {
|
||||
const searchResult = product;
|
||||
|
||||
return of(searchResult).pipe(delay(this.delayInMs));
|
||||
}
|
||||
|
||||
getFilters(params: { remissionProcessId: number }): Observable<Filter[]> {
|
||||
const remission = this.getRemissionFromStore(params.remissionProcessId);
|
||||
|
||||
const filterForGivenSourceType =
|
||||
remission.value.filter.source === 'zentral' ? filter : filterUeberlauf;
|
||||
return of(filterForGivenSourceType).pipe(delay(this.delayInMs));
|
||||
}
|
||||
|
||||
getPlacementTypes(): Observable<RemissionPlacementType[]> {
|
||||
return of(remissionPlacementTypes).pipe(delay(this.delayInMs));
|
||||
}
|
||||
|
||||
getRemissionReasons(): Observable<string[]> {
|
||||
return of(remissionReasons).pipe(delay(this.delayInMs));
|
||||
}
|
||||
|
||||
getRemissionTargets(): Observable<RemissionSupplier[]> {
|
||||
return of(remissionTargets).pipe(delay(this.delayInMs));
|
||||
}
|
||||
getRemissionSources(): Observable<RemissionSourceType[]> {
|
||||
return of(remissionSources).pipe(delay(this.delayInMs));
|
||||
}
|
||||
|
||||
getShippingDocuments(params: {
|
||||
remissionProcessId: number;
|
||||
shippingDocumentId: number;
|
||||
}): Observable<ShippingDocument> {
|
||||
const remissionSub = this.getRemissionFromStore(params.remissionProcessId);
|
||||
|
||||
return remissionSub.pipe(
|
||||
map((remission) =>
|
||||
remission.shippingDocuments.find(
|
||||
(shippingDoc) => shippingDoc.id === params.shippingDocumentId
|
||||
)
|
||||
),
|
||||
distinctUntilChanged(),
|
||||
delay(this.delayInMs)
|
||||
);
|
||||
}
|
||||
|
||||
deleteProductFromRemissionList(input: {
|
||||
remissionProcessId: number;
|
||||
remissionProductId: number;
|
||||
}): Observable<ActionResult<boolean>> {
|
||||
return of({
|
||||
error: false,
|
||||
result: true,
|
||||
});
|
||||
}
|
||||
|
||||
addProductToRemit(input: {
|
||||
product: Product;
|
||||
remissionReason: string;
|
||||
remissionQuantity: number;
|
||||
}): Observable<RemissionProduct> {
|
||||
const productToAdd = removeSourcePriceAndProductFromProduct({ ...product });
|
||||
|
||||
const newProduct = createRemissionProduct({
|
||||
remissionReason: input.remissionReason,
|
||||
remissionQuantity: input.remissionQuantity,
|
||||
...productToAdd,
|
||||
});
|
||||
|
||||
const newProductSubject = [...this.productSubject.value, newProduct];
|
||||
|
||||
this.productSubject.next(newProductSubject);
|
||||
|
||||
return of(newProduct).pipe(delay(this.delayInMs));
|
||||
}
|
||||
|
||||
addProductToShippingDocument(params: {
|
||||
remissionProcessId: number;
|
||||
remissionProductId: number;
|
||||
shippingDocumentId: number;
|
||||
placementType?: RemissionPlacementType;
|
||||
quantity?: number;
|
||||
inStock?: number;
|
||||
}): Observable<ActionResult<boolean>> {
|
||||
const processSubject = this.getRemissionFromStore(
|
||||
params.remissionProcessId
|
||||
);
|
||||
const process = processSubject.value;
|
||||
const products = this.productSubject.value;
|
||||
|
||||
if (!processSubject) {
|
||||
throw new Error('Prozess nicht gefunden');
|
||||
}
|
||||
|
||||
let productToAdd = products.find(
|
||||
(product) => product.id === params.remissionProductId
|
||||
);
|
||||
let newProducts = products.filter(
|
||||
(product) => product.id !== params.remissionProductId
|
||||
);
|
||||
|
||||
if (!!params.placementType || !!params.quantity) {
|
||||
const productToUpdateInProductList = {
|
||||
...productToAdd,
|
||||
remissionQuantity: productToAdd.remissionQuantity - params.quantity,
|
||||
};
|
||||
newProducts =
|
||||
productToAdd.remissionQuantity - params.quantity < 1
|
||||
? newProducts
|
||||
: [...newProducts, productToUpdateInProductList];
|
||||
|
||||
productToAdd = {
|
||||
...productToAdd,
|
||||
remissionQuantity: Number(params.quantity),
|
||||
};
|
||||
}
|
||||
|
||||
const shippingDocumentToUpdate = process.shippingDocuments.find(
|
||||
(document) => document.id === params.shippingDocumentId
|
||||
);
|
||||
const updatedShippingDocument = {
|
||||
...shippingDocumentToUpdate,
|
||||
products: [...shippingDocumentToUpdate.products, productToAdd],
|
||||
};
|
||||
|
||||
const updatedProcess = {
|
||||
...process,
|
||||
shippingDocuments: [
|
||||
...process.shippingDocuments.filter(
|
||||
(document) => document.id !== params.shippingDocumentId
|
||||
),
|
||||
updatedShippingDocument,
|
||||
],
|
||||
};
|
||||
|
||||
processSubject.next(updatedProcess);
|
||||
this.productSubject.next(newProducts);
|
||||
|
||||
return of<ActionResult<boolean>>({
|
||||
error: false,
|
||||
result: true,
|
||||
}).pipe(delay(this.delayInMs));
|
||||
}
|
||||
|
||||
removeProductFromShippingDocument(params: {
|
||||
remissionProcessId: number;
|
||||
shippingDocumentId: number;
|
||||
remissionProductId: number;
|
||||
placementType?: string;
|
||||
}): Observable<boolean> {
|
||||
const processSubject = this.getRemissionFromStore(
|
||||
params.remissionProcessId
|
||||
);
|
||||
const process = processSubject.value;
|
||||
const products = this.productSubject.value;
|
||||
|
||||
if (!processSubject) {
|
||||
throw new Error('Prozess nicht gefunden');
|
||||
}
|
||||
|
||||
const shippingDocumentToUpdate = process.shippingDocuments.find(
|
||||
(document) => document.id === params.shippingDocumentId
|
||||
);
|
||||
const updatedShippingDocument = {
|
||||
...shippingDocumentToUpdate,
|
||||
products: shippingDocumentToUpdate.products.filter(
|
||||
(product) => product.id !== params.remissionProductId
|
||||
),
|
||||
};
|
||||
const productToRemove = shippingDocumentToUpdate.products.find(
|
||||
(product) => product.id === params.remissionProductId
|
||||
);
|
||||
const productInProductList = products.find(
|
||||
(product) => product.id === params.remissionProductId
|
||||
);
|
||||
const updatedProductInProductList = !!productInProductList
|
||||
? {
|
||||
...productInProductList,
|
||||
remissionQuantity:
|
||||
Number(productInProductList.remissionQuantity) +
|
||||
Number(productToRemove.remissionQuantity),
|
||||
}
|
||||
: productToRemove;
|
||||
|
||||
const updatedProcess = {
|
||||
...process,
|
||||
shippingDocuments: [
|
||||
...process.shippingDocuments.filter(
|
||||
(document) => document.id !== params.shippingDocumentId
|
||||
),
|
||||
updatedShippingDocument,
|
||||
],
|
||||
};
|
||||
|
||||
const updatedProducts = [
|
||||
...this.productSubject.value.filter(
|
||||
(product) => product.id !== updatedProductInProductList.id
|
||||
),
|
||||
updatedProductInProductList,
|
||||
];
|
||||
|
||||
processSubject.next(updatedProcess);
|
||||
this.productSubject.next(updatedProducts);
|
||||
|
||||
return of(true).pipe(delay(this.delayInMs));
|
||||
}
|
||||
|
||||
reloadProducts(): void {
|
||||
this.reloadProductsSubject.next();
|
||||
}
|
||||
|
||||
createShippingDocument(params: {
|
||||
remissionProcessId: number;
|
||||
}): Observable<ShippingDocument> {
|
||||
const processSubject = this.getRemissionFromStore(
|
||||
params.remissionProcessId
|
||||
);
|
||||
|
||||
if (!processSubject) {
|
||||
throw new Error('Prozess nicht gefunden');
|
||||
}
|
||||
|
||||
const process = processSubject.value;
|
||||
const newShippingDocument: ShippingDocument = {
|
||||
...shippingDocument,
|
||||
id: createRandomId(),
|
||||
shippingDocumentNumber: createRandomStringId(),
|
||||
};
|
||||
const updatedShippingDocuments = [
|
||||
...process.shippingDocuments,
|
||||
newShippingDocument,
|
||||
];
|
||||
const updatedProcess = {
|
||||
...process,
|
||||
shippingDocuments: updatedShippingDocuments,
|
||||
};
|
||||
|
||||
processSubject.next(updatedProcess);
|
||||
|
||||
return of(newShippingDocument).pipe(delay(this.delayInMs));
|
||||
}
|
||||
|
||||
completeShippingDocument(params: {
|
||||
remissionProcessId: number;
|
||||
shippingDocumentId: number;
|
||||
containerId: string;
|
||||
}): Observable<ActionResult<boolean>> {
|
||||
const processSubject = this.getRemissionFromStore(
|
||||
params.remissionProcessId
|
||||
);
|
||||
|
||||
if (!processSubject) {
|
||||
throw new Error('Prozess nicht gefunden');
|
||||
}
|
||||
|
||||
const process = processSubject.value;
|
||||
const shippingContainerToUpdate = process.shippingDocuments.find(
|
||||
(document) => document.id === params.shippingDocumentId
|
||||
);
|
||||
const updatedShippingContainer = {
|
||||
...shippingContainerToUpdate,
|
||||
isCompleted: true,
|
||||
};
|
||||
const updatedProcess = {
|
||||
...process,
|
||||
shippingDocuments: [
|
||||
...process.shippingDocuments.filter(
|
||||
(document) => document.id !== params.shippingDocumentId
|
||||
),
|
||||
updatedShippingContainer,
|
||||
],
|
||||
};
|
||||
|
||||
processSubject.next(updatedProcess);
|
||||
|
||||
return of({
|
||||
error: false,
|
||||
message: '',
|
||||
}).pipe(delay(this.delayInMs));
|
||||
}
|
||||
|
||||
completeRemissions(params: {
|
||||
remissionProcessId: number;
|
||||
}): Observable<boolean> {
|
||||
return;
|
||||
}
|
||||
|
||||
getAllRemissions(params: {
|
||||
showOpen?: boolean;
|
||||
showOpenLastWeekOnly?: boolean;
|
||||
showCompleted?: boolean;
|
||||
showCompletedLastWeekOnly?: boolean;
|
||||
receiptNumber?: string;
|
||||
returnGroup?: number;
|
||||
take?: number;
|
||||
}): Observable<RemissionProcess[]> {
|
||||
return;
|
||||
}
|
||||
|
||||
getUncompletedRemissions(): Observable<RemissionProcess[]> {
|
||||
return of([]);
|
||||
}
|
||||
|
||||
deleteRemission(): Observable<boolean> {
|
||||
return of(true);
|
||||
}
|
||||
|
||||
deleteShippingDocument(): Observable<
|
||||
ActionResult<{ deleted: boolean; completedRemissionsExist: boolean }>
|
||||
> {
|
||||
return of({
|
||||
result: {
|
||||
deleted: true,
|
||||
completedRemissionsExist: false,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
getAllShippingDocuments(): Observable<ShippingDocument[]> {
|
||||
return;
|
||||
}
|
||||
|
||||
getCapacities(params: {
|
||||
selectedFilters?: { [filterId: string]: string[] };
|
||||
supplierId: number;
|
||||
}): Observable<CapacityType[]> {
|
||||
return of([]);
|
||||
}
|
||||
}
|
||||
7
apps/isa/remission/src/lib/mock/util.ts
Normal file
7
apps/isa/remission/src/lib/mock/util.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export function createRandomId(): number {
|
||||
return Math.floor(Math.random() * Math.pow(10, 10));
|
||||
}
|
||||
|
||||
export function createRandomStringId(): string {
|
||||
return createRandomId().toString();
|
||||
}
|
||||
11
apps/isa/remission/src/lib/models/action-result.ts
Normal file
11
apps/isa/remission/src/lib/models/action-result.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { StringDictionary } from '@cmf/core';
|
||||
|
||||
export interface ActionResult<T> {
|
||||
error?: boolean;
|
||||
errorReasons?: StringDictionary<string>;
|
||||
http?: {
|
||||
code: number;
|
||||
};
|
||||
message?: string;
|
||||
result?: T;
|
||||
}
|
||||
21
apps/isa/remission/src/lib/models/capacity-type.ts
Normal file
21
apps/isa/remission/src/lib/models/capacity-type.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
export interface CapacityType {
|
||||
/**
|
||||
* Kapazitätsbezeichnung / Name (z.B. Leistungsplatz)
|
||||
*/
|
||||
name: string;
|
||||
|
||||
/**
|
||||
* Kapazitätsauslastung (abs.)
|
||||
*/
|
||||
utilized: number;
|
||||
|
||||
/**
|
||||
* Verfügbare Kapazität
|
||||
*/
|
||||
available: number;
|
||||
|
||||
/**
|
||||
* Kapazitätsname (z.B. Titel)
|
||||
*/
|
||||
label: string;
|
||||
}
|
||||
43
apps/isa/remission/src/lib/models/filter.ts
Normal file
43
apps/isa/remission/src/lib/models/filter.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
export interface Filter {
|
||||
/**
|
||||
* ID der Filterkategorie
|
||||
*/
|
||||
id: string;
|
||||
|
||||
/**
|
||||
* Name der Filterkategorie
|
||||
*/
|
||||
name: string;
|
||||
|
||||
/**
|
||||
* Liste der Filteroptionen (die Filteroptionen der jeweiligen Filterkategorie)
|
||||
*/
|
||||
options: FilterOption[];
|
||||
|
||||
/**
|
||||
* Maximale Anzahl ausgewählter Filter Optionen
|
||||
*/
|
||||
max?: number;
|
||||
}
|
||||
|
||||
export interface FilterOption {
|
||||
/**
|
||||
* ID der Filteroption
|
||||
*/
|
||||
id: string;
|
||||
|
||||
/**
|
||||
* Name der Filteroption
|
||||
*/
|
||||
name: string;
|
||||
|
||||
/**
|
||||
* Key der Filteroption
|
||||
*/
|
||||
key?: string;
|
||||
|
||||
/**
|
||||
* Liste der Filteroptionen (die Filteroptionen der jeweiligen Filterkategorie)
|
||||
*/
|
||||
options?: FilterOption[];
|
||||
}
|
||||
14
apps/isa/remission/src/lib/models/index.ts
Normal file
14
apps/isa/remission/src/lib/models/index.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
// start:ng42.barrel
|
||||
export * from './action-result';
|
||||
export * from './capacity-type';
|
||||
export * from './filter';
|
||||
export * from './printer';
|
||||
export * from './product';
|
||||
export * from './remission-filter';
|
||||
export * from './remission-process';
|
||||
export * from './remission-product';
|
||||
export * from './remission-products-filter';
|
||||
export * from './remission-supplier';
|
||||
export * from './remission-selected-filters';
|
||||
export * from './shipping-document';
|
||||
// end:ng42.barrel
|
||||
26
apps/isa/remission/src/lib/models/printer.ts
Normal file
26
apps/isa/remission/src/lib/models/printer.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
export interface Printer {
|
||||
/**
|
||||
* Ist Drucker aktiv
|
||||
*/
|
||||
enabled: boolean;
|
||||
|
||||
/**
|
||||
* Pfad des Druckers
|
||||
*/
|
||||
key: string;
|
||||
|
||||
/**
|
||||
* Name des Druckers
|
||||
*/
|
||||
value: string;
|
||||
|
||||
/**
|
||||
* Ist Drucker ausgewählt
|
||||
*/
|
||||
selected: boolean;
|
||||
|
||||
/**
|
||||
* Beschreibung des Druckers
|
||||
*/
|
||||
description: string;
|
||||
}
|
||||
63
apps/isa/remission/src/lib/models/product.ts
Normal file
63
apps/isa/remission/src/lib/models/product.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
import { PriceDTO, ProductDTO } from '@cmf/inventory-api';
|
||||
|
||||
export interface Product {
|
||||
/**
|
||||
* Produkt PK
|
||||
*/
|
||||
id?: number;
|
||||
|
||||
/**
|
||||
* Autor(en)
|
||||
*/
|
||||
contributors?: string;
|
||||
|
||||
/**
|
||||
* Bild Identifikationsnummber
|
||||
*/
|
||||
imageId?: string;
|
||||
|
||||
/**
|
||||
* Name des Artikels
|
||||
*/
|
||||
name?: string;
|
||||
|
||||
/**
|
||||
* Format des Buchs Kurzform (z.B: HC)
|
||||
*/
|
||||
format?: string;
|
||||
|
||||
/**
|
||||
* Format des Buchs Langform (z.B: Buch (gebunden))
|
||||
*/
|
||||
formatDetail?: string;
|
||||
|
||||
/**
|
||||
* Artikelnummer
|
||||
*/
|
||||
ean?: string;
|
||||
|
||||
/**
|
||||
* Produktgruppe (z.B. 112)
|
||||
*/
|
||||
productGroup?: string;
|
||||
|
||||
/**
|
||||
* Name der Produktgruppe (z.B. Romane)
|
||||
*/
|
||||
productGroupName?: string;
|
||||
|
||||
/**
|
||||
* Artikel-Features (z.B. key: 'SOE')
|
||||
*/
|
||||
features: { key: string; name: string }[];
|
||||
|
||||
/**
|
||||
* Produkt-Stammdaten
|
||||
*/
|
||||
sourceProduct?: ProductDTO;
|
||||
|
||||
/**
|
||||
* Preis (VK)
|
||||
*/
|
||||
sourcePrice?: PriceDTO;
|
||||
}
|
||||
30
apps/isa/remission/src/lib/models/remission-filter.ts
Normal file
30
apps/isa/remission/src/lib/models/remission-filter.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import { RemissionSupplier } from './remission-supplier';
|
||||
import { RemissionSourceType } from '../types/remission-source.type';
|
||||
import { RemissionSelectedFilters } from './remission-selected-filters';
|
||||
|
||||
export interface RemissionFilter {
|
||||
/**
|
||||
* Liste aller Produktfilter
|
||||
*/
|
||||
filter?: RemissionSelectedFilters;
|
||||
|
||||
/**
|
||||
* Artikel-Ursprung (zentrales Sortiment oder Überlauf)
|
||||
*/
|
||||
source: RemissionSourceType;
|
||||
|
||||
/**
|
||||
* Remissions-Ziel / Lieferant (z.B. Libri)
|
||||
*/
|
||||
target: RemissionSupplier;
|
||||
|
||||
/**
|
||||
* Skip
|
||||
*/
|
||||
skip: number;
|
||||
|
||||
/**
|
||||
* Take
|
||||
*/
|
||||
take: number;
|
||||
}
|
||||
50
apps/isa/remission/src/lib/models/remission-process.ts
Normal file
50
apps/isa/remission/src/lib/models/remission-process.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
import { CapacityType } from './capacity-type';
|
||||
import { ShippingDocument } from './shipping-document';
|
||||
import { RemissionFilter } from './remission-filter';
|
||||
|
||||
export interface RemissionProcess {
|
||||
/**
|
||||
* RemissionProcess PK
|
||||
*/
|
||||
id: number;
|
||||
|
||||
/**
|
||||
* Group ID
|
||||
*/
|
||||
returnGroup: number;
|
||||
|
||||
/**
|
||||
* Remissionsnummer
|
||||
*/
|
||||
externalId?: number;
|
||||
|
||||
/**
|
||||
* PK Lager
|
||||
*/
|
||||
stockId: number;
|
||||
|
||||
/**
|
||||
* Kapazitäts-Informationen (z.B. Leistungsplatz 2 von 5 Artikel)
|
||||
*/
|
||||
capacities: CapacityType[];
|
||||
|
||||
/**
|
||||
* Liste aller Produktfilter
|
||||
*/
|
||||
filter: RemissionFilter;
|
||||
|
||||
/**
|
||||
* Warenbegleitschein
|
||||
*/
|
||||
shippingDocuments?: ShippingDocument[];
|
||||
|
||||
/**
|
||||
* Beginn der Retourenerstellung / Remission
|
||||
*/
|
||||
startDate?: string;
|
||||
|
||||
/**
|
||||
* Bereits Abgeschlossen
|
||||
*/
|
||||
completed?: boolean;
|
||||
}
|
||||
115
apps/isa/remission/src/lib/models/remission-product.ts
Normal file
115
apps/isa/remission/src/lib/models/remission-product.ts
Normal file
@@ -0,0 +1,115 @@
|
||||
import { RemissionPlacementType } from '../types/remission-placement-types';
|
||||
import { RemissionSupplier } from './remission-supplier';
|
||||
|
||||
export interface RemissionProduct {
|
||||
/**
|
||||
* Produkt PK
|
||||
*/
|
||||
id: number;
|
||||
|
||||
/**
|
||||
* Bild Identifikationsnummber
|
||||
*/
|
||||
imageId: string;
|
||||
|
||||
/**
|
||||
* Autor(en)
|
||||
*/
|
||||
|
||||
contributors: string;
|
||||
|
||||
/**
|
||||
* Name des Artikels
|
||||
*/
|
||||
name: string;
|
||||
|
||||
/**
|
||||
* Format des Buchs Kurzform (z.B: HC)
|
||||
*/
|
||||
format: string;
|
||||
|
||||
/**
|
||||
* Format des Buchs Langform (z.B: Buch (gebunden))
|
||||
*/
|
||||
formatDetail: string;
|
||||
|
||||
/**
|
||||
* Artikelnummer
|
||||
*/
|
||||
ean: string;
|
||||
|
||||
/**
|
||||
* Preis des Artikels
|
||||
*/
|
||||
price: number;
|
||||
|
||||
/**
|
||||
* Währeng des Artikelpreis
|
||||
*/
|
||||
currency: string;
|
||||
|
||||
/**
|
||||
* Produktgruppe (z.B. 112)
|
||||
*/
|
||||
productGroup: string;
|
||||
|
||||
/**
|
||||
* Name der Produktgruppe (z.B. Romane)
|
||||
*/
|
||||
productGroupName: string;
|
||||
|
||||
/**
|
||||
* Aktueller Bestand des Artikels
|
||||
*/
|
||||
inStock: number;
|
||||
|
||||
/**
|
||||
* Remi-Menge
|
||||
*/
|
||||
remissionQuantity: number;
|
||||
|
||||
/**
|
||||
* Aktueller Bestand minus Remi-Menge
|
||||
*/
|
||||
remainingQuantity: number;
|
||||
|
||||
/**
|
||||
* Artikel-Platzierung (z.B. Stapelplatz)
|
||||
*/
|
||||
placementType: RemissionPlacementType;
|
||||
|
||||
/**
|
||||
* Grund für Remissions (Remi-Grund)
|
||||
*/
|
||||
remissionReason: string;
|
||||
|
||||
/**
|
||||
* Ausgabe / Edition
|
||||
*/
|
||||
edition: string;
|
||||
|
||||
/**
|
||||
* Artikel-Features (z.B. key: 'SOE')
|
||||
*/
|
||||
features: { key: string; name: string }[];
|
||||
|
||||
/**
|
||||
* Produktnummer des internen Warenkatalogs
|
||||
*/
|
||||
catalogProductNumber?: string;
|
||||
|
||||
/**
|
||||
* Restmenge (=Teilmenge des Artikels auf Warenbegleitschein)
|
||||
*/
|
||||
isResidual?: boolean;
|
||||
|
||||
/**
|
||||
* Remissions-Ziel / Lieferant (z.B. Libri)
|
||||
*/
|
||||
target?: RemissionSupplier;
|
||||
|
||||
/**
|
||||
* Wurde das Produkt manuell zur Remissionsliste hinzugefügt
|
||||
*/
|
||||
isManuallyAdded?: boolean;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import { RemissionSupplier } from './remission-supplier';
|
||||
import { CapacityType } from './capacity-type';
|
||||
import { Filter } from './filter';
|
||||
import { RemissionSourceType } from '../types/remission-source.type';
|
||||
|
||||
export interface RemissionProductsFilter {
|
||||
/**
|
||||
* PK Lager
|
||||
*/
|
||||
stockId: number;
|
||||
|
||||
/**
|
||||
* Artikel-Ursprung (zentrales Sortiment oder Überlauf)
|
||||
*/
|
||||
source: RemissionSourceType;
|
||||
|
||||
/**
|
||||
* Remissions-Ziel / Lieferant (z.B. Libri)
|
||||
*/
|
||||
target: RemissionSupplier;
|
||||
|
||||
/**
|
||||
* Kapazitäts-Informationen (z.B. Leistungsplatz 2 von 5 Artikel)
|
||||
*/
|
||||
capacities: CapacityType[];
|
||||
|
||||
/**
|
||||
* Liste aller Produktfilter
|
||||
*/
|
||||
filter: Filter[];
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
export interface RemissionSelectedFilters {
|
||||
ueberlauf?: {
|
||||
Blank?: { [filterId: string]: string[] };
|
||||
ZL?: { [filterId: string]: string[] };
|
||||
};
|
||||
zentral?: {
|
||||
Blank?: { [filterId: string]: string[] };
|
||||
ZL?: { [filterId: string]: string[] };
|
||||
};
|
||||
}
|
||||
16
apps/isa/remission/src/lib/models/remission-supplier.ts
Normal file
16
apps/isa/remission/src/lib/models/remission-supplier.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
export interface RemissionSupplier {
|
||||
/**
|
||||
* PK
|
||||
*/
|
||||
id: number;
|
||||
|
||||
/**
|
||||
* Name des Lieferanten (z.B. ZL)
|
||||
*/
|
||||
name: string;
|
||||
|
||||
/**
|
||||
* Lieferantennummer
|
||||
*/
|
||||
supplierNumber: string;
|
||||
}
|
||||
35
apps/isa/remission/src/lib/models/shipping-document.ts
Normal file
35
apps/isa/remission/src/lib/models/shipping-document.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import { RemissionProduct } from './remission-product';
|
||||
|
||||
export interface ShippingDocument {
|
||||
/**
|
||||
* ShippingDocument ID
|
||||
*/
|
||||
id?: number;
|
||||
|
||||
/**
|
||||
* Warenbegleitscheinnummer
|
||||
*/
|
||||
shippingDocumentNumber?: string;
|
||||
|
||||
/**
|
||||
* Liste aller Produkte auf dem Warenbegleitschein
|
||||
*/
|
||||
products?: RemissionProduct[];
|
||||
|
||||
/**
|
||||
* Status des Wannenbegleitschein
|
||||
* True = Wanne ist abgeschlossen
|
||||
*/
|
||||
isCompleted?: boolean;
|
||||
|
||||
/**
|
||||
* Wurde die Wanne bereits gelöscht
|
||||
* True = Wanne ist gelöscht
|
||||
*/
|
||||
isDeleted?: boolean;
|
||||
|
||||
/**
|
||||
* Wannennummer (Paketnummer)
|
||||
*/
|
||||
packageNumber?: string;
|
||||
}
|
||||
15
apps/isa/remission/src/lib/remission-module.options.ts
Normal file
15
apps/isa/remission/src/lib/remission-module.options.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable()
|
||||
export class RemissionModuleOptions {
|
||||
/**
|
||||
* Sollen Testdaten (Services) verwendet werden
|
||||
*/
|
||||
useMock?: boolean;
|
||||
|
||||
endpoints?: {
|
||||
catsearch?: string;
|
||||
remi?: string;
|
||||
print?: string;
|
||||
};
|
||||
}
|
||||
142
apps/isa/remission/src/lib/remission.module.ts
Normal file
142
apps/isa/remission/src/lib/remission.module.ts
Normal file
@@ -0,0 +1,142 @@
|
||||
import { RemissionModuleOptions } from './remission-module.options';
|
||||
import { CatsearchApiRequestOptions } from '@isa/catsearch-api';
|
||||
import { RemiApiRequestOptions } from '@isa/remi-api';
|
||||
import { PrintApiRequestOptions } from '@isa/print-api';
|
||||
import { NgModule, ModuleWithProviders } from '@angular/core';
|
||||
import { RestRemissionService } from './services/rest-remission.service';
|
||||
import { MockRemissionService } from './mock/mock-remission.service';
|
||||
import { Mapper } from './mappings/mapper';
|
||||
import { ReturnSuggestionDtoToRemissionProductMapping } from './mappings/return-suggestion-dto-to-remission-product.mapping';
|
||||
import { ItemDtoToProductMapping } from './mappings/item-dto-to-product.mapping';
|
||||
import { ProductToPriceDTOMapping } from './mappings/product-to-price-dto';
|
||||
import { ProductToProductDTOMapping } from './mappings/product-to-product-dto';
|
||||
import { ReturnItemDtoToRemissionProductMapping } from './mappings/return-item-dto-to-remission-product.mapping';
|
||||
import { ReceiptItemDtoToRemissionProductMapping } from './mappings/receipt-item-dto-to-remission-product.mapping';
|
||||
import { ReceiptDTOToShippingDocumentMapping } from './mappings/receipt-dto-to-shipping-document.mapping';
|
||||
import { RemissionService } from './services/remission.service';
|
||||
import { BaseUrlInterceptor, CatchResponseArgsErrorInterceptor, LogErrorInterceptor } from '@cmf/core';
|
||||
import { HTTP_INTERCEPTORS } from '@angular/common/http';
|
||||
import { FeaturesToAssortmentMapping } from './mappings/features-to-assortment.mapping';
|
||||
import { SupplierDtoToRemissionSupplier } from './mappings/supplier-dto-to-remssion-supplier.mapping';
|
||||
|
||||
export function catsearchApiRequestOptionsFactory(options: RemissionModuleOptions): CatsearchApiRequestOptions {
|
||||
return {
|
||||
baseUrl: (options.endpoints && options.endpoints.catsearch) || '',
|
||||
catchResponseArgsError: true,
|
||||
};
|
||||
}
|
||||
export function remiApiRequestOptionsFactory(options: RemissionModuleOptions): RemiApiRequestOptions {
|
||||
return {
|
||||
baseUrl: (options.endpoints && options.endpoints.remi) || '',
|
||||
catchResponseArgsError: true,
|
||||
};
|
||||
}
|
||||
export function printApiRequestOptionsFactory(options: RemissionModuleOptions): PrintApiRequestOptions {
|
||||
return {
|
||||
baseUrl: (options.endpoints && options.endpoints.print) || '',
|
||||
catchResponseArgsError: true,
|
||||
};
|
||||
}
|
||||
|
||||
export function remissionServiceFactory(options: RemissionModuleOptions, rest: RestRemissionService, mock: MockRemissionService) {
|
||||
return options.useMock ? mock : rest;
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
declarations: [],
|
||||
imports: [],
|
||||
exports: [],
|
||||
})
|
||||
export class RemissionModule {
|
||||
static forRoot(options: RemissionModuleOptions): ModuleWithProviders {
|
||||
return {
|
||||
ngModule: RemissionModule,
|
||||
providers: [
|
||||
{
|
||||
provide: RemissionModuleOptions,
|
||||
useValue: options,
|
||||
},
|
||||
{
|
||||
provide: CatsearchApiRequestOptions,
|
||||
useFactory: catsearchApiRequestOptionsFactory,
|
||||
deps: [RemissionModuleOptions],
|
||||
},
|
||||
{
|
||||
provide: RemiApiRequestOptions,
|
||||
useFactory: remiApiRequestOptionsFactory,
|
||||
deps: [RemissionModuleOptions],
|
||||
},
|
||||
{
|
||||
provide: PrintApiRequestOptions,
|
||||
useFactory: printApiRequestOptionsFactory,
|
||||
deps: [RemissionModuleOptions],
|
||||
},
|
||||
{
|
||||
provide: Mapper,
|
||||
useClass: ReturnSuggestionDtoToRemissionProductMapping,
|
||||
multi: true,
|
||||
},
|
||||
{
|
||||
provide: Mapper,
|
||||
useClass: ItemDtoToProductMapping,
|
||||
multi: true,
|
||||
},
|
||||
{
|
||||
provide: Mapper,
|
||||
useClass: ProductToPriceDTOMapping,
|
||||
multi: true,
|
||||
},
|
||||
{
|
||||
provide: Mapper,
|
||||
useClass: ProductToProductDTOMapping,
|
||||
multi: true,
|
||||
},
|
||||
{
|
||||
provide: Mapper,
|
||||
useClass: ReturnItemDtoToRemissionProductMapping,
|
||||
multi: true,
|
||||
},
|
||||
{
|
||||
provide: Mapper,
|
||||
useClass: ReceiptItemDtoToRemissionProductMapping,
|
||||
multi: true,
|
||||
},
|
||||
{
|
||||
provide: Mapper,
|
||||
useClass: ReceiptDTOToShippingDocumentMapping,
|
||||
multi: true,
|
||||
},
|
||||
{
|
||||
provide: Mapper,
|
||||
useClass: FeaturesToAssortmentMapping,
|
||||
multi: true,
|
||||
},
|
||||
{
|
||||
provide: Mapper,
|
||||
useClass: SupplierDtoToRemissionSupplier,
|
||||
multi: true,
|
||||
},
|
||||
{
|
||||
provide: RemissionService,
|
||||
useFactory: remissionServiceFactory,
|
||||
deps: [RemissionModuleOptions, RestRemissionService, MockRemissionService],
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: BaseUrlInterceptor,
|
||||
multi: true,
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: CatchResponseArgsErrorInterceptor,
|
||||
multi: true,
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: LogErrorInterceptor,
|
||||
multi: true,
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
}
|
||||
4
apps/isa/remission/src/lib/rest/index.ts
Normal file
4
apps/isa/remission/src/lib/rest/index.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
// start:ng42.barrel
|
||||
export * from './rest-filter.service';
|
||||
export * from './rest-remission-products.service';
|
||||
// end:ng42.barrel
|
||||
127
apps/isa/remission/src/lib/rest/rest-filter.service.ts
Normal file
127
apps/isa/remission/src/lib/rest/rest-filter.service.ts
Normal file
@@ -0,0 +1,127 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Observable, of } from 'rxjs';
|
||||
import { StringDictionary, InputDTO, OptionDTO } from '@cmf/core';
|
||||
import { RemiService, FilterParams } from '@isa/remi-api';
|
||||
import { map, shareReplay } from 'rxjs/operators';
|
||||
import { FilterOption, Filter } from '../models/filter';
|
||||
import { RemissionSourceType } from '../types/remission-source.type';
|
||||
import { RemissionFilter, RemissionSelectedFilters } from '../models';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class RestFilterService {
|
||||
private cachedFilters$ = new Map<string, Observable<InputDTO[]>>();
|
||||
|
||||
constructor(private remiService: RemiService) {}
|
||||
|
||||
mapOptionToFilterOption(option: OptionDTO): FilterOption {
|
||||
const result = {
|
||||
id: option.value,
|
||||
key: option.key,
|
||||
name: option.label,
|
||||
options: !!option.values && option.values.length > 0 ? option.values.map((i) => this.mapOptionToFilterOption(i)) : undefined,
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
getFilter(params: { remissionSourceType: RemissionSourceType; supplierId: number; stockId: number }): Observable<Filter[]> {
|
||||
return this.getRestFilter({
|
||||
remissionSourceType: params.remissionSourceType,
|
||||
supplierId: params.supplierId,
|
||||
stockId: params.stockId,
|
||||
}).pipe(
|
||||
map((response) =>
|
||||
response.map((input) => ({
|
||||
id: input.key,
|
||||
key: input.key,
|
||||
name: input.label,
|
||||
max: input.options.max,
|
||||
options: input.options.values.map((option) => this.mapOptionToFilterOption(option)),
|
||||
}))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
getRestFilter(params: { remissionSourceType: RemissionSourceType; supplierId: number; stockId: number }): Observable<InputDTO[]> {
|
||||
const cacheIdentifier = params.remissionSourceType + params.supplierId;
|
||||
|
||||
if (!this.cachedFilters$.get(cacheIdentifier)) {
|
||||
this.cachedFilters$.set(cacheIdentifier, this.getFiltersFromService(params).pipe(shareReplay()));
|
||||
}
|
||||
|
||||
return this.cachedFilters$
|
||||
.get(cacheIdentifier)
|
||||
.pipe(map((result) => this.getSourceTypeSpecificFilters(result, params.remissionSourceType)));
|
||||
}
|
||||
|
||||
createQueryRemiTokenFilter(params: {
|
||||
remissionSourceType: RemissionSourceType;
|
||||
remissionTargetName: string;
|
||||
stockId: number;
|
||||
filter: RemissionFilter;
|
||||
}): Observable<StringDictionary<string>> {
|
||||
const queryTokenFilter: StringDictionary<string> = {};
|
||||
const filter =
|
||||
params.filter.filter[params.remissionSourceType] && params.filter.filter[params.remissionSourceType][params.remissionTargetName];
|
||||
|
||||
if (!filter) {
|
||||
return of({});
|
||||
}
|
||||
|
||||
for (const key in filter) {
|
||||
if (filter.hasOwnProperty(key) && Array.isArray(filter[key])) {
|
||||
const values = filter[key].filter((value) => !!value);
|
||||
queryTokenFilter[key] = values.join(';');
|
||||
}
|
||||
}
|
||||
|
||||
return of(queryTokenFilter);
|
||||
}
|
||||
|
||||
getSourceTypeSpecificFilters(inputs: InputDTO[], remissionSourceType: RemissionSourceType): InputDTO[] {
|
||||
return remissionSourceType === 'zentral' ? inputs : inputs.filter((option) => option.key !== 'aktionen');
|
||||
}
|
||||
|
||||
private getFiltersFromService(params: {
|
||||
remissionSourceType: RemissionSourceType;
|
||||
supplierId: number;
|
||||
stockId: number;
|
||||
}): Observable<InputDTO[]> {
|
||||
let filter$: Observable<InputDTO[]>;
|
||||
const filterQuery: FilterParams = {
|
||||
stockId: params.stockId,
|
||||
supplierId: params.supplierId,
|
||||
};
|
||||
|
||||
if (params.remissionSourceType === 'zentral') {
|
||||
filter$ = this.remiService.getPflichtremissionFilter(filterQuery).pipe(map((response) => response.result));
|
||||
} else {
|
||||
filter$ = this.remiService.getUeberlaufFilter(filterQuery).pipe(map((response) => response.result));
|
||||
}
|
||||
|
||||
return filter$;
|
||||
}
|
||||
|
||||
checkFilterValidity(filter: RemissionSelectedFilters): boolean {
|
||||
const isValidRemissionSelectedFilter = filter.hasOwnProperty('zentral') && filter.hasOwnProperty('ueberlauf');
|
||||
|
||||
return isValidRemissionSelectedFilter;
|
||||
}
|
||||
|
||||
resetRemissionSelectedFilters(): RemissionSelectedFilters {
|
||||
return {
|
||||
ueberlauf: {
|
||||
Blank: {},
|
||||
ZL: {},
|
||||
},
|
||||
zentral: {
|
||||
Blank: {},
|
||||
ZL: {},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
getSelectedFilters(filter: RemissionFilter): { [filterId: string]: string[] } {
|
||||
return (filter.filter && filter.filter[filter.source] && filter.filter[filter.source][filter.target.name]) || {};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,333 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Observable, combineLatest, BehaviorSubject, forkJoin, of } from 'rxjs';
|
||||
import { RemiService, ReturnApiService } from '@isa/remi-api';
|
||||
import { RestFilterService } from './rest-filter.service';
|
||||
import {
|
||||
switchMap,
|
||||
map,
|
||||
flatMap,
|
||||
mergeMap,
|
||||
startWith,
|
||||
take,
|
||||
shareReplay,
|
||||
} from 'rxjs/operators';
|
||||
import { filter as rxjsFilter } from 'rxjs/operators';
|
||||
import { MappingService } from '../mappings/mapping.service';
|
||||
import { Mapper } from '../mappings/mapper';
|
||||
import { ReturnSuggestionDTO, ReturnItemDTO } from '@cmf/inventory-api';
|
||||
import { RemissionFilter } from '../models/remission-filter';
|
||||
import { RemissionProduct } from '../models/remission-product';
|
||||
import { KeyValueDTO } from '@cmf/core';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class RestRemissionProductsService {
|
||||
constructor(
|
||||
private remiService: RemiService,
|
||||
private returnApi: ReturnApiService,
|
||||
private restFilterService: RestFilterService,
|
||||
private mapping: MappingService
|
||||
) {}
|
||||
|
||||
// Store priority products for supplierId
|
||||
priorityProducts = new Map<number, BehaviorSubject<number[]>>([
|
||||
[1, new BehaviorSubject<number[]>([])],
|
||||
[2, new BehaviorSubject<number[]>([])],
|
||||
]);
|
||||
|
||||
productGroupNames$: Observable<KeyValueDTO<string, string>[]>;
|
||||
|
||||
// Products that should be shown on top right after adding to remission list
|
||||
updatePriorityProducts(productId: number, supplierId: number) {
|
||||
const applicablePriorityProducts$ = this.priorityProducts.get(supplierId);
|
||||
|
||||
if (!applicablePriorityProducts$) {
|
||||
return;
|
||||
}
|
||||
|
||||
applicablePriorityProducts$.next([
|
||||
productId,
|
||||
...applicablePriorityProducts$.value,
|
||||
]);
|
||||
}
|
||||
|
||||
// Delete priority products
|
||||
deletePriorityProducts() {
|
||||
this.priorityProducts = new Map<number, BehaviorSubject<number[]>>([
|
||||
[1, new BehaviorSubject<number[]>([])],
|
||||
[2, new BehaviorSubject<number[]>([])],
|
||||
]);
|
||||
}
|
||||
|
||||
// Products that need to be removed from priority list
|
||||
removePriorityProducts(productId: number, supplierId: number) {
|
||||
const applicablePriorityProducts$ = this.priorityProducts.get(supplierId);
|
||||
|
||||
if (!applicablePriorityProducts$) {
|
||||
return;
|
||||
}
|
||||
|
||||
applicablePriorityProducts$.next(
|
||||
applicablePriorityProducts$.value.filter((id) => productId !== id)
|
||||
);
|
||||
|
||||
// TODO Only temporary until applicable supplierId is known
|
||||
const tempSupplierId = supplierId === 1 ? 2 : 1;
|
||||
const applicablePriorityProducts2$ = this.priorityProducts.get(
|
||||
tempSupplierId
|
||||
);
|
||||
applicablePriorityProducts2$.next(
|
||||
applicablePriorityProducts$.value.filter((id) => productId !== id)
|
||||
);
|
||||
}
|
||||
|
||||
getProductGroupNames(
|
||||
stockId: number
|
||||
): Observable<KeyValueDTO<string, string>[]> {
|
||||
if (!this.productGroupNames$) {
|
||||
this.productGroupNames$ = this.remiService
|
||||
.productgroups({ stockId })
|
||||
.pipe(map((response) => response.result))
|
||||
.pipe(shareReplay());
|
||||
}
|
||||
|
||||
return this.productGroupNames$;
|
||||
}
|
||||
|
||||
getRemissionproducts({
|
||||
filter,
|
||||
stockId,
|
||||
}: {
|
||||
filter: RemissionFilter;
|
||||
stockId: number;
|
||||
}) {
|
||||
let allProducts$: Observable<{
|
||||
skip?: number;
|
||||
take?: number;
|
||||
hits?: number;
|
||||
items: RemissionProduct[];
|
||||
completed: boolean;
|
||||
}>;
|
||||
|
||||
const filter$ = this.restFilterService.createQueryRemiTokenFilter({
|
||||
remissionSourceType: filter.source,
|
||||
remissionTargetName: filter.target.name,
|
||||
stockId,
|
||||
filter,
|
||||
});
|
||||
|
||||
if (filter.source === 'ueberlauf') {
|
||||
const mapper = this.mapping.get<
|
||||
Mapper<ReturnSuggestionDTO, RemissionProduct>
|
||||
>('ReturnSuggestionDTO', 'RemissionProduct');
|
||||
|
||||
const regularProducts$ = filter$.pipe(
|
||||
switchMap((qtFilter) =>
|
||||
this.remiService.ueberlauf({
|
||||
queryToken: {
|
||||
stockId,
|
||||
supplierId: filter.target.id,
|
||||
filter: qtFilter,
|
||||
skip: filter.skip,
|
||||
take: filter.take,
|
||||
},
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
allProducts$ = regularProducts$.pipe(
|
||||
take(1),
|
||||
map((regular) => ({
|
||||
skip: regular.skip,
|
||||
take: regular.take,
|
||||
hits: regular.hits,
|
||||
completed:
|
||||
regular.completed || regular.skip + regular.take > regular.hits,
|
||||
items: [...regular.result].map((item) => mapper.map(item)),
|
||||
}))
|
||||
);
|
||||
} else if (filter.source === 'zentral') {
|
||||
const mapper = this.mapping.get<Mapper<ReturnItemDTO, RemissionProduct>>(
|
||||
'ReturnItemDTO',
|
||||
'RemissionProduct'
|
||||
);
|
||||
|
||||
const applicablePriorityProducts$ = this.priorityProducts.get(
|
||||
filter.target.id
|
||||
);
|
||||
|
||||
const showPriorityProducts = (priorityProductIds) => {
|
||||
if (!priorityProductIds.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!filter.filter || !filter.filter.zentral) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const filterToCheck = filter.filter.zentral;
|
||||
const filterGroups = Object.keys(filterToCheck[filter.target.name]);
|
||||
let isFilterSet = false;
|
||||
|
||||
for (const group of filterGroups) {
|
||||
if (!!filterToCheck[filter.target.name][group].length) {
|
||||
isFilterSet = true;
|
||||
}
|
||||
}
|
||||
|
||||
return !isFilterSet;
|
||||
};
|
||||
|
||||
const priorityItems$ = applicablePriorityProducts$.pipe(
|
||||
switchMap((ids) => (!!showPriorityProducts(ids) ? of(ids) : of([]))),
|
||||
mergeMap((ids) =>
|
||||
forkJoin(
|
||||
ids.map((id) => this.returnApi.getReturnItemById({ itemId: id }))
|
||||
)
|
||||
),
|
||||
map((products) => products.map((product) => product.result)),
|
||||
startWith([]),
|
||||
map((products) => products.slice(filter.skip))
|
||||
);
|
||||
|
||||
const regularProducts$ = filter$.pipe(
|
||||
switchMap((qtFilter) =>
|
||||
this.remiService.pflichtremissionsartikel({
|
||||
queryToken: {
|
||||
stockId,
|
||||
supplierId: filter.target.id,
|
||||
filter: qtFilter,
|
||||
skip: filter.skip,
|
||||
take: filter.take,
|
||||
},
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
allProducts$ = combineLatest([regularProducts$, priorityItems$]).pipe(
|
||||
map(([regular, priority]) => ({
|
||||
skip: regular.skip,
|
||||
take: regular.take,
|
||||
hits: regular.hits,
|
||||
completed:
|
||||
regular.completed || regular.skip + regular.take > regular.hits,
|
||||
items: [...priority, ...regular.result].map((item) =>
|
||||
mapper.map(item)
|
||||
),
|
||||
}))
|
||||
);
|
||||
}
|
||||
|
||||
// Setzen der productGroup im RemissionProduct
|
||||
const result1$ = allProducts$.pipe(
|
||||
flatMap((products) => {
|
||||
const itemsWithGroupnames$ = this.addGroupnameToProducts(
|
||||
products.items,
|
||||
stockId
|
||||
);
|
||||
|
||||
return itemsWithGroupnames$.pipe(
|
||||
map((items) => ({
|
||||
...products,
|
||||
items,
|
||||
}))
|
||||
);
|
||||
})
|
||||
);
|
||||
|
||||
// Setzen des Lagerbestands im Remissionproduct
|
||||
const result2$ = result1$.pipe(
|
||||
flatMap((result) =>
|
||||
!result.items.length
|
||||
? of({ items: [], completed: true })
|
||||
: this.remiService
|
||||
.inStock({
|
||||
stockId,
|
||||
articleIds:
|
||||
result.items &&
|
||||
result.items
|
||||
.filter((item) => !!item.catalogProductNumber)
|
||||
.map((product) => Number(product.catalogProductNumber)),
|
||||
})
|
||||
.pipe(
|
||||
rxjsFilter((stocks) => !stocks.error),
|
||||
map((stocks) => {
|
||||
return {
|
||||
...result,
|
||||
items: result.items.map((item) => {
|
||||
const stock = stocks.result.find(
|
||||
(info) => info.itemId === +item.catalogProductNumber
|
||||
);
|
||||
|
||||
if (!stock) {
|
||||
const defaultStockData = {
|
||||
inStock: 0,
|
||||
remainingQuantity: 0,
|
||||
remissionQuantity: item.remissionQuantity || 0,
|
||||
};
|
||||
return { ...item, ...defaultStockData };
|
||||
}
|
||||
|
||||
// Available stock after stock in active remission
|
||||
const availableStock =
|
||||
stock.inStock - stock.removedFromStock;
|
||||
const remainingStock =
|
||||
availableStock < 0 ? 0 : availableStock;
|
||||
|
||||
return {
|
||||
...item,
|
||||
inStock: remainingStock,
|
||||
remainingQuantity:
|
||||
typeof item.remainingQuantity === 'number'
|
||||
? item.remainingQuantity
|
||||
: remainingStock - (item.remissionQuantity || 0) >=
|
||||
0
|
||||
? remainingStock - (item.remissionQuantity || 0)
|
||||
: 0,
|
||||
remissionQuantity:
|
||||
typeof item.remissionQuantity === 'number'
|
||||
? item.remissionQuantity
|
||||
: remainingStock - (item.remainingQuantity || 0),
|
||||
};
|
||||
}),
|
||||
};
|
||||
})
|
||||
)
|
||||
),
|
||||
map((products) => {
|
||||
products.items = products.items.filter(
|
||||
(item) => !!item && item.inStock !== (undefined || null)
|
||||
);
|
||||
return products;
|
||||
})
|
||||
);
|
||||
|
||||
return result2$;
|
||||
}
|
||||
|
||||
addGroupnameToProducts(
|
||||
products: RemissionProduct[],
|
||||
stockId: number
|
||||
): Observable<RemissionProduct[]> {
|
||||
if (!products.length) {
|
||||
return of(products);
|
||||
}
|
||||
|
||||
const productGroupNames$ = this.getProductGroupNames(stockId);
|
||||
|
||||
return productGroupNames$.pipe(
|
||||
map((groupNames) =>
|
||||
products.map((product) => {
|
||||
const proudctGroupNameMatch = groupNames.find(
|
||||
(name) => name.key === product.productGroup
|
||||
);
|
||||
return {
|
||||
...product,
|
||||
productGroupName: proudctGroupNameMatch
|
||||
? proudctGroupNameMatch.value
|
||||
: '',
|
||||
} as RemissionProduct;
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
5
apps/isa/remission/src/lib/services/index.ts
Normal file
5
apps/isa/remission/src/lib/services/index.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
// start:ng42.barrel
|
||||
export * from './process-store.service';
|
||||
export * from './remission.service';
|
||||
export * from './rest-remission.service';
|
||||
// end:ng42.barrel
|
||||
39
apps/isa/remission/src/lib/services/process-store.service.ts
Normal file
39
apps/isa/remission/src/lib/services/process-store.service.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import { RemissionProcess } from '../models/remission-process';
|
||||
import { compare } from '../utils/compare';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class ProcessStoreService {
|
||||
private readonly store: Map<number, BehaviorSubject<RemissionProcess>> = new Map();
|
||||
|
||||
constructor() {}
|
||||
|
||||
set(process: RemissionProcess) {
|
||||
let processSub: BehaviorSubject<RemissionProcess> = this.get(process.id);
|
||||
|
||||
if (processSub instanceof BehaviorSubject) {
|
||||
if (!compare(processSub.value, process)) {
|
||||
processSub.next(process);
|
||||
}
|
||||
} else {
|
||||
processSub = new BehaviorSubject(process);
|
||||
this.store.set(process.id, processSub);
|
||||
}
|
||||
|
||||
return processSub;
|
||||
}
|
||||
|
||||
get(processId: number) {
|
||||
return this.store.get(processId);
|
||||
}
|
||||
|
||||
remove(processId: number) {
|
||||
const processSub = this.get(processId);
|
||||
|
||||
if (processSub instanceof BehaviorSubject) {
|
||||
processSub.complete();
|
||||
this.store.delete(processId);
|
||||
}
|
||||
}
|
||||
}
|
||||
323
apps/isa/remission/src/lib/services/remission.service.ts
Normal file
323
apps/isa/remission/src/lib/services/remission.service.ts
Normal file
@@ -0,0 +1,323 @@
|
||||
import { Observable } from 'rxjs';
|
||||
import { RemissionProcess } from '../models/remission-process';
|
||||
import { RemissionProduct } from '../models/remission-product';
|
||||
import { RemissionFilter } from '../models/remission-filter';
|
||||
import { Printer } from '../models/printer';
|
||||
import { Product } from '../models/product';
|
||||
import { RemissionSourceType } from '../types/remission-source.type';
|
||||
import { Filter } from '../models/filter';
|
||||
import { RemissionPlacementType } from '../types/remission-placement-types';
|
||||
import { RemissionSupplier } from '../models/remission-supplier';
|
||||
import { ShippingDocument } from '../models/shipping-document';
|
||||
import { ActionResult, CapacityType } from '../models';
|
||||
|
||||
export abstract class RemissionService {
|
||||
/**
|
||||
* Notwendige Informationen für View (Start-Screen) und Starten einer Remission
|
||||
* @returns Remission Prozess Default Settings
|
||||
*/
|
||||
abstract createProcess(
|
||||
source?: RemissionProcess
|
||||
): Observable<RemissionProcess>;
|
||||
|
||||
/**
|
||||
* Wiederaufnahme eines vorhandenen Prozesses
|
||||
*/
|
||||
abstract continueProcess(
|
||||
source: RemissionProcess
|
||||
): Observable<RemissionProcess>;
|
||||
|
||||
/**
|
||||
* Wiederaufnahme eines vorhandenen Prozesses anhand der PachstückId
|
||||
*/
|
||||
abstract continueProcessFromScan(
|
||||
containerId: string
|
||||
): Observable<RemissionProcess>;
|
||||
|
||||
/**
|
||||
* Starten einer Remission
|
||||
* @param params.remissionProcessId Remissionsnummer
|
||||
* @returns Remissionsprozess
|
||||
*/
|
||||
abstract startRemission(params: {
|
||||
remissionProcessId: number;
|
||||
createShippingDocument?: boolean;
|
||||
}): Observable<RemissionProcess>;
|
||||
|
||||
/**
|
||||
* Remission abschließen
|
||||
* @param params.remissionProcessId Remissionsnummer
|
||||
* @returns Ergebnis des Remissionsabschlusses
|
||||
*/
|
||||
protected abstract completeRemission(params: {
|
||||
remissionProcessId: number;
|
||||
}): Observable<boolean>;
|
||||
|
||||
/**
|
||||
* Alle Remissionen abschließen
|
||||
* @param params.remissionProcessId Remissionsnummer
|
||||
* @returns Ergebnis des Remissionsabschlusses
|
||||
*/
|
||||
abstract completeRemissions(params: {
|
||||
remissionProcessId: number;
|
||||
}): Observable<boolean>;
|
||||
|
||||
/**
|
||||
* Abruf einer Remission
|
||||
* @param params.remissionProcessId Remissionsnummer
|
||||
* @returns Remissionsprozess
|
||||
*/
|
||||
abstract getRemission(params: {
|
||||
remissionProcessId: number;
|
||||
}): Observable<RemissionProcess>;
|
||||
|
||||
/**
|
||||
* Gibt anhand der remissionprocessId und der darin
|
||||
* definierten Einstellungen die Produktliste zurück
|
||||
* @param params param.remissionProcessId
|
||||
* @param params param.skip
|
||||
* @param params param.take
|
||||
* @returns Produktliste und Metainformationen (skip, take, completed)
|
||||
*/
|
||||
abstract getRemissionProducts(params: {
|
||||
remissionProcessId: number;
|
||||
}): Observable<{
|
||||
skip?: number;
|
||||
take?: number;
|
||||
hits?: number;
|
||||
items: RemissionProduct[];
|
||||
completed: boolean;
|
||||
}>;
|
||||
|
||||
/**
|
||||
* Aktualisieren der Remissions-Filter
|
||||
* @param changes.remissionProcessId Remissionsnummer
|
||||
* @param changes.changes Remissionsfilter
|
||||
* @returns Remissionsfilter
|
||||
*/
|
||||
abstract updateRemissionFilter(changes: {
|
||||
remissionProcessId: number;
|
||||
changes: Partial<RemissionFilter>;
|
||||
}): Observable<RemissionFilter>;
|
||||
|
||||
/**
|
||||
* Abfrage ob für Remission Druckauftrag erforderlich
|
||||
* @param remissionProcessId Remissionsnummer
|
||||
* @returns Ob physischer Druck nötig
|
||||
*/
|
||||
abstract isPrintingRequired(params: {
|
||||
remissionProcessId: number;
|
||||
}): Observable<boolean>;
|
||||
|
||||
/**
|
||||
* Abfrage der verfügbaren Drucker
|
||||
* @returns Liste der verfügbaren Drucker
|
||||
*/
|
||||
abstract getPrinters(): Observable<Printer[]>;
|
||||
|
||||
/**
|
||||
* Druckauftrag für Remissionsliste
|
||||
* @param remissionProcessId Remissionsnummer
|
||||
* @param params.printerKey Name des Druckers
|
||||
* @returns Ob Druckauftrag ausgeführt wurde
|
||||
*/
|
||||
abstract printRemissionList(params: {
|
||||
remissionProcessId: number;
|
||||
printerKey: string;
|
||||
}): Observable<boolean>;
|
||||
|
||||
/**
|
||||
* Druckauftrag für Warenbegleitschein
|
||||
* @param params.remissionProcessId Remissionsnummer
|
||||
* @param params.shippingDocumentId ID des Warenbegleitscheins (default: alle Warenbegleitscheine)
|
||||
* @param params.printerKey Name des Druckers
|
||||
* @returns Ob Druckauftrag ausgeführt wurde
|
||||
*/
|
||||
abstract printShippingDocument(params: {
|
||||
remissionProcessId: number;
|
||||
shippingDocumentId?: number;
|
||||
printerKey: string;
|
||||
}): Observable<boolean>;
|
||||
|
||||
/**
|
||||
* Produktsuche über EAN
|
||||
* @param ean Artikelidentifikationsnummer
|
||||
* @returns Produktinformation zur Artikelidentifikationsnummer
|
||||
*/
|
||||
abstract searchProduct(params: { ean: string }): Observable<Product>;
|
||||
|
||||
/**
|
||||
* Anwendbare Filter für die Suche
|
||||
* @param remissionSourceType Artikel-Ursprung (z.B. 'zentral')
|
||||
* @returns Mögliche Filteroptionen (inkl. Sub-gruppen)
|
||||
*/
|
||||
abstract getFilters(params: {
|
||||
remissionProcessId: number;
|
||||
}): Observable<Filter[]>;
|
||||
|
||||
/**
|
||||
* Arten der Produktplatzierung (z.B. Stapelplatz)
|
||||
* @returns Mögliche Platzierungen eines Produkts
|
||||
*/
|
||||
abstract getPlacementTypes(): Observable<RemissionPlacementType[]>;
|
||||
|
||||
/**
|
||||
* Gründe für Remission (z.B. beschädigtes Exemplar)
|
||||
* @returns Mögliche Gründe für Remission
|
||||
*/
|
||||
abstract getRemissionReasons(): Observable<string[]>;
|
||||
|
||||
/**
|
||||
* Remissions-Ziele / Lieferanten (z.B. Libri, Blank)
|
||||
* @returns Mägliche Remissions-Ziele
|
||||
*/
|
||||
abstract getRemissionTargets(): Observable<RemissionSupplier[]>;
|
||||
|
||||
/**
|
||||
* Artikel-Ursprung (z.B. zentrales Sortiment oder Überlauf)
|
||||
* @returns Mögliche Artikel-Ursprünge
|
||||
*/
|
||||
abstract getRemissionSources(): Observable<RemissionSourceType[]>;
|
||||
|
||||
/**
|
||||
* Abfrage der Kapazitätsauslastung
|
||||
* @returns Kapazitätsauslastung
|
||||
*/
|
||||
abstract getCapacities(params: {
|
||||
selectedFilters?: { [filterId: string]: string[] };
|
||||
supplierId: number;
|
||||
}): Observable<CapacityType[]>;
|
||||
|
||||
/**
|
||||
* Abruf eines Warenbegleitscheins (Shipping Documents)
|
||||
* @param params.remissionProcessId Remissionsnummer
|
||||
* @param params.shippingDocumentId ID des Warenbegleitscheins
|
||||
* @returns Warenbegleitscheins
|
||||
*/
|
||||
abstract getShippingDocuments(params: {
|
||||
remissionProcessId: number;
|
||||
shippingDocumentId: number;
|
||||
}): Observable<ShippingDocument>;
|
||||
|
||||
/**
|
||||
* Entfernen eiens Produkts von der Remissionsliste
|
||||
* @param input.remissionProcessId Remissionsnummer
|
||||
* @param input.product Remissionsprodukt
|
||||
* @returns Ob Produkt entfernt werden konnte
|
||||
*/
|
||||
abstract deleteProductFromRemissionList(input: {
|
||||
remissionProcessId: number;
|
||||
remissionProductId: number;
|
||||
}): Observable<ActionResult<boolean>>;
|
||||
|
||||
/**
|
||||
* Produkt der Remissionsliste hinzufügen
|
||||
* @param input.remissionProductId ID des hinzuzufügenden Produkts
|
||||
* @param input.remissionReason Remissionsgrund
|
||||
* @param input.remissionQuantity Anzahl der zur Remission hinzuzufügenden Exemplare
|
||||
* @returns Produktinformation über Remissionsprodukt
|
||||
*/
|
||||
abstract addProductToRemit(input: {
|
||||
product: Product;
|
||||
remissionReason: string;
|
||||
remissionQuantity: number;
|
||||
}): Observable<RemissionProduct>;
|
||||
|
||||
/**
|
||||
* Artikel zu Warenbegleitschein hinzufügen
|
||||
* @param params.remissionProcessId Remissionsnummer
|
||||
* @param params.remissionProductId ID des hinzuzufügenden Produkts
|
||||
* @param params.shippingDocumentId ID des Warenbegleitscheins
|
||||
* @param params.placementType Platzierungsart (z.B. Stapelplatz)
|
||||
* @param params.quantity Anzahl der zu hinzuzufügenden Exemplare
|
||||
* @returns Ob Artikel dem Warenbegleitschein hinzugefügt werden konnte
|
||||
*/
|
||||
abstract addProductToShippingDocument(params: {
|
||||
remissionProcessId: number;
|
||||
remissionProductId: number;
|
||||
shippingDocumentId: number;
|
||||
placementType?: string;
|
||||
quantity?: number;
|
||||
inStock?: number;
|
||||
predefinedRemissionQuantity?: number;
|
||||
}): Observable<ActionResult<boolean>>;
|
||||
|
||||
/**
|
||||
* Artikel von Warenbegleitschein entfernen
|
||||
* @param params.remissionProcessId Remissionsnummer
|
||||
* @param params.shippingDocumentId ID des Warenbegleitscheins
|
||||
* @param params.remissionProductId ID des entfernenden Produkts
|
||||
* @param params.placementType Platzierungsart (default: alle)
|
||||
* @returns Ob Artikel vom Warenbegleitschein entfernt werden konnte
|
||||
*/
|
||||
abstract removeProductFromShippingDocument(params: {
|
||||
remissionProcessId: number;
|
||||
remissionProductId: number;
|
||||
shippingDocumentId: number;
|
||||
placementType?: string;
|
||||
}): Observable<boolean>;
|
||||
|
||||
/**
|
||||
* Neuladen/Refresh der Remissions-Produkte (getRemission-Products Stream)
|
||||
* Beispiel: CtA 'Filtern" in Filter
|
||||
* @param params.remissionProcessId Remissionsnummer
|
||||
*/
|
||||
abstract reloadProducts(params: { remissionProcessId: number }): void;
|
||||
|
||||
/**
|
||||
* Warenbegleitschein abschließen
|
||||
* @param params.remissionProcessId Remissionsnummer
|
||||
* @param params.shippingDocumentId ID des Warenbegleitscheins
|
||||
* @param params.containerId Wannennummer
|
||||
* @returns Ob Warenbegleitschein abgeschlossen werden konnte
|
||||
*/
|
||||
abstract completeShippingDocument(params: {
|
||||
remissionProcessId: number;
|
||||
shippingDocumentId: number;
|
||||
containerId: string;
|
||||
}): Observable<ActionResult<boolean>>;
|
||||
|
||||
/**
|
||||
* Warenbegleitschein anlegen
|
||||
* @param params.remissionProcessId Remissionsprozess
|
||||
* @param params.shippingDocumentId PachstückId
|
||||
* @returns Neu erstellten Warenbegleitschein
|
||||
*/
|
||||
abstract createShippingDocument(params: {
|
||||
remissionProcessId: number;
|
||||
}): Observable<ShippingDocument>;
|
||||
|
||||
/**
|
||||
* Liste aller Remissionen
|
||||
*/
|
||||
abstract getAllRemissions(params: {
|
||||
showOpen?: boolean;
|
||||
showOpenLastWeekOnly?: boolean;
|
||||
showCompleted?: boolean;
|
||||
showCompletedLastWeekOnly?: boolean;
|
||||
receiptNumber?: string;
|
||||
returnGroup?: number;
|
||||
take?: number;
|
||||
}): Observable<RemissionProcess[]>;
|
||||
|
||||
/**
|
||||
* Liste nicht abgeschlossener Remissionen
|
||||
*/
|
||||
abstract getUncompletedRemissions(): Observable<RemissionProcess[]>;
|
||||
|
||||
/**
|
||||
* Remission abbrechen
|
||||
*/
|
||||
abstract deleteRemission(params: {
|
||||
remissionProcessId: number;
|
||||
externalId?: number;
|
||||
}): Observable<boolean>;
|
||||
|
||||
abstract deleteShippingDocument(params: {
|
||||
remissionProcessId: number;
|
||||
shippingDocumentId: number;
|
||||
externalId?: number;
|
||||
}): Observable<
|
||||
ActionResult<{ deleted: boolean; completedRemissionsExist: boolean }>
|
||||
>;
|
||||
}
|
||||
1700
apps/isa/remission/src/lib/services/rest-remission.service.ts
Normal file
1700
apps/isa/remission/src/lib/services/rest-remission.service.ts
Normal file
File diff suppressed because it is too large
Load Diff
4
apps/isa/remission/src/lib/types/index.ts
Normal file
4
apps/isa/remission/src/lib/types/index.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
// start:ng42.barrel
|
||||
export * from './remission-placement-types';
|
||||
export * from './remission-source.type';
|
||||
// end:ng42.barrel
|
||||
@@ -0,0 +1 @@
|
||||
export type RemissionPlacementType = 'Leistung' | 'Stapel';
|
||||
@@ -0,0 +1 @@
|
||||
export type RemissionSourceType = 'zentral' | 'ueberlauf';
|
||||
6
apps/isa/remission/src/lib/utils/add-days.ts
Normal file
6
apps/isa/remission/src/lib/utils/add-days.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
export function addDays(startDate: Date, daysToAdd: number): Date {
|
||||
const baseDate = new Date(startDate);
|
||||
const newDate = baseDate.setDate(startDate.getDate() + daysToAdd);
|
||||
|
||||
return new Date(newDate);
|
||||
}
|
||||
46
apps/isa/remission/src/lib/utils/compare.ts
Normal file
46
apps/isa/remission/src/lib/utils/compare.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
export function compare<T>(val1: T, val2: T): boolean {
|
||||
if (!val1 && !val2) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!!val1 && !val2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (typeof val1 !== typeof val2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Array.isArray(val1) && Array.isArray(val2)) {
|
||||
if (val1.length !== val2.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let index = 0; index < val1.length; index++) {
|
||||
if (!compare(val1[index], val2[index])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (typeof val1 === 'object') {
|
||||
if (Object.keys(val1).length !== Object.keys(val2).length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const key in { ...val1, ...val2 }) {
|
||||
if (val1.hasOwnProperty(key) && val2.hasOwnProperty(key)) {
|
||||
if (!compare(val1[key], val2[key])) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return val1 === val2;
|
||||
}
|
||||
11
apps/isa/remission/src/public-api.ts
Normal file
11
apps/isa/remission/src/public-api.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
/*
|
||||
* Public API Surface of remission
|
||||
*/
|
||||
export * from './lib/generators';
|
||||
export * from './lib/mock';
|
||||
export * from './lib/models';
|
||||
export * from './lib/remission-module.options';
|
||||
export * from './lib/remission.module';
|
||||
export * from './lib/rest';
|
||||
export * from './lib/services';
|
||||
export * from './lib/types';
|
||||
16
apps/isa/remission/src/test.ts
Normal file
16
apps/isa/remission/src/test.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
|
||||
|
||||
import 'core-js/es7/reflect';
|
||||
import 'zone.js/dist/zone';
|
||||
import 'zone.js/dist/zone-testing';
|
||||
import { getTestBed } from '@angular/core/testing';
|
||||
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
|
||||
|
||||
declare const require: any;
|
||||
|
||||
// First, initialize the Angular testing environment.
|
||||
getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
|
||||
// Then we find all the tests.
|
||||
const context = require.context('./', true, /\.spec\.ts$/);
|
||||
// And load the modules.
|
||||
context.keys().map(context);
|
||||
26
apps/isa/remission/tsconfig.lib.json
Normal file
26
apps/isa/remission/tsconfig.lib.json
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"extends": "../../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../../out-tsc/lib",
|
||||
"target": "es2015",
|
||||
"declaration": true,
|
||||
"inlineSources": true,
|
||||
"types": [],
|
||||
"lib": [
|
||||
"dom",
|
||||
"es2018"
|
||||
]
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"annotateForClosureCompiler": true,
|
||||
"skipTemplateCodegen": true,
|
||||
"strictMetadataEmit": true,
|
||||
"fullTemplateTypeCheck": true,
|
||||
"strictInjectionParameters": true,
|
||||
"enableResourceInlining": true
|
||||
},
|
||||
"exclude": [
|
||||
"src/test.ts",
|
||||
"**/*.spec.ts"
|
||||
]
|
||||
}
|
||||
17
apps/isa/remission/tsconfig.spec.json
Normal file
17
apps/isa/remission/tsconfig.spec.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"extends": "../../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../../out-tsc/spec",
|
||||
"types": [
|
||||
"jasmine",
|
||||
"node"
|
||||
]
|
||||
},
|
||||
"files": [
|
||||
"src/test.ts"
|
||||
],
|
||||
"include": [
|
||||
"**/*.spec.ts",
|
||||
"**/*.d.ts"
|
||||
]
|
||||
}
|
||||
17
apps/isa/remission/tslint.json
Normal file
17
apps/isa/remission/tslint.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"extends": "../../../tslint.json",
|
||||
"rules": {
|
||||
"directive-selector": [
|
||||
true,
|
||||
"attribute",
|
||||
"lib",
|
||||
"camelCase"
|
||||
],
|
||||
"component-selector": [
|
||||
true,
|
||||
"element",
|
||||
"lib",
|
||||
"kebab-case"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,8 @@ This library was generated with [Angular CLI](https://github.com/angular/angular
|
||||
## Code scaffolding
|
||||
|
||||
Run `ng generate component component-name --project native-container` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project native-container`.
|
||||
> Note: Don't forget to add `--project native-container` or else it will be added to the default project in your `angular.json` file.
|
||||
|
||||
> Note: Don't forget to add `--project native-container` or else it will be added to the default project in your `angular.json` file.
|
||||
|
||||
## Build
|
||||
|
||||
|
||||
@@ -10,15 +10,15 @@ module.exports = function (config) {
|
||||
require('karma-chrome-launcher'),
|
||||
require('karma-jasmine-html-reporter'),
|
||||
require('karma-coverage-istanbul-reporter'),
|
||||
require('@angular-devkit/build-angular/plugins/karma')
|
||||
require('@angular-devkit/build-angular/plugins/karma'),
|
||||
],
|
||||
client: {
|
||||
clearContext: false // leave Jasmine Spec Runner output visible in browser
|
||||
clearContext: false, // leave Jasmine Spec Runner output visible in browser
|
||||
},
|
||||
coverageIstanbulReporter: {
|
||||
dir: require('path').join(__dirname, '../../coverage/native-container'),
|
||||
reports: ['html', 'lcovonly', 'text-summary'],
|
||||
fixWebpackSourcePaths: true
|
||||
fixWebpackSourcePaths: true,
|
||||
},
|
||||
reporters: ['progress', 'kjhtml'],
|
||||
port: 9876,
|
||||
@@ -27,6 +27,6 @@ module.exports = function (config) {
|
||||
autoWatch: true,
|
||||
browsers: ['Chrome'],
|
||||
singleRun: false,
|
||||
restartOnFileChange: true
|
||||
restartOnFileChange: true,
|
||||
});
|
||||
};
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user