diff --git a/package-lock.json b/package-lock.json
index 46fbd6b13..baaa3b95a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "bigcapital-client",
- "version": "1.2.0",
+ "version": "1.5.8",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -1043,6 +1043,28 @@
"to-fast-properties": "^2.0.0"
}
},
+ "@blueprintjs-formik/core": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/@blueprintjs-formik/core/-/core-0.1.5.tgz",
+ "integrity": "sha512-H0aXiNMYC8RwhWR1F2O77dcRcRITijUX5we51G4AK2Vmp1yXCmNb0piN9ftsjL5vVIvIsMKWg+dfbwREmB5VWg==",
+ "requires": {
+ "lodash.get": "^4.4.2",
+ "lodash.keyby": "^4.6.0",
+ "styled-components": "^5.3.3",
+ "web-vitals": "^2.1.4"
+ }
+ },
+ "@blueprintjs-formik/select": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/@blueprintjs-formik/select/-/select-0.1.4.tgz",
+ "integrity": "sha512-eL9UruaKiGKxRBPDUf2VZ/s+U9efX1lsEqXEldTfXVDfjhrFCn1U7wsfyE5NdX2ccjk/z4jcjNauM0LCynJR1g==",
+ "requires": {
+ "lodash.get": "^4.4.2",
+ "lodash.keyby": "^4.6.0",
+ "styled-components": "^5.3.3",
+ "web-vitals": "^2.1.4"
+ }
+ },
"@blueprintjs/colors": {
"version": "4.0.0-alpha.0",
"resolved": "https://registry.npmjs.org/@blueprintjs/colors/-/colors-4.0.0-alpha.0.tgz",
@@ -6475,6 +6497,11 @@
}
}
},
+ "filter-obj": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz",
+ "integrity": "sha1-mzERErxsYSehbgFsbF1/GeCAXFs="
+ },
"finalhandler": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
@@ -9402,6 +9429,16 @@
"resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz",
"integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0="
},
+ "lodash.get": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
+ "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk="
+ },
+ "lodash.keyby": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/lodash.keyby/-/lodash.keyby-4.6.0.tgz",
+ "integrity": "sha1-f2oavak/0k4icopNNh7YvLpaQ1Q="
+ },
"lodash.memoize": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
@@ -12263,6 +12300,17 @@
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
"integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
},
+ "query-string": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/query-string/-/query-string-7.1.1.tgz",
+ "integrity": "sha512-MplouLRDHBZSG9z7fpuAAcI7aAYjDLhtsiVZsevsfaHWDS2IDdORKbSd1kWUA+V4zyva/HZoSfpwnYMMQDhb0w==",
+ "requires": {
+ "decode-uri-component": "^0.2.0",
+ "filter-obj": "^1.1.0",
+ "split-on-first": "^1.0.0",
+ "strict-uri-encode": "^2.0.0"
+ }
+ },
"querystring": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
@@ -12875,9 +12923,9 @@
"integrity": "sha512-hfPF13zDLxPMpLKzIKCE8RZud9T/XrRTsaCIf8zXpWZIZ2juCl7qrGpo3AQw9eAetXV5DP7s2GDm+hht7qq5Dw=="
},
"react-table-sticky": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/react-table-sticky/-/react-table-sticky-1.1.2.tgz",
- "integrity": "sha512-XnVB4Yf6r8L10YC0Ccu2GrY57IxVWofy19m7s8+q5xzZOudYvyADXsBj6+EenHOvBWTYSviLe8RfaLFIp1lC9w=="
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/react-table-sticky/-/react-table-sticky-1.1.3.tgz",
+ "integrity": "sha512-9hyjbveY1aDyo9wkyMOsmKIpQdFUaw2yG6/f8c5SPE4pOTuKm7L2zLnDa+AxpG+3315USulViaO4XSOkX1KdVA=="
},
"react-transition-group": {
"version": "4.4.1",
@@ -14398,6 +14446,11 @@
"wbuf": "^1.7.3"
}
},
+ "split-on-first": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz",
+ "integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw=="
+ },
"split-string": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
@@ -14629,6 +14682,11 @@
"resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz",
"integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ=="
},
+ "strict-uri-encode": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz",
+ "integrity": "sha1-ucczDHBChi9rFC3CdLvMWGbONUY="
+ },
"string-length": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/string-length/-/string-length-2.0.0.tgz",
@@ -16340,6 +16398,11 @@
"minimalistic-assert": "^1.0.0"
}
},
+ "web-vitals": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-2.1.4.tgz",
+ "integrity": "sha512-sVWcwhU5mX6crfI5Vd2dC4qchyTqxV8URinzt25XqVh+bHEPGH4C3NPrNionCP7Obx59wrYEbNlw4Z8sjALzZg=="
+ },
"webidl-conversions": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
diff --git a/package.json b/package.json
index 76def75d8..d4a827375 100644
--- a/package.json
+++ b/package.json
@@ -4,6 +4,8 @@
"private": true,
"dependencies": {
"@babel/core": "7.8.4",
+ "@blueprintjs-formik/core": "^0.2.1",
+ "@blueprintjs-formik/select": "^0.1.4",
"@blueprintjs/core": "^3.50.2",
"@blueprintjs/datetime": "^3.23.12",
"@blueprintjs/popover2": "^0.11.1",
diff --git a/public/icons/flags/AD.svg b/public/icons/flags/AD.svg
new file mode 100644
index 000000000..4855f9fb1
--- /dev/null
+++ b/public/icons/flags/AD.svg
@@ -0,0 +1,35 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/AED.svg b/public/icons/flags/AED.svg
new file mode 100644
index 000000000..3095fe319
--- /dev/null
+++ b/public/icons/flags/AED.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/AFN.svg b/public/icons/flags/AFN.svg
new file mode 100644
index 000000000..75216b744
--- /dev/null
+++ b/public/icons/flags/AFN.svg
@@ -0,0 +1,34 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/AG.svg b/public/icons/flags/AG.svg
new file mode 100644
index 000000000..ac56b808e
--- /dev/null
+++ b/public/icons/flags/AG.svg
@@ -0,0 +1,44 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/AI.svg b/public/icons/flags/AI.svg
new file mode 100644
index 000000000..7f53e4649
--- /dev/null
+++ b/public/icons/flags/AI.svg
@@ -0,0 +1,50 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/AL.svg b/public/icons/flags/AL.svg
new file mode 100644
index 000000000..43ff1a3b3
--- /dev/null
+++ b/public/icons/flags/AL.svg
@@ -0,0 +1,27 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/AMD.svg b/public/icons/flags/AMD.svg
new file mode 100644
index 000000000..5224d30f7
--- /dev/null
+++ b/public/icons/flags/AMD.svg
@@ -0,0 +1,32 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/AO.svg b/public/icons/flags/AO.svg
new file mode 100644
index 000000000..86044f3b3
--- /dev/null
+++ b/public/icons/flags/AO.svg
@@ -0,0 +1,37 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/AR.svg b/public/icons/flags/AR.svg
new file mode 100644
index 000000000..4dbc96f1f
--- /dev/null
+++ b/public/icons/flags/AR.svg
@@ -0,0 +1,26 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/AS.svg b/public/icons/flags/AS.svg
new file mode 100644
index 000000000..afb37540f
--- /dev/null
+++ b/public/icons/flags/AS.svg
@@ -0,0 +1,36 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/AT.svg b/public/icons/flags/AT.svg
new file mode 100644
index 000000000..627245e3b
--- /dev/null
+++ b/public/icons/flags/AT.svg
@@ -0,0 +1,24 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/AU.svg b/public/icons/flags/AU.svg
new file mode 100644
index 000000000..aad6b1e6b
--- /dev/null
+++ b/public/icons/flags/AU.svg
@@ -0,0 +1,36 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/AW.svg b/public/icons/flags/AW.svg
new file mode 100644
index 000000000..892d8aa0e
--- /dev/null
+++ b/public/icons/flags/AW.svg
@@ -0,0 +1,30 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/AX.svg b/public/icons/flags/AX.svg
new file mode 100644
index 000000000..577cd2683
--- /dev/null
+++ b/public/icons/flags/AX.svg
@@ -0,0 +1,32 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/AZ.svg b/public/icons/flags/AZ.svg
new file mode 100644
index 000000000..3f082f336
--- /dev/null
+++ b/public/icons/flags/AZ.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/BA.svg b/public/icons/flags/BA.svg
new file mode 100644
index 000000000..a16324e1f
--- /dev/null
+++ b/public/icons/flags/BA.svg
@@ -0,0 +1,32 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/BB.svg b/public/icons/flags/BB.svg
new file mode 100644
index 000000000..5c89e132d
--- /dev/null
+++ b/public/icons/flags/BB.svg
@@ -0,0 +1,38 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/BD.svg b/public/icons/flags/BD.svg
new file mode 100644
index 000000000..e1a3cd311
--- /dev/null
+++ b/public/icons/flags/BD.svg
@@ -0,0 +1,27 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/BE.svg b/public/icons/flags/BE.svg
new file mode 100644
index 000000000..ac00173d2
--- /dev/null
+++ b/public/icons/flags/BE.svg
@@ -0,0 +1,32 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/BF.svg b/public/icons/flags/BF.svg
new file mode 100644
index 000000000..5b4286bb5
--- /dev/null
+++ b/public/icons/flags/BF.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/BG.svg b/public/icons/flags/BG.svg
new file mode 100644
index 000000000..e8256f476
--- /dev/null
+++ b/public/icons/flags/BG.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/BH.svg b/public/icons/flags/BH.svg
new file mode 100644
index 000000000..e1c110938
--- /dev/null
+++ b/public/icons/flags/BH.svg
@@ -0,0 +1,23 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/BI.svg b/public/icons/flags/BI.svg
new file mode 100644
index 000000000..2f208253b
--- /dev/null
+++ b/public/icons/flags/BI.svg
@@ -0,0 +1,36 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/BJ.svg b/public/icons/flags/BJ.svg
new file mode 100644
index 000000000..b21c46e03
--- /dev/null
+++ b/public/icons/flags/BJ.svg
@@ -0,0 +1,32 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/BL.svg b/public/icons/flags/BL.svg
new file mode 100644
index 000000000..b99bc2c79
--- /dev/null
+++ b/public/icons/flags/BL.svg
@@ -0,0 +1,42 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/BM.svg b/public/icons/flags/BM.svg
new file mode 100644
index 000000000..798dd8b96
--- /dev/null
+++ b/public/icons/flags/BM.svg
@@ -0,0 +1,49 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/BN.svg b/public/icons/flags/BN.svg
new file mode 100644
index 000000000..1fe9afc48
--- /dev/null
+++ b/public/icons/flags/BN.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/BO.svg b/public/icons/flags/BO.svg
new file mode 100644
index 000000000..7ee247bdb
--- /dev/null
+++ b/public/icons/flags/BO.svg
@@ -0,0 +1,32 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/BR.svg b/public/icons/flags/BR.svg
new file mode 100644
index 000000000..17edb1033
--- /dev/null
+++ b/public/icons/flags/BR.svg
@@ -0,0 +1,35 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/BS.svg b/public/icons/flags/BS.svg
new file mode 100644
index 000000000..767423af6
--- /dev/null
+++ b/public/icons/flags/BS.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/BT.svg b/public/icons/flags/BT.svg
new file mode 100644
index 000000000..d2f749bdb
--- /dev/null
+++ b/public/icons/flags/BT.svg
@@ -0,0 +1,27 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/BV.svg b/public/icons/flags/BV.svg
new file mode 100644
index 000000000..00a47ee5a
--- /dev/null
+++ b/public/icons/flags/BV.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/BW.svg b/public/icons/flags/BW.svg
new file mode 100644
index 000000000..ccac652ba
--- /dev/null
+++ b/public/icons/flags/BW.svg
@@ -0,0 +1,29 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/BY.svg b/public/icons/flags/BY.svg
new file mode 100644
index 000000000..d584988d9
--- /dev/null
+++ b/public/icons/flags/BY.svg
@@ -0,0 +1,30 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/BZ.svg b/public/icons/flags/BZ.svg
new file mode 100644
index 000000000..8758df239
--- /dev/null
+++ b/public/icons/flags/BZ.svg
@@ -0,0 +1,30 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/CA.svg b/public/icons/flags/CA.svg
new file mode 100644
index 000000000..786b609b4
--- /dev/null
+++ b/public/icons/flags/CA.svg
@@ -0,0 +1,25 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/CC.svg b/public/icons/flags/CC.svg
new file mode 100644
index 000000000..b96f3016b
--- /dev/null
+++ b/public/icons/flags/CC.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/CD.svg b/public/icons/flags/CD.svg
new file mode 100644
index 000000000..0d351c308
--- /dev/null
+++ b/public/icons/flags/CD.svg
@@ -0,0 +1,31 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/CF.svg b/public/icons/flags/CF.svg
new file mode 100644
index 000000000..68566a2ee
--- /dev/null
+++ b/public/icons/flags/CF.svg
@@ -0,0 +1,43 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/CG.svg b/public/icons/flags/CG.svg
new file mode 100644
index 000000000..bc4eb95bc
--- /dev/null
+++ b/public/icons/flags/CG.svg
@@ -0,0 +1,34 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/CH.svg b/public/icons/flags/CH.svg
new file mode 100644
index 000000000..772f4fa33
--- /dev/null
+++ b/public/icons/flags/CH.svg
@@ -0,0 +1,23 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/CI.svg b/public/icons/flags/CI.svg
new file mode 100644
index 000000000..096d98ab9
--- /dev/null
+++ b/public/icons/flags/CI.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/CK.svg b/public/icons/flags/CK.svg
new file mode 100644
index 000000000..c1ea37345
--- /dev/null
+++ b/public/icons/flags/CK.svg
@@ -0,0 +1,31 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/CL.svg b/public/icons/flags/CL.svg
new file mode 100644
index 000000000..d456d9518
--- /dev/null
+++ b/public/icons/flags/CL.svg
@@ -0,0 +1,29 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/CM.svg b/public/icons/flags/CM.svg
new file mode 100644
index 000000000..482f4a97f
--- /dev/null
+++ b/public/icons/flags/CM.svg
@@ -0,0 +1,38 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/CN.svg b/public/icons/flags/CN.svg
new file mode 100644
index 000000000..883ba157f
--- /dev/null
+++ b/public/icons/flags/CN.svg
@@ -0,0 +1,32 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/CO.svg b/public/icons/flags/CO.svg
new file mode 100644
index 000000000..be492e3df
--- /dev/null
+++ b/public/icons/flags/CO.svg
@@ -0,0 +1,32 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/CR.svg b/public/icons/flags/CR.svg
new file mode 100644
index 000000000..271204ebd
--- /dev/null
+++ b/public/icons/flags/CR.svg
@@ -0,0 +1,29 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/CU.svg b/public/icons/flags/CU.svg
new file mode 100644
index 000000000..23750cd96
--- /dev/null
+++ b/public/icons/flags/CU.svg
@@ -0,0 +1,32 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/CV.svg b/public/icons/flags/CV.svg
new file mode 100644
index 000000000..4b6152fbe
--- /dev/null
+++ b/public/icons/flags/CV.svg
@@ -0,0 +1,30 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/CW.svg b/public/icons/flags/CW.svg
new file mode 100644
index 000000000..14acd27f8
--- /dev/null
+++ b/public/icons/flags/CW.svg
@@ -0,0 +1,29 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/CX.svg b/public/icons/flags/CX.svg
new file mode 100644
index 000000000..b3fe73d93
--- /dev/null
+++ b/public/icons/flags/CX.svg
@@ -0,0 +1,38 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/CY.svg b/public/icons/flags/CY.svg
new file mode 100644
index 000000000..b7860aa93
--- /dev/null
+++ b/public/icons/flags/CY.svg
@@ -0,0 +1,24 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/CZ.svg b/public/icons/flags/CZ.svg
new file mode 100644
index 000000000..d56c61b81
--- /dev/null
+++ b/public/icons/flags/CZ.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/DE.svg b/public/icons/flags/DE.svg
new file mode 100644
index 000000000..4ff1ebd53
--- /dev/null
+++ b/public/icons/flags/DE.svg
@@ -0,0 +1,32 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/DJ.svg b/public/icons/flags/DJ.svg
new file mode 100644
index 000000000..c0a019f9d
--- /dev/null
+++ b/public/icons/flags/DJ.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/DK.svg b/public/icons/flags/DK.svg
new file mode 100644
index 000000000..27900e157
--- /dev/null
+++ b/public/icons/flags/DK.svg
@@ -0,0 +1,23 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/DM.svg b/public/icons/flags/DM.svg
new file mode 100644
index 000000000..d5c401ebc
--- /dev/null
+++ b/public/icons/flags/DM.svg
@@ -0,0 +1,41 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/DO.svg b/public/icons/flags/DO.svg
new file mode 100644
index 000000000..9188e0beb
--- /dev/null
+++ b/public/icons/flags/DO.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/DZ.svg b/public/icons/flags/DZ.svg
new file mode 100644
index 000000000..0920d7121
--- /dev/null
+++ b/public/icons/flags/DZ.svg
@@ -0,0 +1,29 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/EC.svg b/public/icons/flags/EC.svg
new file mode 100644
index 000000000..0fbd3ea61
--- /dev/null
+++ b/public/icons/flags/EC.svg
@@ -0,0 +1,39 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/EE.svg b/public/icons/flags/EE.svg
new file mode 100644
index 000000000..636052239
--- /dev/null
+++ b/public/icons/flags/EE.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/EGP.svg b/public/icons/flags/EGP.svg
new file mode 100644
index 000000000..32d4447e4
--- /dev/null
+++ b/public/icons/flags/EGP.svg
@@ -0,0 +1,30 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/ER.svg b/public/icons/flags/ER.svg
new file mode 100644
index 000000000..bb70368b7
--- /dev/null
+++ b/public/icons/flags/ER.svg
@@ -0,0 +1,40 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/ES.svg b/public/icons/flags/ES.svg
new file mode 100644
index 000000000..883554f89
--- /dev/null
+++ b/public/icons/flags/ES.svg
@@ -0,0 +1,34 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/ET.svg b/public/icons/flags/ET.svg
new file mode 100644
index 000000000..c4387b9fe
--- /dev/null
+++ b/public/icons/flags/ET.svg
@@ -0,0 +1,42 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/EUR.svg b/public/icons/flags/EUR.svg
new file mode 100644
index 000000000..db74ffaf9
--- /dev/null
+++ b/public/icons/flags/EUR.svg
@@ -0,0 +1,27 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/FI.svg b/public/icons/flags/FI.svg
new file mode 100644
index 000000000..9d243ed5b
--- /dev/null
+++ b/public/icons/flags/FI.svg
@@ -0,0 +1,22 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/FJ.svg b/public/icons/flags/FJ.svg
new file mode 100644
index 000000000..e3ebc9bb1
--- /dev/null
+++ b/public/icons/flags/FJ.svg
@@ -0,0 +1,51 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/FK.svg b/public/icons/flags/FK.svg
new file mode 100644
index 000000000..01b0f2a8e
--- /dev/null
+++ b/public/icons/flags/FK.svg
@@ -0,0 +1,58 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/FM.svg b/public/icons/flags/FM.svg
new file mode 100644
index 000000000..befd157c0
--- /dev/null
+++ b/public/icons/flags/FM.svg
@@ -0,0 +1,23 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/FO.svg b/public/icons/flags/FO.svg
new file mode 100644
index 000000000..77618c05e
--- /dev/null
+++ b/public/icons/flags/FO.svg
@@ -0,0 +1,27 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/FR.svg b/public/icons/flags/FR.svg
new file mode 100644
index 000000000..940de6169
--- /dev/null
+++ b/public/icons/flags/FR.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/GA.svg b/public/icons/flags/GA.svg
new file mode 100644
index 000000000..45c680870
--- /dev/null
+++ b/public/icons/flags/GA.svg
@@ -0,0 +1,32 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/GB-ENG.svg b/public/icons/flags/GB-ENG.svg
new file mode 100644
index 000000000..f032cb445
--- /dev/null
+++ b/public/icons/flags/GB-ENG.svg
@@ -0,0 +1,22 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/GB-NIR.svg b/public/icons/flags/GB-NIR.svg
new file mode 100644
index 000000000..5d04864f5
--- /dev/null
+++ b/public/icons/flags/GB-NIR.svg
@@ -0,0 +1,41 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/GB-SCT.svg b/public/icons/flags/GB-SCT.svg
new file mode 100644
index 000000000..6aabe9964
--- /dev/null
+++ b/public/icons/flags/GB-SCT.svg
@@ -0,0 +1,23 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/GB-WLS.svg b/public/icons/flags/GB-WLS.svg
new file mode 100644
index 000000000..607b33306
--- /dev/null
+++ b/public/icons/flags/GB-WLS.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/GB-ZET.svg b/public/icons/flags/GB-ZET.svg
new file mode 100644
index 000000000..7080d48bc
--- /dev/null
+++ b/public/icons/flags/GB-ZET.svg
@@ -0,0 +1,23 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/GB.svg b/public/icons/flags/GB.svg
new file mode 100644
index 000000000..679d27c75
--- /dev/null
+++ b/public/icons/flags/GB.svg
@@ -0,0 +1,32 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/GD.svg b/public/icons/flags/GD.svg
new file mode 100644
index 000000000..210dc3fd8
--- /dev/null
+++ b/public/icons/flags/GD.svg
@@ -0,0 +1,49 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/GE.svg b/public/icons/flags/GE.svg
new file mode 100644
index 000000000..818f3f5b5
--- /dev/null
+++ b/public/icons/flags/GE.svg
@@ -0,0 +1,26 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/GF.svg b/public/icons/flags/GF.svg
new file mode 100644
index 000000000..bae1448dc
--- /dev/null
+++ b/public/icons/flags/GF.svg
@@ -0,0 +1,32 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/GG.svg b/public/icons/flags/GG.svg
new file mode 100644
index 000000000..fa4285352
--- /dev/null
+++ b/public/icons/flags/GG.svg
@@ -0,0 +1,27 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/GH.svg b/public/icons/flags/GH.svg
new file mode 100644
index 000000000..528473ff2
--- /dev/null
+++ b/public/icons/flags/GH.svg
@@ -0,0 +1,37 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/GI.svg b/public/icons/flags/GI.svg
new file mode 100644
index 000000000..ecd8530aa
--- /dev/null
+++ b/public/icons/flags/GI.svg
@@ -0,0 +1,38 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/GL.svg b/public/icons/flags/GL.svg
new file mode 100644
index 000000000..33b223337
--- /dev/null
+++ b/public/icons/flags/GL.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/GM.svg b/public/icons/flags/GM.svg
new file mode 100644
index 000000000..b6330f523
--- /dev/null
+++ b/public/icons/flags/GM.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/GN.svg b/public/icons/flags/GN.svg
new file mode 100644
index 000000000..2d20595ea
--- /dev/null
+++ b/public/icons/flags/GN.svg
@@ -0,0 +1,32 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/GP.svg b/public/icons/flags/GP.svg
new file mode 100644
index 000000000..3dbdcc132
--- /dev/null
+++ b/public/icons/flags/GP.svg
@@ -0,0 +1,40 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/GQ.svg b/public/icons/flags/GQ.svg
new file mode 100644
index 000000000..e2d5c67d2
--- /dev/null
+++ b/public/icons/flags/GQ.svg
@@ -0,0 +1,34 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/GR.svg b/public/icons/flags/GR.svg
new file mode 100644
index 000000000..a9b12c000
--- /dev/null
+++ b/public/icons/flags/GR.svg
@@ -0,0 +1,22 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/GS.svg b/public/icons/flags/GS.svg
new file mode 100644
index 000000000..039845211
--- /dev/null
+++ b/public/icons/flags/GS.svg
@@ -0,0 +1,112 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/GT.svg b/public/icons/flags/GT.svg
new file mode 100644
index 000000000..be45ee89f
--- /dev/null
+++ b/public/icons/flags/GT.svg
@@ -0,0 +1,26 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/GU.svg b/public/icons/flags/GU.svg
new file mode 100644
index 000000000..6233a0bbd
--- /dev/null
+++ b/public/icons/flags/GU.svg
@@ -0,0 +1,65 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/GW.svg b/public/icons/flags/GW.svg
new file mode 100644
index 000000000..b09530d44
--- /dev/null
+++ b/public/icons/flags/GW.svg
@@ -0,0 +1,37 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/GY.svg b/public/icons/flags/GY.svg
new file mode 100644
index 000000000..e5937c245
--- /dev/null
+++ b/public/icons/flags/GY.svg
@@ -0,0 +1,42 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/HK.svg b/public/icons/flags/HK.svg
new file mode 100644
index 000000000..f99b8882c
--- /dev/null
+++ b/public/icons/flags/HK.svg
@@ -0,0 +1,23 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/HM.svg b/public/icons/flags/HM.svg
new file mode 100644
index 000000000..8ef4f3463
--- /dev/null
+++ b/public/icons/flags/HM.svg
@@ -0,0 +1,36 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/HN.svg b/public/icons/flags/HN.svg
new file mode 100644
index 000000000..50a48cd94
--- /dev/null
+++ b/public/icons/flags/HN.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/HR.svg b/public/icons/flags/HR.svg
new file mode 100644
index 000000000..a6cf5daa3
--- /dev/null
+++ b/public/icons/flags/HR.svg
@@ -0,0 +1,35 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/HT.svg b/public/icons/flags/HT.svg
new file mode 100644
index 000000000..0cd82be12
--- /dev/null
+++ b/public/icons/flags/HT.svg
@@ -0,0 +1,46 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/HU.svg b/public/icons/flags/HU.svg
new file mode 100644
index 000000000..795319ea1
--- /dev/null
+++ b/public/icons/flags/HU.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/ID.svg b/public/icons/flags/ID.svg
new file mode 100644
index 000000000..8101da05c
--- /dev/null
+++ b/public/icons/flags/ID.svg
@@ -0,0 +1,23 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/IE.svg b/public/icons/flags/IE.svg
new file mode 100644
index 000000000..60d9af87c
--- /dev/null
+++ b/public/icons/flags/IE.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/IL.svg b/public/icons/flags/IL.svg
new file mode 100644
index 000000000..7646f91e9
--- /dev/null
+++ b/public/icons/flags/IL.svg
@@ -0,0 +1,26 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/IM.svg b/public/icons/flags/IM.svg
new file mode 100644
index 000000000..ecc7c12e2
--- /dev/null
+++ b/public/icons/flags/IM.svg
@@ -0,0 +1,30 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/IN.svg b/public/icons/flags/IN.svg
new file mode 100644
index 000000000..3726ceb79
--- /dev/null
+++ b/public/icons/flags/IN.svg
@@ -0,0 +1,31 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/IO.svg b/public/icons/flags/IO.svg
new file mode 100644
index 000000000..4d8b52291
--- /dev/null
+++ b/public/icons/flags/IO.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/IQ.svg b/public/icons/flags/IQ.svg
new file mode 100644
index 000000000..16c4cf185
--- /dev/null
+++ b/public/icons/flags/IQ.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/IR.svg b/public/icons/flags/IR.svg
new file mode 100644
index 000000000..af3250176
--- /dev/null
+++ b/public/icons/flags/IR.svg
@@ -0,0 +1,31 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/IS.svg b/public/icons/flags/IS.svg
new file mode 100644
index 000000000..385a2bf93
--- /dev/null
+++ b/public/icons/flags/IS.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/IT.svg b/public/icons/flags/IT.svg
new file mode 100644
index 000000000..9e76f24c3
--- /dev/null
+++ b/public/icons/flags/IT.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/JE.svg b/public/icons/flags/JE.svg
new file mode 100644
index 000000000..6663c5042
--- /dev/null
+++ b/public/icons/flags/JE.svg
@@ -0,0 +1,32 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/JM.svg b/public/icons/flags/JM.svg
new file mode 100644
index 000000000..54779e777
--- /dev/null
+++ b/public/icons/flags/JM.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/JO.svg b/public/icons/flags/JO.svg
new file mode 100644
index 000000000..b0788e769
--- /dev/null
+++ b/public/icons/flags/JO.svg
@@ -0,0 +1,34 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/JP.svg b/public/icons/flags/JP.svg
new file mode 100644
index 000000000..0a655c041
--- /dev/null
+++ b/public/icons/flags/JP.svg
@@ -0,0 +1,22 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/KE.svg b/public/icons/flags/KE.svg
new file mode 100644
index 000000000..6c6a6cf6f
--- /dev/null
+++ b/public/icons/flags/KE.svg
@@ -0,0 +1,43 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/KG.svg b/public/icons/flags/KG.svg
new file mode 100644
index 000000000..12e6a244d
--- /dev/null
+++ b/public/icons/flags/KG.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/KH.svg b/public/icons/flags/KH.svg
new file mode 100644
index 000000000..9ea454bbe
--- /dev/null
+++ b/public/icons/flags/KH.svg
@@ -0,0 +1,29 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/KI.svg b/public/icons/flags/KI.svg
new file mode 100644
index 000000000..e00e2352a
--- /dev/null
+++ b/public/icons/flags/KI.svg
@@ -0,0 +1,35 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/KM.svg b/public/icons/flags/KM.svg
new file mode 100644
index 000000000..2da152d57
--- /dev/null
+++ b/public/icons/flags/KM.svg
@@ -0,0 +1,39 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/KN.svg b/public/icons/flags/KN.svg
new file mode 100644
index 000000000..e65b7b61f
--- /dev/null
+++ b/public/icons/flags/KN.svg
@@ -0,0 +1,39 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/KP.svg b/public/icons/flags/KP.svg
new file mode 100644
index 000000000..649feb275
--- /dev/null
+++ b/public/icons/flags/KP.svg
@@ -0,0 +1,30 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/KR.svg b/public/icons/flags/KR.svg
new file mode 100644
index 000000000..078665a50
--- /dev/null
+++ b/public/icons/flags/KR.svg
@@ -0,0 +1,38 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/KW.svg b/public/icons/flags/KW.svg
new file mode 100644
index 000000000..a73b01139
--- /dev/null
+++ b/public/icons/flags/KW.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/KY.svg b/public/icons/flags/KY.svg
new file mode 100644
index 000000000..2240dbc6b
--- /dev/null
+++ b/public/icons/flags/KY.svg
@@ -0,0 +1,44 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/KZ.svg b/public/icons/flags/KZ.svg
new file mode 100644
index 000000000..6076ac54e
--- /dev/null
+++ b/public/icons/flags/KZ.svg
@@ -0,0 +1,29 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/LA.svg b/public/icons/flags/LA.svg
new file mode 100644
index 000000000..5b740da70
--- /dev/null
+++ b/public/icons/flags/LA.svg
@@ -0,0 +1,29 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/LB.svg b/public/icons/flags/LB.svg
new file mode 100644
index 000000000..401a235d6
--- /dev/null
+++ b/public/icons/flags/LB.svg
@@ -0,0 +1,29 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/LC.svg b/public/icons/flags/LC.svg
new file mode 100644
index 000000000..8d809d3e3
--- /dev/null
+++ b/public/icons/flags/LC.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/LGBT.svg b/public/icons/flags/LGBT.svg
new file mode 100644
index 000000000..a3f751934
--- /dev/null
+++ b/public/icons/flags/LGBT.svg
@@ -0,0 +1,42 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/LI.svg b/public/icons/flags/LI.svg
new file mode 100644
index 000000000..1160975a6
--- /dev/null
+++ b/public/icons/flags/LI.svg
@@ -0,0 +1,27 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/LK.svg b/public/icons/flags/LK.svg
new file mode 100644
index 000000000..55386d5c5
--- /dev/null
+++ b/public/icons/flags/LK.svg
@@ -0,0 +1,43 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/LR.svg b/public/icons/flags/LR.svg
new file mode 100644
index 000000000..3d6cef1e0
--- /dev/null
+++ b/public/icons/flags/LR.svg
@@ -0,0 +1,36 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/LS.svg b/public/icons/flags/LS.svg
new file mode 100644
index 000000000..3ec5277d5
--- /dev/null
+++ b/public/icons/flags/LS.svg
@@ -0,0 +1,34 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/LT.svg b/public/icons/flags/LT.svg
new file mode 100644
index 000000000..8e592267e
--- /dev/null
+++ b/public/icons/flags/LT.svg
@@ -0,0 +1,32 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/LU.svg b/public/icons/flags/LU.svg
new file mode 100644
index 000000000..860e730bc
--- /dev/null
+++ b/public/icons/flags/LU.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/LV.svg b/public/icons/flags/LV.svg
new file mode 100644
index 000000000..5d0255e6d
--- /dev/null
+++ b/public/icons/flags/LV.svg
@@ -0,0 +1,24 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/LYD.svg b/public/icons/flags/LYD.svg
new file mode 100644
index 000000000..4b9f2a0e3
--- /dev/null
+++ b/public/icons/flags/LYD.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/MA.svg b/public/icons/flags/MA.svg
new file mode 100644
index 000000000..cb22ba958
--- /dev/null
+++ b/public/icons/flags/MA.svg
@@ -0,0 +1,23 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/MC.svg b/public/icons/flags/MC.svg
new file mode 100644
index 000000000..207590a77
--- /dev/null
+++ b/public/icons/flags/MC.svg
@@ -0,0 +1,23 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/MD.svg b/public/icons/flags/MD.svg
new file mode 100644
index 000000000..301e93ee1
--- /dev/null
+++ b/public/icons/flags/MD.svg
@@ -0,0 +1,42 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/ME.svg b/public/icons/flags/ME.svg
new file mode 100644
index 000000000..9b0838e93
--- /dev/null
+++ b/public/icons/flags/ME.svg
@@ -0,0 +1,29 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/MF.svg b/public/icons/flags/MF.svg
new file mode 100644
index 000000000..c45b62a0f
--- /dev/null
+++ b/public/icons/flags/MF.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/MG.svg b/public/icons/flags/MG.svg
new file mode 100644
index 000000000..c173fdd51
--- /dev/null
+++ b/public/icons/flags/MG.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/MH.svg b/public/icons/flags/MH.svg
new file mode 100644
index 000000000..e6b660911
--- /dev/null
+++ b/public/icons/flags/MH.svg
@@ -0,0 +1,29 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/MK.svg b/public/icons/flags/MK.svg
new file mode 100644
index 000000000..35b922973
--- /dev/null
+++ b/public/icons/flags/MK.svg
@@ -0,0 +1,29 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/ML.svg b/public/icons/flags/ML.svg
new file mode 100644
index 000000000..babc6e592
--- /dev/null
+++ b/public/icons/flags/ML.svg
@@ -0,0 +1,32 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/MM.svg b/public/icons/flags/MM.svg
new file mode 100644
index 000000000..eb3c18a30
--- /dev/null
+++ b/public/icons/flags/MM.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/MN.svg b/public/icons/flags/MN.svg
new file mode 100644
index 000000000..8af15a515
--- /dev/null
+++ b/public/icons/flags/MN.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/MO.svg b/public/icons/flags/MO.svg
new file mode 100644
index 000000000..be4bc8756
--- /dev/null
+++ b/public/icons/flags/MO.svg
@@ -0,0 +1,26 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/MP.svg b/public/icons/flags/MP.svg
new file mode 100644
index 000000000..331514895
--- /dev/null
+++ b/public/icons/flags/MP.svg
@@ -0,0 +1,29 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/MQ.svg b/public/icons/flags/MQ.svg
new file mode 100644
index 000000000..adc820743
--- /dev/null
+++ b/public/icons/flags/MQ.svg
@@ -0,0 +1,27 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/MR.svg b/public/icons/flags/MR.svg
new file mode 100644
index 000000000..da5adee6b
--- /dev/null
+++ b/public/icons/flags/MR.svg
@@ -0,0 +1,27 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/MS.svg b/public/icons/flags/MS.svg
new file mode 100644
index 000000000..184c9178a
--- /dev/null
+++ b/public/icons/flags/MS.svg
@@ -0,0 +1,47 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/MT.svg b/public/icons/flags/MT.svg
new file mode 100644
index 000000000..5ce0b3fed
--- /dev/null
+++ b/public/icons/flags/MT.svg
@@ -0,0 +1,29 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/MU.svg b/public/icons/flags/MU.svg
new file mode 100644
index 000000000..f2c6f3f86
--- /dev/null
+++ b/public/icons/flags/MU.svg
@@ -0,0 +1,37 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/MV.svg b/public/icons/flags/MV.svg
new file mode 100644
index 000000000..f10e07d5f
--- /dev/null
+++ b/public/icons/flags/MV.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/MW.svg b/public/icons/flags/MW.svg
new file mode 100644
index 000000000..5b0cc5c6f
--- /dev/null
+++ b/public/icons/flags/MW.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/MX.svg b/public/icons/flags/MX.svg
new file mode 100644
index 000000000..7ed245bc7
--- /dev/null
+++ b/public/icons/flags/MX.svg
@@ -0,0 +1,30 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/MY.svg b/public/icons/flags/MY.svg
new file mode 100644
index 000000000..e7ff885f2
--- /dev/null
+++ b/public/icons/flags/MY.svg
@@ -0,0 +1,32 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/MZ.svg b/public/icons/flags/MZ.svg
new file mode 100644
index 000000000..7f553b00c
--- /dev/null
+++ b/public/icons/flags/MZ.svg
@@ -0,0 +1,43 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/NA.svg b/public/icons/flags/NA.svg
new file mode 100644
index 000000000..cb0ba69fd
--- /dev/null
+++ b/public/icons/flags/NA.svg
@@ -0,0 +1,75 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/NC.svg b/public/icons/flags/NC.svg
new file mode 100644
index 000000000..bae580e8d
--- /dev/null
+++ b/public/icons/flags/NC.svg
@@ -0,0 +1,42 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/NE.svg b/public/icons/flags/NE.svg
new file mode 100644
index 000000000..12bcf8a0d
--- /dev/null
+++ b/public/icons/flags/NE.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/NF.svg b/public/icons/flags/NF.svg
new file mode 100644
index 000000000..b707e52d0
--- /dev/null
+++ b/public/icons/flags/NF.svg
@@ -0,0 +1,29 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/NG.svg b/public/icons/flags/NG.svg
new file mode 100644
index 000000000..4063ff846
--- /dev/null
+++ b/public/icons/flags/NG.svg
@@ -0,0 +1,24 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/NI.svg b/public/icons/flags/NI.svg
new file mode 100644
index 000000000..7adb4ba40
--- /dev/null
+++ b/public/icons/flags/NI.svg
@@ -0,0 +1,26 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/NL.svg b/public/icons/flags/NL.svg
new file mode 100644
index 000000000..c62f42ad8
--- /dev/null
+++ b/public/icons/flags/NL.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/NO.svg b/public/icons/flags/NO.svg
new file mode 100644
index 000000000..cdc23f499
--- /dev/null
+++ b/public/icons/flags/NO.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/NP.svg b/public/icons/flags/NP.svg
new file mode 100644
index 000000000..c879fa80f
--- /dev/null
+++ b/public/icons/flags/NP.svg
@@ -0,0 +1,35 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/NR.svg b/public/icons/flags/NR.svg
new file mode 100644
index 000000000..1a6c3a21a
--- /dev/null
+++ b/public/icons/flags/NR.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/NU.svg b/public/icons/flags/NU.svg
new file mode 100644
index 000000000..3d9bc80c6
--- /dev/null
+++ b/public/icons/flags/NU.svg
@@ -0,0 +1,41 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/NZ.svg b/public/icons/flags/NZ.svg
new file mode 100644
index 000000000..c1f624df8
--- /dev/null
+++ b/public/icons/flags/NZ.svg
@@ -0,0 +1,34 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/OM.svg b/public/icons/flags/OM.svg
new file mode 100644
index 000000000..cb08ac82a
--- /dev/null
+++ b/public/icons/flags/OM.svg
@@ -0,0 +1,29 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/PA.svg b/public/icons/flags/PA.svg
new file mode 100644
index 000000000..d8516682e
--- /dev/null
+++ b/public/icons/flags/PA.svg
@@ -0,0 +1,30 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/PE.svg b/public/icons/flags/PE.svg
new file mode 100644
index 000000000..98a26cf20
--- /dev/null
+++ b/public/icons/flags/PE.svg
@@ -0,0 +1,24 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/PF.svg b/public/icons/flags/PF.svg
new file mode 100644
index 000000000..b29385f4b
--- /dev/null
+++ b/public/icons/flags/PF.svg
@@ -0,0 +1,52 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/PG.svg b/public/icons/flags/PG.svg
new file mode 100644
index 000000000..0630fab6f
--- /dev/null
+++ b/public/icons/flags/PG.svg
@@ -0,0 +1,36 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/PH.svg b/public/icons/flags/PH.svg
new file mode 100644
index 000000000..4c1087b8b
--- /dev/null
+++ b/public/icons/flags/PH.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/PK.svg b/public/icons/flags/PK.svg
new file mode 100644
index 000000000..7ecb09cfd
--- /dev/null
+++ b/public/icons/flags/PK.svg
@@ -0,0 +1,32 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/PL.svg b/public/icons/flags/PL.svg
new file mode 100644
index 000000000..fadbd2d6b
--- /dev/null
+++ b/public/icons/flags/PL.svg
@@ -0,0 +1,23 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/PM.svg b/public/icons/flags/PM.svg
new file mode 100644
index 000000000..1f39fd0a2
--- /dev/null
+++ b/public/icons/flags/PM.svg
@@ -0,0 +1,66 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/PN.svg b/public/icons/flags/PN.svg
new file mode 100644
index 000000000..f2b2cc4fe
--- /dev/null
+++ b/public/icons/flags/PN.svg
@@ -0,0 +1,51 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/PR.svg b/public/icons/flags/PR.svg
new file mode 100644
index 000000000..7d1204451
--- /dev/null
+++ b/public/icons/flags/PR.svg
@@ -0,0 +1,30 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/PS.svg b/public/icons/flags/PS.svg
new file mode 100644
index 000000000..e68583ba0
--- /dev/null
+++ b/public/icons/flags/PS.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/PT.svg b/public/icons/flags/PT.svg
new file mode 100644
index 000000000..49b59be24
--- /dev/null
+++ b/public/icons/flags/PT.svg
@@ -0,0 +1,38 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/PW.svg b/public/icons/flags/PW.svg
new file mode 100644
index 000000000..4ab7f1661
--- /dev/null
+++ b/public/icons/flags/PW.svg
@@ -0,0 +1,27 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/PY.svg b/public/icons/flags/PY.svg
new file mode 100644
index 000000000..2ae005460
--- /dev/null
+++ b/public/icons/flags/PY.svg
@@ -0,0 +1,30 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/QA.svg b/public/icons/flags/QA.svg
new file mode 100644
index 000000000..985171d17
--- /dev/null
+++ b/public/icons/flags/QA.svg
@@ -0,0 +1,23 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/RE.svg b/public/icons/flags/RE.svg
new file mode 100644
index 000000000..7e1309388
--- /dev/null
+++ b/public/icons/flags/RE.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/RO.svg b/public/icons/flags/RO.svg
new file mode 100644
index 000000000..dd82b266f
--- /dev/null
+++ b/public/icons/flags/RO.svg
@@ -0,0 +1,32 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/RS.svg b/public/icons/flags/RS.svg
new file mode 100644
index 000000000..892dd5e4a
--- /dev/null
+++ b/public/icons/flags/RS.svg
@@ -0,0 +1,39 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/RU.svg b/public/icons/flags/RU.svg
new file mode 100644
index 000000000..a9ba65b57
--- /dev/null
+++ b/public/icons/flags/RU.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/RW.svg b/public/icons/flags/RW.svg
new file mode 100644
index 000000000..43b26156b
--- /dev/null
+++ b/public/icons/flags/RW.svg
@@ -0,0 +1,37 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/SA.svg b/public/icons/flags/SA.svg
new file mode 100644
index 000000000..735b986f8
--- /dev/null
+++ b/public/icons/flags/SA.svg
@@ -0,0 +1,26 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/SB.svg b/public/icons/flags/SB.svg
new file mode 100644
index 000000000..768c45c0b
--- /dev/null
+++ b/public/icons/flags/SB.svg
@@ -0,0 +1,39 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/SC.svg b/public/icons/flags/SC.svg
new file mode 100644
index 000000000..62b380b8d
--- /dev/null
+++ b/public/icons/flags/SC.svg
@@ -0,0 +1,43 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/SD.svg b/public/icons/flags/SD.svg
new file mode 100644
index 000000000..c68d6b1b1
--- /dev/null
+++ b/public/icons/flags/SD.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/SE.svg b/public/icons/flags/SE.svg
new file mode 100644
index 000000000..bb4f4e117
--- /dev/null
+++ b/public/icons/flags/SE.svg
@@ -0,0 +1,27 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/SG.svg b/public/icons/flags/SG.svg
new file mode 100644
index 000000000..270114839
--- /dev/null
+++ b/public/icons/flags/SG.svg
@@ -0,0 +1,24 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/SH.svg b/public/icons/flags/SH.svg
new file mode 100644
index 000000000..e0dde7643
--- /dev/null
+++ b/public/icons/flags/SH.svg
@@ -0,0 +1,53 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/SI.svg b/public/icons/flags/SI.svg
new file mode 100644
index 000000000..497f87054
--- /dev/null
+++ b/public/icons/flags/SI.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/SJ.svg b/public/icons/flags/SJ.svg
new file mode 100644
index 000000000..bef7e5056
--- /dev/null
+++ b/public/icons/flags/SJ.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/SK.svg b/public/icons/flags/SK.svg
new file mode 100644
index 000000000..2b8ba801a
--- /dev/null
+++ b/public/icons/flags/SK.svg
@@ -0,0 +1,46 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/SL.svg b/public/icons/flags/SL.svg
new file mode 100644
index 000000000..817419ef6
--- /dev/null
+++ b/public/icons/flags/SL.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/SM.svg b/public/icons/flags/SM.svg
new file mode 100644
index 000000000..abf621717
--- /dev/null
+++ b/public/icons/flags/SM.svg
@@ -0,0 +1,25 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/SN.svg b/public/icons/flags/SN.svg
new file mode 100644
index 000000000..09484160a
--- /dev/null
+++ b/public/icons/flags/SN.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/SO.svg b/public/icons/flags/SO.svg
new file mode 100644
index 000000000..6372e3770
--- /dev/null
+++ b/public/icons/flags/SO.svg
@@ -0,0 +1,23 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/SR.svg b/public/icons/flags/SR.svg
new file mode 100644
index 000000000..97963b0c6
--- /dev/null
+++ b/public/icons/flags/SR.svg
@@ -0,0 +1,34 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/SS.svg b/public/icons/flags/SS.svg
new file mode 100644
index 000000000..e8d68dd02
--- /dev/null
+++ b/public/icons/flags/SS.svg
@@ -0,0 +1,44 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/ST.svg b/public/icons/flags/ST.svg
new file mode 100644
index 000000000..4b355d712
--- /dev/null
+++ b/public/icons/flags/ST.svg
@@ -0,0 +1,39 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/SV.svg b/public/icons/flags/SV.svg
new file mode 100644
index 000000000..9bfdd5ce9
--- /dev/null
+++ b/public/icons/flags/SV.svg
@@ -0,0 +1,30 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/SX.svg b/public/icons/flags/SX.svg
new file mode 100644
index 000000000..ccefe037b
--- /dev/null
+++ b/public/icons/flags/SX.svg
@@ -0,0 +1,45 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/SY.svg b/public/icons/flags/SY.svg
new file mode 100644
index 000000000..040530b60
--- /dev/null
+++ b/public/icons/flags/SY.svg
@@ -0,0 +1,34 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/SZ.svg b/public/icons/flags/SZ.svg
new file mode 100644
index 000000000..fc4120dec
--- /dev/null
+++ b/public/icons/flags/SZ.svg
@@ -0,0 +1,47 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/TC.svg b/public/icons/flags/TC.svg
new file mode 100644
index 000000000..c3ea149a6
--- /dev/null
+++ b/public/icons/flags/TC.svg
@@ -0,0 +1,40 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/TD.svg b/public/icons/flags/TD.svg
new file mode 100644
index 000000000..74756faf5
--- /dev/null
+++ b/public/icons/flags/TD.svg
@@ -0,0 +1,32 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/TF.svg b/public/icons/flags/TF.svg
new file mode 100644
index 000000000..d1ea69184
--- /dev/null
+++ b/public/icons/flags/TF.svg
@@ -0,0 +1,35 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/TG.svg b/public/icons/flags/TG.svg
new file mode 100644
index 000000000..e9f6360fd
--- /dev/null
+++ b/public/icons/flags/TG.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/TH.svg b/public/icons/flags/TH.svg
new file mode 100644
index 000000000..1bf403a23
--- /dev/null
+++ b/public/icons/flags/TH.svg
@@ -0,0 +1,29 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/TJ.svg b/public/icons/flags/TJ.svg
new file mode 100644
index 000000000..77d6728b6
--- /dev/null
+++ b/public/icons/flags/TJ.svg
@@ -0,0 +1,29 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/TK.svg b/public/icons/flags/TK.svg
new file mode 100644
index 000000000..3cde9608b
--- /dev/null
+++ b/public/icons/flags/TK.svg
@@ -0,0 +1,31 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/TL.svg b/public/icons/flags/TL.svg
new file mode 100644
index 000000000..41b895218
--- /dev/null
+++ b/public/icons/flags/TL.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/TM.svg b/public/icons/flags/TM.svg
new file mode 100644
index 000000000..dac62a132
--- /dev/null
+++ b/public/icons/flags/TM.svg
@@ -0,0 +1,74 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/TN.svg b/public/icons/flags/TN.svg
new file mode 100644
index 000000000..3ff74a9ea
--- /dev/null
+++ b/public/icons/flags/TN.svg
@@ -0,0 +1,23 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/TO.svg b/public/icons/flags/TO.svg
new file mode 100644
index 000000000..e0e42ee2f
--- /dev/null
+++ b/public/icons/flags/TO.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/TR.svg b/public/icons/flags/TR.svg
new file mode 100644
index 000000000..e5c0924d0
--- /dev/null
+++ b/public/icons/flags/TR.svg
@@ -0,0 +1,23 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/TT.svg b/public/icons/flags/TT.svg
new file mode 100644
index 000000000..69bdb9a95
--- /dev/null
+++ b/public/icons/flags/TT.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/TV.svg b/public/icons/flags/TV.svg
new file mode 100644
index 000000000..839c97f12
--- /dev/null
+++ b/public/icons/flags/TV.svg
@@ -0,0 +1,36 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/TW.svg b/public/icons/flags/TW.svg
new file mode 100644
index 000000000..488d1120d
--- /dev/null
+++ b/public/icons/flags/TW.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/TZ.svg b/public/icons/flags/TZ.svg
new file mode 100644
index 000000000..d652e2110
--- /dev/null
+++ b/public/icons/flags/TZ.svg
@@ -0,0 +1,37 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/UA.svg b/public/icons/flags/UA.svg
new file mode 100644
index 000000000..8dac83662
--- /dev/null
+++ b/public/icons/flags/UA.svg
@@ -0,0 +1,27 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/UG.svg b/public/icons/flags/UG.svg
new file mode 100644
index 000000000..7fabd77c8
--- /dev/null
+++ b/public/icons/flags/UG.svg
@@ -0,0 +1,37 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/UM.svg b/public/icons/flags/UM.svg
new file mode 100644
index 000000000..1a8fc6a79
--- /dev/null
+++ b/public/icons/flags/UM.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/US-CA.svg b/public/icons/flags/US-CA.svg
new file mode 100644
index 000000000..8860c7a54
--- /dev/null
+++ b/public/icons/flags/US-CA.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/USD.svg b/public/icons/flags/USD.svg
new file mode 100644
index 000000000..846ec9d20
--- /dev/null
+++ b/public/icons/flags/USD.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/UY.svg b/public/icons/flags/UY.svg
new file mode 100644
index 000000000..81c281549
--- /dev/null
+++ b/public/icons/flags/UY.svg
@@ -0,0 +1,29 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/UZ.svg b/public/icons/flags/UZ.svg
new file mode 100644
index 000000000..f6cf21400
--- /dev/null
+++ b/public/icons/flags/UZ.svg
@@ -0,0 +1,29 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/VA.svg b/public/icons/flags/VA.svg
new file mode 100644
index 000000000..14c78aaa2
--- /dev/null
+++ b/public/icons/flags/VA.svg
@@ -0,0 +1,39 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/VC.svg b/public/icons/flags/VC.svg
new file mode 100644
index 000000000..22cc1d530
--- /dev/null
+++ b/public/icons/flags/VC.svg
@@ -0,0 +1,37 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/VE.svg b/public/icons/flags/VE.svg
new file mode 100644
index 000000000..1a14634f9
--- /dev/null
+++ b/public/icons/flags/VE.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/VG.svg b/public/icons/flags/VG.svg
new file mode 100644
index 000000000..c3c31ed1e
--- /dev/null
+++ b/public/icons/flags/VG.svg
@@ -0,0 +1,42 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/VI.svg b/public/icons/flags/VI.svg
new file mode 100644
index 000000000..071cf62c0
--- /dev/null
+++ b/public/icons/flags/VI.svg
@@ -0,0 +1,49 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/VN.svg b/public/icons/flags/VN.svg
new file mode 100644
index 000000000..2bb795642
--- /dev/null
+++ b/public/icons/flags/VN.svg
@@ -0,0 +1,27 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/VU.svg b/public/icons/flags/VU.svg
new file mode 100644
index 000000000..26e029810
--- /dev/null
+++ b/public/icons/flags/VU.svg
@@ -0,0 +1,38 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/WF.svg b/public/icons/flags/WF.svg
new file mode 100644
index 000000000..26a5e4144
--- /dev/null
+++ b/public/icons/flags/WF.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/WS.svg b/public/icons/flags/WS.svg
new file mode 100644
index 000000000..756c78f56
--- /dev/null
+++ b/public/icons/flags/WS.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/XK.svg b/public/icons/flags/XK.svg
new file mode 100644
index 000000000..a9c245fd1
--- /dev/null
+++ b/public/icons/flags/XK.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/YE.svg b/public/icons/flags/YE.svg
new file mode 100644
index 000000000..535406f9a
--- /dev/null
+++ b/public/icons/flags/YE.svg
@@ -0,0 +1,28 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/YT.svg b/public/icons/flags/YT.svg
new file mode 100644
index 000000000..be67985d1
--- /dev/null
+++ b/public/icons/flags/YT.svg
@@ -0,0 +1,77 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/ZA.svg b/public/icons/flags/ZA.svg
new file mode 100644
index 000000000..f3ad37267
--- /dev/null
+++ b/public/icons/flags/ZA.svg
@@ -0,0 +1,44 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/ZM.svg b/public/icons/flags/ZM.svg
new file mode 100644
index 000000000..3e6f42a81
--- /dev/null
+++ b/public/icons/flags/ZM.svg
@@ -0,0 +1,42 @@
+
+
\ No newline at end of file
diff --git a/public/icons/flags/ZW.svg b/public/icons/flags/ZW.svg
new file mode 100644
index 000000000..dfaf1f3fa
--- /dev/null
+++ b/public/icons/flags/ZW.svg
@@ -0,0 +1,43 @@
+
+
\ No newline at end of file
diff --git a/src/common/accountTypes.js b/src/common/accountTypes.js
index 3e84a1e7d..144e75c30 100644
--- a/src/common/accountTypes.js
+++ b/src/common/accountTypes.js
@@ -221,3 +221,5 @@ export const ACCOUNT_TYPES = [
incomeSheet: true,
},
];
+
+export const FOREIGN_CURRENCY_ACCOUNTS = ['cash', 'bank'];
diff --git a/src/common/cellTypes.js b/src/common/cellTypes.js
new file mode 100644
index 000000000..4c2299a59
--- /dev/null
+++ b/src/common/cellTypes.js
@@ -0,0 +1,7 @@
+
+
+export const CellType = {
+ Text: 'text',
+ Field: 'field',
+ Button: 'button'
+}
\ No newline at end of file
diff --git a/src/common/classes.js b/src/common/classes.js
index 6b0872396..0672377fb 100644
--- a/src/common/classes.js
+++ b/src/common/classes.js
@@ -41,6 +41,7 @@ const CLASSES = {
PAGE_FORM_EXPENSE: 'page-form--expense',
PAGE_FORM_CREDIT_NOTE:'page-form--credit-note',
PAGE_FORM_VENDOR_CREDIT_NOTE:'page-form--vendor-credit-note',
+ PAGE_FORM_WAREHOUSE_TRANSFER:'page-form--warehouse-transfer',
FORM_GROUP_LIST_SELECT: 'form-group--select-list',
@@ -70,6 +71,8 @@ const CLASSES = {
PREFERENCES_PAGE_INSIDE_CONTENT_ACCOUNTANT: 'preferences-page__inside-content--accountant',
PREFERENCES_PAGE_INSIDE_CONTENT_SMS_INTEGRATION: 'preferences-page__inside-content--sms-integration',
PREFERENCES_PAGE_INSIDE_CONTENT_ROLES_FORM: 'preferences-page__inside-content--roles-form',
+ PREFERENCES_PAGE_INSIDE_CONTENT_BRANCHES: 'preferences-page__inside-content--branches',
+ PREFERENCES_PAGE_INSIDE_CONTENT_WAREHOUSES: 'preferences-page__inside-content--warehouses',
FINANCIAL_REPORT_INSIDER: 'dashboard__insider--financial-report',
diff --git a/src/common/drawers.js b/src/common/drawers.js
index 5ec6d05a2..205d7fc53 100644
--- a/src/common/drawers.js
+++ b/src/common/drawers.js
@@ -17,5 +17,6 @@ export const DRAWERS = {
CREDIT_NOTE_DETAIL_DRAWER: 'credit-note-detail-drawer',
VENDOR_CREDIT_DETAIL_DRAWER: 'vendor-credit-detail-drawer',
REFUND_CREDIT_NOTE_DETAIL_DRAWER:'refund-credit-detail-drawer',
- REFUND_VENDOR_CREDIT_DETAIL_DRAWER:'refund-vendor-detail-drawer'
+ REFUND_VENDOR_CREDIT_DETAIL_DRAWER:'refund-vendor-detail-drawer',
+ WAREHOUSE_TRANSFER_DETAIL_DRAWER:'warehouse-transfer-detail-drawer'
};
diff --git a/src/common/features.js b/src/common/features.js
new file mode 100644
index 000000000..a042429eb
--- /dev/null
+++ b/src/common/features.js
@@ -0,0 +1,7 @@
+
+
+export const Features = {
+ Warehouses: 'warehouses',
+ Branches: 'branches',
+ ManualJournal: 'manualJournal',
+}
\ No newline at end of file
diff --git a/src/common/index.js b/src/common/index.js
index 626d9153b..ffd40825e 100644
--- a/src/common/index.js
+++ b/src/common/index.js
@@ -1,3 +1,5 @@
export * from './TableStyle';
+export * from './features';
+export * from './cellTypes';
export const Align = { Left: 'left', Right: 'right', Center: 'center' };
diff --git a/src/common/tables.js b/src/common/tables.js
index 59d6ca127..59c50dff7 100644
--- a/src/common/tables.js
+++ b/src/common/tables.js
@@ -16,6 +16,7 @@ export const TABLES = {
CASHFLOW_Transactions: 'cashflow_transactions',
CREDIT_NOTES: 'credit_notes',
VENDOR_CREDITS: 'vendor_credits',
+ WAREHOUSE_TRANSFERS:'warehouse_transfers'
};
export const TABLE_SIZE = {
diff --git a/src/components/BaseCurrency.js b/src/components/BaseCurrency.js
new file mode 100644
index 000000000..1102178ab
--- /dev/null
+++ b/src/components/BaseCurrency.js
@@ -0,0 +1,18 @@
+import React from 'react';
+import * as R from 'ramda';
+import styled from 'styled-components';
+import { CurrencyTag } from 'components';
+
+import withCurrentOrganization from 'containers/Organization/withCurrentOrganization';
+
+/**
+ * base currecncy.
+ */
+function BaseCurrency({
+ // #withCurrentOrganization
+ organization: { base_currency },
+}) {
+ return {base_currency};
+}
+
+export default R.compose(withCurrentOrganization())(BaseCurrency);
diff --git a/src/components/BranchSuggestField.js b/src/components/BranchSuggestField.js
new file mode 100644
index 000000000..e10bae2e3
--- /dev/null
+++ b/src/components/BranchSuggestField.js
@@ -0,0 +1,124 @@
+import React from 'react';
+import intl from 'react-intl-universal';
+import { MenuItem } from '@blueprintjs/core';
+import { Suggest } from '@blueprintjs/select';
+import { FormattedMessage as T } from 'components';
+
+import classNames from 'classnames';
+import { CLASSES } from 'common/classes';
+
+/**
+ * branch suggest field.
+ * @returns
+ */
+export default function BranchSuggestField({
+ branches,
+ initialBranchId,
+ selectedBranchId,
+ defaultSelectText = intl.get('select_branch'),
+ popoverFill = false,
+ onBranchSelected,
+ ...suggestProps
+}) {
+ const initialBranch = React.useMemo(
+ () => branches.find((b) => b.id === initialBranchId),
+ [initialBranchId, branches],
+ );
+
+ const [selectedBranch, setSelectedBranch] = React.useState(
+ initialBranch || null,
+ );
+
+ React.useEffect(() => {
+ if (typeof selectedBranchId !== 'undefined') {
+ const branch = selectedBranchId
+ ? branches.find((a) => a.id === selectedBranchId)
+ : null;
+ setSelectedBranch(branch);
+ }
+ }, [selectedBranchId, branches, setSelectedBranch]);
+
+ /**
+ *
+ * @param {*} branch
+ * @returns
+ */
+ const branchItemRenderer = (branch, { handleClick, modifiers, query }) => {
+ return (
+
+ );
+ };
+
+ /**
+ *
+ * @param {*} query
+ * @param {*} branch
+ * @param {*} _index
+ * @param {*} exactMatch
+ * @returns
+ */
+ const branchItemPredicate = (query, branch, _index, exactMatch) => {
+ const normalizedTitle = branch.name.toLowerCase();
+ const normalizedQuery = query.toLowerCase();
+
+ if (exactMatch) {
+ return normalizedTitle === normalizedQuery;
+ } else {
+ return `${branch.code}. ${normalizedTitle}`.indexOf(normalizedQuery) >= 0;
+ }
+ };
+
+ /**
+ *
+ * @param {*} branch
+ * @returns
+ */
+ const brnachItemSelect = React.useCallback(
+ (branch) => {
+ if (branch.id) {
+ setSelectedBranch({ ...branch });
+ onBranchSelected && onBranchSelected(branch);
+ }
+ },
+ [setSelectedBranch, onBranchSelected],
+ );
+
+ /**
+ *
+ * @param {*} inputVaue
+ * @returns
+ */
+ const branchInputValueRenderer = (inputValue) => {
+ if (inputValue) {
+ return inputValue.name.toString();
+ }
+ return '';
+ };
+
+ return (
+ } />}
+ itemRenderer={branchItemRenderer}
+ itemPredicate={branchItemPredicate}
+ onItemSelect={brnachItemSelect}
+ selectedItem={selectedBranch}
+ inputProps={{ placeholder: defaultSelectText }}
+ resetOnClose={true}
+ fill={true}
+ popoverProps={{ minimal: true, boundary: 'window' }}
+ inputValueRenderer={branchInputValueRenderer}
+ className={classNames(CLASSES.FORM_GROUP_LIST_SELECT, {
+ [CLASSES.SELECT_LIST_FILL_POPOVER]: popoverFill,
+ })}
+ {...suggestProps}
+ />
+ );
+}
diff --git a/src/components/Branches/BranchMultiSelect.js b/src/components/Branches/BranchMultiSelect.js
new file mode 100644
index 000000000..2d36e02f1
--- /dev/null
+++ b/src/components/Branches/BranchMultiSelect.js
@@ -0,0 +1,72 @@
+import React from 'react';
+import intl from 'react-intl-universal';
+import { MenuItem } from '@blueprintjs/core';
+import { FMultiSelect } from '../Forms';
+
+/**
+ *
+ * @param {*} query
+ * @param {*} branch
+ * @param {*} _index
+ * @param {*} exactMatch
+ * @returns
+ */
+const branchItemPredicate = (query, branch, _index, exactMatch) => {
+ const normalizedTitle = branch.name.toLowerCase();
+ const normalizedQuery = query.toLowerCase();
+
+ if (exactMatch) {
+ return normalizedTitle === normalizedQuery;
+ } else {
+ return `${branch.code}. ${normalizedTitle}`.indexOf(normalizedQuery) >= 0;
+ }
+};
+
+/**
+ *
+ * @param {*} branch
+ * @param {*} param1
+ * @returns
+ */
+const branchItemRenderer = (
+ branch,
+ { handleClick, modifiers, query },
+ { isSelected },
+) => {
+ return (
+
+ );
+};
+
+const branchSelectProps = {
+ itemPredicate: branchItemPredicate,
+ itemRenderer: branchItemRenderer,
+ valueAccessor: (item) => item.id,
+ labelAccessor: (item) => item.code,
+ tagRenderer: (item) => item.name,
+};
+
+/**
+ * branches mulit select.
+ * @param {*} param0
+ * @returns {JSX.Element}
+ */
+export function BranchMultiSelect({ branches, ...rest }) {
+ return (
+
+ );
+}
diff --git a/src/components/Branches/BranchSelect.js b/src/components/Branches/BranchSelect.js
new file mode 100644
index 000000000..b07358ccc
--- /dev/null
+++ b/src/components/Branches/BranchSelect.js
@@ -0,0 +1,69 @@
+import React from 'react';
+
+import { MenuItem, Button } from '@blueprintjs/core';
+import { FSelect } from '../Forms';
+
+/**
+ *
+ * @param {*} query
+ * @param {*} branch
+ * @param {*} _index
+ * @param {*} exactMatch
+ * @returns
+ */
+const branchItemPredicate = (query, branch, _index, exactMatch) => {
+ const normalizedTitle = branch.name.toLowerCase();
+ const normalizedQuery = query.toLowerCase();
+
+ if (exactMatch) {
+ return normalizedTitle === normalizedQuery;
+ } else {
+ return `${branch.code}. ${normalizedTitle}`.indexOf(normalizedQuery) >= 0;
+ }
+};
+
+/**
+ *
+ * @param {*} film
+ * @param {*} param1
+ * @returns
+ */
+const branchItemRenderer = (branch, { handleClick, modifiers, query }) => {
+ const text = `${branch.name}`;
+
+ return (
+
+ );
+};
+
+const branchSelectProps = {
+ itemPredicate: branchItemPredicate,
+ itemRenderer: branchItemRenderer,
+ valueAccessor: 'id',
+ labelAccessor: 'name',
+};
+
+/**
+ *
+ * @param {*} param0
+ * @returns
+ */
+export function BranchSelect({ branches, ...rest }) {
+ return ;
+}
+
+/**
+ *
+ * @param {*} param0
+ * @returns
+ */
+export function BranchSelectButton({ label, ...rest }) {
+ return ;
+}
diff --git a/src/components/Branches/index.js b/src/components/Branches/index.js
new file mode 100644
index 000000000..b9c3a7b24
--- /dev/null
+++ b/src/components/Branches/index.js
@@ -0,0 +1,2 @@
+export * from './BranchSelect';
+export * from './BranchMultiSelect'
\ No newline at end of file
diff --git a/src/components/Currencies/BaseCurrency.js b/src/components/Currencies/BaseCurrency.js
new file mode 100644
index 000000000..98a3a14ff
--- /dev/null
+++ b/src/components/Currencies/BaseCurrency.js
@@ -0,0 +1,10 @@
+import React from 'react';
+import { CurrencyTag } from 'components';
+
+/**
+ * base currecncy.
+ * @returns
+ */
+export function BaseCurrency({ currency }) {
+ return {currency};
+}
diff --git a/src/components/Currencies/CurrencySelect.js b/src/components/Currencies/CurrencySelect.js
new file mode 100644
index 000000000..c5557ff33
--- /dev/null
+++ b/src/components/Currencies/CurrencySelect.js
@@ -0,0 +1,76 @@
+import React from 'react';
+import intl from 'react-intl-universal';
+
+import { MenuItem, Button } from '@blueprintjs/core';
+import { FSelect } from '../Forms';
+
+/**
+ *
+ * @param {*} query
+ * @param {*} currency
+ * @param {*} _index
+ * @param {*} exactMatch
+ * @returns
+ */
+const currencyItemPredicate = (query, currency, _index, exactMatch) => {
+ const normalizedTitle = currency.currency_code.toLowerCase();
+ const normalizedQuery = query.toLowerCase();
+
+ if (exactMatch) {
+ return normalizedTitle === normalizedQuery;
+ } else {
+ return (
+ `${currency.currency_code}. ${normalizedTitle}`.indexOf(
+ normalizedQuery,
+ ) >= 0
+ );
+ }
+};
+
+/**
+ * @param {*} currency
+ * @returns
+ */
+const currencyItemRenderer = (currency, { handleClick, modifiers, query }) => {
+ return (
+
+ );
+};
+
+const currencySelectProps = {
+ itemPredicate: currencyItemPredicate,
+ itemRenderer: currencyItemRenderer,
+ valueAccessor: 'currency_code',
+ labelAccessor: 'currency_code',
+};
+
+/**
+ *
+ * @param {*} currencies
+ * @returns
+ */
+export function CurrencySelect({ currencies, ...rest }) {
+ return (
+
+ );
+}
+
+/**
+ * @param {*} label
+ * @returns
+ */
+function CurrnecySelectButton({ label }) {
+ return ;
+}
diff --git a/src/components/Currencies/index.js b/src/components/Currencies/index.js
new file mode 100644
index 000000000..57a528c05
--- /dev/null
+++ b/src/components/Currencies/index.js
@@ -0,0 +1,2 @@
+export * from './CurrencySelect';
+export * from './BaseCurrency';
diff --git a/src/components/CustomSelectList.js b/src/components/CustomSelectList.js
new file mode 100644
index 000000000..36e783f6b
--- /dev/null
+++ b/src/components/CustomSelectList.js
@@ -0,0 +1,109 @@
+import React from 'react';
+import styled from 'styled-components';
+import {
+ Button,
+ MenuItem,
+ PopoverInteractionKind,
+ Position,
+ Classes,
+} from '@blueprintjs/core';
+import clsx from 'classnames';
+import { defaultTo } from 'lodash';
+import { Select } from '@blueprintjs/select';
+import { FormattedMessage as T, Icon } from 'components';
+
+/**
+ * warehouse & branches select list.
+ * @returns
+ */
+export default function CustomSelectList({
+ // #ownProps
+ items,
+ initialItemId,
+ selectedItemId,
+ loading = false,
+ defaultSelectText,
+ onItemSelected,
+ buttonProps,
+}) {
+ const initialItem = React.useMemo(
+ () => items.find((a) => a.id === initialItemId),
+ [initialItemId, items],
+ );
+
+ const [selecetedItem, setSelectedItem] = React.useState(initialItem || null);
+
+ React.useEffect(() => {
+ if (typeof selectedItemId !== 'undefined') {
+ const item = selectedItemId
+ ? items.find((a) => a.id === selectedItemId)
+ : null;
+ setSelectedItem(item);
+ }
+ }, [selectedItemId, items, setSelectedItem]);
+
+ // Menu items renderer.
+ const itemRenderer = (item, { handleClick, modifiers, query }) => (
+
+ );
+
+ // Filters items items.
+ const filterItemsPredicater = (query, item, _index, exactMatch) => {
+ const normalizedTitle = item.name.toLowerCase();
+ const normalizedQuery = query.toLowerCase();
+
+ if (exactMatch) {
+ return normalizedTitle === normalizedQuery;
+ } else {
+ return `${item.code} ${normalizedTitle}`.indexOf(normalizedQuery) >= 0;
+ }
+ };
+
+ const handleItemMenuSelect = React.useCallback(
+ (item) => {
+ if (item.id) {
+ setSelectedItem({ ...item });
+ onItemSelected && onItemSelected(item);
+ }
+ },
+ [onItemSelected, setSelectedItem],
+ );
+
+ return (
+ } />}
+ itemRenderer={itemRenderer}
+ itemPredicate={filterItemsPredicater}
+ onItemSelect={handleItemMenuSelect}
+ popoverProps={{
+ minimal: true,
+ position: Position.BOTTOM_LEFT,
+ interactionKind: PopoverInteractionKind.CLICK,
+ modifiers: {
+ offset: { offset: '0, 4' },
+ },
+ }}
+ className={clsx({ [Classes.SKELETON]: loading })}
+ >
+
+
+ );
+}
diff --git a/src/components/Customers/CustomerDrawerLink.js b/src/components/Customers/CustomerDrawerLink.js
index a5b075fa9..d4290ff60 100644
--- a/src/components/Customers/CustomerDrawerLink.js
+++ b/src/components/Customers/CustomerDrawerLink.js
@@ -8,16 +8,22 @@ function CustomerDrawerLinkComponent({
// #ownProps
children,
customerId,
+ className,
// #withDrawerActions
openDrawer,
}) {
// Handle view customer drawer.
- const handleCustomerDrawer = () => {
+ const handleCustomerDrawer = (event) => {
openDrawer('customer-details-drawer', { customerId });
+ event.preventDefault();
};
- return {children};
+ return (
+
+ {children}
+
+ );
}
export const CustomerDrawerLink = R.compose(withDrawerActions)(
diff --git a/src/components/DataTableCells/AccountsListFieldCell.js b/src/components/DataTableCells/AccountsListFieldCell.js
index 690e64b24..cc253e6c7 100644
--- a/src/components/DataTableCells/AccountsListFieldCell.js
+++ b/src/components/DataTableCells/AccountsListFieldCell.js
@@ -1,13 +1,12 @@
import React, { useRef, useCallback, useMemo } from 'react';
import classNames from 'classnames';
-import { useCellAutoFocus } from 'hooks';
+import { FormGroup, Classes, Intent } from '@blueprintjs/core';
import intl from 'react-intl-universal';
+import { CellType } from 'common';
+import { useCellAutoFocus } from 'hooks';
import AccountsSuggestField from 'components/AccountsSuggestField';
-// import AccountsSelectList from 'components/AccountsSelectList';
-import { FormGroup, Classes, Intent } from '@blueprintjs/core';
-
/**
* Account cell renderer.
*/
@@ -74,3 +73,4 @@ export default function AccountCellRenderer({
);
}
+AccountCellRenderer.cellType = CellType.Field;
diff --git a/src/components/DataTableCells/BranchesListFieldCell.js b/src/components/DataTableCells/BranchesListFieldCell.js
new file mode 100644
index 000000000..4c49a5701
--- /dev/null
+++ b/src/components/DataTableCells/BranchesListFieldCell.js
@@ -0,0 +1,44 @@
+import React from 'react';
+import { FormGroup, Intent, Classes } from '@blueprintjs/core';
+import classNames from 'classnames';
+
+import { CellType } from 'common';
+import BranchSuggestField from '../BranchSuggestField';
+
+/**
+ * Branches list field cell.
+ * @returns
+ */
+export default function BranchesListFieldCell({
+ column: { id },
+ row: { index, original },
+ payload: { branches, updateData, errors },
+}) {
+ const handleBranchSelected = React.useCallback(
+ (branch) => {
+ updateData(index, 'branch_id', branch.id);
+ },
+ [updateData, index],
+ );
+
+ const error = errors?.[index]?.[id];
+
+ return (
+
+
+
+ );
+}
+
+BranchesListFieldCell.cellType = CellType.Field;
\ No newline at end of file
diff --git a/src/components/DataTableCells/CheckBoxFieldCell.js b/src/components/DataTableCells/CheckBoxFieldCell.js
index 7391a3a1d..77b0d7e50 100644
--- a/src/components/DataTableCells/CheckBoxFieldCell.js
+++ b/src/components/DataTableCells/CheckBoxFieldCell.js
@@ -2,6 +2,7 @@ import React from 'react';
import classNames from 'classnames';
import { get } from 'lodash';
import { Classes, Checkbox, FormGroup, Intent } from '@blueprintjs/core';
+import { CellType } from 'common';
const CheckboxEditableCell = ({
row: { index, original },
@@ -45,4 +46,6 @@ const CheckboxEditableCell = ({
);
};
+CheckboxEditableCell.cellType = CellType.Field;
+
export default CheckboxEditableCell;
diff --git a/src/components/DataTableCells/ContactsListFieldCell.js b/src/components/DataTableCells/ContactsListFieldCell.js
index 468764d62..41ee64805 100644
--- a/src/components/DataTableCells/ContactsListFieldCell.js
+++ b/src/components/DataTableCells/ContactsListFieldCell.js
@@ -1,9 +1,9 @@
import React, { useCallback } from 'react';
import { FormGroup, Intent, Classes } from '@blueprintjs/core';
import classNames from 'classnames';
-import { ContactSelecetList } from 'components';
-import ContactsSuggestField from 'components/ContactsSuggestField';
+import { CellType } from 'common';
+import ContactsSuggestField from 'components/ContactsSuggestField';
export default function ContactsListCellRenderer({
column: { id },
row: { index, original },
@@ -37,3 +37,5 @@ export default function ContactsListCellRenderer({
);
}
+
+ContactsListCellRenderer.cellType = CellType.Field;
diff --git a/src/components/DataTableCells/InputGroupCell.js b/src/components/DataTableCells/InputGroupCell.js
index c34c89291..9eb2d597d 100644
--- a/src/components/DataTableCells/InputGroupCell.js
+++ b/src/components/DataTableCells/InputGroupCell.js
@@ -1,6 +1,7 @@
import React, { useState, useEffect } from 'react';
import classNames from 'classnames';
import { Classes, InputGroup, FormGroup, Intent } from '@blueprintjs/core';
+import { CellType } from 'common';
const InputEditableCell = ({
row: { index },
@@ -37,4 +38,6 @@ const InputEditableCell = ({
);
};
+InputEditableCell.cellType = CellType.Field;
+
export default InputEditableCell;
diff --git a/src/components/DataTableCells/ItemsListCell.js b/src/components/DataTableCells/ItemsListCell.js
index ed6c024c6..97385c8f5 100644
--- a/src/components/DataTableCells/ItemsListCell.js
+++ b/src/components/DataTableCells/ItemsListCell.js
@@ -3,6 +3,7 @@ import classNames from 'classnames';
import { FormGroup, Classes, Intent } from '@blueprintjs/core';
import intl from 'react-intl-universal';
+import { CellType } from 'common';
import ItemsSuggestField from 'components/ItemsSuggestField';
import { useCellAutoFocus } from 'hooks';
@@ -54,3 +55,5 @@ export default function ItemsListCell({
);
}
+
+ItemsListCell.cellType = CellType.Field;
diff --git a/src/components/DataTableCells/MoneyFieldCell.js b/src/components/DataTableCells/MoneyFieldCell.js
index 710840de3..d8a284680 100644
--- a/src/components/DataTableCells/MoneyFieldCell.js
+++ b/src/components/DataTableCells/MoneyFieldCell.js
@@ -1,7 +1,9 @@
import React, { useCallback, useState, useEffect } from 'react';
import { FormGroup, Intent } from '@blueprintjs/core';
+
import { MoneyInputGroup } from 'components';
import { CLASSES } from 'common/classes';
+import { CellType } from 'common';
// Input form cell renderer.
const MoneyFieldCellRenderer = ({
@@ -48,4 +50,6 @@ const MoneyFieldCellRenderer = ({
);
};
+MoneyFieldCellRenderer.cellType = CellType.Field;
+
export default MoneyFieldCellRenderer;
diff --git a/src/components/DataTableCells/NumericInputCell.js b/src/components/DataTableCells/NumericInputCell.js
index eaf933fb8..dfa7e7182 100644
--- a/src/components/DataTableCells/NumericInputCell.js
+++ b/src/components/DataTableCells/NumericInputCell.js
@@ -1,6 +1,8 @@
import React, { useState, useEffect } from 'react';
import { FormGroup, NumericInput, Intent } from '@blueprintjs/core';
import classNames from 'classnames';
+
+import { CellType } from 'common';
import { CLASSES } from 'common/classes';
/**
@@ -36,8 +38,10 @@ export default function NumericInputCell({
onValueChange={handleValueChange}
onBlur={onBlur}
fill={true}
- buttonPosition={"none"}
+ buttonPosition={'none'}
/>
);
}
+
+NumericInputCell.cellType = CellType.Field;
\ No newline at end of file
diff --git a/src/components/DataTableCells/PaymentReceiveListFieldCell.js b/src/components/DataTableCells/PaymentReceiveListFieldCell.js
index 0b37e05f7..909861ea7 100644
--- a/src/components/DataTableCells/PaymentReceiveListFieldCell.js
+++ b/src/components/DataTableCells/PaymentReceiveListFieldCell.js
@@ -1,8 +1,9 @@
import React, { useCallback } from 'react';
-import PaymentReceiveListField from 'components/PaymentReceiveListField';
import classNames from 'classnames';
import { FormGroup, Classes, Intent } from '@blueprintjs/core';
+import PaymentReceiveListField from 'components/PaymentReceiveListField';
+import { CellType } from 'common';
function PaymentReceiveListFieldCell({
column: { id },
row: { index },
@@ -32,4 +33,6 @@ function PaymentReceiveListFieldCell({
);
}
+PaymentReceiveListFieldCell.cellType = CellType.Field;
+
export default PaymentReceiveListFieldCell;
diff --git a/src/components/DataTableCells/PercentFieldCell.js b/src/components/DataTableCells/PercentFieldCell.js
index 5638aa4b3..5d0c70625 100644
--- a/src/components/DataTableCells/PercentFieldCell.js
+++ b/src/components/DataTableCells/PercentFieldCell.js
@@ -1,6 +1,8 @@
import React, { useCallback, useState, useEffect } from 'react';
import { FormGroup, Intent } from '@blueprintjs/core';
+
import { MoneyInputGroup } from 'components';
+import { CellType } from 'common';
const PercentFieldCell = ({
cell: { value: initialValue },
@@ -38,4 +40,6 @@ const PercentFieldCell = ({
);
};
+PercentFieldCell.cellType = CellType.Field;
+
export default PercentFieldCell;
diff --git a/src/components/DataTableCells/SwitchFieldCell.js b/src/components/DataTableCells/SwitchFieldCell.js
index a25e96ae4..876f70474 100644
--- a/src/components/DataTableCells/SwitchFieldCell.js
+++ b/src/components/DataTableCells/SwitchFieldCell.js
@@ -2,6 +2,7 @@ import React from 'react';
import classNames from 'classnames';
import { Classes, Switch, FormGroup, Intent } from '@blueprintjs/core';
+import { CellType } from 'common';
import { safeInvoke } from 'utils';
/**
@@ -48,4 +49,6 @@ const SwitchEditableCell = ({
);
};
-export default SwitchEditableCell;
\ No newline at end of file
+SwitchEditableCell.cellType = CellType.Field;
+
+export default SwitchEditableCell;
diff --git a/src/components/DataTableCells/TextAreaCell.js b/src/components/DataTableCells/TextAreaCell.js
index c8ff97a0c..f36b83981 100644
--- a/src/components/DataTableCells/TextAreaCell.js
+++ b/src/components/DataTableCells/TextAreaCell.js
@@ -1,6 +1,7 @@
import React, { useState, useEffect } from 'react';
import classNames from 'classnames';
import { Classes, TextArea, FormGroup, Intent } from '@blueprintjs/core';
+import { CellType } from 'common';
const TextAreaEditableCell = ({
row: { index },
@@ -39,4 +40,6 @@ const TextAreaEditableCell = ({
);
};
+TextAreaEditableCell.cellType = CellType.Field;
+
export default TextAreaEditableCell;
diff --git a/src/components/DataTableCells/index.js b/src/components/DataTableCells/index.js
index fed349eed..98d4aec24 100644
--- a/src/components/DataTableCells/index.js
+++ b/src/components/DataTableCells/index.js
@@ -9,6 +9,7 @@ import NumericInputCell from './NumericInputCell';
import CheckBoxFieldCell from './CheckBoxFieldCell';
import SwitchFieldCell from './SwitchFieldCell';
import TextAreaCell from './TextAreaCell';
+import BranchesListFieldCell from './BranchesListFieldCell';
export {
AccountsListFieldCell,
@@ -23,4 +24,5 @@ export {
CheckBoxFieldCell,
SwitchFieldCell,
TextAreaCell,
+ BranchesListFieldCell,
};
diff --git a/src/components/Datatable/DatatableEditable.js b/src/components/Datatable/DatatableEditable.js
index f067ea6af..d17f768c0 100644
--- a/src/components/Datatable/DatatableEditable.js
+++ b/src/components/Datatable/DatatableEditable.js
@@ -1,8 +1,7 @@
import React from 'react';
-import classNames from 'classnames';
-import { CLASSES } from 'common/classes';
-import { DataTable, If } from 'components';
-import 'style/components/DataTable/DataTableEditable.scss';
+import styled from 'styled-components';
+
+import { DataTable } from 'components';
/**
* Editable datatable.
@@ -11,26 +10,106 @@ export default function DatatableEditable({
totalRow = false,
actions,
name,
- className,
...tableProps
}) {
return (
-
+
-
-
-
- {actions}
-
-
-
+
);
}
+
+const DatatableEditableRoot = styled.div`
+ .bp3-form-group {
+ margin-bottom: 0;
+ }
+ .table {
+ border: 1px solid #d2dce2;
+ border-radius: 5px;
+ background-color: #fff;
+
+ .th,
+ .td {
+ border-left: 1px solid #e2e2e2;
+
+ &:first-of-type{
+ border-left: 0;
+ }
+ }
+
+ .thead {
+ .tr .th {
+ padding: 9px 14px;
+ background-color: #f2f3fb;
+ font-size: 13px;
+ color: #415060;
+ border-bottom: 1px solid #d2dce2;
+
+ &,
+ .inner-resizer {
+ border-left-color: transparent;
+ }
+ }
+ }
+ .tbody {
+ .tr .td {
+ border-bottom: 0;
+ border-bottom: 1px solid #d8d8d8;
+ min-height: 38px;
+ padding: 4px 14px;
+
+ &.td-field-type,
+ &.td-button-type{
+ padding: 2px;
+ }
+ }
+ .tr:last-of-type .td {
+ border-bottom: 0;
+ }
+ .tr {
+ &:hover .td,
+ .bp3-input {
+ background-color: transparent;
+ }
+ .bp3-form-group:not(.bp3-intent-danger) .bp3-input,
+ .form-group--select-list .bp3-button {
+ border-color: #ffffff;
+ color: #222;
+ border-radius: 3px;
+ text-align: inherit;
+ }
+ .bp3-form-group:not(.bp3-intent-danger) .bp3-input {
+ border-radius: 2px;
+ padding-left: 14px;
+ padding-right: 14px;
+
+ &:focus {
+ box-shadow: 0 0 0 2px #116cd0;
+ }
+ }
+ .form-group--select-list .bp3-button {
+ padding-left: 6px;
+ padding-right: 6px;
+
+ &:after {
+ display: none;
+ }
+ }
+ .form-group--select-list,
+ .bp3-form-group {
+ &.bp3-intent-danger {
+ .bp3-button:not(.bp3-minimal),
+ .bp3-input {
+ border-color: #f7b6b6;
+ }
+ }
+ }
+ .td.actions {
+ .bp3-button {
+ color: #80858f;
+ }
+ }
+ }
+ }
+ }
+`;
diff --git a/src/components/Datatable/TableCell.js b/src/components/Datatable/TableCell.js
index 87c903ef9..db44ac07d 100644
--- a/src/components/Datatable/TableCell.js
+++ b/src/components/Datatable/TableCell.js
@@ -1,7 +1,8 @@
import React, { useContext } from 'react';
import classNames from 'classnames';
-import { If } from 'components';
-import { Skeleton } from 'components';
+import { camelCase} from 'lodash';
+
+import { If, Skeleton } from 'components';
import { useAppIntlContext } from 'components/AppIntlProvider';
import TableContext from './TableContext';
import { saveInvoke, ignoreEventFromSelectors } from 'utils';
@@ -56,7 +57,8 @@ export default function TableCell({ cell, row, index }) {
return;
}
saveInvoke(onCellClick, cell, event);
- };
+ };
+ const cellType = camelCase(cell.column.Cell.cellType) || 'text';
return (
@@ -8,3 +8,5 @@ export default function TableIndeterminateCheckboxRow({ row }) {
);
}
+
+TableIndeterminateCheckboxRow.cellType = CellType.Field;
diff --git a/src/components/DetailExchangeRate.js b/src/components/DetailExchangeRate.js
new file mode 100644
index 000000000..ba2d4622a
--- /dev/null
+++ b/src/components/DetailExchangeRate.js
@@ -0,0 +1,34 @@
+import React from 'react';
+import intl from 'react-intl-universal';
+import * as R from 'ramda';
+import { DetailItem } from 'components';
+import { isEqual } from 'lodash';
+
+import withCurrentOrganization from 'containers/Organization/withCurrentOrganization';
+
+/**
+ * Detail exchange rate item.
+ * @param {*} param0
+ * @param {*} param1
+ * @returns
+ */
+function DetailExchangeRate({
+ exchangeRate,
+ toCurrency,
+ // #withCurrentOrganization
+ organization: { base_currency },
+}) {
+ if (isEqual(base_currency, toCurrency)) {
+ return null;
+ }
+
+ return (
+
+ 1 {base_currency} = {exchangeRate} {toCurrency}
+
+ );
+}
+
+export const ExchangeRateDetailItem = R.compose(withCurrentOrganization())(
+ DetailExchangeRate,
+);
diff --git a/src/components/DialogsContainer.js b/src/components/DialogsContainer.js
index cd8eb745e..8ddff3496 100644
--- a/src/components/DialogsContainer.js
+++ b/src/components/DialogsContainer.js
@@ -34,6 +34,12 @@ import UnlockingTransactionsDialog from '../containers/Dialogs/UnlockingTransact
import UnlockingPartialTransactionsDialog from '../containers/Dialogs/UnlockingPartialTransactionsDialog';
import CreditNotePdfPreviewDialog from '../containers/Dialogs/CreditNotePdfPreviewDialog';
import PaymentReceivePdfPreviewDialog from '../containers/Dialogs/PaymentReceivePdfPreviewDialog';
+import WarehouseFormDialog from '../containers/Dialogs/WarehouseFormDialog';
+import BranchFormDialog from '../containers/Dialogs/BranchFormDialog';
+import BranchActivateDialog from '../containers/Dialogs/BranchActivateDialog';
+import WarehouseActivateDialog from '../containers/Dialogs/WarehouseActivateDialog';
+import CustomerOpeningBalanceDialog from '../containers/Dialogs/CustomerOpeningBalanceDialog';
+import VendorOpeningBalanceDialog from '../containers/Dialogs/VendorOpeningBalanceDialog';
/**
* Dialogs container.
@@ -78,6 +84,12 @@ export default function DialogsContainer() {
/>
+
+
+
+
+
+
);
}
diff --git a/src/components/Drawer/DrawerHeaderContent.js b/src/components/Drawer/DrawerHeaderContent.js
index ff506c267..11c86f380 100644
--- a/src/components/Drawer/DrawerHeaderContent.js
+++ b/src/components/Drawer/DrawerHeaderContent.js
@@ -4,6 +4,7 @@ import { Classes, Icon, H4, Button } from '@blueprintjs/core';
import withDrawerActions from 'containers/Drawer/withDrawerActions';
+import styled from 'styled-components';
import { compose } from 'utils';
/**
@@ -13,6 +14,7 @@ function DrawerHeaderContent(props) {
const {
icon,
title = ,
+ subTitle,
onClose,
name,
closeDrawer,
@@ -30,7 +32,10 @@ function DrawerHeaderContent(props) {
return (
-
{title}
+
+ {title}
+ {subTitle}
+
);
}
diff --git a/src/components/ExchangeRate/ExchangeRateInput.js b/src/components/ExchangeRate/ExchangeRateInput.js
new file mode 100644
index 000000000..81ec4bc9d
--- /dev/null
+++ b/src/components/ExchangeRate/ExchangeRateInput.js
@@ -0,0 +1,58 @@
+import React from 'react';
+import styled from 'styled-components';
+import { ControlGroup } from '@blueprintjs/core';
+
+import { FlagIcon } from '../Tags';
+import { FMoneyInputGroup, FFormGroup } from '../Forms';
+
+export function ExchangeRateInputGroup({
+ fromCurrency,
+ toCurrency,
+ inputGroupProps,
+ formGroupProps,
+ name,
+}) {
+ return (
+
+
+
+ 1 {fromCurrency} =
+
+
+
+ {toCurrency}
+
+
+
+ );
+}
+
+const ExchangeRateField = styled(FMoneyInputGroup)`
+ max-width: 75px;
+`;
+
+const ExchangeRateSideIcon = styled.div`
+ display: flex;
+ align-items: center;
+ font-size: 12px;
+ line-height: 1;
+`;
+
+const ExchangeRatePrepend = styled(ExchangeRateSideIcon)`
+ padding-right: 8px;
+`;
+
+const ExchangeRateAppend = styled(ExchangeRateSideIcon)`
+ padding-left: 8px;
+`;
+
+const ExchangeFlagIcon = styled(FlagIcon)`
+ margin-right: 5px;
+ margin-left: 5px;
+ display: inline-block;
+`;
diff --git a/src/components/ExchangeRate/ExchangeRateMutedField.js b/src/components/ExchangeRate/ExchangeRateMutedField.js
new file mode 100644
index 000000000..606d560bc
--- /dev/null
+++ b/src/components/ExchangeRate/ExchangeRateMutedField.js
@@ -0,0 +1,94 @@
+import React from 'react';
+import styled from 'styled-components';
+import intl from 'react-intl-universal';
+import {
+ Button,
+ Popover,
+ PopoverInteractionKind,
+ FormGroup,
+ Position,
+ Classes,
+} from '@blueprintjs/core';
+import { ExchangeRateInputGroup, Icon } from 'components';
+
+export function ExchangeRateMutedField({
+ name,
+ toCurrency,
+ fromCurrency,
+ date,
+ exchangeRate,
+ exchangeRateFieldProps,
+ popoverProps,
+}) {
+ const content = (
+
+
+
+ );
+
+ return (
+
+ }
+ >
+
+ 1 {fromCurrency} = {exchangeRate} {toCurrency}
+ }
+ small={true}
+ />
+
+
+
+ );
+}
+
+const ExchangeRateFormGroup = styled(FormGroup)`
+ &.bp3-form-group {
+ label.bp3-label {
+ font-size: 12px;
+ opacity: 0.7;
+ line-height: 1;
+ margin-bottom: 5px;
+ }
+ }
+`;
+
+const ExchangeRateButton = styled.div`
+ display: flex;
+ align-items: center;
+ font-size: 13px;
+ font-weight: 400;
+ color: #0d244a;
+ position: relative;
+ padding-right: 28px;
+
+ .bp3-button {
+ position: absolute;
+ right: 0;
+ }
+`;
+
+const ExchangeRateFormGroupContent = styled.div`
+ padding: 5px 0;
+
+ .bp3-form-group {
+ padding: 2px;
+ margin: 2px 4px !important;
+ }
+`;
diff --git a/src/components/ExchangeRate/index.js b/src/components/ExchangeRate/index.js
new file mode 100644
index 000000000..039d6732e
--- /dev/null
+++ b/src/components/ExchangeRate/index.js
@@ -0,0 +1,2 @@
+export * from './ExchangeRateInput';
+export * from './ExchangeRateMutedField'
\ No newline at end of file
diff --git a/src/components/FeatureGuard/FeatureCan.js b/src/components/FeatureGuard/FeatureCan.js
new file mode 100644
index 000000000..9e21441b6
--- /dev/null
+++ b/src/components/FeatureGuard/FeatureCan.js
@@ -0,0 +1,13 @@
+import React from 'react';
+import * as R from 'ramda';
+import withFeatureCan from './withFeatureCan';
+
+function FeatureCanJSX({ feature, children, isFeatureCan }) {
+ return isFeatureCan && children;
+}
+
+export const FeatureCan = R.compose(
+ withFeatureCan(({ isFeatureCan }) => ({
+ isFeatureCan,
+ })),
+)(FeatureCanJSX);
diff --git a/src/components/FeatureGuard/index.js b/src/components/FeatureGuard/index.js
new file mode 100644
index 000000000..d8e32e3b0
--- /dev/null
+++ b/src/components/FeatureGuard/index.js
@@ -0,0 +1 @@
+export * from './FeatureCan';
\ No newline at end of file
diff --git a/src/components/FeatureGuard/withFeatureCan.js b/src/components/FeatureGuard/withFeatureCan.js
new file mode 100644
index 000000000..aee7666a8
--- /dev/null
+++ b/src/components/FeatureGuard/withFeatureCan.js
@@ -0,0 +1,17 @@
+import { connect } from 'react-redux';
+import { getDashboardFeaturesSelector } from '../../store/dashboard/dashboard.selectors';
+
+export default (mapState) => {
+ const featuresSelector = getDashboardFeaturesSelector();
+
+ const mapStateToProps = (state, props) => {
+ const features = featuresSelector(state);
+
+ const mapped = {
+ isFeatureCan: !!features[props.feature],
+ features,
+ };
+ return mapState ? mapState(mapped, state, props) : mapped;
+ };
+ return connect(mapStateToProps);
+};
diff --git a/src/components/FormTopbar.js b/src/components/FormTopbar.js
new file mode 100644
index 000000000..3cf314ab4
--- /dev/null
+++ b/src/components/FormTopbar.js
@@ -0,0 +1,44 @@
+import React from 'react';
+import styled from 'styled-components';
+import { Navbar } from '@blueprintjs/core';
+
+/**
+ * Form the topbar.
+ * @param {JSX.Element} children
+ * @returns {JSX.Element}
+ */
+export function FormTopbar({ className, children }) {
+ return {children};
+}
+
+const FormTopBarRoot = styled(Navbar)`
+ box-shadow: 0 0 0;
+ border-bottom: 1px solid #c7d5db;
+ height: 35px;
+ padding: 0 20px;
+
+ .bp3-navbar-group {
+ height: 35px;
+ }
+ .bp3-navbar-divider {
+ border-left-color: #d2dce2;
+ }
+ .bp3-skeleton {
+ max-height: 10px;
+ }
+ .bp3-button {
+ &:hover {
+ background: rgba(167, 182, 194, 0.12);
+ color: #32304a;
+ }
+ }
+`;
+
+export const DetailsBarSkeletonBase = styled.div`
+ letter-spacing: 10px;
+ margin-right: 10px;
+ margin-left: 10px;
+ font-size: 8px;
+ width: 140px;
+ height: 10px;
+`;
diff --git a/src/components/Forms/BlueprintFormik.js b/src/components/Forms/BlueprintFormik.js
new file mode 100644
index 000000000..a82afbf3c
--- /dev/null
+++ b/src/components/Forms/BlueprintFormik.js
@@ -0,0 +1,24 @@
+import {
+ FormGroup,
+ InputGroup,
+ NumericInput,
+ Checkbox,
+ RadioGroup,
+ Switch,
+ EditableText,
+ TextArea,
+} from '@blueprintjs-formik/core';
+import { Select, MultiSelect } from '@blueprintjs-formik/select';
+
+export {
+ FormGroup as FFormGroup,
+ InputGroup as FInputGroup,
+ NumericInput as FNumericInput,
+ Checkbox as FCheckbox,
+ RadioGroup as FRadioGroup,
+ Switch as FSwitch,
+ Select as FSelect,
+ MultiSelect as FMultiSelect,
+ EditableText as FEditableText,
+ TextArea as FTextArea,
+};
diff --git a/src/components/Forms/FMoneyInputGroup.js b/src/components/Forms/FMoneyInputGroup.js
new file mode 100644
index 000000000..2bc69fd35
--- /dev/null
+++ b/src/components/Forms/FMoneyInputGroup.js
@@ -0,0 +1,36 @@
+import React from 'react';
+import { Intent } from '@blueprintjs/core';
+import { Field, getIn } from 'formik';
+import { CurrencyInput } from './MoneyInputGroup';
+
+const fieldToMoneyInputGroup = ({
+ field: { onBlur: onFieldBlur, ...field },
+ form: { setFieldValue, touched, errors },
+ onBlur,
+ ...props
+}) => {
+ const fieldError = getIn(errors, field.name);
+ const showError = getIn(touched, field.name) && !!fieldError;
+
+ return {
+ intent: showError ? Intent.DANGER : Intent.NONE,
+ onBlurValue:
+ onBlur ??
+ function (e) {
+ onFieldBlur(e ?? field.name);
+ },
+ ...field,
+ onChange: (value) => {
+ setFieldValue(field.name, value);
+ },
+ ...props,
+ };
+};
+
+function FieldToMoneyInputGroup({ ...props }) {
+ return ;
+}
+
+export function FMoneyInputGroup({ ...props }) {
+ return ;
+}
diff --git a/src/components/Forms/FormikObserver.js b/src/components/Forms/FormikObserver.js
index a93b06864..c9e3a3270 100644
--- a/src/components/Forms/FormikObserver.js
+++ b/src/components/Forms/FormikObserver.js
@@ -1,7 +1,9 @@
-
+import { useFormikContext } from 'formik';
import { useDeepCompareEffect } from 'hooks/utils';
-export function FormikObserver({ onChange, values }) {
+export function FormikObserver({ onChange }) {
+ const { values } = useFormikContext();
+
useDeepCompareEffect(() => {
onChange(values);
}, [values]);
diff --git a/src/components/Forms/index.js b/src/components/Forms/index.js
index c531c474b..8c016ac31 100644
--- a/src/components/Forms/index.js
+++ b/src/components/Forms/index.js
@@ -1,2 +1,4 @@
export * from './FormObserver';
-export * from './FormikObserver';
\ No newline at end of file
+export * from './FormikObserver';
+export * from './FMoneyInputGroup'
+export * from './BlueprintFormik';
\ No newline at end of file
diff --git a/src/components/Paper/Paper.js b/src/components/Paper/Paper.js
new file mode 100644
index 000000000..c84c17aab
--- /dev/null
+++ b/src/components/Paper/Paper.js
@@ -0,0 +1,12 @@
+import React from 'react';
+import styled from 'styled-components';
+
+export function Paper({ children, className }) {
+ return {children};
+}
+
+const PaperRoot = styled.div`
+ border: 1px solid #d2dce2;
+ background: #fff;
+ padding: 10px;
+`;
diff --git a/src/components/Paper/index.js b/src/components/Paper/index.js
new file mode 100644
index 000000000..50257d591
--- /dev/null
+++ b/src/components/Paper/index.js
@@ -0,0 +1 @@
+export * from './Paper';
\ No newline at end of file
diff --git a/src/components/Preferences/PreferencesTopbar.js b/src/components/Preferences/PreferencesTopbar.js
index 1633ecc8f..98b593667 100644
--- a/src/components/Preferences/PreferencesTopbar.js
+++ b/src/components/Preferences/PreferencesTopbar.js
@@ -6,6 +6,8 @@ import { CLASSES } from 'common/classes';
import DashboardTopbarUser from 'components/Dashboard/TopbarUser';
import UsersActions from 'containers/Preferences/Users/UsersActions';
import CurrenciesActions from 'containers/Preferences/Currencies/CurrenciesActions';
+import WarehousesActions from '../../containers/Preferences/Warehouses/WarehousesActions';
+import BranchesActions from '../../containers/Preferences/Branches/BranchesActions';
import withDashboard from 'containers/Dashboard/withDashboard';
import { compose } from 'utils';
@@ -35,6 +37,16 @@ function PreferencesTopbar({ preferencesPageTitle }) {
path={'/preferences/currencies'}
component={CurrenciesActions}
/>
+
+
diff --git a/src/components/Tags/CurrencyTag.js b/src/components/Tags/CurrencyTag.js
index a427c0230..7e9a0ee7a 100644
--- a/src/components/Tags/CurrencyTag.js
+++ b/src/components/Tags/CurrencyTag.js
@@ -9,3 +9,13 @@ export const CurrencyTag = styled.span`
line-height: 1;
margin-left: 4px;
`;
+
+export const BaseCurrencyRoot = styled.div`
+ display: flex;
+ align-items: center;
+ font-size: 10px;
+ margin-left: 4px;
+ > span {
+ background: #5c7080;
+ }
+`;
diff --git a/src/components/Tags/FlagIcon.js b/src/components/Tags/FlagIcon.js
new file mode 100644
index 000000000..b90d8e1ed
--- /dev/null
+++ b/src/components/Tags/FlagIcon.js
@@ -0,0 +1,7 @@
+import React from 'react';
+
+export const FlagIcon = ({ currencyCode, className }) => {
+ const source = `/icons/flags/${currencyCode}.svg`;
+
+ return ;
+};
diff --git a/src/components/Tags/index.js b/src/components/Tags/index.js
index 7eca83954..1f765a8ac 100644
--- a/src/components/Tags/index.js
+++ b/src/components/Tags/index.js
@@ -1,3 +1,4 @@
-export * from './CurrencyTag';
\ No newline at end of file
+export * from './CurrencyTag';
+export * from './FlagIcon'
\ No newline at end of file
diff --git a/src/components/TotalLines/index.js b/src/components/TotalLines/index.js
index 1b2d88fc6..43110aa26 100644
--- a/src/components/TotalLines/index.js
+++ b/src/components/TotalLines/index.js
@@ -2,6 +2,7 @@ import React from 'react';
import styled from 'styled-components';
export const TotalLineBorderStyle = {
+ None: 'None',
SingleDark: 'SingleDark',
DoubleDark: 'DoubleDark',
};
@@ -80,6 +81,11 @@ export const TotalLineRoot = styled.div`
`
border-bottom: 1px double #000;
`}
+ ${(props) =>
+ props.borderStyle === TotalLineBorderStyle.None &&
+ `
+ border-bottom-color: transparent;
+ `}
${(props) =>
props.textStyle === TotalLineTextStyle.Bold &&
`
diff --git a/src/components/Vendors/VendorDrawerLink.js b/src/components/Vendors/VendorDrawerLink.js
index de5dbcf50..e2c14d539 100644
--- a/src/components/Vendors/VendorDrawerLink.js
+++ b/src/components/Vendors/VendorDrawerLink.js
@@ -8,16 +8,18 @@ function VendorDrawerLinkComponent({
// #ownProps
children,
vendorId,
+ className,
// #withDrawerActions
openDrawer,
}) {
// Handle view customer drawer.
- const handleVendorDrawer = () => {
+ const handleVendorDrawer = (event) => {
openDrawer('vendor-details-drawer', { vendorId });
+ event.preventDefault();
};
- return {children};
+ return {children};
}
export const VendorDrawerLink = R.compose(withDrawerActions)(VendorDrawerLinkComponent);
diff --git a/src/components/Warehouses/WarehouseMultiSelect.js b/src/components/Warehouses/WarehouseMultiSelect.js
new file mode 100644
index 000000000..0a24eeef7
--- /dev/null
+++ b/src/components/Warehouses/WarehouseMultiSelect.js
@@ -0,0 +1,74 @@
+import React from 'react';
+import intl from 'react-intl-universal';
+import { MenuItem } from '@blueprintjs/core';
+import { FMultiSelect } from '../Forms';
+
+/**
+ *
+ * @param {*} query
+ * @param {*} warehouse
+ * @param {*} _index
+ * @param {*} exactMatch
+ * @returns
+ */
+const warehouseItemPredicate = (query, warehouse, _index, exactMatch) => {
+ const normalizedTitle = warehouse.name.toLowerCase();
+ const normalizedQuery = query.toLowerCase();
+
+ if (exactMatch) {
+ return normalizedTitle === normalizedQuery;
+ } else {
+ return (
+ `${warehouse.code}. ${normalizedTitle}`.indexOf(normalizedQuery) >= 0
+ );
+ }
+};
+
+/**
+ *
+ * @param {*} branch
+ * @param {*} param1
+ * @returns
+ */
+const warehouseItemRenderer = (
+ warehouse,
+ { handleClick, modifiers, query },
+ { isSelected },
+) => {
+ return (
+
+ );
+};
+
+const warehouseSelectProps = {
+ itemPredicate: warehouseItemPredicate,
+ itemRenderer: warehouseItemRenderer,
+ valueAccessor: (item) => item.id,
+ labelAccessor: (item) => item.code,
+ tagRenderer: (item) => item.name,
+};
+
+/**
+ * warehouses mulit select.
+ * @param {*} param0
+ * @returns
+ */
+export function WarehouseMultiSelect({ warehouses, ...rest }) {
+ return (
+
+ );
+}
diff --git a/src/components/Warehouses/WarehouseSelect.js b/src/components/Warehouses/WarehouseSelect.js
new file mode 100644
index 000000000..cb9470d95
--- /dev/null
+++ b/src/components/Warehouses/WarehouseSelect.js
@@ -0,0 +1,74 @@
+import React from 'react';
+
+import { MenuItem, Button } from '@blueprintjs/core';
+import { FSelect } from '../Forms';
+
+/**
+ *
+ * @param {*} query
+ * @param {*} warehouse
+ * @param {*} _index
+ * @param {*} exactMatch
+ * @returns
+ */
+const warehouseItemPredicate = (query, warehouse, _index, exactMatch) => {
+ const normalizedTitle = warehouse.name.toLowerCase();
+ const normalizedQuery = query.toLowerCase();
+
+ if (exactMatch) {
+ return normalizedTitle === normalizedQuery;
+ } else {
+ return (
+ `${warehouse.code}. ${normalizedTitle}`.indexOf(normalizedQuery) >= 0
+ );
+ }
+};
+
+/**
+ *
+ * @param {*} film
+ * @param {*} param1
+ * @returns
+ */
+const warehouseItemRenderer = (
+ warehouse,
+ { handleClick, modifiers, query },
+) => {
+ const text = `${warehouse.name}`;
+
+ return (
+
+ );
+};
+
+const warehouseSelectProps = {
+ itemPredicate: warehouseItemPredicate,
+ itemRenderer: warehouseItemRenderer,
+ valueAccessor: 'id',
+ labelAccessor: 'name',
+};
+
+/**
+ *
+ * @param {*} param0
+ * @returns
+ */
+export function WarehouseSelect({ warehouses, ...rest }) {
+ return ;
+}
+
+/**
+ *
+ * @param {*} param0
+ * @returns
+ */
+export function WarehouseSelectButton({ label, ...rest }) {
+ return ;
+}
diff --git a/src/components/Warehouses/index.js b/src/components/Warehouses/index.js
new file mode 100644
index 000000000..6975b2230
--- /dev/null
+++ b/src/components/Warehouses/index.js
@@ -0,0 +1,2 @@
+export * from './WarehouseSelect';
+export * from './WarehouseMultiSelect';
diff --git a/src/components/index.js b/src/components/index.js
index cdf278b7b..16e1003b6 100644
--- a/src/components/index.js
+++ b/src/components/index.js
@@ -54,6 +54,8 @@ import AvaterCell from './AvaterCell';
import { ItemsMultiSelect } from './Items';
import MoreMenuItems from './MoreMenutItems';
+import CustomSelectList from './CustomSelectList';
+import { ExchangeRateDetailItem } from './DetailExchangeRate';
export * from './Dialog';
export * from './Menu';
@@ -88,13 +90,20 @@ export * from './TextStatus';
export * from './Tags';
export * from './CommercialDoc';
export * from './Card';
-export * from './Customers'
-export * from './Vendors'
+export * from './Customers';
+export * from './Vendors';
export * from './Table';
export * from './Skeleton';
export * from './FinancialStatement';
export * from './FinancialReport';
export * from './FinancialSheet';
+export * from './FeatureGuard';
+export * from './ExchangeRate';
+export * from './Branches';
+export * from './Warehouses';
+export * from './Currencies';
+export * from './FormTopbar'
+export * from './Paper';
const Hint = FieldHint;
@@ -161,4 +170,6 @@ export {
ItemsMultiSelect,
AvaterCell,
MoreMenuItems,
+ CustomSelectList,
+ ExchangeRateDetailItem,
};
diff --git a/src/config/preferencesMenu.js b/src/config/preferencesMenu.js
index 031dfe0e1..48b5d0952 100644
--- a/src/config/preferencesMenu.js
+++ b/src/config/preferencesMenu.js
@@ -13,9 +13,16 @@ export default [
},
{
text: ,
-
href: '/preferences/currencies',
},
+ {
+ text: ,
+ href: '/preferences/branches',
+ },
+ {
+ text: ,
+ href: '/preferences/warehouses',
+ },
{
text: ,
disabled: false,
diff --git a/src/config/sidebarMenu.js b/src/config/sidebarMenu.js
index 1ea65f2a0..2c332ffe3 100644
--- a/src/config/sidebarMenu.js
+++ b/src/config/sidebarMenu.js
@@ -78,6 +78,10 @@ export default [
ability: InventoryAdjustmentAction.View,
},
},
+ {
+ text: ,
+ href: '/warehouses-transfers',
+ },
{
text: ,
href: '/items/categories',
@@ -113,6 +117,10 @@ export default [
ability: ItemAction.Create,
},
},
+ {
+ text: ,
+ href: '/warehouses-transfers/new',
+ },
{
text: ,
href: '/items/new',
@@ -633,6 +641,14 @@ export default [
ability: ReportsAction.READ_AP_AGING_SUMMARY,
},
},
+ // {
+ // text: ,
+ // href: '/financial-reports/realized-gain-loss',
+ // },
+ // {
+ // text: ,
+ // href: '/financial-reports/unrealized-gain-loss',
+ // },
{
text: ,
label: true,
diff --git a/src/containers/Accounting/MakeJournal/MakeJournalEntries.schema.js b/src/containers/Accounting/MakeJournal/MakeJournalEntries.schema.js
index 796f505f9..7c7da60dd 100644
--- a/src/containers/Accounting/MakeJournal/MakeJournalEntries.schema.js
+++ b/src/containers/Accounting/MakeJournal/MakeJournalEntries.schema.js
@@ -13,13 +13,13 @@ const Schema = Yup.object().shape({
.min(1)
.max(DATATYPES_LENGTH.STRING)
.label(intl.get('journal_type')),
- date: Yup.date()
- .required()
- .label(intl.get('date')),
+ date: Yup.date().required().label(intl.get('date')),
currency_code: Yup.string().max(3),
publish: Yup.boolean(),
+ branch_id: Yup.string(),
reference: Yup.string().nullable().min(1).max(DATATYPES_LENGTH.STRING),
description: Yup.string().min(1).max(DATATYPES_LENGTH.STRING).nullable(),
+ exchange_rate: Yup.number(),
entries: Yup.array().of(
Yup.object().shape({
credit: Yup.number().nullable(),
diff --git a/src/containers/Accounting/MakeJournal/MakeJournalEntriesField.js b/src/containers/Accounting/MakeJournal/MakeJournalEntriesField.js
index 8367dc2bd..ccb3572eb 100644
--- a/src/containers/Accounting/MakeJournal/MakeJournalEntriesField.js
+++ b/src/containers/Accounting/MakeJournal/MakeJournalEntriesField.js
@@ -10,7 +10,7 @@ import { useMakeJournalFormContext } from './MakeJournalProvider';
* Make journal entries field.
*/
export default function MakeJournalEntriesField() {
- const { accounts, contacts } = useMakeJournalFormContext();
+ const { accounts, contacts ,branches } = useMakeJournalFormContext();
return (
@@ -18,6 +18,7 @@ export default function MakeJournalEntriesField() {
name={'entries'}
contacts={contacts}
accounts={accounts}
+ branches={branches}
shouldUpdate={entriesFieldShouldUpdate}
>
{({
diff --git a/src/containers/Accounting/MakeJournal/MakeJournalEntriesForm.js b/src/containers/Accounting/MakeJournal/MakeJournalEntriesForm.js
index 538cffe28..d6c867579 100644
--- a/src/containers/Accounting/MakeJournal/MakeJournalEntriesForm.js
+++ b/src/containers/Accounting/MakeJournal/MakeJournalEntriesForm.js
@@ -17,6 +17,7 @@ import MakeJournalFormFloatingActions from './MakeJournalFormFloatingActions';
import MakeJournalEntriesField from './MakeJournalEntriesField';
import MakeJournalFormFooter from './MakeJournalFormFooter';
import MakeJournalFormDialogs from './MakeJournalFormDialogs';
+import MakeJournalFormTopBar from './MakeJournalFormTopBar';
import withSettings from 'containers/Settings/withSettings';
import withCurrentOrganization from 'containers/Organization/withCurrentOrganization';
@@ -58,6 +59,7 @@ function MakeJournalEntriesForm({
journalNumberPrefix,
journalNextNumber,
);
+
// Form initial values.
const initialValues = useMemo(
() => ({
@@ -68,12 +70,12 @@ function MakeJournalEntriesForm({
: {
...defaultManualJournal,
...(journalAutoIncrement && {
- journal_number: defaultTo(journalNumber, ''),
+ journal_number: journalNumber,
}),
currency_code: base_currency,
}),
}),
- [manualJournal, base_currency, journalNumber],
+ [manualJournal, base_currency, journalNumber, journalAutoIncrement],
);
// Handle the form submiting.
@@ -107,7 +109,7 @@ function MakeJournalEntriesForm({
return;
}
const form = {
- ...omit(values, ['journal_number', 'journal_number_manually']),
+ ...omit(values, ['journal_number_manually']),
...(values.journal_number_manually && {
journal_number: values.journal_number,
}),
@@ -169,6 +171,7 @@ function MakeJournalEntriesForm({
onSubmit={handleSubmit}
>
);
}
diff --git a/src/containers/Accounting/MakeJournal/MakeJournalEntriesPage.js b/src/containers/Accounting/MakeJournal/MakeJournalEntriesPage.js
index 452d8ffc9..9d83207ac 100644
--- a/src/containers/Accounting/MakeJournal/MakeJournalEntriesPage.js
+++ b/src/containers/Accounting/MakeJournal/MakeJournalEntriesPage.js
@@ -11,7 +11,7 @@ import { MakeJournalProvider } from './MakeJournalProvider';
*/
export default function MakeJournalEntriesPage() {
const { id: journalId } = useParams();
-
+
return (
diff --git a/src/containers/Accounting/MakeJournal/MakeJournalEntriesTable.js b/src/containers/Accounting/MakeJournal/MakeJournalEntriesTable.js
index 89b2fbd8f..b6f34200d 100644
--- a/src/containers/Accounting/MakeJournal/MakeJournalEntriesTable.js
+++ b/src/containers/Accounting/MakeJournal/MakeJournalEntriesTable.js
@@ -21,15 +21,16 @@ export default function MakeJournalEntriesTable({
entries,
defaultEntry,
error,
- initialLinesNumber = 4,
- minLinesNumber = 4,
+ initialLinesNumber = 1,
+ minLinesNumber = 1,
currencyCode,
}) {
- const { accounts, contacts } = useMakeJournalFormContext();
+ const { accounts, contacts, branches } = useMakeJournalFormContext();
// Memorized data table columns.
const columns = useJournalTableEntriesColumns();
+
// Handles update datatable data.
const handleUpdateData = (rowIndex, columnId, value) => {
const newRows = compose(
@@ -62,13 +63,13 @@ export default function MakeJournalEntriesTable({
data={entries}
sticky={true}
totalRow={true}
- footer={true}
payload={{
accounts,
errors: error,
updateData: handleUpdateData,
removeRow: handleRemoveRow,
contacts,
+ branches,
autoFocus: ['account_id', 0],
currencyCode,
}}
diff --git a/src/containers/Accounting/MakeJournal/MakeJournalFormFooter.js b/src/containers/Accounting/MakeJournal/MakeJournalFormFooter.js
index fd1315e05..26c11aa29 100644
--- a/src/containers/Accounting/MakeJournal/MakeJournalFormFooter.js
+++ b/src/containers/Accounting/MakeJournal/MakeJournalFormFooter.js
@@ -1,44 +1,29 @@
import React from 'react';
-import { FastField } from 'formik';
import classNames from 'classnames';
+import styled from 'styled-components';
+
import { CLASSES } from 'common/classes';
-import { FormGroup, TextArea } from '@blueprintjs/core';
-import { FormattedMessage as T } from 'components';
-import { Postbox, ErrorMessage, Row, Col } from 'components';
-import Dragzone from 'components/Dragzone';
-import { inputIntent } from 'utils';
+import { Row, Col, Paper } from 'components';
+import { MakeJournalFormFooterLeft } from './MakeJournalFormFooterLeft';
+import { MakeJournalFormFooterRight } from './MakeJournalFormFooterRight';
export default function MakeJournalFormFooter() {
return (
-
} defaultOpen={false}>
+
-
- {({ field, meta: { error, touched } }) => (
- }
- className={'form-group--description'}
- intent={inputIntent({ error, touched })}
- helperText={}
- fill={true}
- >
-
-
- )}
-
+
- }
- />
+
-
+
);
}
+const MakeJournalFooterPaper = styled(Paper)`
+ padding: 20px;
+`;
diff --git a/src/containers/Accounting/MakeJournal/MakeJournalFormFooterLeft.js b/src/containers/Accounting/MakeJournal/MakeJournalFormFooterLeft.js
new file mode 100644
index 000000000..9a5185523
--- /dev/null
+++ b/src/containers/Accounting/MakeJournal/MakeJournalFormFooterLeft.js
@@ -0,0 +1,32 @@
+import React from 'react';
+import styled from 'styled-components';
+import { FFormGroup, FEditableText, FormattedMessage as T } from 'components';
+
+export function MakeJournalFormFooterLeft() {
+ return (
+
+ {/* --------- Description --------- */}
+ }
+ name={'description'}
+ >
+ }
+ />
+
+
+ );
+}
+
+const DescriptionFormGroup = styled(FFormGroup)`
+ &.bp3-form-group {
+ .bp3-label {
+ font-size: 12px;
+ margin-bottom: 12px;
+ }
+ .bp3-form-content {
+ margin-left: 10px;
+ }
+ }
+`;
diff --git a/src/containers/Accounting/MakeJournal/MakeJournalFormFooterRight.js b/src/containers/Accounting/MakeJournal/MakeJournalFormFooterRight.js
new file mode 100644
index 000000000..69e4e57bc
--- /dev/null
+++ b/src/containers/Accounting/MakeJournal/MakeJournalFormFooterRight.js
@@ -0,0 +1,34 @@
+import React from 'react';
+import styled from 'styled-components';
+import {
+ T,
+ TotalLines,
+ TotalLine,
+ TotalLineBorderStyle,
+ TotalLineTextStyle,
+} from 'components';
+import { useJournalTotals } from './utils';
+
+export function MakeJournalFormFooterRight() {
+ const { formattedSubtotal, formattedTotal } = useJournalTotals();
+
+ return (
+
+ }
+ value={formattedSubtotal}
+ borderStyle={TotalLineBorderStyle.None}
+ />
+ }
+ value={formattedTotal}
+ textStyle={TotalLineTextStyle.Bold}
+ />
+
+ );
+}
+
+const MakeJouranlTotalLines = styled(TotalLines)`
+ width: 100%;
+ color: #555555;
+`;
diff --git a/src/containers/Accounting/MakeJournal/MakeJournalFormTopBar.js b/src/containers/Accounting/MakeJournal/MakeJournalFormTopBar.js
new file mode 100644
index 000000000..9f96f4912
--- /dev/null
+++ b/src/containers/Accounting/MakeJournal/MakeJournalFormTopBar.js
@@ -0,0 +1,68 @@
+import React from 'react';
+import intl from 'react-intl-universal';
+import { Button, Alignment, NavbarGroup, Classes } from '@blueprintjs/core';
+import styled from 'styled-components';
+import { useSetPrimaryBranchToForm } from './utils';
+import { useFeatureCan } from 'hooks/state';
+import {
+ Icon,
+ BranchSelect,
+ FeatureCan,
+ FormTopbar,
+ DetailsBarSkeletonBase,
+} from 'components';
+import { useMakeJournalFormContext } from './MakeJournalProvider';
+import { Features } from 'common';
+
+/**
+ * Make journal form topbar.
+ * @returns
+ */
+export default function MakeJournalFormTopBar() {
+ // Features guard.
+ const { featureCan } = useFeatureCan();
+
+ // Sets the primary branch to form.
+ useSetPrimaryBranchToForm();
+
+ // Can't display the navigation bar if branches feature is not enabled.
+ if (!featureCan(Features.Branches)) {
+ return null;
+ }
+
+ return (
+
+
+
+
+
+
+
+ );
+}
+
+function MakeJournalFormSelectBranch() {
+ // Invoice form context.
+ const { branches, isBranchesLoading } = useMakeJournalFormContext();
+
+ return isBranchesLoading ? (
+
+ ) : (
+
+ );
+}
+function MakeJournalBranchSelectButton({ label }) {
+ return (
+ }
+ />
+ );
+}
diff --git a/src/containers/Accounting/MakeJournal/MakeJournalProvider.js b/src/containers/Accounting/MakeJournal/MakeJournalProvider.js
index e382c1661..2e51a5551 100644
--- a/src/containers/Accounting/MakeJournal/MakeJournalProvider.js
+++ b/src/containers/Accounting/MakeJournal/MakeJournalProvider.js
@@ -1,4 +1,7 @@
import React, { createContext, useState } from 'react';
+import { isEqual, isUndefined } from 'lodash';
+import { Features } from 'common';
+import { useFeatureCan } from 'hooks/state';
import DashboardInsider from 'components/Dashboard/DashboardInsider';
import {
useAccounts,
@@ -8,7 +11,8 @@ import {
useCreateJournal,
useEditJournal,
useSettings,
- useSettingsManualJournals
+ useBranches,
+ useSettingsManualJournals,
} from 'hooks/query';
const MakeJournalFormContext = createContext();
@@ -16,15 +20,17 @@ const MakeJournalFormContext = createContext();
/**
* Make journal form provider.
*/
-function MakeJournalProvider({ journalId, ...props }) {
+function MakeJournalProvider({ journalId, query, ...props }) {
+ // Features guard.
+ const { featureCan } = useFeatureCan();
+ const isBranchFeatureCan = featureCan(Features.Branches);
+
// Load the accounts list.
const { data: accounts, isLoading: isAccountsLoading } = useAccounts();
// Load the customers list.
- const {
- data: contacts,
- isLoading: isContactsLoading,
- } = useAutoCompleteContacts();
+ const { data: contacts, isLoading: isContactsLoading } =
+ useAutoCompleteContacts();
// Load the currencies list.
const { data: currencies, isLoading: isCurrenciesLoading } = useCurrencies();
@@ -43,15 +49,27 @@ function MakeJournalProvider({ journalId, ...props }) {
// Loading the journal settings.
const { isLoading: isSettingsLoading } = useSettingsManualJournals();
+ // Fetches the branches list.
+ const {
+ data: branches,
+ isLoading: isBranchesLoading,
+ isSuccess: isBranchesSuccess,
+ } = useBranches(query, { enabled: isBranchFeatureCan });
+
// Submit form payload.
const [submitPayload, setSubmitPayload] = useState({});
+ // Determines whether the warehouse and branches are loading.
+ const isFeatureLoading = isBranchesLoading;
+
const provider = {
accounts,
contacts,
currencies,
manualJournal,
+ branches,
+
createJournalMutate,
editJournalMutate,
@@ -59,12 +77,13 @@ function MakeJournalProvider({ journalId, ...props }) {
isContactsLoading,
isCurrenciesLoading,
isJournalLoading,
+ isFeatureLoading,
isSettingsLoading,
-
+ isBranchesSuccess,
isNewMode: !journalId,
submitPayload,
- setSubmitPayload
+ setSubmitPayload,
};
return (
@@ -73,7 +92,7 @@ function MakeJournalProvider({ journalId, ...props }) {
isJournalLoading ||
isAccountsLoading ||
isCurrenciesLoading ||
- isContactsLoading ||
+ isContactsLoading ||
isSettingsLoading
}
name={'make-journal-page'}
diff --git a/src/containers/Accounting/MakeJournal/components.js b/src/containers/Accounting/MakeJournal/components.js
index f79926091..cec39f28c 100644
--- a/src/containers/Accounting/MakeJournal/components.js
+++ b/src/containers/Accounting/MakeJournal/components.js
@@ -1,15 +1,23 @@
import React from 'react';
-import { Intent, Position, Button, Tooltip } from '@blueprintjs/core';
-import { FormattedMessage as T } from 'components';
-import { Icon, Money, Hint } from 'components';
+import { Menu, MenuItem, Position, Button } from '@blueprintjs/core';
+import { Popover2 } from '@blueprintjs/popover2';
+import { useFormikContext } from 'formik';
import intl from 'react-intl-universal';
+
+import { ExchangeRateInputGroup, Icon, Hint, FormattedMessage as T } from 'components';
import {
AccountsListFieldCell,
MoneyFieldCell,
InputGroupCell,
ContactsListFieldCell,
+ BranchesListFieldCell,
} from 'components/DataTableCells';
-import { safeSumBy } from 'utils';
+
+import { CellType, Features, Align } from 'common';
+
+import { useFeatureCan } from 'hooks/state';
+import { useCurrentOrganization } from 'hooks/state';
+import { useJournalIsForeign } from './utils';
/**
* Contact header cell.
@@ -40,42 +48,6 @@ export function DebitHeaderCell({ payload: { currencyCode } }) {
return intl.get('debit_currency', { currency: currencyCode });
}
-/**
- * Account footer cell.
- */
-function AccountFooterCell({ payload: { currencyCode } }) {
- return (
-
- {intl.get('total_currency', { currency: currencyCode })}
-
- );
-}
-
-/**
- * Total credit table footer cell.
- */
-function TotalCreditFooterCell({ payload: { currencyCode }, rows }) {
- const credit = safeSumBy(rows, 'original.credit');
-
- return (
-
-
-
- );
-}
-
-/**
- * Total debit table footer cell.
- */
-function TotalDebitFooterCell({ payload: { currencyCode }, rows }) {
- const debit = safeSumBy(rows, 'original.debit');
-
- return (
-
-
-
- );
-}
/**
* Actions cell renderer.
*/
@@ -86,95 +58,120 @@ export const ActionsCellRenderer = ({
data,
payload,
}) => {
- const onClickRemoveRole = () => {
+ const handleClickRemoveRole = () => {
payload.removeRow(index);
};
+ const exampleMenu = (
+
+ );
return (
- } position={Position.LEFT}>
+
}
+ icon={}
iconSize={14}
- className="ml2"
+ className="m12"
minimal={true}
- intent={Intent.DANGER}
- onClick={onClickRemoveRole}
/>
-
+
);
};
+ActionsCellRenderer.cellType = CellType.Button;
/**
* Retrieve columns of make journal entries table.
*/
export const useJournalTableEntriesColumns = () => {
+ const { featureCan } = useFeatureCan();
+
return React.useMemo(
() => [
- {
- Header: '#',
- accessor: 'index',
- Cell: ({ row: { index } }) => {index + 1},
- className: 'index',
- width: 40,
- disableResizing: true,
- disableSortBy: true,
- sticky: 'left',
- },
{
Header: intl.get('account'),
id: 'account_id',
accessor: 'account_id',
Cell: AccountsListFieldCell,
- Footer: AccountFooterCell,
- className: 'account',
disableSortBy: true,
width: 160,
- fieldProps: { allowCreate: true }
+ fieldProps: { allowCreate: true },
},
{
Header: CreditHeaderCell,
accessor: 'credit',
Cell: MoneyFieldCell,
- Footer: TotalCreditFooterCell,
- className: 'credit',
disableSortBy: true,
width: 100,
+ align: Align.Right,
},
{
Header: DebitHeaderCell,
accessor: 'debit',
Cell: MoneyFieldCell,
- Footer: TotalDebitFooterCell,
- className: 'debit',
disableSortBy: true,
width: 100,
+ align: Align.Right,
},
{
Header: ContactHeaderCell,
id: 'contact_id',
accessor: 'contact_id',
Cell: ContactsListFieldCell,
- className: 'contact',
disableSortBy: true,
width: 120,
},
+ ...(featureCan(Features.Branches)
+ ? [
+ {
+ Header: intl.get('branch'),
+ id: 'branch_id',
+ accessor: 'branch_id',
+ Cell: BranchesListFieldCell,
+ disableSortBy: true,
+ width: 120,
+ },
+ ]
+ : []),
{
Header: intl.get('note'),
accessor: 'note',
Cell: InputGroupCell,
disableSortBy: true,
- className: 'note',
width: 200,
},
{
Header: '',
accessor: 'action',
Cell: ActionsCellRenderer,
- className: 'actions',
disableSortBy: true,
disableResizing: true,
width: 45,
+ align: Align.Center,
},
],
[],
);
};
+
+/**
+ * Journal exchange rate input field.
+ * @returns {JSX.Element}
+ */
+export function JournalExchangeRateInputField({ ...props }) {
+ const currentOrganization = useCurrentOrganization();
+ const { values } = useFormikContext();
+
+ const isForeignJouranl = useJournalIsForeign();
+
+ // Can't continue if the customer is not foreign.
+ if (!isForeignJouranl) {
+ return null;
+ }
+ return (
+
+ );
+}
diff --git a/src/containers/Accounting/MakeJournal/utils.js b/src/containers/Accounting/MakeJournal/utils.js
index 67bb68990..7b49d5376 100644
--- a/src/containers/Accounting/MakeJournal/utils.js
+++ b/src/containers/Accounting/MakeJournal/utils.js
@@ -1,6 +1,6 @@
import React from 'react';
import { Intent } from '@blueprintjs/core';
-import { sumBy, setWith, toSafeInteger, get } from 'lodash';
+import { sumBy, setWith, toSafeInteger, get, first } from 'lodash';
import moment from 'moment';
import * as R from 'ramda';
import {
@@ -9,11 +9,15 @@ import {
repeatValue,
transformToForm,
defaultFastFieldShouldUpdate,
- ensureEntriesHasEmptyLine
+ ensureEntriesHasEmptyLine,
+ formattedAmount,
+ safeSumBy,
} from 'utils';
import { AppToaster } from 'components';
import intl from 'react-intl-universal';
import { useFormikContext } from 'formik';
+import { useMakeJournalFormContext } from './MakeJournalProvider';
+import { useCurrentOrganization } from 'hooks/state';
const ERROR = {
JOURNAL_NUMBER_ALREADY_EXISTS: 'JOURNAL.NUMBER.ALREADY.EXISTS',
@@ -26,25 +30,30 @@ const ERROR = {
ENTRIES_SHOULD_ASSIGN_WITH_CONTACT: 'ENTRIES_SHOULD_ASSIGN_WITH_CONTACT',
};
-export const MIN_LINES_NUMBER = 4;
+export const MIN_LINES_NUMBER = 1;
+export const DEFAULT_LINES_NUMBER = 1;
export const defaultEntry = {
account_id: '',
credit: '',
debit: '',
contact_id: '',
+ branch_id: '',
note: '',
};
export const defaultManualJournal = {
journal_number: '',
+ journal_number_manually: false,
journal_type: 'Journal',
date: moment(new Date()).format('YYYY-MM-DD'),
description: '',
reference: '',
currency_code: '',
publish: '',
- entries: [...repeatValue(defaultEntry, 4)],
+ branch_id: '',
+ exchange_rate: 1,
+ entries: [...repeatValue(defaultEntry, DEFAULT_LINES_NUMBER)],
};
// Transform to edit form.
@@ -179,6 +188,7 @@ export const entriesFieldShouldUpdate = (newProps, oldProps) => {
return (
newProps.accounts !== oldProps.accounts ||
newProps.contacts !== oldProps.contacts ||
+ newProps.branches !== oldProps.branches ||
defaultFastFieldShouldUpdate(newProps, oldProps)
);
};
@@ -192,3 +202,63 @@ export const currenciesFieldShouldUpdate = (newProps, oldProps) => {
defaultFastFieldShouldUpdate(newProps, oldProps)
);
};
+
+export const useSetPrimaryBranchToForm = () => {
+ const { setFieldValue } = useFormikContext();
+ const { branches, isBranchesSuccess } = useMakeJournalFormContext();
+
+ React.useEffect(() => {
+ if (isBranchesSuccess) {
+ const primaryBranch = branches.find((b) => b.primary) || first(branches);
+
+ if (primaryBranch) {
+ setFieldValue('branch_id', primaryBranch.id);
+ }
+ }
+ }, [isBranchesSuccess, setFieldValue, branches]);
+};
+
+/**
+ * Retreives the Journal totals.
+ */
+export const useJournalTotals = () => {
+ const {
+ values: { entries, currency_code: currencyCode },
+ } = useFormikContext();
+
+ // Retrieves the invoice entries total.
+ const totalCredit = safeSumBy(entries, 'credit');
+ const totalDebit = safeSumBy(entries, 'debit');
+
+ const total = Math.max(totalCredit, totalDebit);
+ // Retrieves the formatted total money.
+ const formattedTotal = React.useMemo(
+ () => formattedAmount(total, currencyCode),
+ [total, currencyCode],
+ );
+ // Retrieves the formatted subtotal.
+ const formattedSubtotal = React.useMemo(
+ () => formattedAmount(total, currencyCode, { money: false }),
+ [total, currencyCode],
+ );
+
+ return {
+ formattedTotal,
+ formattedSubtotal,
+ };
+};
+
+/**
+ * Detarmines whether the expenses has foreign .
+ * @returns {boolean}
+ */
+export const useJournalIsForeign = () => {
+ const { values } = useFormikContext();
+ const currentOrganization = useCurrentOrganization();
+
+ const isForeignJournal = React.useMemo(
+ () => values.currency_code !== currentOrganization.base_currency,
+ [values.currency_code, currentOrganization.base_currency],
+ );
+ return isForeignJournal;
+};
diff --git a/src/containers/Alerts/Branches/BranchDeleteAlert.js b/src/containers/Alerts/Branches/BranchDeleteAlert.js
new file mode 100644
index 000000000..68fcffdf6
--- /dev/null
+++ b/src/containers/Alerts/Branches/BranchDeleteAlert.js
@@ -0,0 +1,79 @@
+import React from 'react';
+import intl from 'react-intl-universal';
+import { FormattedMessage as T, FormattedHTMLMessage } from 'components';
+import { Intent, Alert } from '@blueprintjs/core';
+import { AppToaster } from 'components';
+
+import { useDeleteBranch } from 'hooks/query';
+import { handleDeleteErrors } from '../../Preferences/Branches/utils';
+
+import withAlertStoreConnect from 'containers/Alert/withAlertStoreConnect';
+import withAlertActions from 'containers/Alert/withAlertActions';
+
+import { compose } from 'utils';
+
+/**
+ * Branch delete alert.
+ */
+function BranchDeleteAlert({
+ name,
+
+ // #withAlertStoreConnect
+ isOpen,
+ payload: { branchId },
+
+ // #withAlertActions
+ closeAlert,
+}) {
+ const { mutateAsync: deleteBranch, isLoading } = useDeleteBranch();
+
+ // Handle cancel delete alert.
+ const handleCancelDelete = () => {
+ closeAlert(name);
+ };
+
+ // Handle confirm delete branch.
+ const handleConfirmDeleteBranch = () => {
+ deleteBranch(branchId)
+ .then(() => {
+ AppToaster.show({
+ message: intl.get('branch.alert.delete_message'),
+ intent: Intent.SUCCESS,
+ });
+ })
+ .catch(
+ ({
+ response: {
+ data: { errors },
+ },
+ }) => {
+ handleDeleteErrors(errors);
+ },
+ )
+ .finally(() => {
+ closeAlert(name);
+ });
+ };
+
+ return (
+ }
+ confirmButtonText={}
+ icon="trash"
+ intent={Intent.DANGER}
+ isOpen={isOpen}
+ onCancel={handleCancelDelete}
+ onConfirm={handleConfirmDeleteBranch}
+ loading={isLoading}
+ >
+
+
+
+
+ );
+}
+
+export default compose(
+ withAlertStoreConnect(),
+ withAlertActions,
+)(BranchDeleteAlert);
diff --git a/src/containers/Alerts/Branches/BranchMarkPrimaryAlert.js b/src/containers/Alerts/Branches/BranchMarkPrimaryAlert.js
new file mode 100644
index 000000000..d508353d1
--- /dev/null
+++ b/src/containers/Alerts/Branches/BranchMarkPrimaryAlert.js
@@ -0,0 +1,70 @@
+import React from 'react';
+import intl from 'react-intl-universal';
+import { Intent, Alert } from '@blueprintjs/core';
+import { FormattedMessage as T } from 'components';
+
+import { useMarkBranchAsPrimary } from 'hooks/query';
+import { AppToaster } from 'components';
+
+import withAlertActions from 'containers/Alert/withAlertActions';
+import withAlertStoreConnect from 'containers/Alert/withAlertStoreConnect';
+
+import { compose } from 'utils';
+
+/**
+ * branch mark primary alert.
+ */
+function BranchMarkPrimaryAlert({
+ name,
+
+ // #withAlertStoreConnect
+ isOpen,
+ payload: { branchId },
+
+ // #withAlertActions
+ closeAlert,
+}) {
+ const { mutateAsync: markPrimaryBranchMutate, isLoading } =
+ useMarkBranchAsPrimary();
+
+ // Handle cancel mark primary alert.
+ const handleCancelMarkPrimaryAlert = () => {
+ closeAlert(name);
+ };
+
+ // andle cancel mark primary confirm.
+ const handleConfirmMarkPrimaryBranch = () => {
+ markPrimaryBranchMutate(branchId)
+ .then(() => {
+ AppToaster.show({
+ message: intl.get('branch.alert.mark_primary_message'),
+ intent: Intent.SUCCESS,
+ });
+ closeAlert(name);
+ })
+ .catch((error) => {
+ closeAlert(name);
+ });
+ };
+
+ return (
+ }
+ // confirmButtonText={}
+ intent={Intent.WARNING}
+ isOpen={isOpen}
+ onCancel={handleCancelMarkPrimaryAlert}
+ onConfirm={handleConfirmMarkPrimaryBranch}
+ loading={isLoading}
+ >
+
+
+
+
+ );
+}
+
+export default compose(
+ withAlertStoreConnect(),
+ withAlertActions,
+)(BranchMarkPrimaryAlert);
diff --git a/src/containers/Alerts/Warehouses/WarehouseDeleteAlert.js b/src/containers/Alerts/Warehouses/WarehouseDeleteAlert.js
new file mode 100644
index 000000000..66c88f6a7
--- /dev/null
+++ b/src/containers/Alerts/Warehouses/WarehouseDeleteAlert.js
@@ -0,0 +1,80 @@
+import React from 'react';
+import intl from 'react-intl-universal';
+import { FormattedMessage as T, FormattedHTMLMessage } from 'components';
+import { Intent, Alert } from '@blueprintjs/core';
+import { AppToaster } from 'components';
+import { useDeleteWarehouse } from 'hooks/query';
+import { handleDeleteErrors } from '../../Preferences/Warehouses/utils';
+
+import withAlertStoreConnect from 'containers/Alert/withAlertStoreConnect';
+import withAlertActions from 'containers/Alert/withAlertActions';
+
+import { compose } from 'utils';
+
+/**
+ * Warehouse delete alert
+ * @returns
+ */
+function WarehouseDeleteAlert({
+ name,
+
+ // #withAlertStoreConnect
+ isOpen,
+ payload: { warehouseId },
+
+ // #withAlertActions
+ closeAlert,
+}) {
+ const { mutateAsync: deleteWarehouseMutate, isLoading } =
+ useDeleteWarehouse();
+
+ // handle cancel delete warehouse alert.
+ const handleCancelDeleteAlert = () => {
+ closeAlert(name);
+ };
+
+ // handleConfirm delete invoice
+ const handleConfirmWarehouseDelete = () => {
+ deleteWarehouseMutate(warehouseId)
+ .then(() => {
+ AppToaster.show({
+ message: intl.get('warehouse.alert.delete_message'),
+ intent: Intent.SUCCESS,
+ });
+ })
+ .catch(
+ ({
+ response: {
+ data: { errors },
+ },
+ }) => {
+ handleDeleteErrors(errors);
+ },
+ )
+ .finally(() => {
+ closeAlert(name);
+ });
+ };
+
+ return (
+ }
+ confirmButtonText={}
+ icon="trash"
+ intent={Intent.DANGER}
+ isOpen={isOpen}
+ onCancel={handleCancelDeleteAlert}
+ onConfirm={handleConfirmWarehouseDelete}
+ loading={isLoading}
+ >
+
+
+
+
+ );
+}
+
+export default compose(
+ withAlertStoreConnect(),
+ withAlertActions,
+)(WarehouseDeleteAlert);
diff --git a/src/containers/Alerts/WarehousesTransfer/TransferredWarehouseTransferAlert.js b/src/containers/Alerts/WarehousesTransfer/TransferredWarehouseTransferAlert.js
new file mode 100644
index 000000000..a649c44b0
--- /dev/null
+++ b/src/containers/Alerts/WarehousesTransfer/TransferredWarehouseTransferAlert.js
@@ -0,0 +1,71 @@
+import React from 'react';
+import { FormattedMessage as T } from 'components';
+import intl from 'react-intl-universal';
+import { Intent, Alert } from '@blueprintjs/core';
+
+import { useTransferredWarehouseTransfer } from 'hooks/query';
+import { AppToaster } from 'components';
+
+import withAlertStoreConnect from 'containers/Alert/withAlertStoreConnect';
+import withAlertActions from 'containers/Alert/withAlertActions';
+
+import { compose } from 'utils';
+
+/**
+ * warehouse transfer transferred alert.
+ * @returns
+ */
+function TransferredWarehouseTransferAlert({
+ name,
+
+ // #withAlertStoreConnect
+ isOpen,
+ payload: { warehouseTransferId },
+
+ // #withAlertActions
+ closeAlert,
+}) {
+ const { mutateAsync: transferredWarehouseTransferMutate, isLoading } =
+ useTransferredWarehouseTransfer();
+
+ // handle cancel alert.
+ const handleCancelAlert = () => {
+ closeAlert(name);
+ };
+
+ // Handle confirm alert.
+ const handleConfirmTransferred = () => {
+ transferredWarehouseTransferMutate(warehouseTransferId)
+ .then(() => {
+ AppToaster.show({
+ message: intl.get('warehouse_transfer.alert.transferred_warehouse'),
+ intent: Intent.SUCCESS,
+ });
+ })
+ .catch((error) => {})
+ .finally(() => {
+ closeAlert(name);
+ });
+ };
+
+ return (
+ }
+ confirmButtonText={}
+ intent={Intent.WARNING}
+ isOpen={isOpen}
+ onCancel={handleCancelAlert}
+ onConfirm={handleConfirmTransferred}
+ loading={isLoading}
+ >
+
+
+
+
+ );
+}
+
+export default compose(
+ withAlertStoreConnect(),
+ withAlertActions,
+)(TransferredWarehouseTransferAlert);
diff --git a/src/containers/Alerts/WarehousesTransfer/WarehouseMarkPrimaryAlert.js b/src/containers/Alerts/WarehousesTransfer/WarehouseMarkPrimaryAlert.js
new file mode 100644
index 000000000..874c29d0b
--- /dev/null
+++ b/src/containers/Alerts/WarehousesTransfer/WarehouseMarkPrimaryAlert.js
@@ -0,0 +1,70 @@
+import React from 'react';
+import intl from 'react-intl-universal';
+import { Intent, Alert } from '@blueprintjs/core';
+import { FormattedMessage as T } from 'components';
+
+import { useMarkWarehouseAsPrimary } from 'hooks/query';
+import { AppToaster } from 'components';
+
+import withAlertActions from 'containers/Alert/withAlertActions';
+import withAlertStoreConnect from 'containers/Alert/withAlertStoreConnect';
+
+import { compose } from 'utils';
+
+/**
+ * warehouse mark primary alert.
+ */
+function WarehouseMarkPrimaryAlert({
+ name,
+
+ // #withAlertStoreConnect
+ isOpen,
+ payload: { warehouseId },
+
+ // #withAlertActions
+ closeAlert,
+}) {
+ // const { mutateAsync: markPrimaryWarehouseMutate, isLoading } =
+ // useMarkWarehouseAsPrimary();
+
+ // Handle cancel mark primary alert.
+ const handleCancelMarkPrimaryAlert = () => {
+ closeAlert(name);
+ };
+
+ // andle cancel mark primary confirm.
+ const handleConfirmMarkPrimaryWarehouse = () => {
+ markPrimaryWarehouseMutate(warehouseId)
+ .then(() => {
+ AppToaster.show({
+ message: intl.get('warehouse.alert.mark_primary_message'),
+ intent: Intent.SUCCESS,
+ });
+ closeAlert(name);
+ })
+ .catch((error) => {
+ closeAlert(name);
+ });
+ };
+
+ return (
+ }
+ confirmButtonText={}
+ intent={Intent.WARNING}
+ isOpen={isOpen}
+ onCancel={handleCancelMarkPrimaryAlert}
+ onConfirm={handleConfirmMarkPrimaryWarehouse}
+ loading={isLoading}
+ >
+
+
+
+
+ );
+}
+
+export default compose(
+ withAlertStoreConnect(),
+ withAlertActions,
+)(WarehouseMarkPrimaryAlert);
diff --git a/src/containers/Alerts/WarehousesTransfer/WarehouseTransferDeleteAlert.js b/src/containers/Alerts/WarehousesTransfer/WarehouseTransferDeleteAlert.js
new file mode 100644
index 000000000..a602be329
--- /dev/null
+++ b/src/containers/Alerts/WarehousesTransfer/WarehouseTransferDeleteAlert.js
@@ -0,0 +1,85 @@
+import React from 'react';
+import intl from 'react-intl-universal';
+import { FormattedMessage as T, FormattedHTMLMessage } from 'components';
+import { Intent, Alert } from '@blueprintjs/core';
+import { AppToaster } from 'components';
+import { useDeleteWarehouseTransfer } from 'hooks/query';
+
+import withAlertStoreConnect from 'containers/Alert/withAlertStoreConnect';
+import withAlertActions from 'containers/Alert/withAlertActions';
+import withDrawerActions from 'containers/Drawer/withDrawerActions';
+
+import { compose } from 'utils';
+
+/**
+ * Warehouse transfer delete alert
+ * @returns
+ */
+function WarehouseTransferDeleteAlert({
+ name,
+
+ // #withAlertStoreConnect
+ isOpen,
+ payload: { warehouseTransferId },
+
+ // #withAlertActions
+ closeAlert,
+
+ // #withDrawerActions
+ closeDrawer,
+}) {
+ const { mutateAsync: deleteWarehouseTransferMutate, isLoading } =
+ useDeleteWarehouseTransfer();
+
+ // handle cancel delete warehouse alert.
+ const handleCancelDeleteAlert = () => {
+ closeAlert(name);
+ };
+
+ // handleConfirm delete warehouse transfer.
+ const handleConfirmWarehouseTransferDelete = () => {
+ deleteWarehouseTransferMutate(warehouseTransferId)
+ .then(() => {
+ AppToaster.show({
+ message: intl.get('warehouse_transfer.alert.delete_message'),
+ intent: Intent.SUCCESS,
+ });
+ closeDrawer('warehouse-transfer-detail-drawer');
+ })
+ .catch(
+ ({
+ response: {
+ data: { errors },
+ },
+ }) => {},
+ )
+ .finally(() => {
+ closeAlert(name);
+ });
+ };
+
+ return (
+ }
+ confirmButtonText={}
+ icon="trash"
+ intent={Intent.DANGER}
+ isOpen={isOpen}
+ onCancel={handleCancelDeleteAlert}
+ onConfirm={handleConfirmWarehouseTransferDelete}
+ loading={isLoading}
+ >
+
+
+
+
+ );
+}
+
+export default compose(
+ withAlertStoreConnect(),
+ withAlertActions,
+ withDrawerActions,
+)(WarehouseTransferDeleteAlert);
diff --git a/src/containers/Alerts/WarehousesTransfer/WarehouseTransferInitiateAlert.js b/src/containers/Alerts/WarehousesTransfer/WarehouseTransferInitiateAlert.js
new file mode 100644
index 000000000..699f89e03
--- /dev/null
+++ b/src/containers/Alerts/WarehousesTransfer/WarehouseTransferInitiateAlert.js
@@ -0,0 +1,71 @@
+import React from 'react';
+import { FormattedMessage as T } from 'components';
+import intl from 'react-intl-universal';
+import { Intent, Alert } from '@blueprintjs/core';
+
+import { useInitiateWarehouseTransfer } from 'hooks/query';
+import { AppToaster } from 'components';
+
+import withAlertStoreConnect from 'containers/Alert/withAlertStoreConnect';
+import withAlertActions from 'containers/Alert/withAlertActions';
+
+import { compose } from 'utils';
+
+/**
+ * warehouse transfer initiate alert.
+ * @returns
+ */
+function WarehouseTransferInitiateAlert({
+ name,
+
+ // #withAlertStoreConnect
+ isOpen,
+ payload: { warehouseTransferId },
+
+ // #withAlertActions
+ closeAlert,
+}) {
+ const { mutateAsync: initialWarehouseTransferMutate, isLoading } =
+ useInitiateWarehouseTransfer();
+
+ // handle cancel alert.
+ const handleCancelAlert = () => {
+ closeAlert(name);
+ };
+
+ // Handle confirm alert.
+ const handleConfirmInitiated = () => {
+ initialWarehouseTransferMutate(warehouseTransferId)
+ .then(() => {
+ AppToaster.show({
+ message: intl.get('warehouse_transfer.alert.initiate_warehouse'),
+ intent: Intent.SUCCESS,
+ });
+ })
+ .catch((error) => {})
+ .finally(() => {
+ closeAlert(name);
+ });
+ };
+
+ return (
+ }
+ confirmButtonText={}
+ intent={Intent.WARNING}
+ isOpen={isOpen}
+ onCancel={handleCancelAlert}
+ onConfirm={handleConfirmInitiated}
+ loading={isLoading}
+ >
+
+
+
+
+ );
+}
+
+export default compose(
+ withAlertStoreConnect(),
+ withAlertActions,
+)(WarehouseTransferInitiateAlert);
diff --git a/src/containers/AlertsContainer/registered.js b/src/containers/AlertsContainer/registered.js
index 57d66288a..86ecefdbc 100644
--- a/src/containers/AlertsContainer/registered.js
+++ b/src/containers/AlertsContainer/registered.js
@@ -19,7 +19,10 @@ import CurrenciesAlerts from '../Preferences/Currencies/CurrenciesAlerts';
import RolesAlerts from '../Preferences/Users/Roles/RolesAlerts';
import CreditNotesAlerts from '../Sales/CreditNotes/CreditNotesAlerts';
import VendorCreditNotesAlerts from '../Purchases/CreditNotes/VendorCreditNotesAlerts';
-import TransactionsLockingAlerts from '../TransactionsLocking/TransactionsLockingAlerts'
+import TransactionsLockingAlerts from '../TransactionsLocking/TransactionsLockingAlerts';
+import WarehousesAlerts from '../Preferences/Warehouses/WarehousesAlerts';
+import WarehousesTransfersAlerts from '../WarehouseTransfers/WarehousesTransfersAlerts';
+import BranchesAlerts from '../Preferences/Branches/BranchesAlerts';
export default [
...AccountsAlerts,
@@ -43,5 +46,8 @@ export default [
...RolesAlerts,
...CreditNotesAlerts,
...VendorCreditNotesAlerts,
- ...TransactionsLockingAlerts
+ ...TransactionsLockingAlerts,
+ ...WarehousesAlerts,
+ ...WarehousesTransfersAlerts,
+ ...BranchesAlerts,
];
diff --git a/src/containers/Customers/CustomerForm/CustomerFinancialPanel.js b/src/containers/Customers/CustomerForm/CustomerFinancialPanel.js
index 4193487bb..a8b0c1d69 100644
--- a/src/containers/Customers/CustomerForm/CustomerFinancialPanel.js
+++ b/src/containers/Customers/CustomerForm/CustomerFinancialPanel.js
@@ -3,32 +3,33 @@ import classNames from 'classnames';
import { FormGroup, Position, Classes, ControlGroup } from '@blueprintjs/core';
import { DateInput } from '@blueprintjs/datetime';
import { FastField, ErrorMessage } from 'formik';
+import { FFormGroup } from '../../../components/Forms';
import moment from 'moment';
+import { Features } from 'common';
import {
MoneyInputGroup,
InputPrependText,
CurrencySelectList,
+ BranchSelect,
+ BranchSelectButton,
+ FeatureCan,
Row,
Col,
} from 'components';
import { FormattedMessage as T } from 'components';
import { useCustomerFormContext } from './CustomerFormProvider';
-
-import {
- momentFormatter,
- tansformDateValue,
- inputIntent,
-} from 'utils';
+import { useSetPrimaryBranchToForm } from './utils';
+import { momentFormatter, tansformDateValue, inputIntent } from 'utils';
/**
* Customer financial panel.
*/
export default function CustomerFinancialPanel() {
- const {
- currencies,
- customerId
- } = useCustomerFormContext();
+ const { currencies, customerId, branches } = useCustomerFormContext();
+
+ // Sets the primary branch to form.
+ useSetPrimaryBranchToForm();
return (
@@ -62,12 +63,7 @@ export default function CustomerFinancialPanel() {
{/*------------ Opening balance -----------*/}
- {({
- form,
- field,
- field: { value },
- meta: { error, touched },
- }) => (
+ {({ form, field, field: { value }, meta: { error, touched } }) => (
}
className={classNames(
@@ -92,6 +88,23 @@ export default function CustomerFinancialPanel() {
)}
+ {/*------------ Opening branch -----------*/}
+
+ }
+ name={'opening_balance_branch_id'}
+ inline={true}
+ className={classNames('form-group--select-list', Classes.FILL)}
+ >
+
+
+
+
{/*------------ Currency -----------*/}
{({ form, field: { value }, meta: { error, touched } }) => (
@@ -110,7 +123,6 @@ export default function CustomerFinancialPanel() {
onCurrencySelected={(currency) => {
form.setFieldValue('currency_code', currency.currency_code);
}}
- disabled={true}
/>
)}
diff --git a/src/containers/Customers/CustomerForm/CustomerForm.schema.js b/src/containers/Customers/CustomerForm/CustomerForm.schema.js
index 140abe9c9..6203bfca1 100644
--- a/src/containers/Customers/CustomerForm/CustomerForm.schema.js
+++ b/src/containers/Customers/CustomerForm/CustomerForm.schema.js
@@ -42,6 +42,7 @@ const Schema = Yup.object().shape({
opening_balance: Yup.number().nullable(),
currency_code: Yup.string(),
opening_balance_at: Yup.date(),
+ opening_balance_branch_id: Yup.string(),
});
export const CreateCustomerForm = Schema;
diff --git a/src/containers/Customers/CustomerForm/CustomerFormProvider.js b/src/containers/Customers/CustomerForm/CustomerFormProvider.js
index ae678b4b8..a956897b3 100644
--- a/src/containers/Customers/CustomerForm/CustomerFormProvider.js
+++ b/src/containers/Customers/CustomerForm/CustomerFormProvider.js
@@ -6,15 +6,21 @@ import {
useCreateCustomer,
useEditCustomer,
useContact,
+ useBranches,
} from 'hooks/query';
+import { Features } from 'common';
+import { useFeatureCan } from 'hooks/state';
const CustomerFormContext = createContext();
-function CustomerFormProvider({ customerId, ...props }) {
+function CustomerFormProvider({ query, customerId, ...props }) {
const { state } = useLocation();
-
const contactId = state?.action;
+ // Features guard.
+ const { featureCan } = useFeatureCan();
+ const isBranchFeatureCan = featureCan(Features.Branches);
+
// Handle fetch customer details.
const { data: customer, isLoading: isCustomerLoading } = useCustomer(
customerId,
@@ -28,6 +34,13 @@ function CustomerFormProvider({ customerId, ...props }) {
// Handle fetch Currencies data table
const { data: currencies, isLoading: isCurrenciesLoading } = useCurrencies();
+ // Fetches the branches list.
+ const {
+ data: branches,
+ isLoading: isBranchesLoading,
+ isSuccess: isBranchesSuccess,
+ } = useBranches(query, { enabled: isBranchFeatureCan });
+
// Form submit payload.
const [submitPayload, setSubmitPayload] = useState({});
@@ -38,18 +51,20 @@ function CustomerFormProvider({ customerId, ...props }) {
const isNewMode = contactId || !customerId;
const isFormLoading =
- isCustomerLoading || isCurrenciesLoading || isContactLoading;
+ isCustomerLoading || isCurrenciesLoading || isBranchesLoading;
const provider = {
customerId,
customer,
currencies,
+ branches,
contactDuplicate,
submitPayload,
isNewMode,
isCustomerLoading,
isCurrenciesLoading,
+ isBranchesSuccess,
isFormLoading,
setSubmitPayload,
diff --git a/src/containers/Customers/CustomerForm/utils.js b/src/containers/Customers/CustomerForm/utils.js
index d72cfb92d..ba830c844 100644
--- a/src/containers/Customers/CustomerForm/utils.js
+++ b/src/containers/Customers/CustomerForm/utils.js
@@ -1,5 +1,9 @@
+import React from 'react';
import moment from 'moment';
+import { useFormikContext } from 'formik';
+import { first } from 'lodash';
+import { useCustomerFormContext } from './CustomerFormProvider';
export const defaultInitialValues = {
customer_type: 'business',
@@ -35,4 +39,20 @@ export const defaultInitialValues = {
opening_balance: '',
currency_code: '',
opening_balance_at: moment(new Date()).format('YYYY-MM-DD'),
+ opening_balance_branch_id: '',
+};
+
+export const useSetPrimaryBranchToForm = () => {
+ const { setFieldValue } = useFormikContext();
+ const { branches, isBranchesSuccess } = useCustomerFormContext();
+
+ React.useEffect(() => {
+ if (isBranchesSuccess) {
+ const primaryBranch = branches.find((b) => b.primary) || first(branches);
+
+ if (primaryBranch) {
+ setFieldValue('opening_balance_branch_id', primaryBranch.id);
+ }
+ }
+ }, [isBranchesSuccess, setFieldValue, branches]);
};
diff --git a/src/containers/Dialogs/AccountDialog/AccountDialogForm.js b/src/containers/Dialogs/AccountDialog/AccountDialogForm.js
index 1ac575f2f..809ae6ea6 100644
--- a/src/containers/Dialogs/AccountDialog/AccountDialogForm.js
+++ b/src/containers/Dialogs/AccountDialog/AccountDialogForm.js
@@ -25,6 +25,7 @@ const defaultInitialValues = {
name: '',
code: '',
description: '',
+ currency_code:'',
subaccount: false,
};
diff --git a/src/containers/Dialogs/AccountDialog/AccountDialogFormContent.js b/src/containers/Dialogs/AccountDialog/AccountDialogFormContent.js
index 93cfbbfa2..2350b0f4e 100644
--- a/src/containers/Dialogs/AccountDialog/AccountDialogFormContent.js
+++ b/src/containers/Dialogs/AccountDialog/AccountDialogFormContent.js
@@ -17,12 +17,14 @@ import {
Hint,
AccountsSelectList,
AccountsTypesSelect,
+ CurrencySelect,
} from 'components';
import withAccounts from 'containers/Accounts/withAccounts';
import { inputIntent } from 'utils';
import { compose } from 'redux';
import { useAutofocus } from 'hooks';
+import { FOREIGN_CURRENCY_ACCOUNTS } from '../../../common/accountTypes';
import { useAccountDialogContext } from './AccountDialogProvider';
/**
@@ -37,7 +39,7 @@ function AccountFormDialogFields({
const accountNameFieldRef = useAutofocus();
// Account form context.
- const { accounts, accountsTypes } = useAccountDialogContext();
+ const { accounts, accountsTypes, currencies } = useAccountDialogContext();
return (