Compare commits
668 Commits
devel_10.2
...
developmen
Author | SHA1 | Date |
---|---|---|
|
064112e731 | |
|
d6a238a224 | |
|
dc5e938f75 | |
|
eb4da7ccc4 | |
|
46caaba6bd | |
|
7953c7dbbd | |
|
6911f6f0a2 | |
|
762340a72b | |
|
61cbbf81ef | |
|
4ea53f7088 | |
|
0548141e5f | |
|
29e4dc5400 | |
|
f9d8f85179 | |
|
769e8174f4 | |
|
3ace59c450 | |
|
187555a543 | |
|
551bd12f5b | |
|
1692c8234a | |
|
903b7cfd18 | |
|
26a6af2044 | |
|
d7ed77934d | |
|
66720c5b8b | |
|
44e74de315 | |
|
82e7879969 | |
|
d612b6725a | |
|
54b9658075 | |
|
661dbb8cf2 | |
|
6dc6579450 | |
|
e3db958e0d | |
|
d73752252a | |
|
b38c489777 | |
|
8cfc003261 | |
|
55e89426d9 | |
|
5f6214eeb6 | |
|
d71c2096b8 | |
|
f661276c58 | |
|
4a3e77043e | |
|
b4f141e628 | |
|
9db5c4b326 | |
|
f7e3d5399c | |
|
7305dfd068 | |
|
b4bc31463e | |
|
83d53847d7 | |
|
e09190df42 | |
|
61045a39ab | |
|
60b5bcf638 | |
|
4eedca12e7 | |
|
cb452cf5f3 | |
|
ea25e0cae1 | |
|
5e4401a974 | |
|
c05af5c16b | |
|
5988a592ac | |
|
1148a72481 | |
|
3b7d7ea80b | |
|
3b19484f29 | |
|
4dc21c4ebd | |
|
99d0fc8560 | |
|
ac3fde14e3 | |
|
8d54c686fc | |
|
c0a68db9f1 | |
|
3cf4fbdada | |
|
9eacb7dca5 | |
|
eae529bce9 | |
|
a0de16575f | |
|
53ef4656eb | |
|
ec916ab574 | |
|
72827aa83e | |
|
0e9ae569ba | |
|
37334ecb19 | |
|
86c73058fd | |
|
fb7f925c78 | |
|
2b132c53a8 | |
|
e9535749d4 | |
|
94696e765d | |
|
9805b9903a | |
|
af9818d44c | |
|
2bcd7a34fb | |
|
577f8ea9ea | |
|
1878d03c0f | |
|
6807d00cbe | |
|
ad3e3593fd | |
|
8e7e43b09d | |
|
6c53610ec4 | |
|
c129a59d47 | |
|
d413f1fa7b | |
|
bf5914af92 | |
|
28c1ab36da | |
|
3ed25e1366 | |
|
4c403293db | |
|
dac42b754c | |
|
5ef7521e9b | |
|
ba7b81c320 | |
|
7137b98043 | |
|
3ddd837622 | |
|
217362193a | |
|
a3647b536b | |
|
5f46432327 | |
|
319d9eecef | |
|
50e7f66bb7 | |
|
492a4ca2ba | |
|
4ed7ecce5e | |
|
e6787aed89 | |
|
1d54b709b6 | |
|
bd32d4fbdd | |
|
78fb5b7fac | |
|
dea9989914 | |
|
c8d0b32cc6 | |
|
93b1208278 | |
|
86251f43a2 | |
|
9977a7456a | |
|
487f59ae93 | |
|
e9de46fff8 | |
|
5b507a1c3c | |
|
143bf76417 | |
|
ac86289182 | |
|
32d4064f0a | |
|
01b2796c26 | |
|
e9d864c922 | |
|
d6c02ac29f | |
|
4f0b378ec6 | |
|
efa245048a | |
|
2d0ccf67f2 | |
|
77cf19c06e | |
|
77a6afbbbc | |
|
fea0420ae4 | |
|
3eee8d73f4 | |
|
07d2ec3b46 | |
|
8ba5646bb6 | |
|
ce1aa86944 | |
|
4d20955764 | |
|
6a8816aa90 | |
|
8f43907091 | |
|
7afe06e96c | |
|
c0a0b2316d | |
|
95ee8dce8d | |
|
55ddc9b605 | |
|
e2a6878e71 | |
|
f2c409fc35 | |
|
7213e7915b | |
|
0e65fb8a9a | |
|
6efe5618cb | |
|
60167cd807 | |
|
0dfaeb2045 | |
|
18dc15e442 | |
|
198dcb4933 | |
|
901c67137b | |
|
411458fe4c | |
|
d911f80ff9 | |
|
79f3966b49 | |
|
e6066b534c | |
|
c5590ab7b1 | |
|
1a633cc574 | |
|
1348f5a79b | |
|
90ab3668b4 | |
|
49b98cd56c | |
|
d6ae891de4 | |
|
9026f85a66 | |
|
d40261e919 | |
|
e1c6b809e4 | |
|
c47f1e2616 | |
|
df0536157a | |
|
92bf8fc342 | |
|
437793a2a1 | |
|
48a48e6e7a | |
|
22f4e732db | |
|
34ae5964c4 | |
|
f2fef65f20 | |
|
039531de3b | |
|
0b8bb72392 | |
|
256c8f38bd | |
|
109898b076 | |
|
b2be2e0160 | |
|
b4266d5d68 | |
|
f23a9f3510 | |
|
91370940d7 | |
|
c15b4d8079 | |
|
b16edb73e3 | |
|
ea58096287 | |
|
1dfcaf7b15 | |
|
8b58598955 | |
|
5eb50c952f | |
|
aaa0ca6f76 | |
|
3de7bfbbe5 | |
|
60c03fefa0 | |
|
b34d54e7d0 | |
|
3fd97b8879 | |
|
93c822f34e | |
|
e09c76309e | |
|
43deb04d92 | |
|
23043fb7f9 | |
|
1d377b574c | |
|
7d9f619858 | |
|
c06a2a0a2b | |
|
cc71814648 | |
|
004dfc9de5 | |
|
09d6dbaab2 | |
|
c76594d767 | |
|
f4cf5178b8 | |
|
ffbbf6e140 | |
|
614a9346fb | |
|
f7c49d27d5 | |
|
2ee96a617f | |
|
10049abc55 | |
|
01fbedab77 | |
|
b2659def9a | |
|
d597734467 | |
|
27a0c56af7 | |
|
50ac2d97a4 | |
|
d788a9f1a1 | |
|
c897e4fcde | |
|
14dd2880bc | |
|
3e920755bd | |
|
88b4c66139 | |
|
52c82a9a41 | |
|
19494b3328 | |
|
e1f2cdfa4d | |
|
918055beb9 | |
|
283b783007 | |
|
a2be2bb331 | |
|
d708ef9eee | |
|
9709c4719b | |
|
d2db62339f | |
|
07d1cc78e2 | |
|
8f430574ed | |
|
f7198010d3 | |
|
a1641504f1 | |
|
6c5019f814 | |
|
ff0ef28783 | |
|
40aafaf571 | |
|
6fbb2e33b2 | |
|
b20385dacc | |
|
6e5b19380b | |
|
ab9ec4ac0e | |
|
0457fc9e1d | |
|
3658ae4cdf | |
|
d1b20e6b96 | |
|
f4ecbf0e66 | |
|
7da22277f1 | |
|
bf73cb6b43 | |
|
6fb582204a | |
|
d283caa898 | |
|
1320492bf1 | |
|
4c25b2cbec | |
|
a6b1e5f49f | |
|
ac3ee266b9 | |
|
3720df31d8 | |
|
7fb2995f38 | |
|
07e7b86cd4 | |
|
db57b1973e | |
|
92d60d4496 | |
|
b716c75a2c | |
|
45306dde57 | |
|
539676aa30 | |
|
1a2a37d185 | |
|
5666c31dfa | |
|
665eacd39f | |
|
9d98003a2d | |
|
45c4bde838 | |
|
b9927da0c4 | |
|
d523009acd | |
|
457ce30cc1 | |
|
e7a7ffb2bc | |
|
2527437577 | |
|
ce372de1fd | |
|
7e7d40ea1a | |
|
8590165755 | |
|
cb9421622d | |
|
dc97d5e14a | |
|
79adf156db | |
|
9f50d56cea | |
|
4a13730231 | |
|
c3950c7041 | |
|
464c10722c | |
|
9815c667f0 | |
|
84b829a7fa | |
|
eaf0f43a24 | |
|
22b418b257 | |
|
d5adc48d9b | |
|
009576c841 | |
|
7c7b121b49 | |
|
8abdbb7b55 | |
|
fc15cb9db6 | |
|
9a72c40984 | |
|
f2bc4dd46d | |
|
f4387767a8 | |
|
8b82f9b7db | |
|
ee232447b6 | |
|
a2a9c16619 | |
|
6227555671 | |
|
fa286820fc | |
|
e966de6158 | |
|
50e8951b71 | |
|
cefeef8854 | |
|
f30a23d3c4 | |
|
dcf0a55dfc | |
|
3678353f34 | |
|
ab903d4554 | |
|
bd13f50bc0 | |
|
f4939ffe89 | |
|
4fe385bca1 | |
|
be7c74ec72 | |
|
88cc9f4bc3 | |
|
dc595dfb07 | |
|
211a1e8a3c | |
|
08e018e16b | |
|
cc62910493 | |
|
ff44be66e2 | |
|
b9b1695dc5 | |
|
617a08e3f2 | |
|
aaf6f97e57 | |
|
538bd0e58e | |
|
ceae06779e | |
|
5e78669b6c | |
|
a015353990 | |
|
01b4ee2bbd | |
|
c65f0dc9dc | |
|
c98b8da9ba | |
|
bca3682826 | |
|
11aeb44bac | |
|
07347c9244 | |
|
29cc6dfae6 | |
|
f9937d84ab | |
|
a14119719c | |
|
ae75578b65 | |
|
93fa32df80 | |
|
f7d7fba267 | |
|
ebcc5515e5 | |
|
b597a2f184 | |
|
7a6c784612 | |
|
d6fc817cef | |
|
89aa2a68b4 | |
|
64d812bef1 | |
|
3b8310581b | |
|
21b9549b52 | |
|
76b518614f | |
|
841f8889ec | |
|
bc8476a56e | |
|
fe6572a770 | |
|
acf8861823 | |
|
a319b64abe | |
|
3938504fd3 | |
|
3b07c8de99 | |
|
fc67c222f8 | |
|
f0c1410532 | |
|
c5fdca615f | |
|
e00a6aae31 | |
|
f5425ccfb1 | |
|
995f4b963c | |
|
13895394b3 | |
|
b36e35ea00 | |
|
e9c819987e | |
|
a61f8b853d | |
|
efe5661a57 | |
|
30d3d91bba | |
|
1fa4d315be | |
|
bcdf656d5d | |
|
63152ec90e | |
|
990d73bdb1 | |
|
1dae9ec356 | |
|
8de744bc58 | |
|
f8618ec0cd | |
|
1e8a07ec55 | |
|
810a1c5bf5 | |
|
1d8a3d7ff9 | |
|
b57da1d21a | |
|
8dd36042eb | |
|
72e47c2486 | |
|
cfb0d3c60f | |
|
0c3abc6a8f | |
|
1fcbe57018 | |
|
ba6ee4a408 | |
|
e4a631b929 | |
|
dbdc7a0203 | |
|
fcaf4a07a1 | |
|
9efa56b2bc | |
|
0658b503bd | |
|
9802d983bb | |
|
583b754315 | |
|
4ef139b2f5 | |
|
b137e1abce | |
|
e8baaa12d2 | |
|
6ca74ad6f7 | |
|
955f00cc9d | |
|
b48a469720 | |
|
61d8f56385 | |
|
2a42d85814 | |
|
bacdb1773b | |
|
655157239d | |
|
33014394d1 | |
|
aaee458df6 | |
|
ffcbf65d9d | |
|
2f19db8dd7 | |
|
e7664be8a8 | |
|
a2c1af2a65 | |
|
26db7d2745 | |
|
e922db827d | |
|
5dde995ab8 | |
|
79d1c564ff | |
|
e7abc7db13 | |
|
81a463e761 | |
|
c741a55577 | |
|
81dad9a69c | |
|
8999ed1bf0 | |
|
ebfcbb85fe | |
|
feee9a3439 | |
|
b05e6fab5a | |
|
37350e454f | |
|
b08325a53c | |
|
a1f7108bc5 | |
|
2e4d5df17a | |
|
4fcd852d8d | |
|
0f05656ca2 | |
|
0bec3c6590 | |
|
8eee99fce5 | |
|
239e2d778a | |
|
cc01b23e2a | |
|
0b502188af | |
|
e38fbc65bd | |
|
0e47b99ca7 | |
|
e401a1bf4c | |
|
1636f6b930 | |
|
d1892e7aa5 | |
|
d14d9101ae | |
|
746e24feb6 | |
|
39d7eb28b9 | |
|
9d0d76120e | |
|
971407612c | |
|
03ec533e86 | |
|
d413bd771b | |
|
11171b2859 | |
|
1e9cc9da4f | |
|
46307774e1 | |
|
62eccf29a5 | |
|
383fdce9f7 | |
|
1ae7f4e097 | |
|
33f955c209 | |
|
d4bd3d746c | |
|
45f11003f2 | |
|
2188d63943 | |
|
3af56fa5d5 | |
|
77d8e7ae1e | |
|
c49bb379bd | |
|
0648eeffee | |
|
e8deba2882 | |
|
19386c336e | |
|
58cf3f7ab0 | |
|
d7c4b27749 | |
|
0ac5754170 | |
|
b7557a5f19 | |
|
1590080468 | |
|
61c512f7f4 | |
|
30ffdca550 | |
|
c154af6cb7 | |
|
197b3478ae | |
|
c6be42299e | |
|
9bcc72a69e | |
|
dc6476a66f | |
|
4a9ca5eb5b | |
|
e1004b3843 | |
|
6632222c4b | |
|
945edbf76d | |
|
190f42d598 | |
|
d9bbe1290d | |
|
3e85d40885 | |
|
7e38a67e80 | |
|
b91d9f7da8 | |
|
bf8987242b | |
|
57f2700c94 | |
|
b3f0752ca0 | |
|
33438f37ec | |
|
593955574a | |
|
4ac711add5 | |
|
c7fa402663 | |
|
6096771597 | |
|
76fa380f1e | |
|
1f4bf80908 | |
|
66c481c9b0 | |
|
9cd50ad817 | |
|
82105e8214 | |
|
e68524380a | |
|
d333ba03a7 | |
|
a63eaf0110 | |
|
e32a7c2eaf | |
|
07f379a6b0 | |
|
39896fed90 | |
|
a671404947 | |
|
00d5eba7ab | |
|
d0163ae003 | |
|
aa550f9d38 | |
|
2fc80c7cfc | |
|
20848aab3c | |
|
d81eaac4f6 | |
|
679b98d198 | |
|
1ff5461311 | |
|
2f9c96bdec | |
|
b1bc05fcb9 | |
|
ef2697a3b1 | |
|
000c3f1800 | |
|
c5cec31ab5 | |
|
cc92ef26a1 | |
|
1560cb0512 | |
|
fba7b9aae5 | |
|
0b236cb879 | |
|
41f4773df6 | |
|
908834cdd9 | |
|
4840abf18e | |
|
cd6a5737e7 | |
|
853543ece5 | |
|
37b12c960f | |
|
8c9d0d6585 | |
|
2551521539 | |
|
403a75c835 | |
|
12359f3685 | |
|
d20fd4e175 | |
|
05c98dcb14 | |
|
d5bafe4f4f | |
|
6ca3766457 | |
|
9ac1fa9ae2 | |
|
4178b72af9 | |
|
bfa8d6d524 | |
|
7a74711834 | |
|
9056b60937 | |
|
75663c4f99 | |
|
c2b5f27b3b | |
|
84f7ed6d09 | |
|
eaa1e64899 | |
|
bad83aef69 | |
|
fc36997b91 | |
|
7e18580540 | |
|
e64799f7de | |
|
78ae2a5d8e | |
|
b574d3a39d | |
|
eafd815463 | |
|
5a96282bce | |
|
55d25644dd | |
|
7a3d4b9432 | |
|
af1a642907 | |
|
0d2e49f93a | |
|
688be5828d | |
|
001f371244 | |
|
2a8d5e87cf | |
|
5c0886316c | |
|
daf325b1a0 | |
|
2ed4ce0199 | |
|
66fd9c16b2 | |
|
9242f43760 | |
|
de2041ae95 | |
|
eb32584205 | |
|
f4969a837c | |
|
59cf933abc | |
|
2f03f18d51 | |
|
12543ea00b | |
|
c9b55c3d91 | |
|
0d7951d5f0 | |
|
34909a30b0 | |
|
99847ce85b | |
|
28dcac39f0 | |
|
6261592339 | |
|
c87c852509 | |
|
99261f37cd | |
|
56e7d25acd | |
|
66a5245e61 | |
|
d149a15530 | |
|
0df0f30de5 | |
|
bc25b9d020 | |
|
df1b130dc6 | |
|
3f33ab6850 | |
|
fa2bbbf5e2 | |
|
be738bb49b | |
|
edf8ab173d | |
|
7e50ef1bf8 | |
|
677732d511 | |
|
f023e01c6c | |
|
32ae6481e6 | |
|
389c26e1b0 | |
|
2038f0a74f | |
|
1827cdb592 | |
|
a2e05b4d59 | |
|
94bb218d50 | |
|
d48ac84244 | |
|
91a01a2857 | |
|
313843591e | |
|
36b48b9257 | |
|
b6d067c9cd | |
|
40c92dacd1 | |
|
1cd933d64f | |
|
4aa03226de | |
|
0db0f75cb9 | |
|
e99071f9ce | |
|
8cdf75c2a0 | |
|
d2fd665236 | |
|
c69bdc2295 | |
|
3e83ee3077 | |
|
ce6343dfa2 | |
|
5f3e05a9e3 | |
|
cafbb82af6 | |
|
b9c5cb17d3 | |
|
f9c36582e1 | |
|
ed66b88dd0 | |
|
6fbccb0c9d | |
|
d4d4101d69 | |
|
5ab14f5c62 | |
|
0410b481e1 | |
|
fc37e0c502 | |
|
85d461c70a | |
|
4dc9f7ee99 | |
|
c3ffb2b13f | |
|
6bb8c928c0 | |
|
603632b6af | |
|
dba03ff81c | |
|
1d8cc6e13d | |
|
fec27cf294 | |
|
e2135c841f | |
|
241501815b | |
|
e586a7bad1 | |
|
c0f8d5ad9d | |
|
e139c2bcd8 | |
|
35b3cfac8c | |
|
5dfe9da0ff | |
|
0a7678471d | |
|
7bd66b47a4 | |
|
ac522bc55a | |
|
36d430484e | |
|
db005426bd | |
|
a84a48c292 | |
|
f62dc15075 | |
|
e51e5a51a1 | |
|
8db2256852 | |
|
0b1cdabea4 | |
|
4b31dd40b5 | |
|
3bb6ed1082 | |
|
ced08bebd3 | |
|
8ce58981c7 | |
|
1e0766dc50 | |
|
9f471aafbf | |
|
03769873d0 | |
|
67d0b4b262 | |
|
c862bf2289 | |
|
655229ddbd | |
|
bc296cc52a | |
|
0bed18b439 | |
|
c35f966b5a | |
|
cb8b1bfd6b | |
|
0368f3452b | |
|
cc7a345fff | |
|
067025312e | |
|
5fa89e8666 | |
|
bc0d8cbb10 | |
|
9445d561ac | |
|
23f5ed0946 | |
|
507bc99510 | |
|
9315854143 | |
|
84bf55011d | |
|
766909798f | |
|
f170c2e017 | |
|
a3d67ff5be | |
|
86f81f3027 | |
|
54c5738676 | |
|
5b5c3efccc | |
|
08dea7965d | |
|
99a82c164a | |
|
f159b905ec | |
|
bc8b79b9c9 | |
|
5880a6051f | |
|
554cda2144 | |
|
af6266c8d6 | |
|
84e65d2599 | |
|
aa3c8fa359 |
107
.drone.yml
107
.drone.yml
|
@ -1,38 +1,109 @@
|
||||||
kind: pipeline
|
kind: pipeline
|
||||||
type: docker
|
type: docker
|
||||||
name: build
|
name: server
|
||||||
steps:
|
steps:
|
||||||
- name: build-dev
|
# - name: build
|
||||||
|
# image: appleboy/drone-ssh
|
||||||
|
# settings:
|
||||||
|
# host:
|
||||||
|
# - 172.10.10.10
|
||||||
|
# username: eigen
|
||||||
|
# key:
|
||||||
|
# from_secret: DEVOPS_SSH_PRIVATE_OPEN
|
||||||
|
# port: 22
|
||||||
|
# script:
|
||||||
|
# - cd /home/eigen/PROJECT/POS/POS.DEV/BE
|
||||||
|
# - sh build.sh
|
||||||
|
# when:
|
||||||
|
# ref:
|
||||||
|
# - refs/tags/devel_*
|
||||||
|
# - refs/tags/*-alpha.*
|
||||||
|
- name: build-testing
|
||||||
image: plugins/docker
|
image: plugins/docker
|
||||||
settings:
|
settings:
|
||||||
registry: registry.eigen.co.id
|
registry: registry.eigen.co.id
|
||||||
repo: registry.eigen.co.id/eigen/${DRONE_REPO_NAME}
|
repo: registry.eigen.co.id/eigen/${DRONE_REPO_NAME}
|
||||||
build_args:
|
tags: ${DRONE_TAG}
|
||||||
- env_target=env.development
|
|
||||||
tags: latest
|
|
||||||
custom_dns: 172.10.10.16
|
custom_dns: 172.10.10.16
|
||||||
|
when:
|
||||||
|
ref:
|
||||||
|
- refs/tags/*-alpha.*
|
||||||
|
- name: build-production
|
||||||
|
image: plugins/docker
|
||||||
|
settings:
|
||||||
|
registry: registry.eigen.co.id
|
||||||
|
repo: registry.eigen.co.id/eigen/${DRONE_REPO_NAME}
|
||||||
|
tags: ${DRONE_TAG}
|
||||||
|
custom_dns: 172.10.10.16
|
||||||
|
when:
|
||||||
|
ref:
|
||||||
|
- refs/tags/*-production.*
|
||||||
|
- name: send-message
|
||||||
|
image: plugins/webhook
|
||||||
|
settings:
|
||||||
|
urls: https://mattermost.eigen.co.id/api/v4/posts
|
||||||
|
content_type: application/json
|
||||||
|
headers:
|
||||||
|
- Authorization=Bearer 5zubexudb38uuradfa36qy98ca
|
||||||
|
template: |
|
||||||
|
{
|
||||||
|
"channel_id": "s1ekqde1c3du5p35g6budnuotc",
|
||||||
|
"message": "Build {{repo.name}} sudah selesai"
|
||||||
|
}
|
||||||
trigger:
|
trigger:
|
||||||
ref:
|
|
||||||
- refs/tags/devel_*
|
|
||||||
event:
|
event:
|
||||||
exclude:
|
exclude:
|
||||||
- promote
|
- promote
|
||||||
---
|
---
|
||||||
kind: pipeline
|
kind: pipeline
|
||||||
type: docker
|
type: docker
|
||||||
name: deployment
|
name: kustomize
|
||||||
|
|
||||||
|
clone:
|
||||||
|
disable: true
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: deployment
|
- name: kustomize-testing
|
||||||
image: alpine
|
image: registry.k8s.io/kustomize/kustomize:v5.0.0
|
||||||
failure: ignore
|
environment:
|
||||||
|
DEVOPS_SSH_PRIVATE:
|
||||||
|
from_secret: DEVOPS_SSH_PRIVATE
|
||||||
|
DEVOPS_SSH_PUBLIC:
|
||||||
|
from_secret: DEVOPS_SSH_PUBLIC
|
||||||
|
INFRASTRUCTURE_REPO: "k8s-kustomize-external"
|
||||||
|
DIRECTORY_NAME: "weplay-pos-testing"
|
||||||
commands:
|
commands:
|
||||||
- apk add --no-cache curl
|
- mkdir -p ~/.ssh &&
|
||||||
- curl -X POST https://manager.sky.eigen.co.id/api/webhooks/806de7e2-1d3e-4889-b472-a59af0a5eb33
|
- echo $DEVOPS_SSH_PRIVATE | base64 -d > ~/.ssh/id_rsa &&
|
||||||
|
- echo $DEVOPS_SSH_PUBLIC | base64 -d > ~/.ssh/id_rsa.pub &&
|
||||||
|
- ssh-keyscan -H -p 2222 git.eigen.co.id >> ~/.ssh/known_hosts &&
|
||||||
|
- chmod 700 ~/.ssh/ &&
|
||||||
|
- chmod 600 ~/.ssh/id_rsa &&
|
||||||
|
- git clone ssh://git@git.eigen.co.id:2222/eigen/$INFRASTRUCTURE_REPO.git &&
|
||||||
|
- cd $INFRASTRUCTURE_REPO/$DIRECTORY_NAME
|
||||||
|
- kustomize edit set image registry.eigen.co.id/eigen/$DRONE_REPO_NAME=registry.eigen.co.id/eigen/$DRONE_REPO_NAME:$DRONE_TAG &&
|
||||||
|
- git add . &&
|
||||||
|
- |-
|
||||||
|
git commit -m "feat: update $DRONE_REPO_NAME testing to $DRONE_TAG" &&
|
||||||
|
- git push origin master
|
||||||
|
- name: send-message
|
||||||
|
image: harbor.eigen.co.id/docker.com/plugins/webhook
|
||||||
|
settings:
|
||||||
|
urls: https://mattermost.eigen.co.id/api/v4/posts
|
||||||
|
content_type: application/json
|
||||||
|
headers:
|
||||||
|
- Authorization=Bearer 5zubexudb38uuradfa36qy98ca
|
||||||
|
template: |
|
||||||
|
{
|
||||||
|
"channel_id": "s1ekqde1c3du5p35g6budnuotc",
|
||||||
|
"message": "ALERT: {{ repo.name }} gagal update dengan tag ${DRONE_TAG}"
|
||||||
|
}
|
||||||
|
when:
|
||||||
|
status:
|
||||||
|
- failure
|
||||||
trigger:
|
trigger:
|
||||||
ref:
|
ref:
|
||||||
- refs/tags/devel_*
|
include:
|
||||||
event:
|
- refs/tags/*-alpha.*
|
||||||
exclude:
|
|
||||||
- promote
|
|
||||||
depends_on:
|
depends_on:
|
||||||
- build
|
- server
|
|
@ -0,0 +1,38 @@
|
||||||
|
kind: pipeline
|
||||||
|
type: docker
|
||||||
|
name: build
|
||||||
|
steps:
|
||||||
|
- name: build-dev
|
||||||
|
image: plugins/docker
|
||||||
|
settings:
|
||||||
|
registry: registry.eigen.co.id
|
||||||
|
repo: registry.eigen.co.id/eigen/${DRONE_REPO_NAME}
|
||||||
|
build_args:
|
||||||
|
- env_target=env.development
|
||||||
|
tags: latest
|
||||||
|
custom_dns: 172.10.10.16
|
||||||
|
trigger:
|
||||||
|
ref:
|
||||||
|
- refs/tags/devel_*
|
||||||
|
event:
|
||||||
|
exclude:
|
||||||
|
- promote
|
||||||
|
---
|
||||||
|
kind: pipeline
|
||||||
|
type: docker
|
||||||
|
name: deployment
|
||||||
|
steps:
|
||||||
|
- name: deployment
|
||||||
|
image: alpine
|
||||||
|
failure: ignore
|
||||||
|
commands:
|
||||||
|
- apk add --no-cache curl
|
||||||
|
- curl -X POST https://manager.sky.eigen.co.id/api/webhooks/806de7e2-1d3e-4889-b472-a59af0a5eb33
|
||||||
|
trigger:
|
||||||
|
ref:
|
||||||
|
- refs/tags/devel_*
|
||||||
|
event:
|
||||||
|
exclude:
|
||||||
|
- promote
|
||||||
|
depends_on:
|
||||||
|
- build
|
|
@ -35,4 +35,7 @@ docker-compose.yml
|
||||||
!.vscode/settings.json
|
!.vscode/settings.json
|
||||||
!.vscode/tasks.json
|
!.vscode/tasks.json
|
||||||
!.vscode/launch.json
|
!.vscode/launch.json
|
||||||
!.vscode/extensions.json
|
!.vscode/extensions.json
|
||||||
|
|
||||||
|
# IGNORE UPLOAD FOLDER
|
||||||
|
/uploads
|
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"type": "node",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Debug Nest Framework",
|
||||||
|
"runtimeExecutable": "npm",
|
||||||
|
"runtimeArgs": ["run", "start:debug", "--", "--inspect-brk"],
|
||||||
|
"autoAttachChildProcesses": true,
|
||||||
|
"restart": true,
|
||||||
|
"sourceMaps": true,
|
||||||
|
"stopOnEntry": false,
|
||||||
|
"console": "integratedTerminal"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -5,12 +5,13 @@ COPY . .
|
||||||
RUN yarn install
|
RUN yarn install
|
||||||
RUN yarn build
|
RUN yarn build
|
||||||
FROM node:18.17-alpine
|
FROM node:18.17-alpine
|
||||||
ARG env_target
|
# ARG env_target
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
RUN echo ${env_target}
|
# RUN echo ${env_target}
|
||||||
COPY env/$env_target /app/.env
|
# COPY env/$env_target /app/.env
|
||||||
COPY --from=builder /app/env/$env_target .env
|
# COPY --from=builder /app/env/$env_target .env
|
||||||
COPY --from=builder /app/node_modules ./node_modules
|
COPY --from=builder /app/node_modules ./node_modules
|
||||||
COPY --from=builder /app/dist ./dist
|
COPY --from=builder /app/dist ./dist
|
||||||
|
COPY --from=builder /app/assets ./assets
|
||||||
COPY --from=builder /app/package.json ./package.json
|
COPY --from=builder /app/package.json ./package.json
|
||||||
CMD ["node", "--max-old-space-size=8192","--max-http-header-size", "512000", "-r", "dotenv/config", "dist/main"]
|
CMD ["node", "--max-old-space-size=8192","--max-http-header-size", "512000", "-r", "dotenv/config", "dist/main"]
|
|
@ -0,0 +1,404 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta name="viewport" content="width=device-width" />
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
|
<title>Email Confirmation</title>
|
||||||
|
<style>
|
||||||
|
/* -------------------------------------
|
||||||
|
GLOBAL RESETS
|
||||||
|
------------------------------------- */
|
||||||
|
img {
|
||||||
|
border: none;
|
||||||
|
-ms-interpolation-mode: bicubic;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-color: #f6f6f6;
|
||||||
|
font-family: sans-serif;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.4;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
-ms-text-size-adjust: 100%;
|
||||||
|
-webkit-text-size-adjust: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
border-collapse: separate;
|
||||||
|
mso-table-lspace: 0pt;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
table td {
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-size: 14px;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------
|
||||||
|
BODY & CONTAINER
|
||||||
|
------------------------------------- */
|
||||||
|
|
||||||
|
.body {
|
||||||
|
background-color: #f6f6f6;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set a max-width, and make it display as block so it will automatically stretch to that width, but will also shrink
|
||||||
|
down on a phone or something */
|
||||||
|
.container {
|
||||||
|
display: block;
|
||||||
|
Margin: 0 auto !important;
|
||||||
|
/* makes it centered */
|
||||||
|
max-width: 580px;
|
||||||
|
padding: 10px;
|
||||||
|
width: 580px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This should also be a block element, so that it will fill 100% of the .container */
|
||||||
|
.content {
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: block;
|
||||||
|
Margin: 0 auto;
|
||||||
|
max-width: 580px;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------
|
||||||
|
HEADER, FOOTER, MAIN
|
||||||
|
------------------------------------- */
|
||||||
|
.main {
|
||||||
|
background: #ffffff;
|
||||||
|
border-radius: 3px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wrapper {
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-block {
|
||||||
|
padding-bottom: 10px;
|
||||||
|
padding-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
clear: both;
|
||||||
|
Margin-top: 10px;
|
||||||
|
text-align: center;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer td,
|
||||||
|
.footer p,
|
||||||
|
.footer span,
|
||||||
|
.footer a {
|
||||||
|
color: #999999;
|
||||||
|
font-size: 12px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------
|
||||||
|
TYPOGRAPHY
|
||||||
|
------------------------------------- */
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4 {
|
||||||
|
color: #000000;
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 1.4;
|
||||||
|
margin: 0;
|
||||||
|
Margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 35px;
|
||||||
|
font-weight: 300;
|
||||||
|
text-align: center;
|
||||||
|
text-transform: capitalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
p,
|
||||||
|
ul,
|
||||||
|
ol {
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: normal;
|
||||||
|
margin: 0;
|
||||||
|
Margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p li,
|
||||||
|
ul li,
|
||||||
|
ol li {
|
||||||
|
list-style-position: inside;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #3498db;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------
|
||||||
|
BUTTONS
|
||||||
|
------------------------------------- */
|
||||||
|
.btn {
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn>tbody>tr>td {
|
||||||
|
padding-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn table {
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn table td {
|
||||||
|
background-color: #ffffff;
|
||||||
|
border-radius: 5px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn a {
|
||||||
|
background-color: #ffffff;
|
||||||
|
border: solid 1px #3498db;
|
||||||
|
border-radius: 5px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
color: #3498db;
|
||||||
|
cursor: pointer;
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: bold;
|
||||||
|
margin: 0;
|
||||||
|
padding: 12px 25px;
|
||||||
|
text-decoration: none;
|
||||||
|
text-transform: capitalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary table td {
|
||||||
|
background-color: #3498db;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary a {
|
||||||
|
background-color: #3498db;
|
||||||
|
border-color: #3498db;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------
|
||||||
|
OTHER STYLES THAT MIGHT BE USEFUL
|
||||||
|
------------------------------------- */
|
||||||
|
.last {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.first {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.align-center {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.align-right {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.align-left {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.clear {
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mt0 {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mb0 {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preheader {
|
||||||
|
color: transparent;
|
||||||
|
display: none;
|
||||||
|
height: 0;
|
||||||
|
max-height: 0;
|
||||||
|
max-width: 0;
|
||||||
|
opacity: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
visibility: hidden;
|
||||||
|
width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.powered-by a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
border: 0;
|
||||||
|
border-bottom: 1px solid #f6f6f6;
|
||||||
|
Margin: 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------
|
||||||
|
RESPONSIVE AND MOBILE FRIENDLY STYLES
|
||||||
|
------------------------------------- */
|
||||||
|
@media only screen and (max-width: 620px) {
|
||||||
|
table[class=body] h1 {
|
||||||
|
font-size: 28px !important;
|
||||||
|
margin-bottom: 10px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] p,
|
||||||
|
table[class=body] ul,
|
||||||
|
table[class=body] ol,
|
||||||
|
table[class=body] td,
|
||||||
|
table[class=body] span,
|
||||||
|
table[class=body] a {
|
||||||
|
font-size: 16px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] .wrapper,
|
||||||
|
table[class=body] .article {
|
||||||
|
padding: 10px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] .content {
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] .container {
|
||||||
|
padding: 0 !important;
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] .main {
|
||||||
|
border-left-width: 0 !important;
|
||||||
|
border-radius: 0 !important;
|
||||||
|
border-right-width: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] .btn table {
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] .btn a {
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] .img-responsive {
|
||||||
|
height: auto !important;
|
||||||
|
max-width: 100% !important;
|
||||||
|
width: auto !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------
|
||||||
|
PRESERVE THESE STYLES IN THE HEAD
|
||||||
|
------------------------------------- */
|
||||||
|
@media all {
|
||||||
|
.ExternalClass {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ExternalClass,
|
||||||
|
.ExternalClass p,
|
||||||
|
.ExternalClass span,
|
||||||
|
.ExternalClass font,
|
||||||
|
.ExternalClass td,
|
||||||
|
.ExternalClass div {
|
||||||
|
line-height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.apple-link a {
|
||||||
|
color: inherit !important;
|
||||||
|
font-family: inherit !important;
|
||||||
|
font-size: inherit !important;
|
||||||
|
font-weight: inherit !important;
|
||||||
|
line-height: inherit !important;
|
||||||
|
text-decoration: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary table td:hover {
|
||||||
|
background-color: #34495e !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary a:hover {
|
||||||
|
background-color: #34495e !important;
|
||||||
|
border-color: #34495e !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ol {
|
||||||
|
padding: 0 0 0 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol li {
|
||||||
|
margin: 1em 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="">
|
||||||
|
<table border="0" cellpadding="0" cellspacing="0" class="body">
|
||||||
|
<tr>
|
||||||
|
<td> </td>
|
||||||
|
<td class="container">
|
||||||
|
<div class="content">
|
||||||
|
<table class="main">
|
||||||
|
<!-- START MAIN CONTENT AREA -->
|
||||||
|
<tr>
|
||||||
|
<td class="wrapper">
|
||||||
|
<table border="0" cellpadding="0" cellspacing="0">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<p class="mb0"><b>Dear,</b></p>
|
||||||
|
<p class="mb0">{{customer_name}}</p>
|
||||||
|
<p>{{customer_phone}}</p>
|
||||||
|
|
||||||
|
<p class="mb0">Great News! We've successfully updated your booking date as per your request.</p>
|
||||||
|
<p>We're excited to accommodate your new plans and ensure evertyhing goes smoothly.</p>
|
||||||
|
|
||||||
|
<p class="mb0">Here are your updated booking details</p>
|
||||||
|
<b class="mb0">Original Booking Date: {{booking_date_before}}</b>
|
||||||
|
<b>New Booking Date: {{booking_date}}</b>
|
||||||
|
|
||||||
|
<p class="mb0">For yout convenience, we've attached a new confirmation receipt reflecting these changes.</p>
|
||||||
|
<p><b>Please be sure to bring this updated receipt with you on the new date</b></p>
|
||||||
|
|
||||||
|
<p class="mb0">To keep the good times rolling, our friendly support team is just a call away at</p>
|
||||||
|
<b>{{phone_cs}}</b>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<p>Thank you and we can't wait to see you and make sure you have an amazing time!</p>
|
||||||
|
|
||||||
|
<br><br>
|
||||||
|
<b>Best Regrads,</b><br>
|
||||||
|
<b>WEplayground</b>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<!-- END MAIN CONTENT AREA -->
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td> </td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
|
@ -0,0 +1,412 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta name="viewport" content="width=device-width" />
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
|
<title>Email Confirmation</title>
|
||||||
|
<style>
|
||||||
|
/* -------------------------------------
|
||||||
|
GLOBAL RESETS
|
||||||
|
------------------------------------- */
|
||||||
|
img {
|
||||||
|
border: none;
|
||||||
|
-ms-interpolation-mode: bicubic;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-color: #f6f6f6;
|
||||||
|
font-family: sans-serif;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.4;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
-ms-text-size-adjust: 100%;
|
||||||
|
-webkit-text-size-adjust: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
border-collapse: separate;
|
||||||
|
mso-table-lspace: 0pt;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
table td {
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-size: 14px;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------
|
||||||
|
BODY & CONTAINER
|
||||||
|
------------------------------------- */
|
||||||
|
|
||||||
|
.body {
|
||||||
|
background-color: #f6f6f6;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set a max-width, and make it display as block so it will automatically stretch to that width, but will also shrink
|
||||||
|
down on a phone or something */
|
||||||
|
.container {
|
||||||
|
display: block;
|
||||||
|
Margin: 0 auto !important;
|
||||||
|
/* makes it centered */
|
||||||
|
max-width: 580px;
|
||||||
|
padding: 10px;
|
||||||
|
width: 580px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This should also be a block element, so that it will fill 100% of the .container */
|
||||||
|
.content {
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: block;
|
||||||
|
Margin: 0 auto;
|
||||||
|
max-width: 580px;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------
|
||||||
|
HEADER, FOOTER, MAIN
|
||||||
|
------------------------------------- */
|
||||||
|
.main {
|
||||||
|
background: #ffffff;
|
||||||
|
border-radius: 3px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wrapper {
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-block {
|
||||||
|
padding-bottom: 10px;
|
||||||
|
padding-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
clear: both;
|
||||||
|
Margin-top: 10px;
|
||||||
|
text-align: center;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer td,
|
||||||
|
.footer p,
|
||||||
|
.footer span,
|
||||||
|
.footer a {
|
||||||
|
color: #999999;
|
||||||
|
font-size: 12px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------
|
||||||
|
TYPOGRAPHY
|
||||||
|
------------------------------------- */
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4 {
|
||||||
|
color: #000000;
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 1.4;
|
||||||
|
margin: 0;
|
||||||
|
Margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 35px;
|
||||||
|
font-weight: 300;
|
||||||
|
text-align: center;
|
||||||
|
text-transform: capitalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
p,
|
||||||
|
ul,
|
||||||
|
ol {
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: normal;
|
||||||
|
margin: 0;
|
||||||
|
Margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p li,
|
||||||
|
ul li,
|
||||||
|
ol li {
|
||||||
|
list-style-position: inside;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #3498db;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------
|
||||||
|
BUTTONS
|
||||||
|
------------------------------------- */
|
||||||
|
.btn {
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn>tbody>tr>td {
|
||||||
|
padding-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn table {
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn table td {
|
||||||
|
background-color: #ffffff;
|
||||||
|
border-radius: 5px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn a {
|
||||||
|
background-color: #ffffff;
|
||||||
|
border: solid 1px #3498db;
|
||||||
|
border-radius: 5px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
color: #3498db;
|
||||||
|
cursor: pointer;
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: bold;
|
||||||
|
margin: 0;
|
||||||
|
padding: 12px 25px;
|
||||||
|
text-decoration: none;
|
||||||
|
text-transform: capitalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary table td {
|
||||||
|
background-color: #3498db;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary a {
|
||||||
|
background-color: #3498db;
|
||||||
|
border-color: #3498db;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------
|
||||||
|
OTHER STYLES THAT MIGHT BE USEFUL
|
||||||
|
------------------------------------- */
|
||||||
|
.last {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.first {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.align-center {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.align-right {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.align-left {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.clear {
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mt0 {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mb0 {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preheader {
|
||||||
|
color: transparent;
|
||||||
|
display: none;
|
||||||
|
height: 0;
|
||||||
|
max-height: 0;
|
||||||
|
max-width: 0;
|
||||||
|
opacity: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
visibility: hidden;
|
||||||
|
width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.powered-by a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
border: 0;
|
||||||
|
border-bottom: 1px solid #f6f6f6;
|
||||||
|
Margin: 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------
|
||||||
|
RESPONSIVE AND MOBILE FRIENDLY STYLES
|
||||||
|
------------------------------------- */
|
||||||
|
@media only screen and (max-width: 620px) {
|
||||||
|
table[class=body] h1 {
|
||||||
|
font-size: 28px !important;
|
||||||
|
margin-bottom: 10px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] p,
|
||||||
|
table[class=body] ul,
|
||||||
|
table[class=body] ol,
|
||||||
|
table[class=body] td,
|
||||||
|
table[class=body] span,
|
||||||
|
table[class=body] a {
|
||||||
|
font-size: 16px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] .wrapper,
|
||||||
|
table[class=body] .article {
|
||||||
|
padding: 10px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] .content {
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] .container {
|
||||||
|
padding: 0 !important;
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] .main {
|
||||||
|
border-left-width: 0 !important;
|
||||||
|
border-radius: 0 !important;
|
||||||
|
border-right-width: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] .btn table {
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] .btn a {
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] .img-responsive {
|
||||||
|
height: auto !important;
|
||||||
|
max-width: 100% !important;
|
||||||
|
width: auto !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------
|
||||||
|
PRESERVE THESE STYLES IN THE HEAD
|
||||||
|
------------------------------------- */
|
||||||
|
@media all {
|
||||||
|
.ExternalClass {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ExternalClass,
|
||||||
|
.ExternalClass p,
|
||||||
|
.ExternalClass span,
|
||||||
|
.ExternalClass font,
|
||||||
|
.ExternalClass td,
|
||||||
|
.ExternalClass div {
|
||||||
|
line-height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.apple-link a {
|
||||||
|
color: inherit !important;
|
||||||
|
font-family: inherit !important;
|
||||||
|
font-size: inherit !important;
|
||||||
|
font-weight: inherit !important;
|
||||||
|
line-height: inherit !important;
|
||||||
|
text-decoration: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary table td:hover {
|
||||||
|
background-color: #34495e !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary a:hover {
|
||||||
|
background-color: #34495e !important;
|
||||||
|
border-color: #34495e !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ol {
|
||||||
|
padding: 0 0 0 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol li {
|
||||||
|
margin: 1em 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="">
|
||||||
|
<table border="0" cellpadding="0" cellspacing="0" class="body">
|
||||||
|
<tr>
|
||||||
|
<td> </td>
|
||||||
|
<td class="container">
|
||||||
|
<div class="content">
|
||||||
|
<table class="main">
|
||||||
|
<!-- START MAIN CONTENT AREA -->
|
||||||
|
<tr>
|
||||||
|
<td class="wrapper">
|
||||||
|
<table border="0" cellpadding="0" cellspacing="0">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<p class="mb0"><b>Dear,</b></p>
|
||||||
|
<p class="mb0">{{customer_name}}</p>
|
||||||
|
<p>{{customer_phone}}</p>
|
||||||
|
|
||||||
|
<p>Thank you fot choosing us! We're absolutelty thrilled and can't wait to embark on this exciting day with you. See you soon for fun times ahead</p>
|
||||||
|
|
||||||
|
<p class="mb0">Here's a quick recap of your invoice:</p>
|
||||||
|
<p class="mb0">Booking Date: {{booking_date}}</p>
|
||||||
|
<p>Total Invoice: {{payment_total}}</p>
|
||||||
|
|
||||||
|
<p class="mb0">Just a friendly reminder that your invoice will expire on {{expire_date}}</p>
|
||||||
|
<p>To keep things running smoothly, please ensure your payment is completed before this data</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
For your convenience, here is a list of our account details:
|
||||||
|
<ul>
|
||||||
|
{{#each payment_methods}}
|
||||||
|
<li>
|
||||||
|
<p>{{issuer_name}} {{account_number}} a/n >{{account_name}}</p>
|
||||||
|
</li>
|
||||||
|
{{/each}}
|
||||||
|
</ul>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p class="mb0">Once you've made the payment, please kindly email or send the proof of payment so we can proceed with your booking promptly</p>
|
||||||
|
<p class="mb0">If you have any questions or need assistance, feel free to reach out to our support team at</p>
|
||||||
|
<b>{{phone_cs}}</b>
|
||||||
|
|
||||||
|
<br><br>
|
||||||
|
<b>Best Regrads,</b><br>
|
||||||
|
<b>WEplayground</b>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<!-- END MAIN CONTENT AREA -->
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td> </td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
|
@ -0,0 +1,400 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta name="viewport" content="width=device-width" />
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
|
<title>Email Confirmation</title>
|
||||||
|
<style>
|
||||||
|
/* -------------------------------------
|
||||||
|
GLOBAL RESETS
|
||||||
|
------------------------------------- */
|
||||||
|
img {
|
||||||
|
border: none;
|
||||||
|
-ms-interpolation-mode: bicubic;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-color: #f6f6f6;
|
||||||
|
font-family: sans-serif;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.4;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
-ms-text-size-adjust: 100%;
|
||||||
|
-webkit-text-size-adjust: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
border-collapse: separate;
|
||||||
|
mso-table-lspace: 0pt;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
table td {
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-size: 14px;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------
|
||||||
|
BODY & CONTAINER
|
||||||
|
------------------------------------- */
|
||||||
|
|
||||||
|
.body {
|
||||||
|
background-color: #f6f6f6;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set a max-width, and make it display as block so it will automatically stretch to that width, but will also shrink
|
||||||
|
down on a phone or something */
|
||||||
|
.container {
|
||||||
|
display: block;
|
||||||
|
Margin: 0 auto !important;
|
||||||
|
/* makes it centered */
|
||||||
|
max-width: 580px;
|
||||||
|
padding: 10px;
|
||||||
|
width: 580px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This should also be a block element, so that it will fill 100% of the .container */
|
||||||
|
.content {
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: block;
|
||||||
|
Margin: 0 auto;
|
||||||
|
max-width: 580px;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------
|
||||||
|
HEADER, FOOTER, MAIN
|
||||||
|
------------------------------------- */
|
||||||
|
.main {
|
||||||
|
background: #ffffff;
|
||||||
|
border-radius: 3px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wrapper {
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-block {
|
||||||
|
padding-bottom: 10px;
|
||||||
|
padding-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
clear: both;
|
||||||
|
Margin-top: 10px;
|
||||||
|
text-align: center;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer td,
|
||||||
|
.footer p,
|
||||||
|
.footer span,
|
||||||
|
.footer a {
|
||||||
|
color: #999999;
|
||||||
|
font-size: 12px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------
|
||||||
|
TYPOGRAPHY
|
||||||
|
------------------------------------- */
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4 {
|
||||||
|
color: #000000;
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 1.4;
|
||||||
|
margin: 0;
|
||||||
|
Margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 35px;
|
||||||
|
font-weight: 300;
|
||||||
|
text-align: center;
|
||||||
|
text-transform: capitalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
p,
|
||||||
|
ul,
|
||||||
|
ol {
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: normal;
|
||||||
|
margin: 0;
|
||||||
|
Margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p li,
|
||||||
|
ul li,
|
||||||
|
ol li {
|
||||||
|
list-style-position: inside;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #3498db;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------
|
||||||
|
BUTTONS
|
||||||
|
------------------------------------- */
|
||||||
|
.btn {
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn>tbody>tr>td {
|
||||||
|
padding-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn table {
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn table td {
|
||||||
|
background-color: #ffffff;
|
||||||
|
border-radius: 5px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn a {
|
||||||
|
background-color: #ffffff;
|
||||||
|
border: solid 1px #3498db;
|
||||||
|
border-radius: 5px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
color: #3498db;
|
||||||
|
cursor: pointer;
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: bold;
|
||||||
|
margin: 0;
|
||||||
|
padding: 12px 25px;
|
||||||
|
text-decoration: none;
|
||||||
|
text-transform: capitalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary table td {
|
||||||
|
background-color: #3498db;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary a {
|
||||||
|
background-color: #3498db;
|
||||||
|
border-color: #3498db;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------
|
||||||
|
OTHER STYLES THAT MIGHT BE USEFUL
|
||||||
|
------------------------------------- */
|
||||||
|
.last {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.first {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.align-center {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.align-right {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.align-left {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.clear {
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mt0 {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mb0 {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preheader {
|
||||||
|
color: transparent;
|
||||||
|
display: none;
|
||||||
|
height: 0;
|
||||||
|
max-height: 0;
|
||||||
|
max-width: 0;
|
||||||
|
opacity: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
visibility: hidden;
|
||||||
|
width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.powered-by a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
border: 0;
|
||||||
|
border-bottom: 1px solid #f6f6f6;
|
||||||
|
Margin: 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------
|
||||||
|
RESPONSIVE AND MOBILE FRIENDLY STYLES
|
||||||
|
------------------------------------- */
|
||||||
|
@media only screen and (max-width: 620px) {
|
||||||
|
table[class=body] h1 {
|
||||||
|
font-size: 28px !important;
|
||||||
|
margin-bottom: 10px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] p,
|
||||||
|
table[class=body] ul,
|
||||||
|
table[class=body] ol,
|
||||||
|
table[class=body] td,
|
||||||
|
table[class=body] span,
|
||||||
|
table[class=body] a {
|
||||||
|
font-size: 16px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] .wrapper,
|
||||||
|
table[class=body] .article {
|
||||||
|
padding: 10px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] .content {
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] .container {
|
||||||
|
padding: 0 !important;
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] .main {
|
||||||
|
border-left-width: 0 !important;
|
||||||
|
border-radius: 0 !important;
|
||||||
|
border-right-width: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] .btn table {
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] .btn a {
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] .img-responsive {
|
||||||
|
height: auto !important;
|
||||||
|
max-width: 100% !important;
|
||||||
|
width: auto !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------
|
||||||
|
PRESERVE THESE STYLES IN THE HEAD
|
||||||
|
------------------------------------- */
|
||||||
|
@media all {
|
||||||
|
.ExternalClass {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ExternalClass,
|
||||||
|
.ExternalClass p,
|
||||||
|
.ExternalClass span,
|
||||||
|
.ExternalClass font,
|
||||||
|
.ExternalClass td,
|
||||||
|
.ExternalClass div {
|
||||||
|
line-height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.apple-link a {
|
||||||
|
color: inherit !important;
|
||||||
|
font-family: inherit !important;
|
||||||
|
font-size: inherit !important;
|
||||||
|
font-weight: inherit !important;
|
||||||
|
line-height: inherit !important;
|
||||||
|
text-decoration: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary table td:hover {
|
||||||
|
background-color: #34495e !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary a:hover {
|
||||||
|
background-color: #34495e !important;
|
||||||
|
border-color: #34495e !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ol {
|
||||||
|
padding: 0 0 0 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol li {
|
||||||
|
margin: 1em 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="">
|
||||||
|
<table border="0" cellpadding="0" cellspacing="0" class="body">
|
||||||
|
<tr>
|
||||||
|
<td> </td>
|
||||||
|
<td class="container">
|
||||||
|
<div class="content">
|
||||||
|
<table class="main">
|
||||||
|
<!-- START MAIN CONTENT AREA -->
|
||||||
|
<tr>
|
||||||
|
<td class="wrapper">
|
||||||
|
<table border="0" cellpadding="0" cellspacing="0">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<p class="mb0"><b>Dear,</b></p>
|
||||||
|
<p class="mb0">{{customer_name}}</p>
|
||||||
|
<p>{{customer_phone}}</p>
|
||||||
|
|
||||||
|
<p>We hope this message finds you well!</p>
|
||||||
|
|
||||||
|
<p class="mb0">Uh-oh! it looks like your invoice, dated {{invoice_date}}, has officially expired as of {{expired_date}}</p>
|
||||||
|
<p>But no worries, we can fix this together!</p>
|
||||||
|
|
||||||
|
<p class="mb0">To keep the good times rolling, our friendly support team is just a call away at</p>
|
||||||
|
<b>{{phone_cs}}</b>
|
||||||
|
|
||||||
|
<p class="mb0">Here are the details of the expired invoice:</p>
|
||||||
|
<p class="mb0">Booking Date: {{booking_date}}</p>
|
||||||
|
<p>Total Invoice: {{total_payment}}</p>
|
||||||
|
|
||||||
|
<br><br>
|
||||||
|
<b>Best Regrads,</b><br>
|
||||||
|
<b>WEplayground</b>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<!-- END MAIN CONTENT AREA -->
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td> </td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
|
@ -0,0 +1,419 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta name="viewport" content="width=device-width" />
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
|
<title>Email Confirmation</title>
|
||||||
|
<style>
|
||||||
|
/* -------------------------------------
|
||||||
|
GLOBAL RESETS
|
||||||
|
------------------------------------- */
|
||||||
|
img {
|
||||||
|
border: none;
|
||||||
|
-ms-interpolation-mode: bicubic;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-color: #f6f6f6;
|
||||||
|
font-family: sans-serif;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.4;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
-ms-text-size-adjust: 100%;
|
||||||
|
-webkit-text-size-adjust: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
border-collapse: separate;
|
||||||
|
mso-table-lspace: 0pt;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
table td {
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-size: 14px;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------
|
||||||
|
BODY & CONTAINER
|
||||||
|
------------------------------------- */
|
||||||
|
|
||||||
|
.body {
|
||||||
|
background-color: #f6f6f6;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set a max-width, and make it display as block so it will automatically stretch to that width, but will also shrink
|
||||||
|
down on a phone or something */
|
||||||
|
.container {
|
||||||
|
display: block;
|
||||||
|
Margin: 0 auto !important;
|
||||||
|
/* makes it centered */
|
||||||
|
max-width: 580px;
|
||||||
|
padding: 10px;
|
||||||
|
width: 580px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This should also be a block element, so that it will fill 100% of the .container */
|
||||||
|
.content {
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: block;
|
||||||
|
Margin: 0 auto;
|
||||||
|
max-width: 580px;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------
|
||||||
|
HEADER, FOOTER, MAIN
|
||||||
|
------------------------------------- */
|
||||||
|
.main {
|
||||||
|
background: #ffffff;
|
||||||
|
border-radius: 3px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wrapper {
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-block {
|
||||||
|
padding-bottom: 10px;
|
||||||
|
padding-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
clear: both;
|
||||||
|
Margin-top: 10px;
|
||||||
|
text-align: center;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer td,
|
||||||
|
.footer p,
|
||||||
|
.footer span,
|
||||||
|
.footer a {
|
||||||
|
color: #999999;
|
||||||
|
font-size: 12px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------
|
||||||
|
TYPOGRAPHY
|
||||||
|
------------------------------------- */
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4 {
|
||||||
|
color: #000000;
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 1.4;
|
||||||
|
margin: 0;
|
||||||
|
Margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 35px;
|
||||||
|
font-weight: 300;
|
||||||
|
text-align: center;
|
||||||
|
text-transform: capitalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
p,
|
||||||
|
ul,
|
||||||
|
ol {
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: normal;
|
||||||
|
margin: 0;
|
||||||
|
Margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p li,
|
||||||
|
ul li,
|
||||||
|
ol li {
|
||||||
|
list-style-position: inside;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #3498db;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------
|
||||||
|
BUTTONS
|
||||||
|
------------------------------------- */
|
||||||
|
.btn {
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn>tbody>tr>td {
|
||||||
|
padding-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn table {
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn table td {
|
||||||
|
background-color: #ffffff;
|
||||||
|
border-radius: 5px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn a {
|
||||||
|
background-color: #ffffff;
|
||||||
|
border: solid 1px #3498db;
|
||||||
|
border-radius: 5px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
color: #3498db;
|
||||||
|
cursor: pointer;
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: bold;
|
||||||
|
margin: 0;
|
||||||
|
padding: 12px 25px;
|
||||||
|
text-decoration: none;
|
||||||
|
text-transform: capitalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary table td {
|
||||||
|
background-color: #3498db;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary a {
|
||||||
|
background-color: #3498db;
|
||||||
|
border-color: #3498db;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------
|
||||||
|
OTHER STYLES THAT MIGHT BE USEFUL
|
||||||
|
------------------------------------- */
|
||||||
|
.last {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.first {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.align-center {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.align-right {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.align-left {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.clear {
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mt0 {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mb0 {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preheader {
|
||||||
|
color: transparent;
|
||||||
|
display: none;
|
||||||
|
height: 0;
|
||||||
|
max-height: 0;
|
||||||
|
max-width: 0;
|
||||||
|
opacity: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
visibility: hidden;
|
||||||
|
width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.powered-by a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
border: 0;
|
||||||
|
border-bottom: 1px solid #f6f6f6;
|
||||||
|
Margin: 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------
|
||||||
|
RESPONSIVE AND MOBILE FRIENDLY STYLES
|
||||||
|
------------------------------------- */
|
||||||
|
@media only screen and (max-width: 620px) {
|
||||||
|
table[class=body] h1 {
|
||||||
|
font-size: 28px !important;
|
||||||
|
margin-bottom: 10px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] p,
|
||||||
|
table[class=body] ul,
|
||||||
|
table[class=body] ol,
|
||||||
|
table[class=body] td,
|
||||||
|
table[class=body] span,
|
||||||
|
table[class=body] a {
|
||||||
|
font-size: 16px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] .wrapper,
|
||||||
|
table[class=body] .article {
|
||||||
|
padding: 10px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] .content {
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] .container {
|
||||||
|
padding: 0 !important;
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] .main {
|
||||||
|
border-left-width: 0 !important;
|
||||||
|
border-radius: 0 !important;
|
||||||
|
border-right-width: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] .btn table {
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] .btn a {
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] .img-responsive {
|
||||||
|
height: auto !important;
|
||||||
|
max-width: 100% !important;
|
||||||
|
width: auto !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------
|
||||||
|
PRESERVE THESE STYLES IN THE HEAD
|
||||||
|
------------------------------------- */
|
||||||
|
@media all {
|
||||||
|
.ExternalClass {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ExternalClass,
|
||||||
|
.ExternalClass p,
|
||||||
|
.ExternalClass span,
|
||||||
|
.ExternalClass font,
|
||||||
|
.ExternalClass td,
|
||||||
|
.ExternalClass div {
|
||||||
|
line-height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.apple-link a {
|
||||||
|
color: inherit !important;
|
||||||
|
font-family: inherit !important;
|
||||||
|
font-size: inherit !important;
|
||||||
|
font-weight: inherit !important;
|
||||||
|
line-height: inherit !important;
|
||||||
|
text-decoration: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary table td:hover {
|
||||||
|
background-color: #34495e !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary a:hover {
|
||||||
|
background-color: #34495e !important;
|
||||||
|
border-color: #34495e !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ol {
|
||||||
|
padding: 0 0 0 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol li {
|
||||||
|
margin: 1em 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="">
|
||||||
|
<table border="0" cellpadding="0" cellspacing="0" class="body">
|
||||||
|
<tr>
|
||||||
|
<td> </td>
|
||||||
|
<td class="container">
|
||||||
|
<div class="content">
|
||||||
|
<table class="main">
|
||||||
|
<!-- START MAIN CONTENT AREA -->
|
||||||
|
<tr>
|
||||||
|
<td class="wrapper">
|
||||||
|
<table border="0" cellpadding="0" cellspacing="0">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<p class="mb0"><b>Dear,</b></p>
|
||||||
|
<p class="mb0">{{customer_name}}</p>
|
||||||
|
<p>{{customer_phone}}</p>
|
||||||
|
|
||||||
|
<p>Thank you fot choosing us! We're absolutelty thrilled and can't wait to embark on this exciting day with you. See you soon for fun times ahead</p>
|
||||||
|
|
||||||
|
<p class="mb0">Here's a quick recap of your invoice:</p>
|
||||||
|
<p class="mb0">Booking Date: {{booking_date}}</p>
|
||||||
|
<p>Total Invoice: {{payment_total}}</p>
|
||||||
|
|
||||||
|
<p class="mb0">Just a friendly reminder that your invoice will expire on {{expire_date}}</p>
|
||||||
|
<p>To keep things running smoothly, please ensure your payment is completed before this data</p>
|
||||||
|
|
||||||
|
<p class="mb0">For your convenience, here is a list of our account details:</p>
|
||||||
|
<a href="{{payment_midtrans_url}}">{{payment_midtrans_url}}</a>
|
||||||
|
<br><br>
|
||||||
|
|
||||||
|
<p class="mb0">Once you've made the payment, please kindly email or send the proof of payment so we can proceed with your booking promptly</p>
|
||||||
|
<p class="mb0">If you have any questions or need assistance, feel free to reach out to our support team at</p>
|
||||||
|
<b>{{phone_cs}}</b>
|
||||||
|
|
||||||
|
<br><br>
|
||||||
|
<b>Best Regrads,</b><br>
|
||||||
|
<b>WEplayground</b>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<!-- END MAIN CONTENT AREA -->
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<!-- START FOOTER -->
|
||||||
|
<!-- <div class="footer">
|
||||||
|
<table border="0" cellpadding="0" cellspacing="0">
|
||||||
|
<tr>
|
||||||
|
<td class="content-block powered-by">
|
||||||
|
Powered by Skyworld
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div> -->
|
||||||
|
<!-- END FOOTER -->
|
||||||
|
|
||||||
|
<!-- END CENTERED WHITE CONTAINER -->
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td> </td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
|
@ -0,0 +1,412 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta name="viewport" content="width=device-width" />
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
|
<title>Email Confirmation</title>
|
||||||
|
<style>
|
||||||
|
/* -------------------------------------
|
||||||
|
GLOBAL RESETS
|
||||||
|
------------------------------------- */
|
||||||
|
img {
|
||||||
|
border: none;
|
||||||
|
-ms-interpolation-mode: bicubic;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-color: #f6f6f6;
|
||||||
|
font-family: sans-serif;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.4;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
-ms-text-size-adjust: 100%;
|
||||||
|
-webkit-text-size-adjust: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
border-collapse: separate;
|
||||||
|
mso-table-lspace: 0pt;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
table td {
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-size: 14px;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------
|
||||||
|
BODY & CONTAINER
|
||||||
|
------------------------------------- */
|
||||||
|
|
||||||
|
.body {
|
||||||
|
background-color: #f6f6f6;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set a max-width, and make it display as block so it will automatically stretch to that width, but will also shrink
|
||||||
|
down on a phone or something */
|
||||||
|
.container {
|
||||||
|
display: block;
|
||||||
|
Margin: 0 auto !important;
|
||||||
|
/* makes it centered */
|
||||||
|
max-width: 580px;
|
||||||
|
padding: 10px;
|
||||||
|
width: 580px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This should also be a block element, so that it will fill 100% of the .container */
|
||||||
|
.content {
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: block;
|
||||||
|
Margin: 0 auto;
|
||||||
|
max-width: 580px;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------
|
||||||
|
HEADER, FOOTER, MAIN
|
||||||
|
------------------------------------- */
|
||||||
|
.main {
|
||||||
|
background: #ffffff;
|
||||||
|
border-radius: 3px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wrapper {
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-block {
|
||||||
|
padding-bottom: 10px;
|
||||||
|
padding-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
clear: both;
|
||||||
|
Margin-top: 10px;
|
||||||
|
text-align: center;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer td,
|
||||||
|
.footer p,
|
||||||
|
.footer span,
|
||||||
|
.footer a {
|
||||||
|
color: #999999;
|
||||||
|
font-size: 12px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------
|
||||||
|
TYPOGRAPHY
|
||||||
|
------------------------------------- */
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4 {
|
||||||
|
color: #000000;
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 1.4;
|
||||||
|
margin: 0;
|
||||||
|
Margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 35px;
|
||||||
|
font-weight: 300;
|
||||||
|
text-align: center;
|
||||||
|
text-transform: capitalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
p,
|
||||||
|
ul,
|
||||||
|
ol {
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: normal;
|
||||||
|
margin: 0;
|
||||||
|
Margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p li,
|
||||||
|
ul li,
|
||||||
|
ol li {
|
||||||
|
list-style-position: inside;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #3498db;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------
|
||||||
|
BUTTONS
|
||||||
|
------------------------------------- */
|
||||||
|
.btn {
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn>tbody>tr>td {
|
||||||
|
padding-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn table {
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn table td {
|
||||||
|
background-color: #ffffff;
|
||||||
|
border-radius: 5px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn a {
|
||||||
|
background-color: #ffffff;
|
||||||
|
border: solid 1px #3498db;
|
||||||
|
border-radius: 5px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
color: #3498db;
|
||||||
|
cursor: pointer;
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: bold;
|
||||||
|
margin: 0;
|
||||||
|
padding: 12px 25px;
|
||||||
|
text-decoration: none;
|
||||||
|
text-transform: capitalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary table td {
|
||||||
|
background-color: #3498db;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary a {
|
||||||
|
background-color: #3498db;
|
||||||
|
border-color: #3498db;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------
|
||||||
|
OTHER STYLES THAT MIGHT BE USEFUL
|
||||||
|
------------------------------------- */
|
||||||
|
.last {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.first {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.align-center {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.align-right {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.align-left {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.clear {
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mt0 {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mb0 {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preheader {
|
||||||
|
color: transparent;
|
||||||
|
display: none;
|
||||||
|
height: 0;
|
||||||
|
max-height: 0;
|
||||||
|
max-width: 0;
|
||||||
|
opacity: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
visibility: hidden;
|
||||||
|
width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.powered-by a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
border: 0;
|
||||||
|
border-bottom: 1px solid #f6f6f6;
|
||||||
|
Margin: 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------
|
||||||
|
RESPONSIVE AND MOBILE FRIENDLY STYLES
|
||||||
|
------------------------------------- */
|
||||||
|
@media only screen and (max-width: 620px) {
|
||||||
|
table[class=body] h1 {
|
||||||
|
font-size: 28px !important;
|
||||||
|
margin-bottom: 10px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] p,
|
||||||
|
table[class=body] ul,
|
||||||
|
table[class=body] ol,
|
||||||
|
table[class=body] td,
|
||||||
|
table[class=body] span,
|
||||||
|
table[class=body] a {
|
||||||
|
font-size: 16px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] .wrapper,
|
||||||
|
table[class=body] .article {
|
||||||
|
padding: 10px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] .content {
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] .container {
|
||||||
|
padding: 0 !important;
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] .main {
|
||||||
|
border-left-width: 0 !important;
|
||||||
|
border-radius: 0 !important;
|
||||||
|
border-right-width: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] .btn table {
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] .btn a {
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] .img-responsive {
|
||||||
|
height: auto !important;
|
||||||
|
max-width: 100% !important;
|
||||||
|
width: auto !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------
|
||||||
|
PRESERVE THESE STYLES IN THE HEAD
|
||||||
|
------------------------------------- */
|
||||||
|
@media all {
|
||||||
|
.ExternalClass {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ExternalClass,
|
||||||
|
.ExternalClass p,
|
||||||
|
.ExternalClass span,
|
||||||
|
.ExternalClass font,
|
||||||
|
.ExternalClass td,
|
||||||
|
.ExternalClass div {
|
||||||
|
line-height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.apple-link a {
|
||||||
|
color: inherit !important;
|
||||||
|
font-family: inherit !important;
|
||||||
|
font-size: inherit !important;
|
||||||
|
font-weight: inherit !important;
|
||||||
|
line-height: inherit !important;
|
||||||
|
text-decoration: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary table td:hover {
|
||||||
|
background-color: #34495e !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary a:hover {
|
||||||
|
background-color: #34495e !important;
|
||||||
|
border-color: #34495e !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ol {
|
||||||
|
padding: 0 0 0 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol li {
|
||||||
|
margin: 1em 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="">
|
||||||
|
<table border="0" cellpadding="0" cellspacing="0" class="body">
|
||||||
|
<tr>
|
||||||
|
<td> </td>
|
||||||
|
<td class="container">
|
||||||
|
<div class="content">
|
||||||
|
<table class="main">
|
||||||
|
<!-- START MAIN CONTENT AREA -->
|
||||||
|
<tr>
|
||||||
|
<td class="wrapper">
|
||||||
|
<table border="0" cellpadding="0" cellspacing="0">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<p class="mb0"><b>Dear,</b></p>
|
||||||
|
<p class="mb0">{{customer_name}}</p>
|
||||||
|
<p>{{customer_phone}}</p>
|
||||||
|
|
||||||
|
<p class="mb0">We are excited to inform you that your payment has been successfully received!</p>
|
||||||
|
<p class="mb0">Attached to this email, you will find your confirmatin receipt</p>
|
||||||
|
<p class="mb0">Please keep this safe as you will need to show it at the entrance upon your arrival</p>
|
||||||
|
<p>It's your golden ticket to all the fun and excitement awaiting you!</p>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
<p class="mb0">Here's a quick recap:</p>
|
||||||
|
|
||||||
|
<p class="mb0">Booking Date: {{booking_date}}</p>
|
||||||
|
<p class="mb0">Invoice Code: {{invoice_code}}</p>
|
||||||
|
<p class="mb0">Payment Date: {{payment_date}}</p>
|
||||||
|
<p class="mb0">Payment Code: {{payment_code}}</p>
|
||||||
|
<p class="mb0">Payment Via: {{payment_via}}</p>
|
||||||
|
<p class="mb0">Account No: {{account_no}}</p>
|
||||||
|
<p>On Behalf Of: {{account_name}}</p>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<p class="mb0">If you have any questions or need assistance, feel free to reach out to our support team at</p>
|
||||||
|
<b>{{phone_cs}}</b>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<p class="mb0">Font forget to bring a smile and your confirmation receipt (attached) for a smooth entry</p>
|
||||||
|
<p>We can't wait to see you and ensure you have an amazing time with us!</p>
|
||||||
|
|
||||||
|
<br><br>
|
||||||
|
<b>Best Regrads,</b><br>
|
||||||
|
<b>WEplayground</b>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<!-- END MAIN CONTENT AREA -->
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td> </td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,415 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta name="viewport" content="width=device-width" />
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
|
<title>Email Confirmation</title>
|
||||||
|
<style>
|
||||||
|
/* -------------------------------------
|
||||||
|
GLOBAL RESETS
|
||||||
|
------------------------------------- */
|
||||||
|
img {
|
||||||
|
border: none;
|
||||||
|
-ms-interpolation-mode: bicubic;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-color: #f6f6f6;
|
||||||
|
font-family: sans-serif;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.4;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
-ms-text-size-adjust: 100%;
|
||||||
|
-webkit-text-size-adjust: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
border-collapse: separate;
|
||||||
|
mso-table-lspace: 0pt;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
table td {
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-size: 14px;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------
|
||||||
|
BODY & CONTAINER
|
||||||
|
------------------------------------- */
|
||||||
|
|
||||||
|
.body {
|
||||||
|
background-color: #f6f6f6;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set a max-width, and make it display as block so it will automatically stretch to that width, but will also shrink
|
||||||
|
down on a phone or something */
|
||||||
|
.container {
|
||||||
|
display: block;
|
||||||
|
Margin: 0 auto !important;
|
||||||
|
/* makes it centered */
|
||||||
|
max-width: 580px;
|
||||||
|
padding: 10px;
|
||||||
|
width: 580px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This should also be a block element, so that it will fill 100% of the .container */
|
||||||
|
.content {
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: block;
|
||||||
|
Margin: 0 auto;
|
||||||
|
max-width: 580px;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------
|
||||||
|
HEADER, FOOTER, MAIN
|
||||||
|
------------------------------------- */
|
||||||
|
.main {
|
||||||
|
background: #ffffff;
|
||||||
|
border-radius: 3px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wrapper {
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-block {
|
||||||
|
padding-bottom: 10px;
|
||||||
|
padding-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
clear: both;
|
||||||
|
Margin-top: 10px;
|
||||||
|
text-align: center;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer td,
|
||||||
|
.footer p,
|
||||||
|
.footer span,
|
||||||
|
.footer a {
|
||||||
|
color: #999999;
|
||||||
|
font-size: 12px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------
|
||||||
|
TYPOGRAPHY
|
||||||
|
------------------------------------- */
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4 {
|
||||||
|
color: #000000;
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 1.4;
|
||||||
|
margin: 0;
|
||||||
|
Margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 35px;
|
||||||
|
font-weight: 300;
|
||||||
|
text-align: center;
|
||||||
|
text-transform: capitalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
p,
|
||||||
|
ul,
|
||||||
|
ol {
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: normal;
|
||||||
|
margin: 0;
|
||||||
|
Margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p li,
|
||||||
|
ul li,
|
||||||
|
ol li {
|
||||||
|
list-style-position: inside;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #3498db;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------
|
||||||
|
BUTTONS
|
||||||
|
------------------------------------- */
|
||||||
|
.btn {
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn>tbody>tr>td {
|
||||||
|
padding-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn table {
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn table td {
|
||||||
|
background-color: #ffffff;
|
||||||
|
border-radius: 5px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn a {
|
||||||
|
background-color: #ffffff;
|
||||||
|
border: solid 1px #3498db;
|
||||||
|
border-radius: 5px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
color: #3498db;
|
||||||
|
cursor: pointer;
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: bold;
|
||||||
|
margin: 0;
|
||||||
|
padding: 12px 25px;
|
||||||
|
text-decoration: none;
|
||||||
|
text-transform: capitalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary table td {
|
||||||
|
background-color: #3498db;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary a {
|
||||||
|
background-color: #3498db;
|
||||||
|
border-color: #3498db;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------
|
||||||
|
OTHER STYLES THAT MIGHT BE USEFUL
|
||||||
|
------------------------------------- */
|
||||||
|
.last {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.first {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.align-center {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.align-right {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.align-left {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.clear {
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mt0 {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mb0 {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preheader {
|
||||||
|
color: transparent;
|
||||||
|
display: none;
|
||||||
|
height: 0;
|
||||||
|
max-height: 0;
|
||||||
|
max-width: 0;
|
||||||
|
opacity: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
visibility: hidden;
|
||||||
|
width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.powered-by a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
border: 0;
|
||||||
|
border-bottom: 1px solid #f6f6f6;
|
||||||
|
Margin: 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------
|
||||||
|
RESPONSIVE AND MOBILE FRIENDLY STYLES
|
||||||
|
------------------------------------- */
|
||||||
|
@media only screen and (max-width: 620px) {
|
||||||
|
table[class=body] h1 {
|
||||||
|
font-size: 28px !important;
|
||||||
|
margin-bottom: 10px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] p,
|
||||||
|
table[class=body] ul,
|
||||||
|
table[class=body] ol,
|
||||||
|
table[class=body] td,
|
||||||
|
table[class=body] span,
|
||||||
|
table[class=body] a {
|
||||||
|
font-size: 16px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] .wrapper,
|
||||||
|
table[class=body] .article {
|
||||||
|
padding: 10px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] .content {
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] .container {
|
||||||
|
padding: 0 !important;
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] .main {
|
||||||
|
border-left-width: 0 !important;
|
||||||
|
border-radius: 0 !important;
|
||||||
|
border-right-width: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] .btn table {
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] .btn a {
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] .img-responsive {
|
||||||
|
height: auto !important;
|
||||||
|
max-width: 100% !important;
|
||||||
|
width: auto !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------
|
||||||
|
PRESERVE THESE STYLES IN THE HEAD
|
||||||
|
------------------------------------- */
|
||||||
|
@media all {
|
||||||
|
.ExternalClass {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ExternalClass,
|
||||||
|
.ExternalClass p,
|
||||||
|
.ExternalClass span,
|
||||||
|
.ExternalClass font,
|
||||||
|
.ExternalClass td,
|
||||||
|
.ExternalClass div {
|
||||||
|
line-height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.apple-link a {
|
||||||
|
color: inherit !important;
|
||||||
|
font-family: inherit !important;
|
||||||
|
font-size: inherit !important;
|
||||||
|
font-weight: inherit !important;
|
||||||
|
line-height: inherit !important;
|
||||||
|
text-decoration: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary table td:hover {
|
||||||
|
background-color: #34495e !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary a:hover {
|
||||||
|
background-color: #34495e !important;
|
||||||
|
border-color: #34495e !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ol {
|
||||||
|
padding: 0 0 0 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol li {
|
||||||
|
margin: 1em 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="">
|
||||||
|
<table border="0" cellpadding="0" cellspacing="0" class="body">
|
||||||
|
<tr>
|
||||||
|
<td> </td>
|
||||||
|
<td class="container">
|
||||||
|
<div class="content">
|
||||||
|
<table class="main">
|
||||||
|
<!-- START MAIN CONTENT AREA -->
|
||||||
|
<tr>
|
||||||
|
<td class="wrapper">
|
||||||
|
<table border="0" cellpadding="0" cellspacing="0">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<p class="mb0"><b>Dear,</b></p>
|
||||||
|
<p class="mb0">{{customer_name}}</p>
|
||||||
|
<p>{{customer_phone}}</p>
|
||||||
|
|
||||||
|
<p class="mb-0">Good News!</p>
|
||||||
|
<p>We've successfully processed your refund for:</p>
|
||||||
|
|
||||||
|
<p class="mb0">Here are the details of your refund:</p>
|
||||||
|
<p class="mb0">Transaction Date: <b>{{booking_date}}</b></p>
|
||||||
|
<p class="mb0">Transaction Code: <b>{{invoice_code}}</b></p>
|
||||||
|
<p class="mb0">Total Refund: <b>{{refund.refund_total}}</b></p>
|
||||||
|
<p>{{{refund_items}}}</p>
|
||||||
|
|
||||||
|
<p class="mb0">Transaction Number: <b>{{invoice_code}}</b></p>
|
||||||
|
<p class="mb0">Refund Processed Date: <b>{{refund.refund_date}}</b></p>
|
||||||
|
<p class="mb0">Bank Account: <b>{{refund.bank_name}}</b></p>
|
||||||
|
<p class="mb0">Account Number: <b>{{refund.bank_account_number}}</b></p>
|
||||||
|
<p>Account Name: <b>{{refund.bank_account_name}}</b></p>
|
||||||
|
|
||||||
|
<p class="mb0">We hope this helps make things right, and we're here to assist if you need anything else</p>
|
||||||
|
<p>You should see the refund in your account within 3 business days</p>
|
||||||
|
|
||||||
|
|
||||||
|
<p class="mb0">Thank you for your patience and understanding</p>
|
||||||
|
<p>If you have any questions or need further assistance, don't hesitate to reach out us at</p>
|
||||||
|
<b>{{phone_cs}}</b>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<p class="mb0">Thank you and we can't wait to see you and make sure you have an amazing time!</p>
|
||||||
|
|
||||||
|
<br><br>
|
||||||
|
<b>Best Regrads,</b><br>
|
||||||
|
<b>WEplayground</b>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<!-- END MAIN CONTENT AREA -->
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td> </td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
|
@ -0,0 +1,409 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta name="viewport" content="width=device-width" />
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
|
<title>Email Confirmation</title>
|
||||||
|
<style>
|
||||||
|
/* -------------------------------------
|
||||||
|
GLOBAL RESETS
|
||||||
|
------------------------------------- */
|
||||||
|
img {
|
||||||
|
border: none;
|
||||||
|
-ms-interpolation-mode: bicubic;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-color: #f6f6f6;
|
||||||
|
font-family: sans-serif;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.4;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
-ms-text-size-adjust: 100%;
|
||||||
|
-webkit-text-size-adjust: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
border-collapse: separate;
|
||||||
|
mso-table-lspace: 0pt;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
table td {
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-size: 14px;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------
|
||||||
|
BODY & CONTAINER
|
||||||
|
------------------------------------- */
|
||||||
|
|
||||||
|
.body {
|
||||||
|
background-color: #f6f6f6;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set a max-width, and make it display as block so it will automatically stretch to that width, but will also shrink
|
||||||
|
down on a phone or something */
|
||||||
|
.container {
|
||||||
|
display: block;
|
||||||
|
Margin: 0 auto !important;
|
||||||
|
/* makes it centered */
|
||||||
|
max-width: 580px;
|
||||||
|
padding: 10px;
|
||||||
|
width: 580px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This should also be a block element, so that it will fill 100% of the .container */
|
||||||
|
.content {
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: block;
|
||||||
|
Margin: 0 auto;
|
||||||
|
max-width: 580px;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------
|
||||||
|
HEADER, FOOTER, MAIN
|
||||||
|
------------------------------------- */
|
||||||
|
.main {
|
||||||
|
background: #ffffff;
|
||||||
|
border-radius: 3px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wrapper {
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-block {
|
||||||
|
padding-bottom: 10px;
|
||||||
|
padding-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
clear: both;
|
||||||
|
Margin-top: 10px;
|
||||||
|
text-align: center;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer td,
|
||||||
|
.footer p,
|
||||||
|
.footer span,
|
||||||
|
.footer a {
|
||||||
|
color: #999999;
|
||||||
|
font-size: 12px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------
|
||||||
|
TYPOGRAPHY
|
||||||
|
------------------------------------- */
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4 {
|
||||||
|
color: #000000;
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 1.4;
|
||||||
|
margin: 0;
|
||||||
|
Margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 35px;
|
||||||
|
font-weight: 300;
|
||||||
|
text-align: center;
|
||||||
|
text-transform: capitalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
p,
|
||||||
|
ul,
|
||||||
|
ol {
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: normal;
|
||||||
|
margin: 0;
|
||||||
|
Margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p li,
|
||||||
|
ul li,
|
||||||
|
ol li {
|
||||||
|
list-style-position: inside;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #3498db;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------
|
||||||
|
BUTTONS
|
||||||
|
------------------------------------- */
|
||||||
|
.btn {
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn>tbody>tr>td {
|
||||||
|
padding-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn table {
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn table td {
|
||||||
|
background-color: #ffffff;
|
||||||
|
border-radius: 5px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn a {
|
||||||
|
background-color: #ffffff;
|
||||||
|
border: solid 1px #3498db;
|
||||||
|
border-radius: 5px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
color: #3498db;
|
||||||
|
cursor: pointer;
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: bold;
|
||||||
|
margin: 0;
|
||||||
|
padding: 12px 25px;
|
||||||
|
text-decoration: none;
|
||||||
|
text-transform: capitalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary table td {
|
||||||
|
background-color: #3498db;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary a {
|
||||||
|
background-color: #3498db;
|
||||||
|
border-color: #3498db;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------
|
||||||
|
OTHER STYLES THAT MIGHT BE USEFUL
|
||||||
|
------------------------------------- */
|
||||||
|
.last {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.first {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.align-center {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.align-right {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.align-left {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.clear {
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mt0 {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mb0 {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preheader {
|
||||||
|
color: transparent;
|
||||||
|
display: none;
|
||||||
|
height: 0;
|
||||||
|
max-height: 0;
|
||||||
|
max-width: 0;
|
||||||
|
opacity: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
visibility: hidden;
|
||||||
|
width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.powered-by a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
border: 0;
|
||||||
|
border-bottom: 1px solid #f6f6f6;
|
||||||
|
Margin: 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------
|
||||||
|
RESPONSIVE AND MOBILE FRIENDLY STYLES
|
||||||
|
------------------------------------- */
|
||||||
|
@media only screen and (max-width: 620px) {
|
||||||
|
table[class=body] h1 {
|
||||||
|
font-size: 28px !important;
|
||||||
|
margin-bottom: 10px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] p,
|
||||||
|
table[class=body] ul,
|
||||||
|
table[class=body] ol,
|
||||||
|
table[class=body] td,
|
||||||
|
table[class=body] span,
|
||||||
|
table[class=body] a {
|
||||||
|
font-size: 16px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] .wrapper,
|
||||||
|
table[class=body] .article {
|
||||||
|
padding: 10px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] .content {
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] .container {
|
||||||
|
padding: 0 !important;
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] .main {
|
||||||
|
border-left-width: 0 !important;
|
||||||
|
border-radius: 0 !important;
|
||||||
|
border-right-width: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] .btn table {
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] .btn a {
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table[class=body] .img-responsive {
|
||||||
|
height: auto !important;
|
||||||
|
max-width: 100% !important;
|
||||||
|
width: auto !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------
|
||||||
|
PRESERVE THESE STYLES IN THE HEAD
|
||||||
|
------------------------------------- */
|
||||||
|
@media all {
|
||||||
|
.ExternalClass {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ExternalClass,
|
||||||
|
.ExternalClass p,
|
||||||
|
.ExternalClass span,
|
||||||
|
.ExternalClass font,
|
||||||
|
.ExternalClass td,
|
||||||
|
.ExternalClass div {
|
||||||
|
line-height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.apple-link a {
|
||||||
|
color: inherit !important;
|
||||||
|
font-family: inherit !important;
|
||||||
|
font-size: inherit !important;
|
||||||
|
font-weight: inherit !important;
|
||||||
|
line-height: inherit !important;
|
||||||
|
text-decoration: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary table td:hover {
|
||||||
|
background-color: #34495e !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary a:hover {
|
||||||
|
background-color: #34495e !important;
|
||||||
|
border-color: #34495e !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ol {
|
||||||
|
padding: 0 0 0 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol li {
|
||||||
|
margin: 1em 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="">
|
||||||
|
<table border="0" cellpadding="0" cellspacing="0" class="body">
|
||||||
|
<tr>
|
||||||
|
<td> </td>
|
||||||
|
<td class="container">
|
||||||
|
<div class="content">
|
||||||
|
<table class="main">
|
||||||
|
<!-- START MAIN CONTENT AREA -->
|
||||||
|
<tr>
|
||||||
|
<td class="wrapper">
|
||||||
|
<table border="0" cellpadding="0" cellspacing="0">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<p class="mb0"><b>Dear,</b></p>
|
||||||
|
<p class="mb0">{{customer_name}}</p>
|
||||||
|
<p>{{customer_phone}}</p>
|
||||||
|
|
||||||
|
<p class="mb0">We're trully sorry for any inconvenience that led to this request</p>
|
||||||
|
<p>We've received your refund request for :</p>
|
||||||
|
|
||||||
|
<p class="mb0">Transaction Date: <b>{{booking_date}}</b></p>
|
||||||
|
<p class="mb0">Transaction Code: <b>{{invoice_code}}</b></p>
|
||||||
|
<p class="mb0">Refund Code: <b>{{refund.code}}</b></p>
|
||||||
|
<p class="mb0">Total Refund: <b>{{refund.refund_total}}</b></p>
|
||||||
|
<p>{{{refund_items}}}</p>
|
||||||
|
|
||||||
|
<p class="mb0">Your satisfaction is important to us, and we're commited to resolving this as quickly as possible</p>
|
||||||
|
<p class="mb0">Our team is already on it and will process your refund request promptly</p>
|
||||||
|
<p>We'll keep you updated and notify you once the refund has been processed</p>
|
||||||
|
|
||||||
|
<p class="mb0">If you have any questions or need assistance, feel free to reach out to our support team at</p>
|
||||||
|
<b>{{phone_cs}}</b>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<p class="mb0">Thank you for your patience and understanding</p>
|
||||||
|
<p>We appriciate your feedback and are here to make things right</p>
|
||||||
|
|
||||||
|
<br><br>
|
||||||
|
<b>Best Regrads,</b><br>
|
||||||
|
<b>WEplayground</b>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<!-- END MAIN CONTENT AREA -->
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td> </td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
After Width: | Height: | Size: 120 KiB |
Binary file not shown.
After Width: | Height: | Size: 504 KiB |
|
@ -0,0 +1,13 @@
|
||||||
|
{
|
||||||
|
"type": "service_account",
|
||||||
|
"project_id": "weplayground-app",
|
||||||
|
"private_key_id": "e3ed1a4430140ac589c6e9e7ce125d16d8f7304a",
|
||||||
|
"private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDCmEl90K7ojdx1\nnJv5BKq3THI+l+pgC4dlqOuEV4sc2SFXECgyEgEYAFH6U8eH9TTl5wW5hFhvpiWl\nHSxZA2nMa1ojp97mkufzaGgsJbcB4ni9ydoJyN9Hqs2Wz+JiBtjscGOrmOP1bNyn\nBO9RhHInh0bfTNMrtsIicr4DPNIfM2sl95v6pCDGt7Cfu2NoEnDhId50d73KVONI\n0+rf90WhehEMwoZEzYI0gLmSVbnPEm1j4/OOQfQl7FjaFKyle+A5BWaiRsIqiSue\n0jvZz0DlGmjeHx1yjBIKpq5omOku7aYi4kTNEZKKxzs5HhRFKi2KuYNK/WD5ApQg\ncIhGhhCfAgMBAAECggEANX+LmNjh9VJm/Tigkt4LFxifwgCe8WfKAhNmKHyu5K/3\nIAnzmwxjG5ee8gzNat3pfJk+dCnj7FIHwHScSB6NnCMZZXsV51sVBNC77wMxZIXA\nPyE63fzJEdlt6xvc96k9QweFB1yhs0wJ/6r2JnmcrqxcujBTUA3PIoxcG+TBOc08\ndo5Rcbeq6/3txjGlFM1820WViuFSQQiL6PgNVb+l0JrQ8rAOflKYFOkUb8wux9LX\nnD4vJMwa0j+GRvH5BCcZCguIQZn2JR3rTgcavWtcaHiTNsc49Lsj/hGGOsbkFROo\nGWaSgXE169xiVR/MMEblzqpSXq1qXF2iUeaqyUFIZQKBgQDxxrNlDs1qMfcaQ0S2\nVVtU/f1NfY+kCjQaC4CoYJaaoZINs5ODPs8/2DGnHuhNXMtnPeQ+SzNaK1e1eLbw\nmvq1+n3aGZTvUq2L3b+v7JJ6TQmQ4eBLZBzNjxrxC3EkCULTuROtsAhfzORuE0mE\nwnhR5LpPraEBrPi0re9yDDXVHQKBgQDOCwGw1gNVLh622qR65Zhx5rs2q6ktPxq2\neiUV0KDug6/7QbJzg1pNeoVQmadJR86H0fzKMsN5C7t7z3MIkqXc0+T1NmdN2fPm\ndLthnR1grCDYykoet/CITbAfiip27/o3TJ7YIYItefyZ4GnNH82R/4z3LBDnXB9f\n565hbUj76wKBgEnNMpOFijSBXgFZSU8zDPcLtNeDnWYgazkMC9DZ8v7ulOuzxjKI\n6LB/aOCvsY9z5O712IcfY2SB2HsfhxA47pDADsyVhH3tSeZo4QttdmT4wRPFrza0\nL4qbxUiRCo9KeGiylQwusM+1doEXSBjLV/j/jdOml4AwcZaNhYrVqVUNAoGAU0uD\nzXdXNZJFfGp7X+t9a155hKp05APEyswqPd1vkbzO4eY3PBd35CaJyoGzbR6IUcQE\nS8Gl4ENr8at1t5uBTfqjbrYloQVhYmMCdX3MqI4tYTa2LCD0LkYp0zZJ4Hc3Ui+5\nb2psc/ICujpMy032DvWeiTXZR46oaF8C0gQaIy0CgYEAmKCP4CXmPlWoWqebFp3W\nz2eKWUfASioQ+ZGUVNEge4a6iutciydQJZxBfg9ZXWqDfI0FoRSPfs2zUZFO0AcM\n6oaPGiFnTnH8FGcSHu3p0YysevyoSY6tgsAhb3IiKjJd4e7btsYzpPZbIfyfUVHK\nQFOOSkE+x4J5ts+XO6isQ+w=\n-----END PRIVATE KEY-----\n",
|
||||||
|
"client_email": "weplayground@weplayground-app.iam.gserviceaccount.com",
|
||||||
|
"client_id": "106351339097550564510",
|
||||||
|
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
|
||||||
|
"token_uri": "https://oauth2.googleapis.com/token",
|
||||||
|
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
|
||||||
|
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/weplayground%40weplayground-app.iam.gserviceaccount.com",
|
||||||
|
"universe_domain": "googleapis.com"
|
||||||
|
}
|
|
@ -6,6 +6,8 @@ JWT_REFRESH_EXPIRES="7d"
|
||||||
ENC_KEY="921c83f3b90c92dca4ba9b947f99b4c9"
|
ENC_KEY="921c83f3b90c92dca4ba9b947f99b4c9"
|
||||||
IV="a671a96159e97a4f"
|
IV="a671a96159e97a4f"
|
||||||
|
|
||||||
|
COUCHDB_CONFIG="http://root:password@172.10.10.2:5970"
|
||||||
|
|
||||||
DEFAULT_DB_HOST="postgres"
|
DEFAULT_DB_HOST="postgres"
|
||||||
DEFAULT_DB_PORT="5432"
|
DEFAULT_DB_PORT="5432"
|
||||||
DEFAULT_DB_USER="root"
|
DEFAULT_DB_USER="root"
|
||||||
|
@ -15,3 +17,33 @@ DEFAULT_DB_NAME="pos"
|
||||||
ELASTIC_APM_ACTIVATE=true
|
ELASTIC_APM_ACTIVATE=true
|
||||||
ELASTIC_APM_SERVICE_NAME="Skyworld POS"
|
ELASTIC_APM_SERVICE_NAME="Skyworld POS"
|
||||||
ELASTIC_APM_SERVER_URL="http://172.10.10.10:8200"
|
ELASTIC_APM_SERVER_URL="http://172.10.10.10:8200"
|
||||||
|
|
||||||
|
CRON_MIDNIGHT="55 11 * * *"
|
||||||
|
CRON_EVERY_MINUTE="55 11 * * *"
|
||||||
|
CRON_EVERY_HOUR="0 * * * *"
|
||||||
|
|
||||||
|
EMAIL_HOST=smtp.gmail.com
|
||||||
|
EMAIL_POST=465
|
||||||
|
EMAIL_USER=weplayground.app@gmail.com
|
||||||
|
EMAIL_TOKEN="sonv vwiu khse vtmv"
|
||||||
|
|
||||||
|
// nama email yang akan muncul ke user sebagai pengirim
|
||||||
|
EMAIL_SENDER=no-reply@eigen.co.id
|
||||||
|
|
||||||
|
MIDTRANS_URL=https://app.sandbox.midtrans.com
|
||||||
|
MIDTRANS_PRODUCTION=false
|
||||||
|
MIDTRANS_SERVER_KEY=SB-Mid-server-kH9_RBZrTwaUkxSrC5vOVaeG
|
||||||
|
MIDTRANS_CLIENT_KEY=SB-Mid-client-7XLwqG5cgjUmZj-7
|
||||||
|
|
||||||
|
EXPORT_LIMIT_PARTITION=200
|
||||||
|
ASSETS="https://asset.sky.eigen.co.id/"
|
||||||
|
|
||||||
|
GOOGLE_CALENDAR_KEY="AIzaSyCSg4P3uC9Z7kD1P4f3rf1BbBaz4Q-M55o"
|
||||||
|
GOOGLE_CALENDAR_ID="326464ac296874c7121825f5ef2e2799baa90b51da240f0045aae22beec10bd5@group.calendar.google.com"
|
||||||
|
|
||||||
|
SUPERSET_URL=https://dashboard.weplayground.eigen.co.id
|
||||||
|
SUPERSET_ADMIN_USERNAME=admin
|
||||||
|
SUPERSET_ADMIN_PASSWORD=admin
|
||||||
|
|
||||||
|
WHATSAPP_BUSINESS_ACCOUNT_NUMBER_ID=604883366037548
|
||||||
|
WHATSAPP_BUSINESS_ACCESS_TOKEN=EAAINOvRRiEEBO9yQsYDnYtjHZB7q1nZCwbBpRcxIGMDWajKZBtmWxNRKvPYkS95KQZBsZBOvSFyjiEg5CcCZBZBtaSZApxyV8fiA3cEyVwf7iVZBQP2YCTPRQZArMFeeXbO0uq5TGygmjsIz3M4YxcUHxPzKO4pKxIyxnzcoUZCqCSo1NqQSLVf3a0JyZAwgDXGL55dV
|
|
@ -0,0 +1,46 @@
|
||||||
|
PORT="3346"
|
||||||
|
|
||||||
|
JWT_SECRET="ftyYM4t4kjuj/0ixvIrS18gpdvBJw42NnW71GrFrEhcn0alQkkH7TQIHU5MFFJ1e"
|
||||||
|
JWT_EXPIRES="24h"
|
||||||
|
JWT_REFRESH_EXPIRES="7d"
|
||||||
|
ENC_KEY="921c83f3b90c92dca4ba9b947f99b4c9"
|
||||||
|
IV="a671a96159e97a4f"
|
||||||
|
|
||||||
|
COUCHDB_CONFIG="http://root:password@172.10.10.2:5970"
|
||||||
|
|
||||||
|
DEFAULT_DB_HOST="postgres"
|
||||||
|
DEFAULT_DB_PORT="5432"
|
||||||
|
DEFAULT_DB_USER="root"
|
||||||
|
DEFAULT_DB_PASS="password"
|
||||||
|
DEFAULT_DB_NAME="pos"
|
||||||
|
|
||||||
|
ELASTIC_APM_ACTIVATE=true
|
||||||
|
ELASTIC_APM_SERVICE_NAME="Skyworld POS"
|
||||||
|
ELASTIC_APM_SERVER_URL="http://172.10.10.10:8200"
|
||||||
|
|
||||||
|
CRON_MIDNIGHT="55 11 * * *"
|
||||||
|
CRON_EVERY_MINUTE="55 11 * * *"
|
||||||
|
CRON_EVERY_HOUR="0 * * * *"
|
||||||
|
|
||||||
|
EMAIL_HOST=smtp.gmail.com
|
||||||
|
EMAIL_POST=465
|
||||||
|
EMAIL_USER=weplayground.app@gmail.com
|
||||||
|
EMAIL_TOKEN="sonv vwiu khse vtmv"
|
||||||
|
|
||||||
|
MIDTRANS_URL=https://app.midtrans.com
|
||||||
|
MIDTRANS_PRODUCTION=true
|
||||||
|
MIDTRANS_SERVER_KEY=Mid-server-BZlPCcrWHDuSxW48oxBs5uAl
|
||||||
|
MIDTRANS_CLIENT_KEY=Mid-client-YhOPuo0NZPNZfiKq
|
||||||
|
|
||||||
|
EXPORT_LIMIT_PARTITION=200
|
||||||
|
ASSETS="https://asset.sky.eigen.co.id/"
|
||||||
|
|
||||||
|
GOOGLE_CALENDAR_KEY="AIzaSyCSg4P3uC9Z7kD1P4f3rf1BbBaz4Q-M55o"
|
||||||
|
GOOGLE_CALENDAR_ID="326464ac296874c7121825f5ef2e2799baa90b51da240f0045aae22beec10bd5@group.calendar.google.com"
|
||||||
|
|
||||||
|
SUPERSET_URL=https://dashboard.weplayground.eigen.co.id
|
||||||
|
SUPERSET_ADMIN_USERNAME=admin
|
||||||
|
SUPERSET_ADMIN_PASSWORD=admin
|
||||||
|
|
||||||
|
WHATSAPP_BUSINESS_ACCOUNT_NUMBER_ID=604883366037548
|
||||||
|
WHATSAPP_BUSINESS_ACCESS_TOKEN=EAAINOvRRiEEBO9yQsYDnYtjHZB7q1nZCwbBpRcxIGMDWajKZBtmWxNRKvPYkS95KQZBsZBOvSFyjiEg5CcCZBZBtaSZApxyV8fiA3cEyVwf7iVZBQP2YCTPRQZArMFeeXbO0uq5TGygmjsIz3M4YxcUHxPzKO4pKxIyxnzcoUZCqCSo1NqQSLVf3a0JyZAwgDXGL55dV
|
|
@ -0,0 +1,42 @@
|
||||||
|
## Formula Calculation
|
||||||
|
|
||||||
|
### Instalation
|
||||||
|
```
|
||||||
|
yarn add mathjs algebra.js
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Example
|
||||||
|
```ts
|
||||||
|
import * as math from 'mathjs'
|
||||||
|
import { Equation, parse } from 'algebra.js'
|
||||||
|
|
||||||
|
const formula = 'dpp - (dpp*ppn) - (dpp*retribusi) - (dpp*service) - (dpp*ppn3)'
|
||||||
|
const total = '300000'
|
||||||
|
|
||||||
|
const variable = {
|
||||||
|
ppn: 11,
|
||||||
|
retribusi: 5000,
|
||||||
|
service: 5,
|
||||||
|
ppn3: 5000
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
const x1 = math.simplify(formula, variable).toString()
|
||||||
|
console.log('Formula ', x1)
|
||||||
|
const dppFormula = parse(x1)
|
||||||
|
const totalFormula = parse(total)
|
||||||
|
const equation = new Equation(totalFormula, dppFormula)
|
||||||
|
|
||||||
|
console.log(equation.toString())
|
||||||
|
const result = equation.solveFor('dpp').toString()
|
||||||
|
console.log(result)
|
||||||
|
|
||||||
|
const value = math.evaluate(result)
|
||||||
|
console.log(value)
|
||||||
|
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e)
|
||||||
|
}
|
||||||
|
```
|
18
package.json
18
package.json
|
@ -23,24 +23,40 @@
|
||||||
"seed:config": "ts-node -r tsconfig-paths/register ./node_modules/typeorm-seeding/dist/cli.js -n ./src/database/seed-ormconfig.ts config",
|
"seed:config": "ts-node -r tsconfig-paths/register ./node_modules/typeorm-seeding/dist/cli.js -n ./src/database/seed-ormconfig.ts config",
|
||||||
"seed:run": "ts-node -r tsconfig-paths/register ./node_modules/typeorm-seeding/dist/cli.js -n ./src/database/seed-ormconfig.ts seed",
|
"seed:run": "ts-node -r tsconfig-paths/register ./node_modules/typeorm-seeding/dist/cli.js -n ./src/database/seed-ormconfig.ts seed",
|
||||||
"factory:config": "ts-node -r tsconfig-paths/register ./node_modules/typeorm-seeding/dist/cli.js -n ./src/database/seed-data-ormconfig.ts config",
|
"factory:config": "ts-node -r tsconfig-paths/register ./node_modules/typeorm-seeding/dist/cli.js -n ./src/database/seed-data-ormconfig.ts config",
|
||||||
"factory:run": "ts-node -r tsconfig-paths/register ./node_modules/typeorm-seeding/dist/cli.js -n ./src/database/seed-data-ormconfig.ts seed"
|
"factory:run": "ts-node -r tsconfig-paths/register ./node_modules/typeorm-seeding/dist/cli.js -n ./src/database/seed-data-ormconfig.ts seed",
|
||||||
|
"db:generate": "npm run orm migration:generate"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@faker-js/faker": "^8.4.1",
|
"@faker-js/faker": "^8.4.1",
|
||||||
|
"@nestjs/axios": "^3.0.3",
|
||||||
"@nestjs/common": "^10.0.0",
|
"@nestjs/common": "^10.0.0",
|
||||||
"@nestjs/config": "^3.2.2",
|
"@nestjs/config": "^3.2.2",
|
||||||
"@nestjs/core": "^10.0.0",
|
"@nestjs/core": "^10.0.0",
|
||||||
"@nestjs/cqrs": "^10.2.7",
|
"@nestjs/cqrs": "^10.2.7",
|
||||||
"@nestjs/jwt": "^10.2.0",
|
"@nestjs/jwt": "^10.2.0",
|
||||||
"@nestjs/platform-express": "^10.0.0",
|
"@nestjs/platform-express": "^10.0.0",
|
||||||
|
"@nestjs/schedule": "^4.1.0",
|
||||||
"@nestjs/swagger": "^7.3.1",
|
"@nestjs/swagger": "^7.3.1",
|
||||||
"@nestjs/typeorm": "^10.0.2",
|
"@nestjs/typeorm": "^10.0.2",
|
||||||
|
"@types/multer": "^1.4.11",
|
||||||
|
"algebra.js": "^0.2.6",
|
||||||
|
"axios": "^1.7.5",
|
||||||
"bcrypt": "^5.1.1",
|
"bcrypt": "^5.1.1",
|
||||||
"class-transformer": "^0.5.1",
|
"class-transformer": "^0.5.1",
|
||||||
"class-validator": "^0.14.1",
|
"class-validator": "^0.14.1",
|
||||||
"dotenv": "^16.4.5",
|
"dotenv": "^16.4.5",
|
||||||
"elastic-apm-node": "^4.5.4",
|
"elastic-apm-node": "^4.5.4",
|
||||||
|
"exceljs": "^4.4.0",
|
||||||
|
"fs-extra": "^11.2.0",
|
||||||
|
"googleapis": "^140.0.0",
|
||||||
|
"gtts": "^0.2.1",
|
||||||
|
"handlebars": "^4.7.8",
|
||||||
|
"mathjs": "^13.0.2",
|
||||||
|
"midtrans-client": "^1.3.1",
|
||||||
|
"moment": "^2.30.1",
|
||||||
"nano": "^10.1.3",
|
"nano": "^10.1.3",
|
||||||
|
"nodemailer": "^6.9.14",
|
||||||
|
"pdfmake": "^0.2.10",
|
||||||
"pg": "^8.11.5",
|
"pg": "^8.11.5",
|
||||||
"plop": "^4.0.1",
|
"plop": "^4.0.1",
|
||||||
"reflect-metadata": "^0.2.0",
|
"reflect-metadata": "^0.2.0",
|
||||||
|
|
|
@ -29,7 +29,7 @@ module.exports = function (plop) {
|
||||||
name: 'location',
|
name: 'location',
|
||||||
message: 'Location: ',
|
message: 'Location: ',
|
||||||
choices: function () {
|
choices: function () {
|
||||||
return ['item related', 'user related', 'season related', 'transaction'];
|
return ['item related', 'user related', 'season related', 'transaction', 'web information'];
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
|
@ -37,6 +37,62 @@ import { SalesPriceFormulaModel } from './modules/transaction/sales-price-formul
|
||||||
import { ProfitShareFormulaModule } from './modules/transaction/profit-share-formula/profit-share-formula.module';
|
import { ProfitShareFormulaModule } from './modules/transaction/profit-share-formula/profit-share-formula.module';
|
||||||
import { PaymentMethodModule } from './modules/transaction/payment-method/payment-method.module';
|
import { PaymentMethodModule } from './modules/transaction/payment-method/payment-method.module';
|
||||||
import { PaymentMethodModel } from './modules/transaction/payment-method/data/models/payment-method.model';
|
import { PaymentMethodModel } from './modules/transaction/payment-method/data/models/payment-method.model';
|
||||||
|
import { SeasonPeriodModule } from './modules/season-related/season-period/season-period.module';
|
||||||
|
import { SeasonPeriodModel } from './modules/season-related/season-period/data/models/season-period.model';
|
||||||
|
import { ItemRateModule } from './modules/item-related/item-rate/item-rate.module';
|
||||||
|
import { ItemRateModel } from './modules/item-related/item-rate/data/models/item-rate.model';
|
||||||
|
import { GoogleCalendarModule } from './modules/configuration/google-calendar/google-calendar.module';
|
||||||
|
import { TransactionModule } from './modules/transaction/transaction/transaction.module';
|
||||||
|
import { TransactionModel } from './modules/transaction/transaction/data/models/transaction.model';
|
||||||
|
import {
|
||||||
|
TransactionBreakdownTaxModel,
|
||||||
|
TransactionItemBreakdownModel,
|
||||||
|
TransactionItemModel,
|
||||||
|
TransactionItemTaxModel,
|
||||||
|
} from './modules/transaction/transaction/data/models/transaction-item.model';
|
||||||
|
import { TransactionTaxModel } from './modules/transaction/transaction/data/models/transaction-tax.model';
|
||||||
|
import { ReconciliationModule } from './modules/transaction/reconciliation/reconciliation.module';
|
||||||
|
import { ReportModule } from './modules/reports/report/report.module';
|
||||||
|
import { ReportBookmarkModule } from './modules/reports/report-bookmark/report-bookmark.module';
|
||||||
|
import { ReportExportModule } from './modules/reports/report-export/report-export.module';
|
||||||
|
import { ReportBookmarkModel } from './modules/reports/shared/models/report-bookmark.model';
|
||||||
|
import { ExportReportHistoryModel } from './modules/reports/shared/models/export-report-history.model';
|
||||||
|
import { CronModule } from './modules/configuration/cron/cron.module';
|
||||||
|
import { MidtransModule } from './modules/configuration/midtrans/midtrans.module';
|
||||||
|
import { RefundModule } from './modules/transaction/refund/refund.module';
|
||||||
|
import { RefundModel } from './modules/transaction/refund/data/models/refund.model';
|
||||||
|
import { RefundItemModel } from './modules/transaction/refund/data/models/refund-item.model';
|
||||||
|
import { GateModule } from './modules/web-information/gate/gate.module';
|
||||||
|
import { GateModel } from './modules/web-information/gate/data/models/gate.model';
|
||||||
|
import { TermConditionModule } from './modules/web-information/term-condition/term-condition.module';
|
||||||
|
import { TermConditionModel } from './modules/web-information/term-condition/data/models/term-condition.model';
|
||||||
|
import { FaqModel } from './modules/web-information/faq/data/models/faq.model';
|
||||||
|
import { FaqModule } from './modules/web-information/faq/faq.module';
|
||||||
|
import { UploadModule } from './modules/configuration/upload/upload.module';
|
||||||
|
import { NewsModule } from './modules/web-information/news/news.module';
|
||||||
|
import { NewsModel } from './modules/web-information/news/data/models/news.model';
|
||||||
|
import { BannerModule } from './modules/web-information/banner/banner.module';
|
||||||
|
import { BannerModel } from './modules/web-information/banner/data/models/banner.model';
|
||||||
|
import { MailModule } from './modules/configuration/mail/mail.module';
|
||||||
|
import { PosLogModel } from './modules/configuration/log/data/models/pos-log.model';
|
||||||
|
import { ExportModule } from './modules/configuration/export/export.module';
|
||||||
|
import { TransactionDemographyModel } from './modules/transaction/transaction/data/models/transaction-demography.model';
|
||||||
|
import { SupersetModule } from './modules/configuration/superset/superset.module';
|
||||||
|
import { GateScanModule } from './modules/gates/gate.module';
|
||||||
|
import { UserLoginModel } from './modules/user-related/user/data/models/user-login.model';
|
||||||
|
import { LogUserLoginModel } from './modules/configuration/log/data/models/log-user-login.model';
|
||||||
|
import { AuthService } from './core/guards/domain/services/auth.service';
|
||||||
|
import { ReportSummaryModule } from './modules/reports/report-summary/report-summary.module';
|
||||||
|
import { QueueModule } from './modules/queue/queue.module';
|
||||||
|
import {
|
||||||
|
QueueOrderModel,
|
||||||
|
QueueTicketModel,
|
||||||
|
QueueItemModel,
|
||||||
|
QueueModel,
|
||||||
|
} from './modules/queue/data/models/queue.model';
|
||||||
|
import { ItemQueueModule } from './modules/item-related/item-queue/item-queue.module';
|
||||||
|
import { ItemQueueModel } from './modules/item-related/item-queue/data/models/item-queue.model';
|
||||||
|
import { QueueBucketModel } from './modules/queue/data/models/queue-bucket.model';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
|
@ -54,26 +110,64 @@ import { PaymentMethodModel } from './modules/transaction/payment-method/data/mo
|
||||||
database: process.env.DEFAULT_DB_NAME,
|
database: process.env.DEFAULT_DB_NAME,
|
||||||
entities: [
|
entities: [
|
||||||
...UserPrivilegeModels,
|
...UserPrivilegeModels,
|
||||||
|
BannerModel,
|
||||||
ErrorLogModel,
|
ErrorLogModel,
|
||||||
|
FaqModel,
|
||||||
|
GateModel,
|
||||||
ItemModel,
|
ItemModel,
|
||||||
ItemCategoryModel,
|
ItemCategoryModel,
|
||||||
|
ItemRateModel,
|
||||||
|
ItemQueueModel,
|
||||||
LogModel,
|
LogModel,
|
||||||
|
LogUserLoginModel,
|
||||||
|
NewsModel,
|
||||||
PaymentMethodModel,
|
PaymentMethodModel,
|
||||||
|
PosLogModel,
|
||||||
|
RefundModel,
|
||||||
|
RefundItemModel,
|
||||||
SalesPriceFormulaModel,
|
SalesPriceFormulaModel,
|
||||||
|
SeasonPeriodModel,
|
||||||
SeasonTypeModel,
|
SeasonTypeModel,
|
||||||
TaxModel,
|
TaxModel,
|
||||||
|
TermConditionModel,
|
||||||
|
TransactionModel,
|
||||||
|
TransactionItemModel,
|
||||||
|
TransactionTaxModel,
|
||||||
|
TransactionDemographyModel,
|
||||||
|
TransactionItemBreakdownModel,
|
||||||
|
TransactionItemTaxModel,
|
||||||
|
TransactionBreakdownTaxModel,
|
||||||
UserModel,
|
UserModel,
|
||||||
|
UserLoginModel,
|
||||||
|
|
||||||
VipCategoryModel,
|
VipCategoryModel,
|
||||||
VipCodeModel,
|
VipCodeModel,
|
||||||
|
|
||||||
|
// report
|
||||||
|
ReportBookmarkModel,
|
||||||
|
ExportReportHistoryModel,
|
||||||
|
|
||||||
|
// Queue
|
||||||
|
QueueOrderModel,
|
||||||
|
QueueTicketModel,
|
||||||
|
QueueItemModel,
|
||||||
|
QueueModel,
|
||||||
|
QueueBucketModel,
|
||||||
],
|
],
|
||||||
synchronize: false,
|
synchronize: false,
|
||||||
}),
|
}),
|
||||||
|
AuthModule,
|
||||||
ConstantModule,
|
ConstantModule,
|
||||||
CqrsModule,
|
CqrsModule,
|
||||||
SessionModule,
|
|
||||||
AuthModule,
|
|
||||||
CouchModule,
|
CouchModule,
|
||||||
|
CronModule,
|
||||||
|
ExportModule,
|
||||||
|
GoogleCalendarModule,
|
||||||
LogModule,
|
LogModule,
|
||||||
|
MailModule,
|
||||||
|
MidtransModule,
|
||||||
|
SessionModule,
|
||||||
|
UploadModule,
|
||||||
|
|
||||||
// user
|
// user
|
||||||
TenantModule,
|
TenantModule,
|
||||||
|
@ -83,20 +177,47 @@ import { PaymentMethodModel } from './modules/transaction/payment-method/data/mo
|
||||||
// Item
|
// Item
|
||||||
ItemCategoryModule,
|
ItemCategoryModule,
|
||||||
ItemModule,
|
ItemModule,
|
||||||
|
ItemRateModule,
|
||||||
|
ItemQueueModule,
|
||||||
|
|
||||||
// transaction
|
// transaction
|
||||||
PaymentMethodModule,
|
PaymentMethodModule,
|
||||||
ProfitShareFormulaModule,
|
ProfitShareFormulaModule,
|
||||||
|
ReconciliationModule,
|
||||||
|
RefundModule,
|
||||||
SalesPriceFormulaModule,
|
SalesPriceFormulaModule,
|
||||||
TaxModule,
|
TaxModule,
|
||||||
|
TransactionModule,
|
||||||
VipCategoryModule,
|
VipCategoryModule,
|
||||||
VipCodeModule,
|
VipCodeModule,
|
||||||
|
|
||||||
// session
|
// session
|
||||||
SeasonTypeModule,
|
SeasonTypeModule,
|
||||||
|
SeasonPeriodModule,
|
||||||
|
|
||||||
|
// web information
|
||||||
|
BannerModule,
|
||||||
|
FaqModule,
|
||||||
|
GateModule,
|
||||||
|
NewsModule,
|
||||||
|
TermConditionModule,
|
||||||
|
|
||||||
|
// report
|
||||||
|
ReportModule,
|
||||||
|
ReportBookmarkModule,
|
||||||
|
ReportExportModule,
|
||||||
|
ReportSummaryModule,
|
||||||
|
|
||||||
|
// superset
|
||||||
|
SupersetModule,
|
||||||
|
|
||||||
|
GateScanModule,
|
||||||
|
|
||||||
|
QueueModule,
|
||||||
],
|
],
|
||||||
controllers: [],
|
controllers: [],
|
||||||
providers: [
|
providers: [
|
||||||
|
AuthService,
|
||||||
PrivilegeService,
|
PrivilegeService,
|
||||||
/**
|
/**
|
||||||
* By default all request from client will protect by JWT
|
* By default all request from client will protect by JWT
|
||||||
|
|
|
@ -7,10 +7,10 @@ import {
|
||||||
UnauthorizedException,
|
UnauthorizedException,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { Reflector } from '@nestjs/core';
|
import { Reflector } from '@nestjs/core';
|
||||||
import { Observable } from 'rxjs';
|
|
||||||
import { SessionService, UsersSession } from 'src/core/sessions';
|
import { SessionService, UsersSession } from 'src/core/sessions';
|
||||||
import { UNPROTECTED_URL } from '../constants';
|
import { UNPROTECTED_URL } from '../constants';
|
||||||
import { PrivilegeService } from './services/privilege.service';
|
import { PrivilegeService } from './services/privilege.service';
|
||||||
|
import { AuthService } from './services/auth.service';
|
||||||
|
|
||||||
@Injectable({ scope: Scope.REQUEST })
|
@Injectable({ scope: Scope.REQUEST })
|
||||||
export class JWTGuard implements CanActivate {
|
export class JWTGuard implements CanActivate {
|
||||||
|
@ -18,14 +18,13 @@ export class JWTGuard implements CanActivate {
|
||||||
protected readonly session: SessionService,
|
protected readonly session: SessionService,
|
||||||
protected readonly reflector: Reflector,
|
protected readonly reflector: Reflector,
|
||||||
protected readonly privilege: PrivilegeService,
|
protected readonly privilege: PrivilegeService,
|
||||||
|
protected readonly authService: AuthService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
protected isPublic = false;
|
protected isPublic = false;
|
||||||
protected userSession: UsersSession;
|
protected userSession: UsersSession;
|
||||||
|
|
||||||
canActivate(
|
async canActivate(context: ExecutionContext) {
|
||||||
context: ExecutionContext,
|
|
||||||
): boolean | Promise<boolean> | Observable<boolean> {
|
|
||||||
/**
|
/**
|
||||||
* Check if access url is protected or not
|
* Check if access url is protected or not
|
||||||
* By default `isUnprotected` equals `false`
|
* By default `isUnprotected` equals `false`
|
||||||
|
@ -61,9 +60,29 @@ export class JWTGuard implements CanActivate {
|
||||||
*/
|
*/
|
||||||
try {
|
try {
|
||||||
this.userSession = this.session.verifyToken(token);
|
this.userSession = this.session.verifyToken(token);
|
||||||
|
await this.authService.verifyRegisteredLoginToken(token);
|
||||||
|
|
||||||
Logger.log(`Access from ${this.userSession.name}`, 'AuthGuard');
|
Logger.log(`Access from ${this.userSession.name}`, 'AuthGuard');
|
||||||
return true;
|
return true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
const expiredError = error.message;
|
||||||
|
if (expiredError === 'jwt expired') {
|
||||||
|
const [, body] = token.split('.');
|
||||||
|
const bodyToken = JSON.parse(atob(body));
|
||||||
|
|
||||||
|
const user = {
|
||||||
|
role: bodyToken.role,
|
||||||
|
user_id: bodyToken.id,
|
||||||
|
username: bodyToken.username,
|
||||||
|
user_privilege_id: bodyToken.user_privilege_id,
|
||||||
|
item_id: bodyToken.item_id,
|
||||||
|
item_name: bodyToken.item_name,
|
||||||
|
source: bodyToken.source,
|
||||||
|
};
|
||||||
|
|
||||||
|
this.authService.logoutUser(user, token);
|
||||||
|
}
|
||||||
|
|
||||||
throw new UnauthorizedException({
|
throw new UnauthorizedException({
|
||||||
code: 10001,
|
code: 10001,
|
||||||
message:
|
message:
|
||||||
|
|
|
@ -9,7 +9,7 @@ import { MAIN_MENU } from '../constants';
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class RolesGuard extends JWTGuard {
|
export class RolesGuard extends JWTGuard {
|
||||||
async canActivate(context: ExecutionContext): Promise<boolean> {
|
async canActivate(context: ExecutionContext): Promise<boolean> {
|
||||||
super.canActivate(context);
|
await super.canActivate(context);
|
||||||
|
|
||||||
// jika endpoint tersebut bukan public, maka lakukan check lanjutan
|
// jika endpoint tersebut bukan public, maka lakukan check lanjutan
|
||||||
if (!this.isPublic) {
|
if (!this.isPublic) {
|
||||||
|
@ -25,7 +25,7 @@ export class RolesGuard extends JWTGuard {
|
||||||
if (isNotAllow) {
|
if (isNotAllow) {
|
||||||
throw new ForbiddenException({
|
throw new ForbiddenException({
|
||||||
statusCode: 10003,
|
statusCode: 10003,
|
||||||
message: `Forbidden Access, you don't have access to this module!`,
|
message: `Akses Terlarang, anda tidak punya akses ke module ini!`,
|
||||||
error: 'ACCESS_FORBIDDEN',
|
error: 'ACCESS_FORBIDDEN',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
import {
|
||||||
|
HttpStatus,
|
||||||
|
Injectable,
|
||||||
|
Scope,
|
||||||
|
UnauthorizedException,
|
||||||
|
} from '@nestjs/common';
|
||||||
|
import { InjectDataSource } from '@nestjs/typeorm';
|
||||||
|
import {
|
||||||
|
CONNECTION_NAME,
|
||||||
|
OPERATION,
|
||||||
|
} from 'src/core/strings/constants/base.constants';
|
||||||
|
import { DataSource } from 'typeorm';
|
||||||
|
import { UserRole } from 'src/modules/user-related/user/constants';
|
||||||
|
import { UserModel } from 'src/modules/user-related/user/data/models/user.model';
|
||||||
|
import { AppSource, LogUserType } from 'src/core/helpers/constant';
|
||||||
|
import { EventBus } from '@nestjs/cqrs';
|
||||||
|
import { LogUserLoginEvent } from 'src/modules/configuration/log/domain/entities/log-user-login.event';
|
||||||
|
import { UserLoginModel } from 'src/modules/user-related/user/data/models/user-login.model';
|
||||||
|
|
||||||
|
interface UserEntity {
|
||||||
|
user_id: string;
|
||||||
|
username: string;
|
||||||
|
role: UserRole;
|
||||||
|
user_privilege_id: string;
|
||||||
|
item_id: string;
|
||||||
|
item_name: string;
|
||||||
|
source: AppSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable({ scope: Scope.REQUEST })
|
||||||
|
export class AuthService {
|
||||||
|
constructor(
|
||||||
|
@InjectDataSource(CONNECTION_NAME.DEFAULT)
|
||||||
|
protected readonly dataSource: DataSource,
|
||||||
|
|
||||||
|
private eventBus: EventBus,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
get repository() {
|
||||||
|
return this.dataSource.getRepository(UserLoginModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
async logoutUser(user: UserEntity, token: string) {
|
||||||
|
await this.repository.delete({ login_token: token });
|
||||||
|
|
||||||
|
const userLogout = {
|
||||||
|
type: LogUserType.logout,
|
||||||
|
created_at: new Date().getTime(),
|
||||||
|
name: user.username,
|
||||||
|
user_privilege_id: user.user_privilege_id,
|
||||||
|
...user,
|
||||||
|
};
|
||||||
|
|
||||||
|
this.eventBus.publish(
|
||||||
|
new LogUserLoginEvent({
|
||||||
|
id: user.user_id,
|
||||||
|
old: null,
|
||||||
|
data: userLogout,
|
||||||
|
user: userLogout as any,
|
||||||
|
description: 'Logout',
|
||||||
|
module: UserModel.name,
|
||||||
|
op: OPERATION.UPDATE,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async verifyRegisteredLoginToken(token: string) {
|
||||||
|
const data = await this.repository.findOneBy({ login_token: token });
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
throw new UnauthorizedException({
|
||||||
|
statusCode: HttpStatus.UNAUTHORIZED,
|
||||||
|
message: `Invalid token`,
|
||||||
|
error: 'Unauthorized',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -52,7 +52,7 @@ export class PrivilegeService {
|
||||||
if (!moduleKey) {
|
if (!moduleKey) {
|
||||||
throw new ForbiddenException({
|
throw new ForbiddenException({
|
||||||
statusCode: 10005,
|
statusCode: 10005,
|
||||||
message: `Forbidden Access, access Module is Require!`,
|
message: `Akses Terlarang, anda tidak punya akses ke module ini!`,
|
||||||
error: 'MODULE_KEY_NOT_FOUND',
|
error: 'MODULE_KEY_NOT_FOUND',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,7 @@ export class PrivilegeService {
|
||||||
}
|
}
|
||||||
|
|
||||||
async privilegeConfiguration(): Promise<UserPrivilegeConfigurationEntity> {
|
async privilegeConfiguration(): Promise<UserPrivilegeConfigurationEntity> {
|
||||||
const { module, menu, sub_menu, section } = this.moduleKey();
|
const { module, menu } = this.moduleKey();
|
||||||
return await this.repository.findOne({
|
return await this.repository.findOne({
|
||||||
select: ['id', 'view', 'create', 'edit', 'delete', 'cancel', 'confirm'],
|
select: ['id', 'view', 'create', 'edit', 'delete', 'cancel', 'confirm'],
|
||||||
where: {
|
where: {
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
export enum LogUserType {
|
||||||
|
login = 'login',
|
||||||
|
logout = 'logout',
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum AppSource {
|
||||||
|
POS_ADMIN = 'POS_ADMIN',
|
||||||
|
POS_COUNTER = 'POS_COUNTER',
|
||||||
|
QUEUE_ADMIN = 'QUEUE_ADMIN',
|
||||||
|
QUEUE_CUSTOMER = 'QUEUE_CUSTOMER',
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
import * as fs from 'fs-extra';
|
||||||
|
import * as path from 'path';
|
||||||
|
|
||||||
|
export async function MoveFilePathHelper(data) {
|
||||||
|
const imagePath = data['qr_image'] ?? data['image_url'];
|
||||||
|
const sourcePath = path.join(__dirname, '../../../../uploads/', imagePath);
|
||||||
|
const movePath =
|
||||||
|
'data/' +
|
||||||
|
imagePath
|
||||||
|
.split('/')
|
||||||
|
.filter((item) => !['uploads', 'tmp'].includes(item))
|
||||||
|
.join('/');
|
||||||
|
const destinationPath = path.join(
|
||||||
|
__dirname,
|
||||||
|
'../../../../uploads/',
|
||||||
|
movePath,
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await fs.move(sourcePath, destinationPath);
|
||||||
|
|
||||||
|
Object.assign(data, {
|
||||||
|
image_url: movePath,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.log(`Failed! Error move file data`);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
import { extname } from 'path';
|
||||||
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
|
import { HttpException, HttpStatus } from '@nestjs/common';
|
||||||
|
import * as fs from 'fs';
|
||||||
|
import { MulterOptions } from '@nestjs/platform-express/multer/interfaces/multer-options.interface';
|
||||||
|
import { diskStorage } from 'multer';
|
||||||
|
|
||||||
|
const MB = 1024 * 1024;
|
||||||
|
|
||||||
|
const fileFilter = (req, file, callback) => {
|
||||||
|
if (
|
||||||
|
file.mimetype.match(/\/(jpg|jpeg|png|flv|mp4|m3u8|ts|3gp|mov|avi|wmv)$/)
|
||||||
|
) {
|
||||||
|
callback(null, true);
|
||||||
|
} else {
|
||||||
|
callback(
|
||||||
|
new HttpException(
|
||||||
|
`Unsupported file type ${extname(file.originalname)}`,
|
||||||
|
HttpStatus.BAD_REQUEST,
|
||||||
|
),
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const editFileName = (req, file, callback) => {
|
||||||
|
const fileExtName = extname(file.originalname);
|
||||||
|
const randomName = uuidv4();
|
||||||
|
callback(null, `${randomName}${fileExtName}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
const destinationPath = (req, file, cb) => {
|
||||||
|
let modulePath = req.body.module;
|
||||||
|
if (req.body.sub_module) modulePath = `${modulePath}/${req.body.sub_module}`;
|
||||||
|
|
||||||
|
fs.mkdirSync(`./uploads/tmp/${modulePath}`, { recursive: true });
|
||||||
|
cb(null, `./uploads/tmp/${modulePath}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const StoreFileConfig: MulterOptions = {
|
||||||
|
storage: diskStorage({
|
||||||
|
destination: destinationPath,
|
||||||
|
filename: editFileName,
|
||||||
|
}),
|
||||||
|
fileFilter: fileFilter,
|
||||||
|
};
|
|
@ -43,9 +43,9 @@ export class CheckDuplicateHelper {
|
||||||
if (data_exists > 0) {
|
if (data_exists > 0) {
|
||||||
throw new UnprocessableEntityException({
|
throw new UnprocessableEntityException({
|
||||||
statusCode: HttpStatus.UNPROCESSABLE_ENTITY,
|
statusCode: HttpStatus.UNPROCESSABLE_ENTITY,
|
||||||
message: `Entity with ${columnCheck.column} : ${
|
message: `Gagal! Data dengan ${columnCheck.column} : ${
|
||||||
this.entity[columnCheck.column]
|
this.entity[columnCheck.column]
|
||||||
} already exist`,
|
} telah ada`,
|
||||||
error: 'Unprocessable Entity',
|
error: 'Unprocessable Entity',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,39 +10,14 @@ export function setQueryFilterDefault(
|
||||||
baseFilter: BaseFilterEntity,
|
baseFilter: BaseFilterEntity,
|
||||||
tableName: TABLE_NAME,
|
tableName: TABLE_NAME,
|
||||||
): SelectQueryBuilder<any> {
|
): SelectQueryBuilder<any> {
|
||||||
// filter berdasarkan statuses
|
|
||||||
if (!!baseFilter.statuses) {
|
|
||||||
queryBuilder.andWhere(
|
|
||||||
new Brackets((qb) => {
|
|
||||||
baseFilter.statuses.map((status) => {
|
|
||||||
// trim search
|
|
||||||
const statusData = status.includes("'")
|
|
||||||
? status.trim().replace(/'/g, "''").replace(/\s+/g, ' ')
|
|
||||||
: status.trim().replace(/\s+/g, ' ');
|
|
||||||
|
|
||||||
// jika searching status terdapat dalam enum, maka dia mencari specific data
|
|
||||||
// ? karena jika tidak, ketika dia search "active" maka "inactive" juga ikut
|
|
||||||
if (STATUS[statusData.toUpperCase()])
|
|
||||||
qb.orWhere(`${tableName}.status = :statusData`, {
|
|
||||||
statusData: statusData,
|
|
||||||
});
|
|
||||||
else
|
|
||||||
qb['orWhere'](
|
|
||||||
`${tableName}.status::text ILIKE '%${[statusData]}%'`,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// filter berdasarkan id pembuat
|
// filter berdasarkan id pembuat
|
||||||
if (!!baseFilter.created_ids)
|
if (!!baseFilter.created_ids)
|
||||||
new WhereInQueryHelper(
|
new WhereInQueryHelper(
|
||||||
queryBuilder,
|
queryBuilder,
|
||||||
tableName,
|
tableName,
|
||||||
'created_id',
|
'creator_id',
|
||||||
baseFilter.created_ids,
|
baseFilter.created_ids,
|
||||||
'created_ids',
|
'creator_ids',
|
||||||
).getQuery();
|
).getQuery();
|
||||||
|
|
||||||
// filter berdasarkan tanggal terakhir dibuat
|
// filter berdasarkan tanggal terakhir dibuat
|
||||||
|
@ -85,15 +60,28 @@ export function getOrderBy(
|
||||||
queryBuilder: SelectQueryBuilder<any>,
|
queryBuilder: SelectQueryBuilder<any>,
|
||||||
tableName: TABLE_NAME,
|
tableName: TABLE_NAME,
|
||||||
) {
|
) {
|
||||||
let orderBy: string = `${tableName}.created_at`;
|
let orderBys: string[] = [`${tableName}.created_at`];
|
||||||
const orderType = baseFilter.order_type ?? ORDER_TYPE.DESC;
|
const orderType = baseFilter.order_type ?? ORDER_TYPE.DESC;
|
||||||
|
|
||||||
if (!!baseFilter.order_by) {
|
if (!!baseFilter.order_by) {
|
||||||
orderBy =
|
orderBys =
|
||||||
baseFilter.order_by.split('.').length > 1
|
baseFilter.order_by.split('.').length > 1
|
||||||
? `${baseFilter.order_by}`
|
? [`${baseFilter.order_by}`]
|
||||||
: `${tableName}.${baseFilter.order_by}`;
|
: [`${tableName}.${baseFilter.order_by}`];
|
||||||
|
|
||||||
|
if (
|
||||||
|
baseFilter.order_by.split('.').length == 1 &&
|
||||||
|
baseFilter.order_by.split('.').pop() != 'id'
|
||||||
|
) {
|
||||||
|
orderBys.push(`${tableName}.created_at`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
queryBuilder.orderBy(orderBy, orderType);
|
for (let i = 0; i < orderBys.length; i++) {
|
||||||
|
if (i == 0) {
|
||||||
|
queryBuilder.orderBy(orderBys[i], orderType);
|
||||||
|
} else {
|
||||||
|
queryBuilder.addOrderBy(orderBys[i], orderType);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,12 +20,16 @@ export class SpecificSearchFilter<Entity = any> {
|
||||||
new Brackets((qb) => {
|
new Brackets((qb) => {
|
||||||
params.forEach((param) => {
|
params.forEach((param) => {
|
||||||
const { cols, data, additional, leftJoin } = param;
|
const { cols, data, additional, leftJoin } = param;
|
||||||
|
const columns = cols.split('.');
|
||||||
|
let arr = data;
|
||||||
|
|
||||||
const arr = data?.map((el) =>
|
if (!columns.includes('status::text')) {
|
||||||
el.includes("'")
|
arr = data?.map((el) =>
|
||||||
? `'%${el.trim().replace(/'/g, "''").replace(/\s+/g, ' ')}%'`
|
el.includes("'")
|
||||||
: `'%${el.trim().replace(/\s+/g, ' ')}%'`,
|
? `'%${el.trim().replace(/'/g, "''").replace(/\s+/g, ' ')}%'`
|
||||||
);
|
: `'%${el.trim().replace(/\s+/g, ' ')}%'`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const aliases = !cols.match(/\./g)
|
const aliases = !cols.match(/\./g)
|
||||||
? this.table.concat(`.${cols}`)
|
? this.table.concat(`.${cols}`)
|
||||||
|
|
|
@ -17,11 +17,26 @@ export class ValidateRelationHelper<Entity> {
|
||||||
|
|
||||||
// load relation
|
// load relation
|
||||||
for (const relation of this.relations) {
|
for (const relation of this.relations) {
|
||||||
queryBuilder.loadRelationCountAndMap(
|
if (relation.singleQuery) {
|
||||||
`${this.tableName}.total_${relation.relation}`,
|
queryBuilder.leftJoinAndMapOne(
|
||||||
`${this.tableName}.${relation.relation}`,
|
`${this.tableName}.${relation.relation}`,
|
||||||
`total_${relation.relation}`,
|
`${this.tableName}.${relation.relation}`,
|
||||||
);
|
relation.relation,
|
||||||
|
);
|
||||||
|
} else if (relation.query) {
|
||||||
|
queryBuilder.loadRelationCountAndMap(
|
||||||
|
`${this.tableName}.total_${relation.relation}`,
|
||||||
|
`${this.tableName}.${relation.relation}`,
|
||||||
|
`total_${relation.relation}`,
|
||||||
|
relation.query,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
queryBuilder.loadRelationCountAndMap(
|
||||||
|
`${this.tableName}.total_${relation.relation}`,
|
||||||
|
`${this.tableName}.${relation.relation}`,
|
||||||
|
`total_${relation.relation}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// filtering data only with specific data
|
// filtering data only with specific data
|
||||||
|
@ -36,8 +51,33 @@ export class ValidateRelationHelper<Entity> {
|
||||||
relation.message ??
|
relation.message ??
|
||||||
`Failed! this data already connected to ${relation.relation}`;
|
`Failed! this data already connected to ${relation.relation}`;
|
||||||
|
|
||||||
if (data[`total_${relation.relation}`])
|
if (relation.singleQuery) {
|
||||||
|
const relationColumn =
|
||||||
|
data[relation.relation]?.[`${relation.singleQuery[0]}`];
|
||||||
|
if (
|
||||||
|
!!relationColumn &&
|
||||||
|
this.mappingValidator(
|
||||||
|
relationColumn,
|
||||||
|
relation.singleQuery[1],
|
||||||
|
relation.singleQuery[2],
|
||||||
|
)
|
||||||
|
)
|
||||||
|
throw new UnprocessableEntityException(message);
|
||||||
|
} else if (data[`total_${relation.relation}`] > 0)
|
||||||
throw new UnprocessableEntityException(message);
|
throw new UnprocessableEntityException(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mappingValidator(column, operator, value) {
|
||||||
|
switch (operator) {
|
||||||
|
case '!=':
|
||||||
|
return column != value;
|
||||||
|
|
||||||
|
case '==':
|
||||||
|
return column == value;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return column == value;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,8 +17,26 @@ export abstract class BaseDataService<Entity> {
|
||||||
entityTarget: EntityTarget<Entity>,
|
entityTarget: EntityTarget<Entity>,
|
||||||
entity: Entity,
|
entity: Entity,
|
||||||
): Promise<Entity> {
|
): Promise<Entity> {
|
||||||
const newEntity = queryRunner.manager.create(entityTarget, entity);
|
// const newEntity = this.repository.create(entityTarget, entity);
|
||||||
return await queryRunner.manager.save(newEntity);
|
return await this.repository.save(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
async createMany(
|
||||||
|
queryRunner: QueryRunner,
|
||||||
|
entityTarget: EntityTarget<Entity>,
|
||||||
|
entity: Entity[],
|
||||||
|
): Promise<Entity[]> {
|
||||||
|
// const newEntity = this.repository.create(entityTarget, entity);
|
||||||
|
return await this.repository.save(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
async createBatch(
|
||||||
|
queryRunner: QueryRunner,
|
||||||
|
entityTarget: EntityTarget<Entity>,
|
||||||
|
entity: Entity[],
|
||||||
|
): Promise<Entity[]> {
|
||||||
|
// const newEntity = this.repository.create(entityTarget, entity);
|
||||||
|
return await this.repository.save(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
async update(
|
async update(
|
||||||
|
@ -27,13 +45,13 @@ export abstract class BaseDataService<Entity> {
|
||||||
filterUpdate: any,
|
filterUpdate: any,
|
||||||
entity: Entity,
|
entity: Entity,
|
||||||
): Promise<Entity> {
|
): Promise<Entity> {
|
||||||
const newEntity = await queryRunner.manager.findOne(entityTarget, {
|
const newEntity = await this.repository.findOne({
|
||||||
where: filterUpdate,
|
where: filterUpdate,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!newEntity) throw new Error('Data not found!');
|
if (!newEntity) throw new Error('Data not found!');
|
||||||
Object.assign(newEntity, entity);
|
Object.assign(newEntity, entity);
|
||||||
return await queryRunner.manager.save(newEntity);
|
return await this.repository.save(newEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
async deleteById(
|
async deleteById(
|
||||||
|
@ -41,7 +59,15 @@ export abstract class BaseDataService<Entity> {
|
||||||
entityTarget: EntityTarget<Entity>,
|
entityTarget: EntityTarget<Entity>,
|
||||||
id: string,
|
id: string,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
await queryRunner.manager.delete(entityTarget, { id });
|
await this.repository.delete(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
async deleteByIds(
|
||||||
|
queryRunner: QueryRunner,
|
||||||
|
entityTarget: EntityTarget<Entity>,
|
||||||
|
ids: string[],
|
||||||
|
): Promise<void> {
|
||||||
|
await this.repository.delete(ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
async deleteByOptions(
|
async deleteByOptions(
|
||||||
|
@ -49,10 +75,15 @@ export abstract class BaseDataService<Entity> {
|
||||||
entityTarget: EntityTarget<Entity>,
|
entityTarget: EntityTarget<Entity>,
|
||||||
findManyOptions: FindManyOptions<Entity>,
|
findManyOptions: FindManyOptions<Entity>,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
await queryRunner.manager.delete(entityTarget, findManyOptions);
|
const datas = await this.repository.find(findManyOptions);
|
||||||
|
await this.repository.delete(datas?.map((item) => item['id']));
|
||||||
}
|
}
|
||||||
|
|
||||||
async getOneByOptions(findOneOptions): Promise<Entity> {
|
async getOneByOptions(findOneOptions): Promise<Entity> {
|
||||||
return await this.repository.findOne(findOneOptions);
|
return await this.repository.findOne(findOneOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getManyByOptions(findOneOptions): Promise<Entity[]> {
|
||||||
|
return await this.repository.find(findOneOptions);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,9 +13,11 @@ export abstract class BaseReadService<Entity> {
|
||||||
queryBuilder: SelectQueryBuilder<Entity>,
|
queryBuilder: SelectQueryBuilder<Entity>,
|
||||||
params: BaseFilterEntity,
|
params: BaseFilterEntity,
|
||||||
): Promise<PaginationResponse<Entity>> {
|
): Promise<PaginationResponse<Entity>> {
|
||||||
|
const limit = params.limit ?? 10;
|
||||||
|
const page = params.page ?? 1;
|
||||||
const [data, total] = await queryBuilder
|
const [data, total] = await queryBuilder
|
||||||
.take(+params.limit)
|
.take(+limit)
|
||||||
.skip(+params.limit * +params.page - +params.limit)
|
.skip(+limit * +page - +limit)
|
||||||
.getManyAndCount();
|
.getManyAndCount();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
export interface BaseCoreEntity {
|
export interface BaseCoreEntity {
|
||||||
id: string;
|
id?: string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ export interface Param {
|
||||||
data: string[];
|
data: string[];
|
||||||
additional?: any[];
|
additional?: any[];
|
||||||
leftJoin?: any[];
|
leftJoin?: any[];
|
||||||
|
isStatus?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RelationParam {
|
export interface RelationParam {
|
||||||
|
|
|
@ -22,22 +22,36 @@ export abstract class BaseManager {
|
||||||
protected eventBus: EventBus;
|
protected eventBus: EventBus;
|
||||||
abstract get validateRelations(): validateRelations[];
|
abstract get validateRelations(): validateRelations[];
|
||||||
|
|
||||||
|
// sebagai optional yang dapat digunakan
|
||||||
|
public dataServiceFirstOpt: any;
|
||||||
|
|
||||||
|
// sebagai optional yang dapat digunakan
|
||||||
|
public dataServiceSecondOpt: any;
|
||||||
|
|
||||||
private readonly baseLog = new Logger(BaseManager.name);
|
private readonly baseLog = new Logger(BaseManager.name);
|
||||||
|
|
||||||
setUser() {
|
setUser() {
|
||||||
try {
|
try {
|
||||||
this.user = this.userProvider?.user;
|
this.user = this.userProvider?.user ?? BLANK_USER;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.user = BLANK_USER;
|
this.user = BLANK_USER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setService(dataService, tableName) {
|
setService(
|
||||||
|
dataService,
|
||||||
|
tableName,
|
||||||
|
dataServiceOpt = null,
|
||||||
|
dataServiceSecondOpt = null,
|
||||||
|
) {
|
||||||
this.dataService = dataService;
|
this.dataService = dataService;
|
||||||
this.tableName = tableName;
|
this.tableName = tableName;
|
||||||
this.queryRunner = this.dataService
|
this.queryRunner = this.dataService
|
||||||
.getRepository()
|
.getRepository()
|
||||||
.manager.connection.createQueryRunner(tableName);
|
.manager.connection.createQueryRunner(tableName);
|
||||||
|
|
||||||
|
if (dataServiceOpt) this.dataServiceFirstOpt = dataServiceOpt;
|
||||||
|
if (dataServiceSecondOpt) this.dataServiceSecondOpt = dataServiceSecondOpt;
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract get eventTopics(): EventTopics[];
|
abstract get eventTopics(): EventTopics[];
|
||||||
|
@ -68,11 +82,11 @@ export abstract class BaseManager {
|
||||||
|
|
||||||
this.baseLog.verbose('commitTransaction');
|
this.baseLog.verbose('commitTransaction');
|
||||||
await this.queryRunner.commitTransaction();
|
await this.queryRunner.commitTransaction();
|
||||||
|
|
||||||
await this.queryRunner.release();
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e.response) throw new Error(JSON.stringify(e.response));
|
if (e.response) throw new Error(JSON.stringify(e.response));
|
||||||
else throw new Error(e.message);
|
else throw new Error(e.message);
|
||||||
|
} finally {
|
||||||
|
await this.queryRunner.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,8 @@ import { BatchResult } from 'src/core/response/domain/ok-response.interface';
|
||||||
import { BaseManager } from '../base.manager';
|
import { BaseManager } from '../base.manager';
|
||||||
import { HttpStatus, NotFoundException } from '@nestjs/common';
|
import { HttpStatus, NotFoundException } from '@nestjs/common';
|
||||||
import { ValidateRelationHelper } from 'src/core/helpers/validation/validate-relation.helper';
|
import { ValidateRelationHelper } from 'src/core/helpers/validation/validate-relation.helper';
|
||||||
|
import { RecordLog } from 'src/modules/configuration/log/domain/entities/log.event';
|
||||||
|
import { OPERATION } from 'src/core/strings/constants/base.constants';
|
||||||
|
|
||||||
export abstract class BaseBatchDeleteManager<Entity> extends BaseManager {
|
export abstract class BaseBatchDeleteManager<Entity> extends BaseManager {
|
||||||
protected dataIds: string[];
|
protected dataIds: string[];
|
||||||
|
@ -23,7 +25,7 @@ export abstract class BaseBatchDeleteManager<Entity> extends BaseManager {
|
||||||
async process(): Promise<void> {
|
async process(): Promise<void> {
|
||||||
let totalFailed = 0;
|
let totalFailed = 0;
|
||||||
let totalSuccess = 0;
|
let totalSuccess = 0;
|
||||||
let messages = [];
|
const messages = [];
|
||||||
|
|
||||||
for (const id of this.dataIds) {
|
for (const id of this.dataIds) {
|
||||||
try {
|
try {
|
||||||
|
@ -36,7 +38,7 @@ export abstract class BaseBatchDeleteManager<Entity> extends BaseManager {
|
||||||
if (!entity) {
|
if (!entity) {
|
||||||
throw new NotFoundException({
|
throw new NotFoundException({
|
||||||
statusCode: HttpStatus.NOT_FOUND,
|
statusCode: HttpStatus.NOT_FOUND,
|
||||||
message: `Failed! Entity with id ${id} not found`,
|
message: `Gagal! data dengan id ${id} tidak ditemukan`,
|
||||||
error: 'Entity Not Found',
|
error: 'Entity Not Found',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -55,6 +57,7 @@ export abstract class BaseBatchDeleteManager<Entity> extends BaseManager {
|
||||||
id,
|
id,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this.publishEvents(entity, entity);
|
||||||
totalSuccess = totalSuccess + 1;
|
totalSuccess = totalSuccess + 1;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
totalFailed = totalFailed + 1;
|
totalFailed = totalFailed + 1;
|
||||||
|
@ -72,4 +75,33 @@ export abstract class BaseBatchDeleteManager<Entity> extends BaseManager {
|
||||||
|
|
||||||
abstract validateData(data: Entity): Promise<void>;
|
abstract validateData(data: Entity): Promise<void>;
|
||||||
abstract getResult(): BatchResult;
|
abstract getResult(): BatchResult;
|
||||||
|
|
||||||
|
async publishEvents(dataOld, dataNew) {
|
||||||
|
this.eventBus.publish(
|
||||||
|
new RecordLog({
|
||||||
|
id: dataNew['id'],
|
||||||
|
old: dataOld,
|
||||||
|
data: dataNew,
|
||||||
|
user: this.user,
|
||||||
|
description: `${this.user.name} delete batch data ${this.tableName}`,
|
||||||
|
module: this.tableName,
|
||||||
|
op: OPERATION.DELETE,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!this.eventTopics.length) return;
|
||||||
|
for (const topic of this.eventTopics) {
|
||||||
|
this.eventBus.publishAll([
|
||||||
|
new topic.topic({
|
||||||
|
id: dataNew['id'],
|
||||||
|
old: dataOld,
|
||||||
|
data: dataNew,
|
||||||
|
user: this.user,
|
||||||
|
description: '',
|
||||||
|
module: this.tableName,
|
||||||
|
op: OPERATION.UPDATE,
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,40 @@
|
||||||
import { BatchResult } from 'src/core/response/domain/ok-response.interface';
|
import { BatchResult } from 'src/core/response/domain/ok-response.interface';
|
||||||
import { BaseManager } from '../base.manager';
|
import { BaseManager } from '../base.manager';
|
||||||
import { HttpStatus, NotFoundException } from '@nestjs/common';
|
import { HttpStatus, NotFoundException } from '@nestjs/common';
|
||||||
import { STATUS } from 'src/core/strings/constants/base.constants';
|
import { OPERATION, STATUS } from 'src/core/strings/constants/base.constants';
|
||||||
import { ValidateRelationHelper } from 'src/core/helpers/validation/validate-relation.helper';
|
import { ValidateRelationHelper } from 'src/core/helpers/validation/validate-relation.helper';
|
||||||
|
import { RecordLog } from 'src/modules/configuration/log/domain/entities/log.event';
|
||||||
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
export abstract class BaseBatchUpdateStatusManager<Entity> extends BaseManager {
|
export abstract class BaseBatchUpdateStatusManager<Entity> extends BaseManager {
|
||||||
protected dataIds: string[];
|
protected dataIds: string[];
|
||||||
|
protected relations: string[] = [];
|
||||||
protected result: BatchResult;
|
protected result: BatchResult;
|
||||||
protected dataStatus: STATUS;
|
protected dataStatus: STATUS;
|
||||||
|
protected oldData: Entity;
|
||||||
abstract get entityTarget(): any;
|
abstract get entityTarget(): any;
|
||||||
|
|
||||||
setData(ids: string[], status: STATUS): void {
|
setData(ids: string[], status: STATUS): void {
|
||||||
|
/**
|
||||||
|
* // TODO: Handle case confirm multiple tabs;
|
||||||
|
* Pola ids yang dikirim dirubah menjadi data_id___updated_at
|
||||||
|
* Untuk mendapatkan value id nya saja dan menghindari breaking change
|
||||||
|
* karena sudah digunakan sebelumnya lakukan split dari data ids yang dikirim
|
||||||
|
* Example:
|
||||||
|
* this.dataIds = ids.map((i)=> {
|
||||||
|
* return i.split('___')[0]
|
||||||
|
* })
|
||||||
|
*
|
||||||
|
* Simpan data ids yang mempunyai update_at kedalam valiable baru
|
||||||
|
* Example:
|
||||||
|
* this.dataIdsWithDate = ids.map((i)=> {
|
||||||
|
* return {
|
||||||
|
* id: i.split('___')[0],
|
||||||
|
* updated_at: i.split('___')[1]
|
||||||
|
* }
|
||||||
|
* })
|
||||||
|
*/
|
||||||
|
|
||||||
this.dataIds = ids;
|
this.dataIds = ids;
|
||||||
this.dataStatus = status;
|
this.dataStatus = status;
|
||||||
}
|
}
|
||||||
|
@ -26,25 +50,46 @@ export abstract class BaseBatchUpdateStatusManager<Entity> extends BaseManager {
|
||||||
async process(): Promise<void> {
|
async process(): Promise<void> {
|
||||||
let totalFailed = 0;
|
let totalFailed = 0;
|
||||||
let totalSuccess = 0;
|
let totalSuccess = 0;
|
||||||
let messages = [];
|
const messages = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* // TODO: Handle case confirm multiple tabs;
|
||||||
|
* Lopping data diambil dari dataIdsWithDate
|
||||||
|
* exp: for (const item of this.dataIdsWithDate)
|
||||||
|
*/
|
||||||
|
|
||||||
for (const id of this.dataIds) {
|
for (const id of this.dataIds) {
|
||||||
try {
|
try {
|
||||||
|
/**
|
||||||
|
* // TODO: Handle case confirm multiple tabs;
|
||||||
|
* buat variable:
|
||||||
|
* const id = item.id
|
||||||
|
* const updated_at = item.updated_at
|
||||||
|
*/
|
||||||
|
|
||||||
const entity = await this.dataService.getOneByOptions({
|
const entity = await this.dataService.getOneByOptions({
|
||||||
where: {
|
where: {
|
||||||
id: id,
|
id: id,
|
||||||
},
|
},
|
||||||
|
relations: this.relations,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!entity) {
|
if (!entity) {
|
||||||
throw new NotFoundException({
|
throw new NotFoundException({
|
||||||
statusCode: HttpStatus.NOT_FOUND,
|
statusCode: HttpStatus.NOT_FOUND,
|
||||||
message: `Failed! Entity with id ${id} not found`,
|
message: `Gagal! data dengan id ${id} tidak ditemukan`,
|
||||||
error: 'Entity Not Found',
|
error: 'Entity Not Found',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
this.oldData = _.cloneDeep(entity);
|
||||||
await this.validateData(entity);
|
await this.validateData(entity);
|
||||||
|
|
||||||
|
Object.assign(entity, {
|
||||||
|
status: this.dataStatus,
|
||||||
|
editor_id: this.user.id,
|
||||||
|
editor_name: this.user.name,
|
||||||
|
updated_at: new Date().getTime(),
|
||||||
|
});
|
||||||
await new ValidateRelationHelper(
|
await new ValidateRelationHelper(
|
||||||
id,
|
id,
|
||||||
this.dataService,
|
this.dataService,
|
||||||
|
@ -52,17 +97,23 @@ export abstract class BaseBatchUpdateStatusManager<Entity> extends BaseManager {
|
||||||
this.tableName,
|
this.tableName,
|
||||||
).execute();
|
).execute();
|
||||||
|
|
||||||
await this.dataService.update(
|
/**
|
||||||
|
* // TODO: Handle case confirm multiple tabs;
|
||||||
|
* lakukan update data dengan where condition id dan updated_at
|
||||||
|
* EXPECTATION => status akan berubah jika updated_at yang dikirim dari FE sama dengen yang di database
|
||||||
|
* IF => updated_at beda tidak perlu melakukan update status dan tidak perlu memanggil eventBus tetapi tetap dihitung sebagai aksi yang berhasil
|
||||||
|
* IF => FE tidak menambahkan updated_at makan lakukan update dan publishEvent
|
||||||
|
*/
|
||||||
|
|
||||||
|
const result = await this.dataService.update(
|
||||||
this.queryRunner,
|
this.queryRunner,
|
||||||
this.entityTarget,
|
this.entityTarget,
|
||||||
{ id: id },
|
{ id: id },
|
||||||
{
|
entity,
|
||||||
status: this.dataStatus,
|
|
||||||
editor_id: this.user.id,
|
|
||||||
editor_name: this.user.name,
|
|
||||||
updated_at: new Date().getTime(),
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this.publishEvents(this.oldData, result);
|
||||||
|
|
||||||
totalSuccess = totalSuccess + 1;
|
totalSuccess = totalSuccess + 1;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
totalFailed = totalFailed + 1;
|
totalFailed = totalFailed + 1;
|
||||||
|
@ -80,4 +131,43 @@ export abstract class BaseBatchUpdateStatusManager<Entity> extends BaseManager {
|
||||||
|
|
||||||
abstract validateData(data: Entity): Promise<void>;
|
abstract validateData(data: Entity): Promise<void>;
|
||||||
abstract getResult(): BatchResult;
|
abstract getResult(): BatchResult;
|
||||||
|
|
||||||
|
async publishEvents(dataOld, dataNew) {
|
||||||
|
this.eventBus.publish(
|
||||||
|
new RecordLog({
|
||||||
|
id: dataNew['id'],
|
||||||
|
old: dataOld,
|
||||||
|
data: dataNew,
|
||||||
|
user: this.user,
|
||||||
|
description: `${this.user.name} update batch data ${this.tableName}`,
|
||||||
|
module: this.tableName,
|
||||||
|
op: OPERATION.UPDATE,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!this.eventTopics.length) return;
|
||||||
|
for (const topic of this.eventTopics) {
|
||||||
|
let data;
|
||||||
|
if (topic.relations?.length) {
|
||||||
|
data = await this.dataService.getOneByOptions({
|
||||||
|
where: {
|
||||||
|
id: dataNew.id,
|
||||||
|
},
|
||||||
|
relations: topic.relations,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
this.eventBus.publishAll([
|
||||||
|
new topic.topic({
|
||||||
|
id: data?.['id'] ?? dataNew?.['id'],
|
||||||
|
old: dataOld,
|
||||||
|
data: data ?? dataNew,
|
||||||
|
user: this.user,
|
||||||
|
description: '',
|
||||||
|
module: this.tableName,
|
||||||
|
op: OPERATION.UPDATE,
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,152 @@
|
||||||
|
import { BaseManager } from '../base.manager';
|
||||||
|
import {
|
||||||
|
EventTopics,
|
||||||
|
columnUniques,
|
||||||
|
validateRelations,
|
||||||
|
} from 'src/core/strings/constants/interface.constants';
|
||||||
|
import { HttpStatus, UnprocessableEntityException } from '@nestjs/common';
|
||||||
|
import { SelectQueryBuilder } from 'typeorm';
|
||||||
|
|
||||||
|
export abstract class BaseChangePosition<Entity> extends BaseManager {
|
||||||
|
protected result: Entity;
|
||||||
|
protected duplicateColumn: string[];
|
||||||
|
protected startData: Entity;
|
||||||
|
protected endData: Entity;
|
||||||
|
protected columnSort: string;
|
||||||
|
|
||||||
|
protected firstDataId: number;
|
||||||
|
protected lastSort: number;
|
||||||
|
protected sortTo: number;
|
||||||
|
|
||||||
|
abstract get entityTarget(): any;
|
||||||
|
|
||||||
|
setData(entity: Entity, columnSort: string): void {
|
||||||
|
this.data = entity;
|
||||||
|
this.columnSort = columnSort;
|
||||||
|
}
|
||||||
|
|
||||||
|
async beforeProcess(): Promise<void> {
|
||||||
|
if (!this.data?.end || this.data.start == this.data?.end) {
|
||||||
|
throw new UnprocessableEntityException({
|
||||||
|
statusCode: HttpStatus.UNPROCESSABLE_ENTITY,
|
||||||
|
message: 'Gagal! tolong pindahkan ke posisi lain',
|
||||||
|
error: 'Unprocessable Entity',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
this.startData = await this.dataService.getOneByOptions({
|
||||||
|
where: {
|
||||||
|
id: this.data.start,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!this.startData) {
|
||||||
|
throw new UnprocessableEntityException({
|
||||||
|
statusCode: HttpStatus.UNPROCESSABLE_ENTITY,
|
||||||
|
message: `Gagal! data dengan id : ${this.data.start} tidak ditemukan`,
|
||||||
|
error: 'Unprocessable Entity',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
this.endData = await this.dataService.getOneByOptions({
|
||||||
|
where: {
|
||||||
|
id: this.data.end,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!this.endData) {
|
||||||
|
throw new UnprocessableEntityException({
|
||||||
|
statusCode: HttpStatus.UNPROCESSABLE_ENTITY,
|
||||||
|
message: `Gagal! data dengan id : ${this.data.end} tidak ditemukan`,
|
||||||
|
error: 'Unprocessable Entity',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.endData[this.columnSort] > this.startData[this.columnSort]) {
|
||||||
|
// drag from up
|
||||||
|
this.firstDataId = this.startData[this.columnSort];
|
||||||
|
this.lastSort = this.endData[this.columnSort];
|
||||||
|
this.sortTo = this.lastSort;
|
||||||
|
} else if (
|
||||||
|
this.endData[this.columnSort] < this.startData[this.columnSort]
|
||||||
|
) {
|
||||||
|
// drag from bottom
|
||||||
|
this.firstDataId = this.endData[this.columnSort];
|
||||||
|
this.lastSort = this.startData[this.columnSort];
|
||||||
|
this.sortTo = this.firstDataId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async prepareData(): Promise<void> {
|
||||||
|
Object.assign(this.data, {
|
||||||
|
creator_id: this.user.id,
|
||||||
|
creator_name: this.user.name,
|
||||||
|
created_at: new Date().getTime(),
|
||||||
|
updated_at: new Date().getTime(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async validateProcess(): Promise<void> {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
async process(): Promise<void> {
|
||||||
|
let dataArrange: Entity[];
|
||||||
|
|
||||||
|
const queryBuilder = this.dataService
|
||||||
|
.getRepository()
|
||||||
|
.createQueryBuilder(this.tableName)
|
||||||
|
.where(`${this.tableName}.${this.columnSort} between :data1 and :data2`, {
|
||||||
|
data1: this.firstDataId,
|
||||||
|
data2: this.lastSort,
|
||||||
|
});
|
||||||
|
|
||||||
|
const datas = await queryBuilder
|
||||||
|
.orderBy(`${this.tableName}.${this.columnSort}`, 'ASC')
|
||||||
|
.getManyAndCount();
|
||||||
|
|
||||||
|
if (datas[0].length) {
|
||||||
|
let dataFirst = datas[0][0][this.columnSort];
|
||||||
|
const data = datas[0];
|
||||||
|
const length = datas[1];
|
||||||
|
|
||||||
|
if (this.endData[this.columnSort] > this.startData[this.columnSort]) {
|
||||||
|
// drag from above
|
||||||
|
const dataDragged = data[0];
|
||||||
|
const arraySlice = data.slice(1, length);
|
||||||
|
dataArrange = arraySlice.concat([dataDragged]);
|
||||||
|
} else if (
|
||||||
|
this.endData[this.columnSort] < this.startData[this.columnSort]
|
||||||
|
) {
|
||||||
|
// drag from bottom
|
||||||
|
const dataDragged = data[length - 1];
|
||||||
|
const arraySlice = data.slice(0, length - 1);
|
||||||
|
|
||||||
|
dataArrange = [dataDragged].concat(arraySlice);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < length; i++) {
|
||||||
|
dataArrange[i][this.columnSort] = dataFirst;
|
||||||
|
dataFirst++;
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.dataService.createMany(
|
||||||
|
this.queryRunner,
|
||||||
|
this.entityTarget,
|
||||||
|
dataArrange,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get validateRelations(): validateRelations[] {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
get eventTopics(): EventTopics[] {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
getResult(): string {
|
||||||
|
return `Success! Data ${this.startData['name']} successfully moved to ${this.sortTo}`;
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,6 +6,7 @@ import {
|
||||||
columnUniques,
|
columnUniques,
|
||||||
validateRelations,
|
validateRelations,
|
||||||
} from 'src/core/strings/constants/interface.constants';
|
} from 'src/core/strings/constants/interface.constants';
|
||||||
|
import { MoveFilePathHelper } from 'src/core/helpers/path/move-file-path.helper';
|
||||||
|
|
||||||
export abstract class BaseCreateManager<Entity> extends BaseManager {
|
export abstract class BaseCreateManager<Entity> extends BaseManager {
|
||||||
protected result: Entity;
|
protected result: Entity;
|
||||||
|
@ -43,6 +44,15 @@ export abstract class BaseCreateManager<Entity> extends BaseManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
async process(): Promise<void> {
|
async process(): Promise<void> {
|
||||||
|
const keys = Object.keys(this.data);
|
||||||
|
if (
|
||||||
|
(keys.includes('qr_image') || keys.includes('image_url')) &&
|
||||||
|
(this.data['image_url']?.includes('tmp') ||
|
||||||
|
this.data['qr_image']?.includes('tmp'))
|
||||||
|
) {
|
||||||
|
await MoveFilePathHelper(this.data);
|
||||||
|
}
|
||||||
|
|
||||||
this.result = await this.dataService.create(
|
this.result = await this.dataService.create(
|
||||||
this.queryRunner,
|
this.queryRunner,
|
||||||
this.entityTarget,
|
this.entityTarget,
|
||||||
|
@ -61,7 +71,7 @@ export abstract class BaseCreateManager<Entity> extends BaseManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
async publishEvents() {
|
async publishEvents() {
|
||||||
this.eventBus.publish(
|
this.eventBus?.publish(
|
||||||
new RecordLog({
|
new RecordLog({
|
||||||
id: this.result['id'],
|
id: this.result['id'],
|
||||||
old: null,
|
old: null,
|
||||||
|
@ -73,6 +83,29 @@ export abstract class BaseCreateManager<Entity> extends BaseManager {
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
// if (!this.eventTopics.length) return;
|
if (!this.eventTopics.length) return;
|
||||||
|
for (const topic of this.eventTopics) {
|
||||||
|
let data;
|
||||||
|
if (!topic.data) {
|
||||||
|
data = await this.dataService.getOneByOptions({
|
||||||
|
where: {
|
||||||
|
id: this.result['id'],
|
||||||
|
},
|
||||||
|
relations: topic.relations,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
this.eventBus.publishAll([
|
||||||
|
new topic.topic({
|
||||||
|
id: this.result['id'],
|
||||||
|
old: null,
|
||||||
|
data: data ?? topic.data,
|
||||||
|
user: this.user,
|
||||||
|
description: '',
|
||||||
|
module: this.tableName,
|
||||||
|
op: OPERATION.CREATE,
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
import { validateRelations } from 'src/core/strings/constants/interface.constants';
|
import { validateRelations } from 'src/core/strings/constants/interface.constants';
|
||||||
import { BaseManager } from '../base.manager';
|
import { BaseManager } from '../base.manager';
|
||||||
|
import { OPERATION } from 'src/core/strings/constants/base.constants';
|
||||||
|
|
||||||
export abstract class BaseCustomManager<Entity> extends BaseManager {
|
export abstract class BaseCustomManager<Entity> extends BaseManager {
|
||||||
protected result: any;
|
protected result: any;
|
||||||
abstract get entityTarget(): any;
|
abstract get entityTarget(): any;
|
||||||
|
|
||||||
setData(entity: Entity): void {
|
setData(entity: any): void {
|
||||||
this.data = entity;
|
this.data = entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,4 +24,31 @@ export abstract class BaseCustomManager<Entity> extends BaseManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract getResult(): any;
|
abstract getResult(): any;
|
||||||
|
|
||||||
|
async publishEvents() {
|
||||||
|
if (!this.eventTopics.length) return;
|
||||||
|
for (const topic of this.eventTopics) {
|
||||||
|
let data;
|
||||||
|
if (!topic.data) {
|
||||||
|
data = await this.dataService.getOneByOptions({
|
||||||
|
where: {
|
||||||
|
id: this.result['id'],
|
||||||
|
},
|
||||||
|
relations: topic.relations,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
this.eventBus.publishAll([
|
||||||
|
new topic.topic({
|
||||||
|
id: data?.['id'] ?? topic?.data?.['id'],
|
||||||
|
old: null,
|
||||||
|
data: data ?? topic.data,
|
||||||
|
user: this.user,
|
||||||
|
description: '',
|
||||||
|
module: this.tableName,
|
||||||
|
op: OPERATION.UPDATE,
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import { HttpStatus, UnprocessableEntityException } from '@nestjs/common';
|
import { HttpStatus, UnprocessableEntityException } from '@nestjs/common';
|
||||||
import { BaseManager } from '../base.manager';
|
import { BaseManager } from '../base.manager';
|
||||||
import { ValidateRelationHelper } from 'src/core/helpers/validation/validate-relation.helper';
|
import { ValidateRelationHelper } from 'src/core/helpers/validation/validate-relation.helper';
|
||||||
|
import { RecordLog } from 'src/modules/configuration/log/domain/entities/log.event';
|
||||||
|
import { OPERATION } from 'src/core/strings/constants/base.constants';
|
||||||
|
|
||||||
export abstract class BaseDeleteManager<Entity> extends BaseManager {
|
export abstract class BaseDeleteManager<Entity> extends BaseManager {
|
||||||
protected dataId: string;
|
protected dataId: string;
|
||||||
|
@ -21,7 +23,7 @@ export abstract class BaseDeleteManager<Entity> extends BaseManager {
|
||||||
if (!this.data)
|
if (!this.data)
|
||||||
throw new UnprocessableEntityException({
|
throw new UnprocessableEntityException({
|
||||||
statusCode: HttpStatus.UNPROCESSABLE_ENTITY,
|
statusCode: HttpStatus.UNPROCESSABLE_ENTITY,
|
||||||
message: `Data with id ${this.dataId} not found`,
|
message: `Gagal! Data denga id ${this.dataId} tidak ditemukan`,
|
||||||
error: 'Unprocessable Entity',
|
error: 'Unprocessable Entity',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -41,7 +43,38 @@ export abstract class BaseDeleteManager<Entity> extends BaseManager {
|
||||||
this.entityTarget,
|
this.entityTarget,
|
||||||
this.dataId,
|
this.dataId,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this.publishEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract getResult(): string;
|
abstract getResult(): string;
|
||||||
|
|
||||||
|
async publishEvents() {
|
||||||
|
this.eventBus.publish(
|
||||||
|
new RecordLog({
|
||||||
|
id: this.data['id'],
|
||||||
|
old: null,
|
||||||
|
data: this.data,
|
||||||
|
user: this.user,
|
||||||
|
description: `${this.user.name} delete data ${this.tableName}`,
|
||||||
|
module: this.tableName,
|
||||||
|
op: OPERATION.CREATE,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!this.eventTopics.length) return;
|
||||||
|
for (const topic of this.eventTopics) {
|
||||||
|
this.eventBus.publishAll([
|
||||||
|
new topic.topic({
|
||||||
|
id: topic.data['id'],
|
||||||
|
old: this.data,
|
||||||
|
data: topic.data,
|
||||||
|
user: this.user,
|
||||||
|
description: '',
|
||||||
|
module: this.tableName,
|
||||||
|
op: OPERATION.DELETE,
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import {
|
||||||
} from 'src/core/helpers/query/default-filter.helper';
|
} from 'src/core/helpers/query/default-filter.helper';
|
||||||
import { Param } from '../../entities/base-filter.entity';
|
import { Param } from '../../entities/base-filter.entity';
|
||||||
import { joinRelationHelper } from 'src/core/helpers/query/join-relations.helper';
|
import { joinRelationHelper } from 'src/core/helpers/query/join-relations.helper';
|
||||||
|
import { STATUS } from 'src/core/strings/constants/base.constants';
|
||||||
|
|
||||||
export abstract class BaseIndexManager<Entity> extends BaseReadManager {
|
export abstract class BaseIndexManager<Entity> extends BaseReadManager {
|
||||||
protected result: PaginationResponse<Entity>;
|
protected result: PaginationResponse<Entity>;
|
||||||
|
@ -19,6 +20,7 @@ export abstract class BaseIndexManager<Entity> extends BaseReadManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
async process(): Promise<void> {
|
async process(): Promise<void> {
|
||||||
|
const specificFilter = this.specificFilter;
|
||||||
const { joinRelations, selectRelations, countRelations } = this.relations;
|
const { joinRelations, selectRelations, countRelations } = this.relations;
|
||||||
|
|
||||||
if (joinRelations?.length)
|
if (joinRelations?.length)
|
||||||
|
@ -40,10 +42,30 @@ export abstract class BaseIndexManager<Entity> extends BaseReadManager {
|
||||||
|
|
||||||
if (this.selects?.length) this.queryBuilder.select(this.selects);
|
if (this.selects?.length) this.queryBuilder.select(this.selects);
|
||||||
|
|
||||||
|
if (this.filterParam.statuses?.length > 0) {
|
||||||
|
const data = this.filterParam.statuses.map((status) => {
|
||||||
|
const statusData = status.includes("'")
|
||||||
|
? status.trim().replace(/'/g, "''").replace(/\s+/g, ' ')
|
||||||
|
: status.trim().replace(/\s+/g, ' ');
|
||||||
|
|
||||||
|
// jika searching status terdapat dalam enum, maka dia mencari specific data
|
||||||
|
// ? karena jika tidak, ketika dia search "active" maka "inactive" juga ikut
|
||||||
|
return `'${STATUS[statusData.toUpperCase()]}'`;
|
||||||
|
});
|
||||||
|
|
||||||
|
const exist = specificFilter.find((item) => item.isStatus);
|
||||||
|
if (!exist) {
|
||||||
|
specificFilter.push({
|
||||||
|
cols: `${this.tableName}.status::text`,
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
new SpecificSearchFilter<Entity>(
|
new SpecificSearchFilter<Entity>(
|
||||||
this.queryBuilder,
|
this.queryBuilder,
|
||||||
this.tableName,
|
this.tableName,
|
||||||
this.specificFilter,
|
specificFilter,
|
||||||
).getFilter();
|
).getFilter();
|
||||||
|
|
||||||
getOrderBy(this.filterParam, this.queryBuilder, this.tableName);
|
getOrderBy(this.filterParam, this.queryBuilder, this.tableName);
|
||||||
|
|
|
@ -1,28 +1,56 @@
|
||||||
import { ValidateRelationHelper } from 'src/core/helpers/validation/validate-relation.helper';
|
import { ValidateRelationHelper } from 'src/core/helpers/validation/validate-relation.helper';
|
||||||
import { BaseManager } from '../base.manager';
|
import { BaseManager } from '../base.manager';
|
||||||
import { STATUS } from 'src/core/strings/constants/base.constants';
|
import {
|
||||||
import { UserPrivilegeModel } from 'src/modules/user-related/user-privilege/data/models/user-privilege.model';
|
OPERATION,
|
||||||
|
QUEUE_STATUS,
|
||||||
|
STATUS,
|
||||||
|
} from 'src/core/strings/constants/base.constants';
|
||||||
|
import * as _ from 'lodash';
|
||||||
|
import { RecordLog } from 'src/modules/configuration/log/domain/entities/log.event';
|
||||||
|
|
||||||
export abstract class BaseUpdateStatusManager<Entity> extends BaseManager {
|
export abstract class BaseUpdateStatusManager<Entity> extends BaseManager {
|
||||||
protected dataId: string;
|
protected dataId: string;
|
||||||
protected result: Entity;
|
protected result: Entity;
|
||||||
protected dataStatus: STATUS;
|
protected oldData: Entity;
|
||||||
|
protected dataStatus: STATUS | QUEUE_STATUS;
|
||||||
|
protected relations = [];
|
||||||
protected duplicateColumn: string[];
|
protected duplicateColumn: string[];
|
||||||
abstract get entityTarget(): any;
|
abstract get entityTarget(): any;
|
||||||
|
|
||||||
setData(id: string, status: STATUS): void {
|
setData(id: string, status: STATUS | QUEUE_STATUS): void {
|
||||||
|
/**
|
||||||
|
* // TODO: Handle case confirm multiple tabs;
|
||||||
|
* Pola id yang dikirim dirubah menjadi data_id___updated_at
|
||||||
|
* Untuk mendapatkan value id nya saja dan menghindari breaking change
|
||||||
|
* karena sudah digunakan sebelumnya lakukan split dari data ids yang dikirim
|
||||||
|
* Example:
|
||||||
|
* this.dataId = id.split('___')[0]
|
||||||
|
*
|
||||||
|
* Simpan data id yang mempunyai update_at kedalam valiable baru
|
||||||
|
* Example:
|
||||||
|
* this.dataIdsWithDate = {
|
||||||
|
* id: id.split('___')[0],
|
||||||
|
* updated_at: id.split('___')[1]
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
|
||||||
this.dataId = id;
|
this.dataId = id;
|
||||||
this.dataStatus = status;
|
this.dataStatus = status;
|
||||||
}
|
}
|
||||||
|
|
||||||
async prepareData(): Promise<void> {
|
async prepareData(): Promise<void> {
|
||||||
this.data = new UserPrivilegeModel();
|
this.data = await this.dataService.getOneByOptions({
|
||||||
|
where: {
|
||||||
|
id: this.dataId,
|
||||||
|
},
|
||||||
|
relations: this.relations,
|
||||||
|
});
|
||||||
|
this.oldData = _.cloneDeep(this.data);
|
||||||
|
|
||||||
Object.assign(this.data, {
|
Object.assign(this.data, {
|
||||||
editor_id: this.user.id,
|
editor_id: this.user.id,
|
||||||
editor_name: this.user.name,
|
editor_name: this.user.name,
|
||||||
updated_at: new Date().getTime(),
|
updated_at: new Date().getTime(),
|
||||||
id: this.dataId,
|
|
||||||
status: this.dataStatus,
|
status: this.dataStatus,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -35,13 +63,64 @@ export abstract class BaseUpdateStatusManager<Entity> extends BaseManager {
|
||||||
this.tableName,
|
this.tableName,
|
||||||
).execute();
|
).execute();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* // TODO: Handle case confirm multiple tabs;
|
||||||
|
* IF => updated_at sama dengen data yang di database
|
||||||
|
* THEN =>
|
||||||
|
* - Lakukan update data dengan where condition id dan updated_at
|
||||||
|
* - EXPECTATION = > status akan berubah jika updated_at yang dikirim dari FE sama dengen yang di database
|
||||||
|
* IF => updated_at beda maka retun curent data tanpa harus malakukan update status dan publish event
|
||||||
|
* IF => FE tidak menambahkan updated_at makan lakukan update dan publishEvent
|
||||||
|
*/
|
||||||
|
|
||||||
this.result = await this.dataService.update(
|
this.result = await this.dataService.update(
|
||||||
this.queryRunner,
|
this.queryRunner,
|
||||||
this.entityTarget,
|
this.entityTarget,
|
||||||
{ id: this.dataId },
|
{ id: this.dataId },
|
||||||
this.data,
|
this.data,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this.publishEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract getResult(): string;
|
abstract getResult(): string;
|
||||||
|
|
||||||
|
async publishEvents() {
|
||||||
|
this.eventBus.publish(
|
||||||
|
new RecordLog({
|
||||||
|
id: this.result['id'],
|
||||||
|
old: this.oldData,
|
||||||
|
data: this.result,
|
||||||
|
user: this.user,
|
||||||
|
description: `${this.user.name} update status data ${this.tableName} to ${this.dataStatus}`,
|
||||||
|
module: this.tableName,
|
||||||
|
op: OPERATION.UPDATE,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!this.eventTopics.length) return;
|
||||||
|
for (const topic of this.eventTopics) {
|
||||||
|
let data;
|
||||||
|
if (!topic.data) {
|
||||||
|
data = await this.dataService.getOneByOptions({
|
||||||
|
where: {
|
||||||
|
id: this.dataId,
|
||||||
|
},
|
||||||
|
relations: topic.relations,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
this.eventBus.publishAll([
|
||||||
|
new topic.topic({
|
||||||
|
id: data?.['id'] ?? topic?.data?.['id'],
|
||||||
|
old: this.oldData,
|
||||||
|
data: data ?? topic.data,
|
||||||
|
user: this.user,
|
||||||
|
description: '',
|
||||||
|
module: this.tableName,
|
||||||
|
op: OPERATION.UPDATE,
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,14 @@ import { CheckDuplicateHelper } from 'src/core/helpers/query/check-duplicate.hel
|
||||||
import { BaseManager } from '../base.manager';
|
import { BaseManager } from '../base.manager';
|
||||||
import { ValidateRelationHelper } from 'src/core/helpers/validation/validate-relation.helper';
|
import { ValidateRelationHelper } from 'src/core/helpers/validation/validate-relation.helper';
|
||||||
import { columnUniques } from 'src/core/strings/constants/interface.constants';
|
import { columnUniques } from 'src/core/strings/constants/interface.constants';
|
||||||
|
import { RecordLog } from 'src/modules/configuration/log/domain/entities/log.event';
|
||||||
|
import { OPERATION } from 'src/core/strings/constants/base.constants';
|
||||||
|
import { HttpStatus, NotFoundException } from '@nestjs/common';
|
||||||
|
|
||||||
export abstract class BaseUpdateManager<Entity> extends BaseManager {
|
export abstract class BaseUpdateManager<Entity> extends BaseManager {
|
||||||
protected dataId: string;
|
protected dataId: string;
|
||||||
protected result: Entity;
|
protected result: Entity;
|
||||||
|
protected oldData: Entity;
|
||||||
protected duplicateColumn: string[];
|
protected duplicateColumn: string[];
|
||||||
abstract get entityTarget(): any;
|
abstract get entityTarget(): any;
|
||||||
abstract get uniqueColumns(): columnUniques[];
|
abstract get uniqueColumns(): columnUniques[];
|
||||||
|
@ -16,6 +20,18 @@ export abstract class BaseUpdateManager<Entity> extends BaseManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
async prepareData(): Promise<void> {
|
async prepareData(): Promise<void> {
|
||||||
|
this.oldData = await this.dataService.getOneByOptions({
|
||||||
|
where: { id: this.dataId },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!this.oldData) {
|
||||||
|
throw new NotFoundException({
|
||||||
|
statusCode: HttpStatus.NOT_FOUND,
|
||||||
|
message: `Gagal! Data denga id ${this.dataId} tidak ditemukan`,
|
||||||
|
error: 'Entity Not Found',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Object.assign(this.data, {
|
Object.assign(this.data, {
|
||||||
editor_id: this.user.id,
|
editor_id: this.user.id,
|
||||||
editor_name: this.user.name,
|
editor_name: this.user.name,
|
||||||
|
@ -47,6 +63,8 @@ export abstract class BaseUpdateManager<Entity> extends BaseManager {
|
||||||
{ id: this.dataId },
|
{ id: this.dataId },
|
||||||
this.data,
|
this.data,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this.publishEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
async getResult(): Promise<Entity> {
|
async getResult(): Promise<Entity> {
|
||||||
|
@ -56,4 +74,43 @@ export abstract class BaseUpdateManager<Entity> extends BaseManager {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async publishEvents() {
|
||||||
|
this.eventBus.publish(
|
||||||
|
new RecordLog({
|
||||||
|
id: this.result['id'],
|
||||||
|
old: this.oldData,
|
||||||
|
data: this.result,
|
||||||
|
user: this.user,
|
||||||
|
description: `${this.user.name} update data ${this.tableName}`,
|
||||||
|
module: this.tableName,
|
||||||
|
op: OPERATION.UPDATE,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!this.eventTopics.length) return;
|
||||||
|
for (const topic of this.eventTopics) {
|
||||||
|
let data;
|
||||||
|
if (!topic.data) {
|
||||||
|
data = await this.dataService.getOneByOptions({
|
||||||
|
where: {
|
||||||
|
id: this.dataId,
|
||||||
|
},
|
||||||
|
relations: topic.relations,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
this.eventBus.publishAll([
|
||||||
|
new topic.topic({
|
||||||
|
id: topic.data?.['id'] ?? this.dataId,
|
||||||
|
old: this.oldData,
|
||||||
|
data: data ?? topic.data,
|
||||||
|
user: this.user,
|
||||||
|
description: '',
|
||||||
|
module: this.tableName,
|
||||||
|
op: OPERATION.UPDATE,
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,9 @@ import { BaseDataOrchestrator } from './base-data.orchestrator';
|
||||||
export abstract class BaseDataTransactionOrchestrator<
|
export abstract class BaseDataTransactionOrchestrator<
|
||||||
Entity,
|
Entity,
|
||||||
> extends BaseDataOrchestrator<Entity> {
|
> extends BaseDataOrchestrator<Entity> {
|
||||||
abstract active(dataId: string): Promise<String>;
|
abstract active(dataId: string): Promise<string>;
|
||||||
abstract confirm(dataId: string): Promise<String>;
|
abstract confirm(dataId: string): Promise<string>;
|
||||||
abstract inactive(dataId: string): Promise<String>;
|
abstract inactive(dataId: string): Promise<string>;
|
||||||
abstract batchConfirm(dataIds: string[]): Promise<BatchResult>;
|
abstract batchConfirm(dataIds: string[]): Promise<BatchResult>;
|
||||||
abstract batchActive(dataIds: string[]): Promise<BatchResult>;
|
abstract batchActive(dataIds: string[]): Promise<BatchResult>;
|
||||||
abstract batchInactive(dataIds: string[]): Promise<BatchResult>;
|
abstract batchInactive(dataIds: string[]): Promise<BatchResult>;
|
||||||
|
|
|
@ -3,6 +3,6 @@ import { BatchResult } from 'src/core/response/domain/ok-response.interface';
|
||||||
export abstract class BaseDataOrchestrator<Entity> {
|
export abstract class BaseDataOrchestrator<Entity> {
|
||||||
abstract create(data: Entity): Promise<Entity>;
|
abstract create(data: Entity): Promise<Entity>;
|
||||||
abstract update(dataId: string, data: Entity): Promise<Entity>;
|
abstract update(dataId: string, data: Entity): Promise<Entity>;
|
||||||
abstract delete(dataId: string): Promise<String>;
|
abstract delete(dataId: string): Promise<string>;
|
||||||
abstract batchDelete(dataIds: string[]): Promise<BatchResult>;
|
abstract batchDelete(dataIds: string[]): Promise<BatchResult>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
export class ChangePositionDto {
|
||||||
|
start: string;
|
||||||
|
end: string;
|
||||||
|
}
|
|
@ -23,6 +23,7 @@ export class BaseFilterDto implements BaseFilterEntity {
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
limit = 10;
|
limit = 10;
|
||||||
|
|
||||||
|
@ApiProperty({ type: String, required: false })
|
||||||
q: string;
|
q: string;
|
||||||
|
|
||||||
@ApiProperty({ type: ['string'], required: false })
|
@ApiProperty({ type: ['string'], required: false })
|
||||||
|
|
|
@ -1 +1,2 @@
|
||||||
export const PAGINATION_RESPONSE = 'PAGINATION_RESPONSE';
|
export const PAGINATION_RESPONSE = 'PAGINATION_RESPONSE';
|
||||||
|
export const GATE_RESPONSE = 'GATE_RESPONSE';
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { SetMetadata } from '@nestjs/common';
|
import { SetMetadata } from '@nestjs/common';
|
||||||
import { PAGINATION_RESPONSE } from '../../constants';
|
import { GATE_RESPONSE, PAGINATION_RESPONSE } from '../../constants';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This decorator will tell the response,
|
* This decorator will tell the response,
|
||||||
|
@ -7,3 +7,5 @@ import { PAGINATION_RESPONSE } from '../../constants';
|
||||||
*/
|
*/
|
||||||
export const Pagination = (isPagination = true) =>
|
export const Pagination = (isPagination = true) =>
|
||||||
SetMetadata(PAGINATION_RESPONSE, isPagination);
|
SetMetadata(PAGINATION_RESPONSE, isPagination);
|
||||||
|
|
||||||
|
export const Gate = () => SetMetadata(GATE_RESPONSE, true);
|
||||||
|
|
|
@ -8,21 +8,28 @@ import { Observable } from 'rxjs';
|
||||||
import { map } from 'rxjs/operators';
|
import { map } from 'rxjs/operators';
|
||||||
import { Request } from 'express';
|
import { Request } from 'express';
|
||||||
import { Reflector } from '@nestjs/core';
|
import { Reflector } from '@nestjs/core';
|
||||||
import { PAGINATION_RESPONSE } from '../constants';
|
import { GATE_RESPONSE, PAGINATION_RESPONSE } from '../constants';
|
||||||
import { createPaginationResponse } from './utils/pagination-meta.helper';
|
import { createPaginationResponse } from './utils/pagination-meta.helper';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class TransformInterceptor implements NestInterceptor {
|
export class TransformInterceptor implements NestInterceptor {
|
||||||
constructor(protected readonly reflector: Reflector) {}
|
constructor(protected readonly reflector: Reflector) {}
|
||||||
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
|
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
|
||||||
|
const isGate = this.reflector.getAllAndOverride<boolean>(GATE_RESPONSE, [
|
||||||
|
context.getHandler(),
|
||||||
|
context.getClass(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (isGate) return next.handle();
|
||||||
|
|
||||||
const isPagination = this.reflector.getAllAndOverride<boolean>(
|
const isPagination = this.reflector.getAllAndOverride<boolean>(
|
||||||
PAGINATION_RESPONSE,
|
PAGINATION_RESPONSE,
|
||||||
[context.getHandler(), context.getClass()],
|
[context.getHandler(), context.getClass()],
|
||||||
);
|
);
|
||||||
|
|
||||||
const request = context.switchToHttp().getRequest<Request>();
|
const request = context.switchToHttp().getRequest<Request>();
|
||||||
const start = request.params.page ?? 1;
|
const start = request.query.page ?? 1;
|
||||||
const limit = request.params.limit ?? 10;
|
const limit = request.query.limit ?? 10;
|
||||||
|
|
||||||
return next.handle().pipe(
|
return next.handle().pipe(
|
||||||
map((data) => {
|
map((data) => {
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
|
import { AppSource } from 'src/core/helpers/constant';
|
||||||
import { UserRole } from 'src/modules/user-related/user/constants';
|
import { UserRole } from 'src/modules/user-related/user/constants';
|
||||||
|
|
||||||
export interface UsersSession {
|
export interface UsersSession {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
role: UserRole;
|
role: UserRole;
|
||||||
|
source?: AppSource;
|
||||||
|
item_id?: string;
|
||||||
user_privilege_id: string;
|
user_privilege_id: string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,4 +23,9 @@ export class UserProvider {
|
||||||
const [, token] = this.request.headers['authorization'].split(' ');
|
const [, token] = this.request.headers['authorization'].split(' ');
|
||||||
return this.session.verifyToken(token);
|
return this.session.verifyToken(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get token(): string {
|
||||||
|
const [, token] = this.request.headers['authorization'].split(' ');
|
||||||
|
return token;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,18 +6,35 @@ export enum STATUS {
|
||||||
DRAFT = 'draft',
|
DRAFT = 'draft',
|
||||||
EXPIRED = 'expired',
|
EXPIRED = 'expired',
|
||||||
INACTIVE = 'inactive',
|
INACTIVE = 'inactive',
|
||||||
|
PARTIAL_REFUND = 'partial refund',
|
||||||
PENDING = 'pending',
|
PENDING = 'pending',
|
||||||
|
PROCESS_REFUND = 'proses refund',
|
||||||
REFUNDED = 'refunded',
|
REFUNDED = 'refunded',
|
||||||
REJECTED = 'rejected',
|
REJECTED = 'rejected',
|
||||||
SETTLED = 'settled',
|
SETTLED = 'settled',
|
||||||
WAITING = 'waiting',
|
WAITING = 'waiting',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum QUEUE_STATUS {
|
||||||
|
DONE = 'done',
|
||||||
|
CALLED = 'called',
|
||||||
|
}
|
||||||
|
|
||||||
export enum ORDER_TYPE {
|
export enum ORDER_TYPE {
|
||||||
ASC = 'ASC',
|
ASC = 'ASC',
|
||||||
DESC = 'DESC',
|
DESC = 'DESC',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const DAY = [
|
||||||
|
'minggu',
|
||||||
|
'senin',
|
||||||
|
'selasa',
|
||||||
|
'rabu',
|
||||||
|
'kamis',
|
||||||
|
'jumat',
|
||||||
|
'sabtu',
|
||||||
|
];
|
||||||
|
|
||||||
export enum CONNECTION_NAME {
|
export enum CONNECTION_NAME {
|
||||||
DEFAULT = 'default',
|
DEFAULT = 'default',
|
||||||
}
|
}
|
||||||
|
@ -46,3 +63,5 @@ export const BLANK_USER = {
|
||||||
role: null,
|
role: null,
|
||||||
user_privilege_id: null,
|
user_privilege_id: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const EMPTY_UUID = '00000000-0000-0000-0000-000000000000';
|
||||||
|
|
|
@ -1,19 +1,30 @@
|
||||||
import { UsersSession } from 'src/core/sessions';
|
import { UsersSession } from 'src/core/sessions';
|
||||||
import { OPERATION } from './base.constants';
|
import { OPERATION } from './base.constants';
|
||||||
|
import { SelectQueryBuilder } from 'typeorm';
|
||||||
|
|
||||||
export interface EventTopics {
|
export interface EventTopics {
|
||||||
topic: any;
|
topic: any;
|
||||||
data?: any;
|
data?: any;
|
||||||
|
relations?: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface validateRelations {
|
export interface validateRelations {
|
||||||
|
// nama relasi
|
||||||
relation: string;
|
relation: string;
|
||||||
|
|
||||||
|
// query digunakan untuk query optional jika ingin specifik data
|
||||||
|
query?: (qb: SelectQueryBuilder<any>) => SelectQueryBuilder<any>;
|
||||||
|
|
||||||
|
// query ini sama dengan yang diatas, akan tetapi ini khusus untuk ManyToOne relation
|
||||||
|
singleQuery?: [string, any, any];
|
||||||
|
|
||||||
|
// custom message
|
||||||
message?: string;
|
message?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface columnUniques {
|
export interface columnUniques {
|
||||||
column: string;
|
column: string;
|
||||||
query?: Object;
|
query?: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IEvent<Entity = any> {
|
export interface IEvent<Entity = any> {
|
||||||
|
|
|
@ -1,13 +1,31 @@
|
||||||
export enum MODULE_NAME {
|
export enum MODULE_NAME {
|
||||||
|
BANNER = 'banners',
|
||||||
|
FAQ = 'faqs',
|
||||||
|
GATE = 'gates',
|
||||||
ITEM = 'items',
|
ITEM = 'items',
|
||||||
ITEM_CATEGORY = 'item-categories',
|
ITEM_CATEGORY = 'item-categories',
|
||||||
|
ITEM_QUEUE = 'item-queues',
|
||||||
|
ITEM_RATE = 'item-rates',
|
||||||
|
NEWS = 'news',
|
||||||
PAYMENT_METHOD = 'payment-methods',
|
PAYMENT_METHOD = 'payment-methods',
|
||||||
|
RECONCILIATION = 'reconciliations',
|
||||||
|
REFUND = 'refunds',
|
||||||
SEASON_TYPE = 'season-types',
|
SEASON_TYPE = 'season-types',
|
||||||
|
SEASON_PERIOD = 'season-periods',
|
||||||
TAX = 'taxes',
|
TAX = 'taxes',
|
||||||
|
TERM_CONDITION = 'term_conditions',
|
||||||
TENANT = 'tenants',
|
TENANT = 'tenants',
|
||||||
|
TRANSACTION = 'transactions',
|
||||||
USER = 'users',
|
USER = 'users',
|
||||||
USER_PRIVILEGE = 'user-privileges',
|
USER_PRIVILEGE = 'user-privileges',
|
||||||
USER_PRIVILEGE_CONFIGURATION = 'user-privilege-configurations',
|
USER_PRIVILEGE_CONFIGURATION = 'user-privilege-configurations',
|
||||||
VIP_CATEGORY = 'vip-categories',
|
VIP_CATEGORY = 'vip-categories',
|
||||||
VIP_CODE = 'vip-codes',
|
VIP_CODE = 'vip-codes',
|
||||||
|
|
||||||
|
REPORT = 'report',
|
||||||
|
REPORT_BOOKMARK = 'report-bookmark',
|
||||||
|
REPORT_EXPORT = 'report-export',
|
||||||
|
REPORT_SUMMARY = 'report-summary',
|
||||||
|
|
||||||
|
QUEUE = 'queue',
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,11 +47,10 @@ export const PrivilegeAdminConstant = [
|
||||||
index: 4,
|
index: 4,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
menu: 'REKONSILIASI',
|
menu: 'RECONCILIATION',
|
||||||
menu_label: 'Rekonsiliasi',
|
menu_label: 'Rekonsiliasi',
|
||||||
actions: [
|
actions: [
|
||||||
PrivilegeAction.VIEW,
|
PrivilegeAction.VIEW,
|
||||||
PrivilegeAction.CREATE,
|
|
||||||
PrivilegeAction.CONFIRM,
|
PrivilegeAction.CONFIRM,
|
||||||
PrivilegeAction.DELETE,
|
PrivilegeAction.DELETE,
|
||||||
PrivilegeAction.CANCEL,
|
PrivilegeAction.CANCEL,
|
||||||
|
@ -71,8 +70,8 @@ export const PrivilegeAdminConstant = [
|
||||||
index: 6,
|
index: 6,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
menu: 'RATE_TYPE',
|
menu: 'SEASON',
|
||||||
menu_label: 'Tipe Rate',
|
menu_label: 'Season',
|
||||||
actions: [
|
actions: [
|
||||||
PrivilegeAction.VIEW,
|
PrivilegeAction.VIEW,
|
||||||
PrivilegeAction.CREATE,
|
PrivilegeAction.CREATE,
|
||||||
|
@ -126,17 +125,23 @@ export const PrivilegeAdminConstant = [
|
||||||
index: 11,
|
index: 11,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
menu: 'LAPORAN',
|
menu: 'REPORT',
|
||||||
menu_label: 'Laporan',
|
menu_label: 'Laporan',
|
||||||
actions: [PrivilegeAction.VIEW],
|
actions: [PrivilegeAction.VIEW],
|
||||||
index: 12,
|
index: 12,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
menu: 'DISKON_CODE',
|
menu: 'DISCOUNT_CODE',
|
||||||
menu_label: 'Generate Diskon Kode',
|
menu_label: 'Generate Diskon Kode',
|
||||||
actions: [PrivilegeAction.CREATE],
|
actions: [PrivilegeAction.CREATE],
|
||||||
index: 13,
|
index: 13,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
menu: 'DOWNLOAD_POS_APP',
|
||||||
|
menu_label: 'Download POS App',
|
||||||
|
actions: [PrivilegeAction.VIEW],
|
||||||
|
index: 20,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export const PrivilegePOSConstant = [
|
export const PrivilegePOSConstant = [
|
||||||
|
@ -146,8 +151,8 @@ export const PrivilegePOSConstant = [
|
||||||
actions: [
|
actions: [
|
||||||
PrivilegeAction.VIEW,
|
PrivilegeAction.VIEW,
|
||||||
PrivilegeAction.CREATE,
|
PrivilegeAction.CREATE,
|
||||||
PrivilegeAction.DELETE,
|
|
||||||
PrivilegeAction.EDIT,
|
PrivilegeAction.EDIT,
|
||||||
|
PrivilegeAction.CANCEL,
|
||||||
],
|
],
|
||||||
index: 14,
|
index: 14,
|
||||||
},
|
},
|
||||||
|
@ -160,7 +165,7 @@ export const PrivilegePOSConstant = [
|
||||||
{
|
{
|
||||||
menu: 'BOOKING',
|
menu: 'BOOKING',
|
||||||
menu_label: 'Pemesanan',
|
menu_label: 'Pemesanan',
|
||||||
actions: [PrivilegeAction.VIEW, PrivilegeAction.CREATE],
|
actions: [PrivilegeAction.VIEW],
|
||||||
index: 16,
|
index: 16,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -170,9 +175,15 @@ export const PrivilegePOSConstant = [
|
||||||
index: 17,
|
index: 17,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
menu: 'POS_DISKON_CODE',
|
menu: 'POS_DISCOUNT_CODE',
|
||||||
menu_label: 'Generate Diskon Kode',
|
menu_label: 'Generate Diskon Kode',
|
||||||
actions: [PrivilegeAction.CREATE],
|
actions: [PrivilegeAction.CREATE],
|
||||||
index: 18,
|
index: 18,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
menu: 'PRINT_RECEIPT',
|
||||||
|
menu_label: 'Print Receipt',
|
||||||
|
actions: [PrivilegeAction.CREATE],
|
||||||
|
index: 19,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
|
@ -1,16 +1,45 @@
|
||||||
export enum TABLE_NAME {
|
export enum TABLE_NAME {
|
||||||
|
BANNER = 'banners',
|
||||||
ERROR_LOG = 'log_errors',
|
ERROR_LOG = 'log_errors',
|
||||||
|
FAQ = 'faqs',
|
||||||
ITEM = 'items',
|
ITEM = 'items',
|
||||||
ITEM_CATEGORY = 'item_categories',
|
ITEM_CATEGORY = 'item_categories',
|
||||||
|
ITEM_QUEUE = 'item_queues',
|
||||||
|
ITEM_RATE = 'item_rates',
|
||||||
|
GATE = 'gates',
|
||||||
LOG = 'logs',
|
LOG = 'logs',
|
||||||
|
LOG_POS = 'logs_pos',
|
||||||
|
NEWS = 'news',
|
||||||
PAYMENT_METHOD = 'payment_methods',
|
PAYMENT_METHOD = 'payment_methods',
|
||||||
PRICE_FORMULA = 'price_formulas',
|
PRICE_FORMULA = 'price_formulas',
|
||||||
|
REFUND = 'refunds',
|
||||||
|
REFUND_ITEM = 'refund_items',
|
||||||
SEASON_TYPE = 'season_types',
|
SEASON_TYPE = 'season_types',
|
||||||
|
SEASON_PERIOD = 'season_periods',
|
||||||
TAX = 'taxes',
|
TAX = 'taxes',
|
||||||
|
TERM_CONDITION = 'term_conditions',
|
||||||
TENANT = 'tenants',
|
TENANT = 'tenants',
|
||||||
|
TRANSACTION = 'transactions',
|
||||||
|
TRANSACTION_ITEM = 'transaction_items',
|
||||||
|
TRANSACTION_ITEM_BREAKDOWN = 'transaction_item_breakdowns',
|
||||||
|
TRANSACTION_TAX = 'transaction_taxes',
|
||||||
|
TRANSACTION_ITEM_TAX = 'transaction_item_taxes',
|
||||||
|
TRANSACTION_ITEM_BREAKDOWN_TAX = 't_breakdown_item_taxes',
|
||||||
|
TRANSACTION_DEMOGRAPHY = 'transaction_demographies',
|
||||||
USER = 'users',
|
USER = 'users',
|
||||||
|
USER_LOGIN = 'users_login',
|
||||||
|
LOG_USER_LOGIN = 'log_users_login',
|
||||||
USER_PRIVILEGE = 'user_privileges',
|
USER_PRIVILEGE = 'user_privileges',
|
||||||
USER_PRIVILEGE_CONFIGURATION = 'user_privilege_configurations',
|
USER_PRIVILEGE_CONFIGURATION = 'user_privilege_configurations',
|
||||||
VIP_CATEGORY = 'vip_categories',
|
VIP_CATEGORY = 'vip_categories',
|
||||||
VIP_CODE = 'vip_codes',
|
VIP_CODE = 'vip_codes',
|
||||||
|
|
||||||
|
REPORT_BOOKMARK = 'report_bookmark',
|
||||||
|
EXPORT_REPORT_HISTORY = 'export_report_history',
|
||||||
|
|
||||||
|
QUEUE = 'queues',
|
||||||
|
QUEUE_ORDER = 'queue_orders',
|
||||||
|
QUEUE_TICKET = 'queue_tickets',
|
||||||
|
QUEUE_ITEM = 'queue_items',
|
||||||
|
QUEUE_BUCKET = 'queue_bucket',
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ import { MODULE_NAME } from 'src/core/strings/constants/module.constants';
|
||||||
import { Public } from 'src/core/guards';
|
import { Public } from 'src/core/guards';
|
||||||
|
|
||||||
@ApiTags(`${MODULE_NAME.{{constantCase name}}.split('-').join(' ')} - read`)
|
@ApiTags(`${MODULE_NAME.{{constantCase name}}.split('-').join(' ')} - read`)
|
||||||
@Controller(MODULE_NAME.{{constantCase name}})
|
@Controller(`v1/${MODULE_NAME.{{constantCase name}} }`)
|
||||||
@Public(false)
|
@Public(false)
|
||||||
@ApiBearerAuth('JWT')
|
@ApiBearerAuth('JWT')
|
||||||
export class {{pascalCase name}}ReadController {
|
export class {{pascalCase name}}ReadController {
|
||||||
|
|
|
@ -17,7 +17,7 @@ import { BatchIdsDto } from 'src/core/modules/infrastructure/dto/base-batch.dto'
|
||||||
import { Public } from 'src/core/guards';
|
import { Public } from 'src/core/guards';
|
||||||
|
|
||||||
@ApiTags(`${MODULE_NAME.{{constantCase name}}.split('-').join(' ')} - data`)
|
@ApiTags(`${MODULE_NAME.{{constantCase name}}.split('-').join(' ')} - data`)
|
||||||
@Controller(MODULE_NAME.{{constantCase name}})
|
@Controller(`v1/${MODULE_NAME.{{constantCase name}} }`)
|
||||||
@Public(false)
|
@Public(false)
|
||||||
@ApiBearerAuth('JWT')
|
@ApiBearerAuth('JWT')
|
||||||
export class {{pascalCase name}}DataController {
|
export class {{pascalCase name}}DataController {
|
||||||
|
@ -36,7 +36,7 @@ export class {{pascalCase name}}DataController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Patch(':id/active')
|
@Patch(':id/active')
|
||||||
async active(@Param('id') dataId: string): Promise<String> {
|
async active(@Param('id') dataId: string): Promise<string> {
|
||||||
return await this.orchestrator.active(dataId);
|
return await this.orchestrator.active(dataId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ export class {{pascalCase name}}DataController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Patch(':id/confirm')
|
@Patch(':id/confirm')
|
||||||
async confirm(@Param('id') dataId: string): Promise<String> {
|
async confirm(@Param('id') dataId: string): Promise<string> {
|
||||||
return await this.orchestrator.confirm(dataId);
|
return await this.orchestrator.confirm(dataId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ export class {{pascalCase name}}DataController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Patch(':id/inactive')
|
@Patch(':id/inactive')
|
||||||
async inactive(@Param('id') dataId: string): Promise<String> {
|
async inactive(@Param('id') dataId: string): Promise<string> {
|
||||||
return await this.orchestrator.inactive(dataId);
|
return await this.orchestrator.inactive(dataId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ export class {{pascalCase name}}DataController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Delete(':id')
|
@Delete(':id')
|
||||||
async delete(@Param('id') dataId: string): Promise<String> {
|
async delete(@Param('id') dataId: string): Promise<string> {
|
||||||
return await this.orchestrator.delete(dataId);
|
return await this.orchestrator.delete(dataId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ import {
|
||||||
import { Public } from 'src/core/guards';
|
import { Public } from 'src/core/guards';
|
||||||
|
|
||||||
@ApiTags(`${MODULE_NAME.{{constantCase name}}.split('-').join(' ')} - data`)
|
@ApiTags(`${MODULE_NAME.{{constantCase name}}.split('-').join(' ')} - data`)
|
||||||
@Controller(MODULE_NAME.{{constantCase name}})
|
@Controller(`v1/${MODULE_NAME.{{constantCase name}} }`)
|
||||||
@Public(false)
|
@Public(false)
|
||||||
@ApiBearerAuth('JWT')
|
@ApiBearerAuth('JWT')
|
||||||
export class {{pascalCase name}}DataController {
|
export class {{pascalCase name}}DataController {
|
||||||
|
@ -43,7 +43,7 @@ import {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Delete(':id')
|
@Delete(':id')
|
||||||
async delete(@Param('id') dataId: string): Promise<String> {
|
async delete(@Param('id') dataId: string): Promise<string> {
|
||||||
return await this.orchestrator.delete(dataId);
|
return await this.orchestrator.delete(dataId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ export class {{pascalCase name}}DataOrchestrator extends Base{{pascalCase orches
|
||||||
return this.updateManager.getResult();
|
return this.updateManager.getResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
async delete(dataId): Promise<String> {
|
async delete(dataId): Promise<string> {
|
||||||
this.deleteManager.setData(dataId);
|
this.deleteManager.setData(dataId);
|
||||||
this.deleteManager.setService(this.serviceData, TABLE_NAME.{{constantCase name}});
|
this.deleteManager.setService(this.serviceData, TABLE_NAME.{{constantCase name}});
|
||||||
await this.deleteManager.execute();
|
await this.deleteManager.execute();
|
||||||
|
@ -65,7 +65,7 @@ export class {{pascalCase name}}DataOrchestrator extends Base{{pascalCase orches
|
||||||
return this.batchDeleteManager.getResult();
|
return this.batchDeleteManager.getResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
async active(dataId): Promise<String> {
|
async active(dataId): Promise<string> {
|
||||||
this.activeManager.setData(dataId, STATUS.ACTIVE);
|
this.activeManager.setData(dataId, STATUS.ACTIVE);
|
||||||
this.activeManager.setService(this.serviceData, TABLE_NAME.{{constantCase name}});
|
this.activeManager.setService(this.serviceData, TABLE_NAME.{{constantCase name}});
|
||||||
await this.activeManager.execute();
|
await this.activeManager.execute();
|
||||||
|
@ -82,7 +82,7 @@ export class {{pascalCase name}}DataOrchestrator extends Base{{pascalCase orches
|
||||||
return this.batchActiveManager.getResult();
|
return this.batchActiveManager.getResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
async confirm(dataId): Promise<String> {
|
async confirm(dataId): Promise<string> {
|
||||||
this.confirmManager.setData(dataId, STATUS.ACTIVE);
|
this.confirmManager.setData(dataId, STATUS.ACTIVE);
|
||||||
this.confirmManager.setService(this.serviceData, TABLE_NAME.{{constantCase name}});
|
this.confirmManager.setService(this.serviceData, TABLE_NAME.{{constantCase name}});
|
||||||
await this.confirmManager.execute();
|
await this.confirmManager.execute();
|
||||||
|
@ -99,7 +99,7 @@ export class {{pascalCase name}}DataOrchestrator extends Base{{pascalCase orches
|
||||||
return this.batchConfirmManager.getResult();
|
return this.batchConfirmManager.getResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
async inactive(dataId): Promise<String> {
|
async inactive(dataId): Promise<string> {
|
||||||
this.inactiveManager.setData(dataId, STATUS.INACTIVE);
|
this.inactiveManager.setData(dataId, STATUS.INACTIVE);
|
||||||
this.inactiveManager.setService(
|
this.inactiveManager.setService(
|
||||||
this.serviceData,
|
this.serviceData,
|
||||||
|
|
|
@ -36,7 +36,7 @@ export class {{pascalCase name}}DataOrchestrator extends Base{{pascalCase orches
|
||||||
return this.updateManager.getResult();
|
return this.updateManager.getResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
async delete(dataId): Promise<String> {
|
async delete(dataId): Promise<string> {
|
||||||
this.deleteManager.setData(dataId);
|
this.deleteManager.setData(dataId);
|
||||||
this.deleteManager.setService(this.serviceData, TABLE_NAME.{{constantCase name}});
|
this.deleteManager.setService(this.serviceData, TABLE_NAME.{{constantCase name}});
|
||||||
await this.deleteManager.execute();
|
await this.deleteManager.execute();
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||||
|
|
||||||
|
export class UpdateColumnTax1718675739425 implements MigrationInterface {
|
||||||
|
name = 'UpdateColumnTax1718675739425';
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`ALTER TABLE "taxes" DROP COLUMN "value"`);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "taxes" ADD "value" double precision NOT NULL DEFAULT '0'`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`ALTER TABLE "taxes" DROP COLUMN "value"`);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "taxes" ADD "value" integer NOT NULL DEFAULT '0'`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||||
|
|
||||||
|
export class SeasonPeriod1718699373958 implements MigrationInterface {
|
||||||
|
name = 'SeasonPeriod1718699373958';
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TYPE "public"."season_periods_status_enum" AS ENUM('active', 'cancel', 'confirmed', 'draft', 'expired', 'inactive', 'pending', 'refunded', 'rejected', 'settled', 'waiting')`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TABLE "season_periods" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "creator_id" character varying(36), "creator_name" character varying(125), "editor_id" character varying(36), "editor_name" character varying(125), "created_at" bigint NOT NULL, "updated_at" bigint NOT NULL, "status" "public"."season_periods_status_enum" NOT NULL DEFAULT 'draft', "start_date" date, "end_date" date, "days" text, "holiday_name" character varying, "season_type_id" uuid, CONSTRAINT "PK_8e25cedd8ffb18516de871fb4e0" PRIMARY KEY ("id"))`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "season_periods" ADD CONSTRAINT "FK_4e9e71a640b450d23177c2add46" FOREIGN KEY ("season_type_id") REFERENCES "season_types"("id") ON DELETE CASCADE ON UPDATE CASCADE`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "season_periods" DROP CONSTRAINT "FK_4e9e71a640b450d23177c2add46"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(`DROP TABLE "season_periods"`);
|
||||||
|
await queryRunner.query(`DROP TYPE "public"."season_periods_status_enum"`);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||||
|
|
||||||
|
export class ItemRate1718792479432 implements MigrationInterface {
|
||||||
|
name = 'ItemRate1718792479432';
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TABLE "item_rates" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "item_id" uuid, "season_period_id" uuid, "price" bigint, CONSTRAINT "PK_e3e0cf3b098409533dc20bf1992" PRIMARY KEY ("id"))`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "item_rates" ADD CONSTRAINT "FK_2bff76c50f678bdf0c4f93990fc" FOREIGN KEY ("item_id") REFERENCES "items"("id") ON DELETE CASCADE ON UPDATE CASCADE`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "item_rates" ADD CONSTRAINT "FK_d309461c7e5a7f83ca596203afa" FOREIGN KEY ("season_period_id") REFERENCES "season_periods"("id") ON DELETE CASCADE ON UPDATE CASCADE`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "item_rates" DROP CONSTRAINT "FK_d309461c7e5a7f83ca596203afa"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "item_rates" DROP CONSTRAINT "FK_2bff76c50f678bdf0c4f93990fc"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(`DROP TABLE "item_rates"`);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||||
|
|
||||||
|
export class AddColumnPrioritySeasonPeriod1719227554657
|
||||||
|
implements MigrationInterface
|
||||||
|
{
|
||||||
|
name = 'AddColumnPrioritySeasonPeriod1719227554657';
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "season_periods" ADD "priority" integer NOT NULL DEFAULT '3'`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "season_periods" DROP COLUMN "priority"`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||||
|
|
||||||
|
export class InitTableReport1719298201894 implements MigrationInterface {
|
||||||
|
name = 'InitTableReport1719298201894';
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TABLE "report_bookmark" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "creator_id" character varying(36), "creator_name" character varying(125), "editor_id" character varying(36), "editor_name" character varying(125), "created_at" bigint NOT NULL, "updated_at" bigint NOT NULL, "group_name" character varying NOT NULL, "unique_name" character varying NOT NULL, "label" character varying NOT NULL, "applied" boolean DEFAULT false, "configuration" json, CONSTRAINT "PK_d72aa68a7ee505edf4f3e156946" PRIMARY KEY ("id"))`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TYPE "public"."export_report_history_status_enum" AS ENUM('processing', 'done', 'failed', 'cancel')`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TABLE "export_report_history" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "creator_id" character varying(36), "creator_name" character varying(125), "editor_id" character varying(36), "editor_name" character varying(125), "created_at" bigint NOT NULL, "updated_at" bigint NOT NULL, "group_name" character varying NOT NULL, "unique_name" character varying NOT NULL, "label" character varying NOT NULL, "file_name" character varying NOT NULL, "file_url" character varying, "total_data" integer NOT NULL DEFAULT '0', "processing_data" integer NOT NULL DEFAULT '0', "status" "public"."export_report_history_status_enum", "last_process_offset" integer NOT NULL DEFAULT '0', "last_process_limit" integer NOT NULL DEFAULT '0', "total_resume" integer NOT NULL DEFAULT '0', "last_resume_created_at" bigint, "query_export" character varying, "canceled_at" bigint, CONSTRAINT "PK_07a632c94dca0728ad1b51ed65c" PRIMARY KEY ("id"))`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`DROP TABLE "export_report_history"`);
|
||||||
|
await queryRunner.query(
|
||||||
|
`DROP TYPE "public"."export_report_history_status_enum"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(`DROP TABLE "report_bookmark"`);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||||
|
|
||||||
|
export class Transaction1719572714752 implements MigrationInterface {
|
||||||
|
name = 'Transaction1719572714752';
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TABLE "transaction_items" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "item_id" character varying, "item_name" character varying, "item_type" character varying, "item_price" bigint, "item_tenant_id" character varying, "item_tenant_name" character varying, "item_tenant_share_margin" numeric, "total_price" numeric, "total_hpp" numeric, "total_profit" numeric, "total_share_tenant" numeric, "qty" integer, "transaction_id" uuid, CONSTRAINT "PK_ff5a487ad820dccafd53bebf578" PRIMARY KEY ("id"))`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TABLE "transaction_taxes" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "tax_id" character varying, "tax_name" character varying, "taxt_value" character varying, "transaction_id" uuid, CONSTRAINT "PK_208b2abdb10640e1991972fc754" PRIMARY KEY ("id"))`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TYPE "public"."transactions_status_enum" AS ENUM('active', 'cancel', 'confirmed', 'draft', 'expired', 'inactive', 'pending', 'refunded', 'rejected', 'settled', 'waiting')`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TYPE "public"."transactions_type_enum" AS ENUM('counter', 'admin', 'online')`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TYPE "public"."transactions_customer_type_enum" AS ENUM('group', 'vip')`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TYPE "public"."transactions_payment_type_enum" AS ENUM('midtrans', 'bank transfer', 'qris', 'counter', 'cash', 'credit card', 'debit', 'e-money')`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TABLE "transactions" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "creator_id" character varying(36), "creator_name" character varying(125), "editor_id" character varying(36), "editor_name" character varying(125), "created_at" bigint NOT NULL, "updated_at" bigint NOT NULL, "status" "public"."transactions_status_enum" NOT NULL DEFAULT 'draft', "type" "public"."transactions_type_enum" NOT NULL DEFAULT 'admin', "invoice_code" character varying, "creator_counter_no" integer, "season_period_id" character varying, "season_period_name" character varying, "season_period_type_id" character varying, "season_period_type_name" character varying, "customer_type" "public"."transactions_customer_type_enum", "customer_category_id" character varying, "customer_category_name" character varying, "customer_name" character varying, "customer_phone" character varying, "customer_email" character varying, "customer_description" character varying, "no_of_group" character varying, "booking_date" date, "settlement_date" date, "invoice_date" date, "discount_code_id" character varying, "discount_code" character varying, "discount_percentage" integer, "discount_value" numeric, "payment_type" "public"."transactions_payment_type_enum" NOT NULL DEFAULT 'bank transfer', "payment_type_method_id" character varying, "payment_type_method_name" character varying, "payment_type_method_qr" character varying, "payment_card_information" character varying, "payment_code_reference" character varying, "payment_date" date, "payment_sub_total" numeric, "payment_discount_total" numeric, "payment_total" numeric, "payment_total_pay" numeric, "payment_change" numeric, "payment_total_share" numeric, "payment_total_tax" numeric, "payment_total_profit" numeric, "profit_share_formula" character varying, "sales_price_formula" character varying, CONSTRAINT "PK_a219afd8dd77ed80f5a862f1db9" PRIMARY KEY ("id"))`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transaction_items" ADD CONSTRAINT "FK_5926425896b30c0d681fe879af0" FOREIGN KEY ("transaction_id") REFERENCES "transactions"("id") ON DELETE CASCADE ON UPDATE CASCADE`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transaction_taxes" ADD CONSTRAINT "FK_d21db1756c6656efc7c082fbaa6" FOREIGN KEY ("transaction_id") REFERENCES "transactions"("id") ON DELETE CASCADE ON UPDATE CASCADE`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transaction_taxes" DROP CONSTRAINT "FK_d21db1756c6656efc7c082fbaa6"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transaction_items" DROP CONSTRAINT "FK_5926425896b30c0d681fe879af0"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(`DROP TABLE "transactions"`);
|
||||||
|
await queryRunner.query(
|
||||||
|
`DROP TYPE "public"."transactions_payment_type_enum"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`DROP TYPE "public"."transactions_customer_type_enum"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(`DROP TYPE "public"."transactions_type_enum"`);
|
||||||
|
await queryRunner.query(`DROP TYPE "public"."transactions_status_enum"`);
|
||||||
|
await queryRunner.query(`DROP TABLE "transaction_taxes"`);
|
||||||
|
await queryRunner.query(`DROP TABLE "transaction_items"`);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||||
|
|
||||||
|
export class AddReconciliationToTransaction1719925690145
|
||||||
|
implements MigrationInterface
|
||||||
|
{
|
||||||
|
name = 'AddReconciliationToTransaction1719925690145';
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transactions" ADD "is_recap_transaction" boolean NOT NULL DEFAULT true`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transactions" ADD "payment_type_method_number" character varying`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transactions" ADD "reconciliation_mdr" numeric`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TYPE "public"."transactions_reconciliation_status_enum" AS ENUM('active', 'cancel', 'confirmed', 'draft', 'expired', 'inactive', 'pending', 'refunded', 'rejected', 'settled', 'waiting')`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transactions" ADD "reconciliation_status" "public"."transactions_reconciliation_status_enum" NOT NULL DEFAULT 'draft'`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transactions" ADD "reconciliation_confirm_date" character varying`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transactions" ADD "reconciliation_confirm_by" character varying`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transactions" ADD "payment_total_net_profit" numeric`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transactions" DROP COLUMN "payment_total_net_profit"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transactions" DROP COLUMN "reconciliation_confirm_by"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transactions" DROP COLUMN "reconciliation_confirm_date"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transactions" DROP COLUMN "reconciliation_status"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`DROP TYPE "public"."transactions_reconciliation_status_enum"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transactions" DROP COLUMN "reconciliation_mdr"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transactions" DROP COLUMN "payment_type_method_number"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transactions" DROP COLUMN "is_recap_transaction"`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||||
|
|
||||||
|
export class UpdateTableTransaction1719934464407 implements MigrationInterface {
|
||||||
|
name = 'UpdateTableTransaction1719934464407';
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transaction_items" ADD "item_hpp" bigint`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transaction_items" ADD "item_category_id" character varying`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transaction_items" ADD "item_category_name" character varying`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transaction_items" ADD "item_bundlings" json`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TYPE "public"."transactions_sending_invoice_status_enum" AS ENUM('active', 'cancel', 'confirmed', 'draft', 'expired', 'inactive', 'pending', 'refunded', 'rejected', 'settled', 'waiting')`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transactions" ADD "sending_invoice_status" "public"."transactions_sending_invoice_status_enum"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transactions" ADD "sending_invoice_at" bigint`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TYPE "public"."transactions_sending_qr_status_enum" AS ENUM('active', 'cancel', 'confirmed', 'draft', 'expired', 'inactive', 'pending', 'refunded', 'rejected', 'settled', 'waiting')`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transactions" ADD "sending_qr_status" "public"."transactions_sending_qr_status_enum"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transactions" ADD "sending_qr_at" bigint`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transactions" DROP COLUMN "sending_qr_at"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transactions" DROP COLUMN "sending_qr_status"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`DROP TYPE "public"."transactions_sending_qr_status_enum"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transactions" DROP COLUMN "sending_invoice_at"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transactions" DROP COLUMN "sending_invoice_status"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`DROP TYPE "public"."transactions_sending_invoice_status_enum"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transaction_items" DROP COLUMN "item_bundlings"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transaction_items" DROP COLUMN "item_category_name"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transaction_items" DROP COLUMN "item_category_id"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transaction_items" DROP COLUMN "item_hpp"`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||||
|
|
||||||
|
export class AddColumnTypeReportBookmark1719982860855
|
||||||
|
implements MigrationInterface
|
||||||
|
{
|
||||||
|
name = 'AddColumnTypeReportBookmark1719982860855';
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TYPE "public"."report_bookmark_type_enum" AS ENUM('TABLE_CONFIG', 'FILTER_TABLE')`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "report_bookmark" ADD "type" "public"."report_bookmark_type_enum" NOT NULL DEFAULT 'TABLE_CONFIG'`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`ALTER TABLE "report_bookmark" DROP COLUMN "type"`);
|
||||||
|
await queryRunner.query(`DROP TYPE "public"."report_bookmark_type_enum"`);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||||
|
|
||||||
|
export class UpdateDefaultColumnTransaction1720077765890
|
||||||
|
implements MigrationInterface
|
||||||
|
{
|
||||||
|
name = 'UpdateDefaultColumnTransaction1720077765890';
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transactions" ALTER COLUMN "is_recap_transaction" SET DEFAULT false`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transactions" ALTER COLUMN "is_recap_transaction" SET DEFAULT true`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||||
|
|
||||||
|
export class UpdateTableTransaction1720436852936 implements MigrationInterface {
|
||||||
|
name = 'UpdateTableTransaction1720436852936';
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transaction_taxes" ADD "tax_total_value" numeric`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transaction_taxes" DROP COLUMN "taxt_value"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transaction_taxes" ADD "taxt_value" numeric`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transaction_taxes" DROP COLUMN "taxt_value"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transaction_taxes" ADD "taxt_value" character varying`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transaction_taxes" DROP COLUMN "tax_total_value"`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||||
|
|
||||||
|
export class UpdateTableTransaction1720767689625 implements MigrationInterface {
|
||||||
|
name = 'UpdateTableTransaction1720767689625';
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transaction_items" ADD "qty_remaining" integer`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(`ALTER TABLE "transaction_items" ADD "taxes" json`);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transactions" ADD "payment_total_dpp" numeric`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transactions" DROP COLUMN "payment_total_dpp"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transaction_items" DROP COLUMN "taxes"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transaction_items" DROP COLUMN "qty_remaining"`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||||
|
|
||||||
|
export class Refund1720768975877 implements MigrationInterface {
|
||||||
|
name = 'Refund1720768975877';
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TYPE "public"."refunds_status_enum" AS ENUM('active', 'cancel', 'confirmed', 'draft', 'expired', 'inactive', 'pending', 'refunded', 'rejected', 'settled', 'waiting')`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TYPE "public"."refunds_type_enum" AS ENUM('pengembalian booking', 'pengembalian wahana')`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TABLE "refunds" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "creator_id" character varying(36), "creator_name" character varying(125), "editor_id" character varying(36), "editor_name" character varying(125), "created_at" bigint NOT NULL, "updated_at" bigint NOT NULL, "status" "public"."refunds_status_enum" NOT NULL DEFAULT 'draft', "type" "public"."refunds_type_enum" NOT NULL DEFAULT 'pengembalian booking', "code" character varying, "request_date" date, "refund_date" date, "refund_total" numeric, "bank_name" character varying, "bank_account_name" character varying, "bank_account_number" character varying, "transaction_id" uuid, CONSTRAINT "REL_8bb3b7579f49990d2e77684acd" UNIQUE ("transaction_id"), CONSTRAINT "PK_5106efb01eeda7e49a78b869738" PRIMARY KEY ("id"))`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TABLE "refund_items" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "qty_refund" numeric, "refund_total" numeric, "refund_item_id" uuid, "transaction_item_id" uuid, CONSTRAINT "REL_07b481a163c219f5de8fb1c90b" UNIQUE ("transaction_item_id"), CONSTRAINT "PK_ef892918375a6101948b90f1140" PRIMARY KEY ("id"))`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "refunds" ADD CONSTRAINT "FK_8bb3b7579f49990d2e77684acd4" FOREIGN KEY ("transaction_id") REFERENCES "transactions"("id") ON DELETE CASCADE ON UPDATE CASCADE`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "refund_items" ADD CONSTRAINT "FK_2a4bd60fb8a9c37f902f4f3da67" FOREIGN KEY ("refund_item_id") REFERENCES "refunds"("id") ON DELETE CASCADE ON UPDATE CASCADE`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "refund_items" ADD CONSTRAINT "FK_07b481a163c219f5de8fb1c90b3" FOREIGN KEY ("transaction_item_id") REFERENCES "transaction_items"("id") ON DELETE CASCADE ON UPDATE CASCADE`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "refund_items" DROP CONSTRAINT "FK_07b481a163c219f5de8fb1c90b3"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "refund_items" DROP CONSTRAINT "FK_2a4bd60fb8a9c37f902f4f3da67"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "refunds" DROP CONSTRAINT "FK_8bb3b7579f49990d2e77684acd4"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(`DROP TABLE "refund_items"`);
|
||||||
|
await queryRunner.query(`DROP TABLE "refunds"`);
|
||||||
|
await queryRunner.query(`DROP TYPE "public"."refunds_type_enum"`);
|
||||||
|
await queryRunner.query(`DROP TYPE "public"."refunds_status_enum"`);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,461 @@
|
||||||
|
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||||
|
|
||||||
|
export class UpdateEnumStatus1720774145470 implements MigrationInterface {
|
||||||
|
name = 'UpdateEnumStatus1720774145470';
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TYPE "public"."item_categories_status_enum" RENAME TO "item_categories_status_enum_old"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TYPE "public"."item_categories_status_enum" AS ENUM('active', 'cancel', 'confirmed', 'draft', 'expired', 'inactive', 'partial refund', 'pending', 'proses refund', 'refunded', 'rejected', 'settled', 'waiting')`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "item_categories" ALTER COLUMN "status" DROP DEFAULT`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "item_categories" ALTER COLUMN "status" TYPE "public"."item_categories_status_enum" USING "status"::"text"::"public"."item_categories_status_enum"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "item_categories" ALTER COLUMN "status" SET DEFAULT 'draft'`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`DROP TYPE "public"."item_categories_status_enum_old"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TYPE "public"."season_types_status_enum" RENAME TO "season_types_status_enum_old"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TYPE "public"."season_types_status_enum" AS ENUM('active', 'cancel', 'confirmed', 'draft', 'expired', 'inactive', 'partial refund', 'pending', 'proses refund', 'refunded', 'rejected', 'settled', 'waiting')`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "season_types" ALTER COLUMN "status" DROP DEFAULT`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "season_types" ALTER COLUMN "status" TYPE "public"."season_types_status_enum" USING "status"::"text"::"public"."season_types_status_enum"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "season_types" ALTER COLUMN "status" SET DEFAULT 'draft'`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`DROP TYPE "public"."season_types_status_enum_old"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TYPE "public"."season_periods_status_enum" RENAME TO "season_periods_status_enum_old"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TYPE "public"."season_periods_status_enum" AS ENUM('active', 'cancel', 'confirmed', 'draft', 'expired', 'inactive', 'partial refund', 'pending', 'proses refund', 'refunded', 'rejected', 'settled', 'waiting')`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "season_periods" ALTER COLUMN "status" DROP DEFAULT`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "season_periods" ALTER COLUMN "status" TYPE "public"."season_periods_status_enum" USING "status"::"text"::"public"."season_periods_status_enum"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "season_periods" ALTER COLUMN "status" SET DEFAULT 'draft'`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`DROP TYPE "public"."season_periods_status_enum_old"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TYPE "public"."items_status_enum" RENAME TO "items_status_enum_old"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TYPE "public"."items_status_enum" AS ENUM('active', 'cancel', 'confirmed', 'draft', 'expired', 'inactive', 'partial refund', 'pending', 'proses refund', 'refunded', 'rejected', 'settled', 'waiting')`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "items" ALTER COLUMN "status" DROP DEFAULT`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "items" ALTER COLUMN "status" TYPE "public"."items_status_enum" USING "status"::"text"::"public"."items_status_enum"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "items" ALTER COLUMN "status" SET DEFAULT 'draft'`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(`DROP TYPE "public"."items_status_enum_old"`);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TYPE "public"."users_status_enum" RENAME TO "users_status_enum_old"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TYPE "public"."users_status_enum" AS ENUM('active', 'cancel', 'confirmed', 'draft', 'expired', 'inactive', 'partial refund', 'pending', 'proses refund', 'refunded', 'rejected', 'settled', 'waiting')`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "users" ALTER COLUMN "status" DROP DEFAULT`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "users" ALTER COLUMN "status" TYPE "public"."users_status_enum" USING "status"::"text"::"public"."users_status_enum"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "users" ALTER COLUMN "status" SET DEFAULT 'draft'`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(`DROP TYPE "public"."users_status_enum_old"`);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TYPE "public"."user_privileges_status_enum" RENAME TO "user_privileges_status_enum_old"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TYPE "public"."user_privileges_status_enum" AS ENUM('active', 'cancel', 'confirmed', 'draft', 'expired', 'inactive', 'partial refund', 'pending', 'proses refund', 'refunded', 'rejected', 'settled', 'waiting')`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "user_privileges" ALTER COLUMN "status" DROP DEFAULT`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "user_privileges" ALTER COLUMN "status" TYPE "public"."user_privileges_status_enum" USING "status"::"text"::"public"."user_privileges_status_enum"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "user_privileges" ALTER COLUMN "status" SET DEFAULT 'draft'`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`DROP TYPE "public"."user_privileges_status_enum_old"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TYPE "public"."refunds_status_enum" RENAME TO "refunds_status_enum_old"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TYPE "public"."refunds_status_enum" AS ENUM('active', 'cancel', 'confirmed', 'draft', 'expired', 'inactive', 'partial refund', 'pending', 'proses refund', 'refunded', 'rejected', 'settled', 'waiting')`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "refunds" ALTER COLUMN "status" DROP DEFAULT`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "refunds" ALTER COLUMN "status" TYPE "public"."refunds_status_enum" USING "status"::"text"::"public"."refunds_status_enum"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "refunds" ALTER COLUMN "status" SET DEFAULT 'draft'`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(`DROP TYPE "public"."refunds_status_enum_old"`);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TYPE "public"."transactions_status_enum" RENAME TO "transactions_status_enum_old"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TYPE "public"."transactions_status_enum" AS ENUM('active', 'cancel', 'confirmed', 'draft', 'expired', 'inactive', 'partial refund', 'pending', 'proses refund', 'refunded', 'rejected', 'settled', 'waiting')`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transactions" ALTER COLUMN "status" DROP DEFAULT`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transactions" ALTER COLUMN "status" TYPE "public"."transactions_status_enum" USING "status"::"text"::"public"."transactions_status_enum"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transactions" ALTER COLUMN "status" SET DEFAULT 'draft'`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`DROP TYPE "public"."transactions_status_enum_old"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TYPE "public"."transactions_reconciliation_status_enum" RENAME TO "transactions_reconciliation_status_enum_old"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TYPE "public"."transactions_reconciliation_status_enum" AS ENUM('active', 'cancel', 'confirmed', 'draft', 'expired', 'inactive', 'partial refund', 'pending', 'proses refund', 'refunded', 'rejected', 'settled', 'waiting')`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transactions" ALTER COLUMN "reconciliation_status" DROP DEFAULT`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transactions" ALTER COLUMN "reconciliation_status" TYPE "public"."transactions_reconciliation_status_enum" USING "reconciliation_status"::"text"::"public"."transactions_reconciliation_status_enum"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transactions" ALTER COLUMN "reconciliation_status" SET DEFAULT 'draft'`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`DROP TYPE "public"."transactions_reconciliation_status_enum_old"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TYPE "public"."transactions_sending_invoice_status_enum" RENAME TO "transactions_sending_invoice_status_enum_old"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TYPE "public"."transactions_sending_invoice_status_enum" AS ENUM('active', 'cancel', 'confirmed', 'draft', 'expired', 'inactive', 'partial refund', 'pending', 'proses refund', 'refunded', 'rejected', 'settled', 'waiting')`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transactions" ALTER COLUMN "sending_invoice_status" TYPE "public"."transactions_sending_invoice_status_enum" USING "sending_invoice_status"::"text"::"public"."transactions_sending_invoice_status_enum"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`DROP TYPE "public"."transactions_sending_invoice_status_enum_old"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TYPE "public"."transactions_sending_qr_status_enum" RENAME TO "transactions_sending_qr_status_enum_old"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TYPE "public"."transactions_sending_qr_status_enum" AS ENUM('active', 'cancel', 'confirmed', 'draft', 'expired', 'inactive', 'partial refund', 'pending', 'proses refund', 'refunded', 'rejected', 'settled', 'waiting')`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transactions" ALTER COLUMN "sending_qr_status" TYPE "public"."transactions_sending_qr_status_enum" USING "sending_qr_status"::"text"::"public"."transactions_sending_qr_status_enum"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`DROP TYPE "public"."transactions_sending_qr_status_enum_old"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TYPE "public"."vip_categories_status_enum" RENAME TO "vip_categories_status_enum_old"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TYPE "public"."vip_categories_status_enum" AS ENUM('active', 'cancel', 'confirmed', 'draft', 'expired', 'inactive', 'partial refund', 'pending', 'proses refund', 'refunded', 'rejected', 'settled', 'waiting')`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "vip_categories" ALTER COLUMN "status" DROP DEFAULT`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "vip_categories" ALTER COLUMN "status" TYPE "public"."vip_categories_status_enum" USING "status"::"text"::"public"."vip_categories_status_enum"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "vip_categories" ALTER COLUMN "status" SET DEFAULT 'draft'`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`DROP TYPE "public"."vip_categories_status_enum_old"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TYPE "public"."taxes_status_enum" RENAME TO "taxes_status_enum_old"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TYPE "public"."taxes_status_enum" AS ENUM('active', 'cancel', 'confirmed', 'draft', 'expired', 'inactive', 'partial refund', 'pending', 'proses refund', 'refunded', 'rejected', 'settled', 'waiting')`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "taxes" ALTER COLUMN "status" DROP DEFAULT`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "taxes" ALTER COLUMN "status" TYPE "public"."taxes_status_enum" USING "status"::"text"::"public"."taxes_status_enum"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "taxes" ALTER COLUMN "status" SET DEFAULT 'draft'`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(`DROP TYPE "public"."taxes_status_enum_old"`);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TYPE "public"."payment_methods_status_enum" RENAME TO "payment_methods_status_enum_old"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TYPE "public"."payment_methods_status_enum" AS ENUM('active', 'cancel', 'confirmed', 'draft', 'expired', 'inactive', 'partial refund', 'pending', 'proses refund', 'refunded', 'rejected', 'settled', 'waiting')`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "payment_methods" ALTER COLUMN "status" DROP DEFAULT`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "payment_methods" ALTER COLUMN "status" TYPE "public"."payment_methods_status_enum" USING "status"::"text"::"public"."payment_methods_status_enum"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "payment_methods" ALTER COLUMN "status" SET DEFAULT 'draft'`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`DROP TYPE "public"."payment_methods_status_enum_old"`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TYPE "public"."payment_methods_status_enum_old" AS ENUM('active', 'cancel', 'confirmed', 'draft', 'expired', 'inactive', 'pending', 'refunded', 'rejected', 'settled', 'waiting')`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "payment_methods" ALTER COLUMN "status" DROP DEFAULT`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "payment_methods" ALTER COLUMN "status" TYPE "public"."payment_methods_status_enum_old" USING "status"::"text"::"public"."payment_methods_status_enum_old"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "payment_methods" ALTER COLUMN "status" SET DEFAULT 'draft'`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(`DROP TYPE "public"."payment_methods_status_enum"`);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TYPE "public"."payment_methods_status_enum_old" RENAME TO "payment_methods_status_enum"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TYPE "public"."taxes_status_enum_old" AS ENUM('active', 'cancel', 'confirmed', 'draft', 'expired', 'inactive', 'pending', 'refunded', 'rejected', 'settled', 'waiting')`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "taxes" ALTER COLUMN "status" DROP DEFAULT`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "taxes" ALTER COLUMN "status" TYPE "public"."taxes_status_enum_old" USING "status"::"text"::"public"."taxes_status_enum_old"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "taxes" ALTER COLUMN "status" SET DEFAULT 'draft'`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(`DROP TYPE "public"."taxes_status_enum"`);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TYPE "public"."taxes_status_enum_old" RENAME TO "taxes_status_enum"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TYPE "public"."vip_categories_status_enum_old" AS ENUM('active', 'cancel', 'confirmed', 'draft', 'expired', 'inactive', 'pending', 'refunded', 'rejected', 'settled', 'waiting')`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "vip_categories" ALTER COLUMN "status" DROP DEFAULT`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "vip_categories" ALTER COLUMN "status" TYPE "public"."vip_categories_status_enum_old" USING "status"::"text"::"public"."vip_categories_status_enum_old"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "vip_categories" ALTER COLUMN "status" SET DEFAULT 'draft'`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(`DROP TYPE "public"."vip_categories_status_enum"`);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TYPE "public"."vip_categories_status_enum_old" RENAME TO "vip_categories_status_enum"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TYPE "public"."transactions_sending_qr_status_enum_old" AS ENUM('active', 'cancel', 'confirmed', 'draft', 'expired', 'inactive', 'pending', 'refunded', 'rejected', 'settled', 'waiting')`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transactions" ALTER COLUMN "sending_qr_status" TYPE "public"."transactions_sending_qr_status_enum_old" USING "sending_qr_status"::"text"::"public"."transactions_sending_qr_status_enum_old"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`DROP TYPE "public"."transactions_sending_qr_status_enum"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TYPE "public"."transactions_sending_qr_status_enum_old" RENAME TO "transactions_sending_qr_status_enum"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TYPE "public"."transactions_sending_invoice_status_enum_old" AS ENUM('active', 'cancel', 'confirmed', 'draft', 'expired', 'inactive', 'pending', 'refunded', 'rejected', 'settled', 'waiting')`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transactions" ALTER COLUMN "sending_invoice_status" TYPE "public"."transactions_sending_invoice_status_enum_old" USING "sending_invoice_status"::"text"::"public"."transactions_sending_invoice_status_enum_old"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`DROP TYPE "public"."transactions_sending_invoice_status_enum"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TYPE "public"."transactions_sending_invoice_status_enum_old" RENAME TO "transactions_sending_invoice_status_enum"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TYPE "public"."transactions_reconciliation_status_enum_old" AS ENUM('active', 'cancel', 'confirmed', 'draft', 'expired', 'inactive', 'pending', 'refunded', 'rejected', 'settled', 'waiting')`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transactions" ALTER COLUMN "reconciliation_status" DROP DEFAULT`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transactions" ALTER COLUMN "reconciliation_status" TYPE "public"."transactions_reconciliation_status_enum_old" USING "reconciliation_status"::"text"::"public"."transactions_reconciliation_status_enum_old"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transactions" ALTER COLUMN "reconciliation_status" SET DEFAULT 'draft'`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`DROP TYPE "public"."transactions_reconciliation_status_enum"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TYPE "public"."transactions_reconciliation_status_enum_old" RENAME TO "transactions_reconciliation_status_enum"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TYPE "public"."transactions_status_enum_old" AS ENUM('active', 'cancel', 'confirmed', 'draft', 'expired', 'inactive', 'pending', 'refunded', 'rejected', 'settled', 'waiting')`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transactions" ALTER COLUMN "status" DROP DEFAULT`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transactions" ALTER COLUMN "status" TYPE "public"."transactions_status_enum_old" USING "status"::"text"::"public"."transactions_status_enum_old"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "transactions" ALTER COLUMN "status" SET DEFAULT 'draft'`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(`DROP TYPE "public"."transactions_status_enum"`);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TYPE "public"."transactions_status_enum_old" RENAME TO "transactions_status_enum"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TYPE "public"."refunds_status_enum_old" AS ENUM('active', 'cancel', 'confirmed', 'draft', 'expired', 'inactive', 'pending', 'refunded', 'rejected', 'settled', 'waiting')`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "refunds" ALTER COLUMN "status" DROP DEFAULT`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "refunds" ALTER COLUMN "status" TYPE "public"."refunds_status_enum_old" USING "status"::"text"::"public"."refunds_status_enum_old"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "refunds" ALTER COLUMN "status" SET DEFAULT 'draft'`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(`DROP TYPE "public"."refunds_status_enum"`);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TYPE "public"."refunds_status_enum_old" RENAME TO "refunds_status_enum"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TYPE "public"."user_privileges_status_enum_old" AS ENUM('active', 'cancel', 'confirmed', 'draft', 'expired', 'inactive', 'pending', 'refunded', 'rejected', 'settled', 'waiting')`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "user_privileges" ALTER COLUMN "status" DROP DEFAULT`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "user_privileges" ALTER COLUMN "status" TYPE "public"."user_privileges_status_enum_old" USING "status"::"text"::"public"."user_privileges_status_enum_old"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "user_privileges" ALTER COLUMN "status" SET DEFAULT 'draft'`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(`DROP TYPE "public"."user_privileges_status_enum"`);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TYPE "public"."user_privileges_status_enum_old" RENAME TO "user_privileges_status_enum"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TYPE "public"."users_status_enum_old" AS ENUM('active', 'cancel', 'confirmed', 'draft', 'expired', 'inactive', 'pending', 'refunded', 'rejected', 'settled', 'waiting')`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "users" ALTER COLUMN "status" DROP DEFAULT`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "users" ALTER COLUMN "status" TYPE "public"."users_status_enum_old" USING "status"::"text"::"public"."users_status_enum_old"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "users" ALTER COLUMN "status" SET DEFAULT 'draft'`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(`DROP TYPE "public"."users_status_enum"`);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TYPE "public"."users_status_enum_old" RENAME TO "users_status_enum"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TYPE "public"."items_status_enum_old" AS ENUM('active', 'cancel', 'confirmed', 'draft', 'expired', 'inactive', 'pending', 'refunded', 'rejected', 'settled', 'waiting')`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "items" ALTER COLUMN "status" DROP DEFAULT`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "items" ALTER COLUMN "status" TYPE "public"."items_status_enum_old" USING "status"::"text"::"public"."items_status_enum_old"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "items" ALTER COLUMN "status" SET DEFAULT 'draft'`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(`DROP TYPE "public"."items_status_enum"`);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TYPE "public"."items_status_enum_old" RENAME TO "items_status_enum"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TYPE "public"."season_periods_status_enum_old" AS ENUM('active', 'cancel', 'confirmed', 'draft', 'expired', 'inactive', 'pending', 'refunded', 'rejected', 'settled', 'waiting')`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "season_periods" ALTER COLUMN "status" DROP DEFAULT`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "season_periods" ALTER COLUMN "status" TYPE "public"."season_periods_status_enum_old" USING "status"::"text"::"public"."season_periods_status_enum_old"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "season_periods" ALTER COLUMN "status" SET DEFAULT 'draft'`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(`DROP TYPE "public"."season_periods_status_enum"`);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TYPE "public"."season_periods_status_enum_old" RENAME TO "season_periods_status_enum"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TYPE "public"."season_types_status_enum_old" AS ENUM('active', 'cancel', 'confirmed', 'draft', 'expired', 'inactive', 'pending', 'refunded', 'rejected', 'settled', 'waiting')`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "season_types" ALTER COLUMN "status" DROP DEFAULT`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "season_types" ALTER COLUMN "status" TYPE "public"."season_types_status_enum_old" USING "status"::"text"::"public"."season_types_status_enum_old"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "season_types" ALTER COLUMN "status" SET DEFAULT 'draft'`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(`DROP TYPE "public"."season_types_status_enum"`);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TYPE "public"."season_types_status_enum_old" RENAME TO "season_types_status_enum"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TYPE "public"."item_categories_status_enum_old" AS ENUM('active', 'cancel', 'confirmed', 'draft', 'expired', 'inactive', 'pending', 'refunded', 'rejected', 'settled', 'waiting')`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "item_categories" ALTER COLUMN "status" DROP DEFAULT`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "item_categories" ALTER COLUMN "status" TYPE "public"."item_categories_status_enum_old" USING "status"::"text"::"public"."item_categories_status_enum_old"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "item_categories" ALTER COLUMN "status" SET DEFAULT 'draft'`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(`DROP TYPE "public"."item_categories_status_enum"`);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TYPE "public"."item_categories_status_enum_old" RENAME TO "item_categories_status_enum"`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||||
|
|
||||||
|
export class Gate1721024987609 implements MigrationInterface {
|
||||||
|
name = 'Gate1721024987609';
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TYPE "public"."gates_status_enum" AS ENUM('active', 'cancel', 'confirmed', 'draft', 'expired', 'inactive', 'partial refund', 'pending', 'proses refund', 'refunded', 'rejected', 'settled', 'waiting')`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TYPE "public"."gates_type_enum" AS ENUM('gate masuk', 'gate keluar')`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TABLE "gates" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "creator_id" character varying(36), "creator_name" character varying(125), "editor_id" character varying(36), "editor_name" character varying(125), "created_at" bigint NOT NULL, "updated_at" bigint NOT NULL, "status" "public"."gates_status_enum" NOT NULL DEFAULT 'draft', "type" "public"."gates_type_enum" NOT NULL DEFAULT 'gate masuk', "code" character varying, "note" text, "item_id" uuid, CONSTRAINT "PK_2dd58a77462dd2c5695ec4a7975" PRIMARY KEY ("id"))`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "gates" ADD CONSTRAINT "FK_29f020cd153bb079722bcbee830" FOREIGN KEY ("item_id") REFERENCES "items"("id") ON DELETE CASCADE ON UPDATE CASCADE`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "gates" DROP CONSTRAINT "FK_29f020cd153bb079722bcbee830"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(`DROP TABLE "gates"`);
|
||||||
|
await queryRunner.query(`DROP TYPE "public"."gates_type_enum"`);
|
||||||
|
await queryRunner.query(`DROP TYPE "public"."gates_status_enum"`);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||||
|
|
||||||
|
export class TermCondition1721029248635 implements MigrationInterface {
|
||||||
|
name = 'TermCondition1721029248635';
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TYPE "public"."term_conditions_status_enum" AS ENUM('active', 'cancel', 'confirmed', 'draft', 'expired', 'inactive', 'partial refund', 'pending', 'proses refund', 'refunded', 'rejected', 'settled', 'waiting')`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TABLE "term_conditions" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "creator_id" character varying(36), "creator_name" character varying(125), "editor_id" character varying(36), "editor_name" character varying(125), "created_at" bigint NOT NULL, "updated_at" bigint NOT NULL, "status" "public"."term_conditions_status_enum" NOT NULL DEFAULT 'draft', "title" character varying, "description" text, CONSTRAINT "PK_fc92769e487820f24ed68337feb" PRIMARY KEY ("id"))`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`DROP TABLE "term_conditions"`);
|
||||||
|
await queryRunner.query(`DROP TYPE "public"."term_conditions_status_enum"`);
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue