Compare commits
86 Commits
release/20
...
release/20
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d4ee6ca8ba | ||
|
|
d6673ed278 | ||
|
|
e0804099ee | ||
|
|
ece0946738 | ||
|
|
9bcc44c0cc | ||
|
|
b9b6759c54 | ||
|
|
1f1274a54a | ||
|
|
35d4188469 | ||
|
|
a8f89c81fc | ||
|
|
c382b3f2e0 | ||
|
|
39dbf40a49 | ||
|
|
037ff4c2a1 | ||
|
|
40037216aa | ||
|
|
5a6a92c260 | ||
|
|
fb4b12233a | ||
|
|
d45f84afbd | ||
|
|
1d80153da1 | ||
|
|
f704fd5f56 | ||
|
|
82c4320f0c | ||
|
|
bebe99f4e6 | ||
|
|
1e24d5d57f | ||
|
|
fbcf2b559e | ||
|
|
4582c493ee | ||
|
|
ecfd284539 | ||
|
|
2a1c046dd6 | ||
|
|
54ebc2e25b | ||
|
|
974a0ec1f1 | ||
|
|
acf99584ea | ||
|
|
d0d4ceb270 | ||
|
|
f2e7808fa0 | ||
|
|
c07458babf | ||
|
|
0892461631 | ||
|
|
623d407a6c | ||
|
|
5e3218a145 | ||
|
|
706f300750 | ||
|
|
4fad4e41c2 | ||
|
|
1e88d5ae1b | ||
|
|
7ba3cc5ffa | ||
|
|
4fdd48c279 | ||
|
|
f5834ae6bc | ||
|
|
db36b27819 | ||
|
|
43fbf32e99 | ||
|
|
1b2afb9e93 | ||
|
|
77cb6a4acc | ||
|
|
6a109d63ce | ||
|
|
17c3b24380 | ||
|
|
a6610309e9 | ||
|
|
c63f2ed035 | ||
|
|
db02b9c1c2 | ||
|
|
2c760948c5 | ||
|
|
446bd9035f | ||
|
|
1f16abf303 | ||
|
|
f116e89c94 | ||
|
|
f0ba00aeb8 | ||
|
|
0089e50a29 | ||
|
|
c01f402f92 | ||
|
|
92fb519642 | ||
|
|
fa1dbc2611 | ||
|
|
447298c07d | ||
|
|
4844c42425 | ||
|
|
82db7a1f14 | ||
|
|
fde0681a93 | ||
|
|
b36b4cb213 | ||
|
|
77cbbef085 | ||
|
|
a1472cd9ff | ||
|
|
d32fd9e697 | ||
|
|
fe5e2a247a | ||
|
|
9bf3974ba0 | ||
|
|
42195fccea | ||
|
|
9491d5f069 | ||
|
|
e003768969 | ||
|
|
d6c8d97715 | ||
|
|
ba55717683 | ||
|
|
78dd14af85 | ||
|
|
e109b5102c | ||
|
|
644f269629 | ||
|
|
320aa9c177 | ||
|
|
a0b238c4bb | ||
|
|
fd8dab911f | ||
|
|
3666b7cd22 | ||
|
|
e846d7fce4 | ||
|
|
46b9359dcb | ||
|
|
bd6553f8e4 | ||
|
|
7be8322a14 | ||
|
|
534f75c9b1 | ||
|
|
87f68f1840 |
@@ -2063,6 +2063,32 @@
|
||||
</concept_node>
|
||||
</children>
|
||||
</folder_node>
|
||||
<folder_node>
|
||||
<name>validation</name>
|
||||
<children>
|
||||
<concept_node>
|
||||
<name>atleastone</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
<description></description>
|
||||
<comment></comment>
|
||||
<default_text></default_text>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-MX</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-CA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
</children>
|
||||
</folder_node>
|
||||
</children>
|
||||
</folder_node>
|
||||
<folder_node>
|
||||
@@ -2181,6 +2207,27 @@
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>existinginventoryline</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
<description></description>
|
||||
<comment></comment>
|
||||
<default_text></default_text>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-MX</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-CA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>exporting</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
@@ -3293,6 +3340,27 @@
|
||||
<folder_node>
|
||||
<name>validation</name>
|
||||
<children>
|
||||
<concept_node>
|
||||
<name>inventoryquantity</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
<description></description>
|
||||
<comment></comment>
|
||||
<default_text></default_text>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-MX</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-CA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>manualinhouse</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
@@ -5691,6 +5759,53 @@
|
||||
</concept_node>
|
||||
</children>
|
||||
</folder_node>
|
||||
<folder_node>
|
||||
<name>inventory</name>
|
||||
<children>
|
||||
<concept_node>
|
||||
<name>delete</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
<description></description>
|
||||
<comment></comment>
|
||||
<default_text></default_text>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-MX</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-CA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>list</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
<description></description>
|
||||
<comment></comment>
|
||||
<default_text></default_text>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-MX</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-CA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
</children>
|
||||
</folder_node>
|
||||
<folder_node>
|
||||
<name>jobs</name>
|
||||
<children>
|
||||
@@ -8049,6 +8164,27 @@
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>default_quote</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
<description></description>
|
||||
<comment></comment>
|
||||
<default_text></default_text>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-MX</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-CA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>default_received</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
@@ -15285,6 +15421,27 @@
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>sizelimit</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
<description></description>
|
||||
<comment></comment>
|
||||
<default_text></default_text>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-MX</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-CA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
</children>
|
||||
</folder_node>
|
||||
<folder_node>
|
||||
@@ -15883,6 +16040,27 @@
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>markedexported</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
<description></description>
|
||||
<comment></comment>
|
||||
<default_text></default_text>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-MX</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-CA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>message</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
@@ -17240,6 +17418,27 @@
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>addtoro</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
<description></description>
|
||||
<comment></comment>
|
||||
<default_text></default_text>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-MX</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-CA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>consumefrominventory</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
@@ -17261,6 +17460,48 @@
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>edit</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
<description></description>
|
||||
<comment></comment>
|
||||
<default_text></default_text>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-MX</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-CA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>new</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
<description></description>
|
||||
<comment></comment>
|
||||
<default_text></default_text>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-MX</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-CA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
</children>
|
||||
</folder_node>
|
||||
<folder_node>
|
||||
@@ -17289,6 +17530,74 @@
|
||||
</concept_node>
|
||||
</children>
|
||||
</folder_node>
|
||||
<folder_node>
|
||||
<name>fields</name>
|
||||
<children>
|
||||
<concept_node>
|
||||
<name>comment</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
<description></description>
|
||||
<comment></comment>
|
||||
<default_text></default_text>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-MX</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-CA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>manualinvoicenumber</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
<description></description>
|
||||
<comment></comment>
|
||||
<default_text></default_text>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-MX</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-CA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>manualvendor</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
<description></description>
|
||||
<comment></comment>
|
||||
<default_text></default_text>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-MX</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-CA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
</children>
|
||||
</folder_node>
|
||||
<folder_node>
|
||||
<name>labels</name>
|
||||
<children>
|
||||
@@ -17313,6 +17622,27 @@
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>deleteconfirm</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
<description></description>
|
||||
<comment></comment>
|
||||
<default_text></default_text>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-MX</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-CA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>frombillinvoicenumber</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
@@ -17423,6 +17753,27 @@
|
||||
<folder_node>
|
||||
<name>successes</name>
|
||||
<children>
|
||||
<concept_node>
|
||||
<name>deleted</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
<description></description>
|
||||
<comment></comment>
|
||||
<default_text></default_text>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-MX</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-CA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>inserted</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
@@ -17444,6 +17795,27 @@
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>updated</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
<description></description>
|
||||
<comment></comment>
|
||||
<default_text></default_text>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-MX</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-CA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
</children>
|
||||
</folder_node>
|
||||
</children>
|
||||
@@ -17454,6 +17826,27 @@
|
||||
<folder_node>
|
||||
<name>actions</name>
|
||||
<children>
|
||||
<concept_node>
|
||||
<name>converttolabor</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
<description></description>
|
||||
<comment></comment>
|
||||
<default_text></default_text>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-MX</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-CA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>new</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
@@ -18634,6 +19027,27 @@
|
||||
<folder_node>
|
||||
<name>labels</name>
|
||||
<children>
|
||||
<concept_node>
|
||||
<name>adjustmenttobeadded</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
<description></description>
|
||||
<comment></comment>
|
||||
<default_text></default_text>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-MX</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-CA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>billref</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
@@ -18655,6 +19069,27 @@
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>convertedtolabor</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
<description></description>
|
||||
<comment></comment>
|
||||
<default_text></default_text>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-MX</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-CA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>edit</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
@@ -33642,6 +34077,27 @@
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>is_quote</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
<description></description>
|
||||
<comment></comment>
|
||||
<default_text></default_text>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-MX</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-CA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>mark_as_received</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
@@ -39721,6 +40177,27 @@
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>jobs_reconcile</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
<description></description>
|
||||
<comment></comment>
|
||||
<default_text></default_text>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-MX</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-CA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>lag_time</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
@@ -40785,6 +41262,27 @@
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>calendarperiod</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
<description></description>
|
||||
<comment></comment>
|
||||
<default_text></default_text>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-MX</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-CA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>dailyactual</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
@@ -41214,37 +41712,6 @@
|
||||
</folder_node>
|
||||
</children>
|
||||
</folder_node>
|
||||
<folder_node>
|
||||
<name>scoredboard</name>
|
||||
<children>
|
||||
<folder_node>
|
||||
<name>successes</name>
|
||||
<children>
|
||||
<concept_node>
|
||||
<name>updated</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
<description></description>
|
||||
<comment></comment>
|
||||
<default_text></default_text>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-MX</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-CA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
</children>
|
||||
</folder_node>
|
||||
</children>
|
||||
</folder_node>
|
||||
<folder_node>
|
||||
<name>tech</name>
|
||||
<children>
|
||||
@@ -44635,6 +45102,27 @@
|
||||
<folder_node>
|
||||
<name>signinerror</name>
|
||||
<children>
|
||||
<concept_node>
|
||||
<name>auth/user-disabled</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
<description></description>
|
||||
<comment></comment>
|
||||
<default_text></default_text>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-MX</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-CA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>auth/user-not-found</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
|
||||
@@ -4,17 +4,18 @@
|
||||
"private": true,
|
||||
"proxy": "http://localhost:4000",
|
||||
"dependencies": {
|
||||
"@apollo/client": "^3.6.2",
|
||||
"@apollo/client": "^3.6.6",
|
||||
"@asseinfo/react-kanban": "^2.2.0",
|
||||
"@craco/craco": "^6.4.3",
|
||||
"@fingerprintjs/fingerprintjs": "^3.3.3",
|
||||
"@sentry/react": "^6.19.7",
|
||||
"@sentry/tracing": "^6.19.7",
|
||||
"@jsreport/browser-client": "^3.1.0",
|
||||
"@sentry/react": "^7.1.1",
|
||||
"@sentry/tracing": "^7.1.1",
|
||||
"@splitsoftware/splitio-react": "^1.4.1",
|
||||
"@stripe/react-stripe-js": "^1.8.0",
|
||||
"@stripe/stripe-js": "^1.29.0",
|
||||
"@tanem/react-nprogress": "^5.0.0",
|
||||
"antd": "^4.20.5",
|
||||
"@stripe/react-stripe-js": "^1.8.1",
|
||||
"@stripe/stripe-js": "^1.31.0",
|
||||
"@tanem/react-nprogress": "^5.0.1",
|
||||
"antd": "^4.21.0",
|
||||
"apollo-link-logger": "^2.0.0",
|
||||
"axios": "^0.27.2",
|
||||
"craco-less": "^1.20.0",
|
||||
@@ -23,19 +24,19 @@
|
||||
"enquire-js": "^0.2.1",
|
||||
"env-cmd": "^10.1.0",
|
||||
"exifr": "^7.1.3",
|
||||
"firebase": "^9.8.1",
|
||||
"firebase": "^9.8.2",
|
||||
"graphql": "^16.5.0",
|
||||
"i18next": "^21.8.2",
|
||||
"i18next": "^21.8.9",
|
||||
"i18next-browser-languagedetector": "^6.1.4",
|
||||
"jsoneditor": "^9.7.4",
|
||||
"jsoneditor": "^9.8.0",
|
||||
"jsreport-browser-client-dist": "^1.3.0",
|
||||
"libphonenumber-js": "^1.9.53",
|
||||
"libphonenumber-js": "^1.10.6",
|
||||
"logrocket": "^3.0.0",
|
||||
"markerjs2": "^2.21.4",
|
||||
"moment-business-days": "^1.2.0",
|
||||
"moment-timezone": "^0.5.34",
|
||||
"normalize-url": "^7.0.3",
|
||||
"phone": "^3.1.17",
|
||||
"phone": "^3.1.20",
|
||||
"preval.macro": "^5.0.0",
|
||||
"prop-types": "^15.8.1",
|
||||
"query-string": "^7.1.1",
|
||||
@@ -46,11 +47,11 @@
|
||||
"react-color": "^2.19.3",
|
||||
"react-cookie": "^4.1.1",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-drag-listview": "^0.2.0",
|
||||
"react-drag-listview": "^0.2.1",
|
||||
"react-grid-gallery": "^0.5.5",
|
||||
"react-grid-layout": "^1.3.4",
|
||||
"react-i18next": "^11.16.9",
|
||||
"react-icons": "^4.3.1",
|
||||
"react-i18next": "^11.17.0",
|
||||
"react-icons": "^4.4.0",
|
||||
"react-number-format": "^4.9.3",
|
||||
"react-redux": "^7.2.8",
|
||||
"react-resizable": "^3.0.4",
|
||||
@@ -59,14 +60,14 @@
|
||||
"react-sticky": "^6.0.3",
|
||||
"react-sublime-video": "^0.2.5",
|
||||
"react-virtualized": "^9.22.3",
|
||||
"recharts": "^2.1.9",
|
||||
"recharts": "^2.1.10",
|
||||
"redux": "^4.2.0",
|
||||
"redux-persist": "^6.0.0",
|
||||
"redux-saga": "^1.1.3",
|
||||
"redux-state-sync": "^3.1.2",
|
||||
"reselect": "^4.1.5",
|
||||
"reselect": "^4.1.6",
|
||||
"sass": "^1.51.0",
|
||||
"socket.io-client": "^4.5.0",
|
||||
"socket.io-client": "^4.5.1",
|
||||
"styled-components": "^5.3.5",
|
||||
"subscriptions-transport-ws": "^0.11.0",
|
||||
"web-vitals": "^2.1.4",
|
||||
|
||||
@@ -5,7 +5,6 @@ import ReadOnlyFormItemComponent from "../form-items-formatted/read-only-form-it
|
||||
import "./bill-cm-returns-table.styles.scss";
|
||||
export default function BillCmdReturnsTableComponent({
|
||||
form,
|
||||
loadOutstandingReturns,
|
||||
returnLoading,
|
||||
returnData,
|
||||
}) {
|
||||
|
||||
@@ -15,7 +15,8 @@ export default function BillDeleteButton({ bill }) {
|
||||
setLoading(true);
|
||||
const result = await deleteBill({
|
||||
variables: { billId: bill.id },
|
||||
update(cache) {
|
||||
update(cache, { errors }) {
|
||||
if (errors) return;
|
||||
cache.modify({
|
||||
fields: {
|
||||
bills(existingBills, { readField }) {
|
||||
@@ -36,11 +37,22 @@ export default function BillDeleteButton({ bill }) {
|
||||
if (!!!result.errors) {
|
||||
notification["success"]({ message: t("bills.successes.deleted") });
|
||||
} else {
|
||||
notification["error"]({
|
||||
message: t("bills.errors.deleting", {
|
||||
error: JSON.stringify(result.errors),
|
||||
}),
|
||||
});
|
||||
//Check if it's an fkey violation.
|
||||
const error = JSON.stringify(result.errors);
|
||||
|
||||
if (error.toLowerCase().includes("inventory_billid_fkey")) {
|
||||
notification["error"]({
|
||||
message: t("bills.errors.deleting", {
|
||||
error: t("bills.errors.existinginventoryline"),
|
||||
}),
|
||||
});
|
||||
} else {
|
||||
notification["error"]({
|
||||
message: t("bills.errors.deleting", {
|
||||
error: JSON.stringify(result.errors),
|
||||
}),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
setLoading(false);
|
||||
|
||||
@@ -127,7 +127,7 @@ export function BillDetailEditcontainer({
|
||||
});
|
||||
|
||||
billlines.forEach((billline) => {
|
||||
const { deductedfromlbr, jobline, ...il } = billline;
|
||||
const { deductedfromlbr, inventories, jobline, ...il } = billline;
|
||||
delete il.__typename;
|
||||
|
||||
if (il.id) {
|
||||
|
||||
@@ -144,6 +144,14 @@ function BillEnterModalContainer({
|
||||
adjKeys.forEach((key) => {
|
||||
newAdjustments[key] =
|
||||
(newAdjustments[key] || 0) + adjustmentsToInsert[key];
|
||||
|
||||
insertAuditTrail({
|
||||
jobid: values.jobid,
|
||||
operation: AuditTrailMapping.jobmodifylbradj({
|
||||
mod_lbr_ty: key,
|
||||
hours: adjustmentsToInsert[key].toFixed(1),
|
||||
}),
|
||||
});
|
||||
});
|
||||
|
||||
const jobUpdate = client.mutate({
|
||||
@@ -161,10 +169,6 @@ function BillEnterModalContainer({
|
||||
});
|
||||
return;
|
||||
}
|
||||
insertAuditTrail({
|
||||
jobid: values.jobid,
|
||||
operation: AuditTrailMapping.jobmodifylbradj(),
|
||||
});
|
||||
}
|
||||
|
||||
const markPolReceived =
|
||||
|
||||
@@ -58,6 +58,7 @@ export function BillFormComponent({
|
||||
{},
|
||||
bodyshop.imexshopid
|
||||
);
|
||||
|
||||
const handleVendorSelect = (props, opt) => {
|
||||
setDiscount(opt.discount);
|
||||
|
||||
@@ -140,13 +141,14 @@ export function BillFormComponent({
|
||||
onBlur={() => {
|
||||
if (form.getFieldValue("jobid") !== null) {
|
||||
loadLines({ variables: { id: form.getFieldValue("jobid") } });
|
||||
if (form.getFieldValue("vendorid") !== null)
|
||||
if (form.getFieldValue("vendorid") !== null) {
|
||||
loadOutstandingReturns({
|
||||
variables: {
|
||||
jobId: form.getFieldValue("jobid"),
|
||||
vendorId: form.getFieldValue("vendorid"),
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}}
|
||||
/>
|
||||
@@ -273,12 +275,13 @@ export function BillFormComponent({
|
||||
getFieldValue("jobid") &&
|
||||
getFieldValue("vendorid")
|
||||
) {
|
||||
loadOutstandingReturns({
|
||||
variables: {
|
||||
jobId: form.getFieldValue("jobid"),
|
||||
vendorId: form.getFieldValue("vendorid"),
|
||||
},
|
||||
});
|
||||
//Removed as this would cause an additional reload when validating the form on submit and clear the values.
|
||||
// loadOutstandingReturns({
|
||||
// variables: {
|
||||
// jobId: form.getFieldValue("jobid"),
|
||||
// vendorId: form.getFieldValue("vendorid"),
|
||||
// },
|
||||
// });
|
||||
}
|
||||
|
||||
if (
|
||||
|
||||
@@ -63,7 +63,6 @@ export function BillFormContainer({
|
||||
{!billEdit && (
|
||||
<BillCmdReturnsTableComponent
|
||||
form={form}
|
||||
loadOutstandingReturns={loadOutstandingReturns}
|
||||
returnLoading={returnLoading}
|
||||
returnData={returnData}
|
||||
/>
|
||||
|
||||
@@ -150,6 +150,24 @@ export function BillEnterModalLinesComponent({
|
||||
required: true,
|
||||
//message: t("general.validation.required"),
|
||||
},
|
||||
({ getFieldValue }) => ({
|
||||
validator(rule, value) {
|
||||
if (
|
||||
value &&
|
||||
getFieldValue("billlines")[field.fieldKey]?.inventories
|
||||
?.length > value
|
||||
) {
|
||||
return Promise.reject(
|
||||
t("bills.validation.inventoryquantity", {
|
||||
number:
|
||||
getFieldValue("billlines")[field.fieldKey]
|
||||
?.inventories?.length,
|
||||
})
|
||||
);
|
||||
}
|
||||
return Promise.resolve();
|
||||
},
|
||||
}),
|
||||
],
|
||||
};
|
||||
},
|
||||
@@ -485,22 +503,33 @@ export function BillEnterModalLinesComponent({
|
||||
|
||||
dataIndex: "actions",
|
||||
render: (text, record) => (
|
||||
<Space wrap>
|
||||
<Button disabled={disabled} onClick={() => remove(record.name)}>
|
||||
<DeleteFilled />
|
||||
</Button>
|
||||
<Form.Item shouldUpdate noStyle>
|
||||
{() =>
|
||||
Simple_Inventory.treatment === "on" && (
|
||||
<Form.Item shouldUpdate noStyle>
|
||||
{() => (
|
||||
<Space wrap>
|
||||
<Button
|
||||
disabled={
|
||||
disabled ||
|
||||
getFieldValue("billlines")[record.fieldKey]?.inventories
|
||||
?.length > 0
|
||||
}
|
||||
onClick={() => remove(record.name)}
|
||||
>
|
||||
<DeleteFilled />
|
||||
</Button>
|
||||
{Simple_Inventory.treatment === "on" && (
|
||||
<BilllineAddInventory
|
||||
disabled={!billEdit || form.isFieldsTouched()}
|
||||
disabled={
|
||||
!billEdit ||
|
||||
form.isFieldsTouched() ||
|
||||
form.getFieldValue("is_credit_memo")
|
||||
}
|
||||
billline={getFieldValue("billlines")[record.fieldKey]}
|
||||
jobid={getFieldValue("jobid")}
|
||||
/>
|
||||
)
|
||||
}
|
||||
</Form.Item>
|
||||
</Space>
|
||||
)}
|
||||
</Space>
|
||||
)}
|
||||
</Form.Item>
|
||||
),
|
||||
},
|
||||
];
|
||||
@@ -523,7 +552,20 @@ export function BillEnterModalLinesComponent({
|
||||
});
|
||||
|
||||
return (
|
||||
<Form.List name="billlines">
|
||||
<Form.List
|
||||
name="billlines"
|
||||
rules={[
|
||||
{
|
||||
validator: async (_, billlines) => {
|
||||
if (!billlines || billlines.length < 1) {
|
||||
return Promise.reject(
|
||||
new Error(t("billlines.validation.atleastone"))
|
||||
);
|
||||
}
|
||||
},
|
||||
},
|
||||
]}
|
||||
>
|
||||
{(fields, { add, remove, move }) => {
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -7,9 +7,11 @@ import "./bill-inventory-table.styles.scss";
|
||||
import { connect } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||
import { selectBillEnterModal } from "../../redux/modals/modals.selectors";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
bodyshop: selectBodyshop,
|
||||
billEnterModal: selectBillEnterModal,
|
||||
});
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
//setUserLanguage: language => dispatch(setUserLanguage(language))
|
||||
@@ -17,6 +19,7 @@ const mapDispatchToProps = (dispatch) => ({
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(BillInventoryTable);
|
||||
|
||||
export function BillInventoryTable({
|
||||
billEnterModal,
|
||||
bodyshop,
|
||||
form,
|
||||
billEdit,
|
||||
@@ -26,12 +29,18 @@ export function BillInventoryTable({
|
||||
const { t } = useTranslation();
|
||||
|
||||
useEffect(() => {
|
||||
if (inventoryData) {
|
||||
if (inventoryData && inventoryData.inventory) {
|
||||
form.setFieldsValue({
|
||||
inventory: inventoryData.inventory,
|
||||
inventory: billEnterModal.context.consumeinventoryid
|
||||
? inventoryData.inventory.map((i) => {
|
||||
if (i.id === billEnterModal.context.consumeinventoryid)
|
||||
i.consumefrominventory = true;
|
||||
return i;
|
||||
})
|
||||
: inventoryData.inventory,
|
||||
});
|
||||
}
|
||||
}, [inventoryData, form]);
|
||||
}, [inventoryData, form, billEnterModal.context.consumeinventoryid]);
|
||||
|
||||
return (
|
||||
<Form.Item
|
||||
@@ -64,6 +73,7 @@ export function BillInventoryTable({
|
||||
<th>{t("billlines.fields.quantity")}</th>
|
||||
<th>{t("billlines.fields.actual_price")}</th>
|
||||
<th>{t("billlines.fields.actual_cost")}</th>
|
||||
<th>{t("inventory.fields.comment")}</th>
|
||||
<th>{t("inventory.actions.consumefrominventory")}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -126,6 +136,16 @@ export function BillInventoryTable({
|
||||
<ReadOnlyFormItemComponent type="currency" />
|
||||
</Form.Item>
|
||||
</td>
|
||||
<td>
|
||||
<Form.Item
|
||||
span={2}
|
||||
//label={t("joblines.fields.mod_lb_hrs")}
|
||||
key={`${index}comment`}
|
||||
name={[field.name, "comment"]}
|
||||
>
|
||||
<ReadOnlyFormItemComponent />
|
||||
</Form.Item>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<Form.Item
|
||||
|
||||
@@ -9,11 +9,14 @@ import { createStructuredSelector } from "reselect";
|
||||
import {
|
||||
selectAuthLevel,
|
||||
selectBodyshop,
|
||||
selectCurrentUser,
|
||||
} from "../../redux/user/user.selectors";
|
||||
import { HasRbacAccess } from "../rbac-wrapper/rbac-wrapper.component";
|
||||
import { INSERT_EXPORT_LOG } from "../../graphql/accounting.queries";
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
bodyshop: selectBodyshop,
|
||||
authLevel: selectAuthLevel,
|
||||
currentUser: selectCurrentUser,
|
||||
});
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
//setUserLanguage: language => dispatch(setUserLanguage(language))
|
||||
@@ -24,9 +27,15 @@ export default connect(
|
||||
mapDispatchToProps
|
||||
)(BillMarkExportedButton);
|
||||
|
||||
export function BillMarkExportedButton({ bodyshop, authLevel, bill }) {
|
||||
export function BillMarkExportedButton({
|
||||
currentUser,
|
||||
bodyshop,
|
||||
authLevel,
|
||||
bill,
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [insertExportLog] = useMutation(INSERT_EXPORT_LOG);
|
||||
|
||||
const [updateBill] = useMutation(gql`
|
||||
mutation UPDATE_BILL($billId: uuid!) {
|
||||
@@ -46,6 +55,20 @@ export function BillMarkExportedButton({ bodyshop, authLevel, bill }) {
|
||||
variables: { billId: bill.id },
|
||||
});
|
||||
|
||||
await insertExportLog({
|
||||
variables: {
|
||||
logs: [
|
||||
{
|
||||
bodyshopid: bodyshop.id,
|
||||
billid: bill.id,
|
||||
successful: true,
|
||||
message: JSON.stringify([t("general.labels.markedexported")]),
|
||||
useremail: currentUser.email,
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
if (!result.errors) {
|
||||
notification["success"]({
|
||||
message: t("bills.successes.markexported"),
|
||||
@@ -69,11 +92,7 @@ export function BillMarkExportedButton({ bodyshop, authLevel, bill }) {
|
||||
|
||||
if (hasAccess)
|
||||
return (
|
||||
<Button
|
||||
loading={loading}
|
||||
disabled={bill.exported}
|
||||
onClick={handleUpdate}
|
||||
>
|
||||
<Button loading={loading} disabled={bill.exported} onClick={handleUpdate}>
|
||||
{t("bills.labels.markexported")}
|
||||
</Button>
|
||||
);
|
||||
|
||||
@@ -64,9 +64,9 @@ export function BilllineAddInventory({
|
||||
cost_center: billline.cost_center,
|
||||
deductedfromlbr: billline.deductedfromlbr,
|
||||
applicable_taxes: {
|
||||
local: false, //billline.applicable_taxes.local,
|
||||
state: false, //billline.applicable_taxes.state,
|
||||
federal: false, // billline.applicable_taxes.federal,
|
||||
local: billline.applicable_taxes.local,
|
||||
state: billline.applicable_taxes.state,
|
||||
federal: billline.applicable_taxes.federal,
|
||||
},
|
||||
},
|
||||
],
|
||||
@@ -76,7 +76,9 @@ export function BilllineAddInventory({
|
||||
|
||||
const insertResult = await insertInventoryLine({
|
||||
variables: {
|
||||
joblineId: billline.joblineid,
|
||||
joblineId:
|
||||
billline.joblineid === "noline" ? billline.id : billline.joblineid, //This will return null as there will be no jobline that has the id of the bill line.
|
||||
//Unfortunately, we can't send null as the GQL syntax validation fails.
|
||||
joblineStatus: bodyshop.md_order_statuses.default_returned,
|
||||
inv: {
|
||||
shopid: bodyshop.id,
|
||||
@@ -99,8 +101,9 @@ export function BilllineAddInventory({
|
||||
act_price: billline.actual_price,
|
||||
cost: billline.actual_cost,
|
||||
quantity: billline.quantity,
|
||||
job_line_id: billline.joblineid,
|
||||
part_type: billline.jobline.part_type,
|
||||
job_line_id:
|
||||
billline.joblineid === "noline" ? null : billline.joblineid,
|
||||
part_type: billline.jobline && billline.jobline.part_type,
|
||||
cm_received: true,
|
||||
},
|
||||
],
|
||||
@@ -137,10 +140,15 @@ export function BilllineAddInventory({
|
||||
<Tooltip title={t("inventory.actions.addtoinventory")}>
|
||||
<Button
|
||||
loading={loading}
|
||||
disabled={disabled || billline?.inventories?.length > 0}
|
||||
disabled={
|
||||
disabled || billline?.inventories?.length >= billline.quantity
|
||||
}
|
||||
onClick={addToInventory}
|
||||
>
|
||||
<FileAddFilled />
|
||||
{billline?.inventories?.length > 0 && (
|
||||
<div>({billline?.inventories?.length} in inv)</div>
|
||||
)}
|
||||
</Button>
|
||||
</Tooltip>
|
||||
);
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { SyncOutlined } from "@ant-design/icons";
|
||||
import { Button, Card, Input, Space, Table } from "antd";
|
||||
import { SyncOutlined, WarningFilled } from "@ant-design/icons";
|
||||
import { Button, Card, Input, Space, Table, Tooltip } from "antd";
|
||||
import React, { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Link } from "react-router-dom";
|
||||
import { DateTimeFormatter } from "../../utils/DateFormatter";
|
||||
import { alphaSort } from "../../utils/sorters";
|
||||
import { OwnerNameDisplayFunction } from "../owner-name-display/owner-name-display.component";
|
||||
|
||||
import moment from "moment";
|
||||
export default function CourtesyCarsList({ loading, courtesycars, refetch }) {
|
||||
const [state, setState] = useState({
|
||||
sortedInfo: {},
|
||||
@@ -56,7 +56,25 @@ export default function CourtesyCarsList({ loading, courtesycars, refetch }) {
|
||||
onFilter: (value, record) => value.includes(record.status),
|
||||
sortOrder:
|
||||
state.sortedInfo.columnKey === "status" && state.sortedInfo.order,
|
||||
render: (text, record) => t(record.status),
|
||||
render: (text, record) => {
|
||||
const { nextservicedate, nextservicekm, mileage } = record;
|
||||
|
||||
const mileageOver = nextservicekm <= mileage;
|
||||
|
||||
const dueForService =
|
||||
nextservicedate && moment(nextservicedate).isBefore(moment());
|
||||
|
||||
return (
|
||||
<Space>
|
||||
{t(record.status)}
|
||||
{(mileageOver || dueForService) && (
|
||||
<Tooltip title={t("contracts.labels.cardueforservice")}>
|
||||
<WarningFilled style={{ color: "tomato" }} />
|
||||
</Tooltip>
|
||||
)}
|
||||
</Space>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: t("courtesycars.fields.year"),
|
||||
|
||||
@@ -54,7 +54,7 @@ export const uploadToCloudinary = async (
|
||||
//Set variables for getting the signed URL.
|
||||
let timestamp = Math.floor(Date.now() / 1000);
|
||||
let public_id = key;
|
||||
let tags = `${bodyshop.textid},${
|
||||
let tags = `${bodyshop.imexshopid},${
|
||||
tagsArray ? tagsArray.map((tag) => `${tag},`) : ""
|
||||
}`;
|
||||
// let eager = process.env.REACT_APP_CLOUDINARY_THUMB_TRANSFORMATIONS;
|
||||
|
||||
@@ -45,6 +45,12 @@ export function EmailDocumentsComponent({
|
||||
{selectedMedia.filter((s) => s.isSelected).length >= 10 ? (
|
||||
<div style={{ color: "red" }}>{t("messaging.labels.maxtenimages")}</div>
|
||||
) : null}
|
||||
{selectedMedia &&
|
||||
selectedMedia
|
||||
.filter((s) => s.isSelected)
|
||||
.reduce((acc, val) => (acc = acc + val.size), 0) >= 9961472 ? (
|
||||
<div style={{ color: "red" }}>{t("general.errors.sizelimit")}</div>
|
||||
) : null}
|
||||
{data && (
|
||||
<JobDocumentsGalleryExternal
|
||||
data={data ? data.documents : []}
|
||||
|
||||
@@ -139,7 +139,9 @@ export function EmailOverlayComponent({
|
||||
</Form.Item>
|
||||
|
||||
<Divider>{t("emails.labels.preview")}</Divider>
|
||||
<strong>{t("emails.labels.pdfcopywillbeattached")}</strong>
|
||||
{bodyshop.attach_pdf_to_email && (
|
||||
<strong>{t("emails.labels.pdfcopywillbeattached")}</strong>
|
||||
)}
|
||||
|
||||
<Form.Item shouldUpdate>
|
||||
{() => {
|
||||
@@ -178,6 +180,23 @@ export function EmailOverlayComponent({
|
||||
}
|
||||
return e && e.fileList;
|
||||
}}
|
||||
rules={[
|
||||
({ getFieldValue }) => ({
|
||||
validator(rule, value) {
|
||||
const totalSize = value.reduce(
|
||||
(acc, val) => (acc = acc + val.size),
|
||||
0
|
||||
);
|
||||
|
||||
const limit = 9961472;
|
||||
|
||||
if (totalSize > limit) {
|
||||
return Promise.reject(t("general.errors.sizelimit"));
|
||||
}
|
||||
return Promise.resolve();
|
||||
},
|
||||
}),
|
||||
]}
|
||||
>
|
||||
<Upload.Dragger
|
||||
beforeUpload={Upload.LIST_IGNORE}
|
||||
|
||||
@@ -30,6 +30,7 @@ class ErrorBoundary extends React.Component {
|
||||
|
||||
static getDerivedStateFromError(error) {
|
||||
console.log("ErrorBoundary -> getDerivedStateFromError -> error", error);
|
||||
|
||||
return { hasErrored: true, error: error };
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
import { Button } from "antd";
|
||||
import React from "react";
|
||||
import { connect } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { setModalContext } from "../../redux/modals/modals.actions";
|
||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||
import moment from "moment";
|
||||
import { useTranslation } from "react-i18next";
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
bodyshop: selectBodyshop,
|
||||
});
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
setBillEnterContext: (context) =>
|
||||
dispatch(setModalContext({ context: context, modal: "billEnter" })),
|
||||
});
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(InventoryBillRo);
|
||||
export function InventoryBillRo({
|
||||
bodyshop,
|
||||
setBillEnterContext,
|
||||
inventoryline,
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<Button
|
||||
onClick={() => {
|
||||
setBillEnterContext({
|
||||
actions: {
|
||||
//refetch: refetch
|
||||
},
|
||||
context: {
|
||||
disableInvNumber: true,
|
||||
//job: { id: job.id },
|
||||
consumeinventoryid: inventoryline.id,
|
||||
bill: {
|
||||
vendorid: bodyshop.inhousevendorid,
|
||||
invoice_number: "ih",
|
||||
isinhouse: true,
|
||||
date: moment(),
|
||||
total: 0,
|
||||
billlines: [{}],
|
||||
// billlines: selectedLines.map((p) => {
|
||||
// return {
|
||||
// joblineid: p.id,
|
||||
// actual_price: p.act_price,
|
||||
// actual_cost: 0, //p.act_price,
|
||||
// line_desc: p.line_desc,
|
||||
// line_remarks: p.line_remarks,
|
||||
// part_type: p.part_type,
|
||||
// quantity: p.quantity || 1,
|
||||
// applicable_taxes: {
|
||||
// local: false,
|
||||
// state: false,
|
||||
// federal: false,
|
||||
// },
|
||||
// };
|
||||
// }),
|
||||
},
|
||||
},
|
||||
});
|
||||
}}
|
||||
>
|
||||
{t("inventory.actions.addtoro")}
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
import { DeleteFilled } from "@ant-design/icons";
|
||||
import { useMutation } from "@apollo/client";
|
||||
import { Button, notification, Popconfirm } from "antd";
|
||||
import React, { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { DELETE_INVENTORY_LINE } from "../../graphql/inventory.queries";
|
||||
import RbacWrapper from "../rbac-wrapper/rbac-wrapper.component";
|
||||
|
||||
export default function InventoryLineDelete({
|
||||
inventoryline,
|
||||
disabled,
|
||||
refetch,
|
||||
}) {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const { t } = useTranslation();
|
||||
const [deleteInventoryLine] = useMutation(DELETE_INVENTORY_LINE);
|
||||
|
||||
const handleDelete = async () => {
|
||||
setLoading(true);
|
||||
const result = await deleteInventoryLine({
|
||||
variables: { lineId: inventoryline.id },
|
||||
// update(cache, { errors }) {
|
||||
// cache.modify({
|
||||
// fields: {
|
||||
// inventory(existingInventory, { readField }) {
|
||||
// console.log(existingInventory);
|
||||
// return existingInventory.filter(
|
||||
// (invRef) => inventoryline.id !== readField("id", invRef)
|
||||
// );
|
||||
// },
|
||||
// },
|
||||
// });
|
||||
// },
|
||||
});
|
||||
|
||||
if (!!!result.errors) {
|
||||
notification["success"]({ message: t("inventory.successes.deleted") });
|
||||
} else {
|
||||
//Check if it's an fkey violation.
|
||||
|
||||
notification["error"]({
|
||||
message: t("bills.errors.deleting", {
|
||||
error: JSON.stringify(result.errors),
|
||||
}),
|
||||
});
|
||||
}
|
||||
if (refetch) refetch();
|
||||
setLoading(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<RbacWrapper action="inventory:delete" noauth={<></>}>
|
||||
<Popconfirm
|
||||
disabled={disabled || inventoryline.consumedbybillid}
|
||||
onConfirm={handleDelete}
|
||||
title={t("inventory.labels.deleteconfirm")}
|
||||
>
|
||||
<Button
|
||||
disabled={disabled || inventoryline.consumedbybillid}
|
||||
loading={loading}
|
||||
>
|
||||
<DeleteFilled />
|
||||
</Button>
|
||||
</Popconfirm>
|
||||
</RbacWrapper>
|
||||
);
|
||||
}
|
||||
@@ -1,22 +1,33 @@
|
||||
import { SyncOutlined } from "@ant-design/icons";
|
||||
import { EditFilled, SyncOutlined, FileAddFilled } from "@ant-design/icons";
|
||||
import { Button, Card, Input, Space, Table, Typography } from "antd";
|
||||
import queryString from "query-string";
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { connect } from "react-redux";
|
||||
import { useHistory, useLocation } from "react-router-dom";
|
||||
import { Link, useHistory, useLocation } from "react-router-dom";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { setModalContext } from "../../redux/modals/modals.actions";
|
||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||
import CurrencyFormatter from "../../utils/CurrencyFormatter";
|
||||
import InventoryBillRo from "../inventory-bill-ro/inventory-bill-ro.component";
|
||||
import InventoryLineDelete from "../inventory-line-delete/inventory-line-delete.component";
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
//currentUser: selectCurrentUser
|
||||
bodyshop: selectBodyshop,
|
||||
});
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
//setUserLanguage: language => dispatch(setUserLanguage(language))
|
||||
setInventoryUpsertContext: (context) =>
|
||||
dispatch(setModalContext({ context: context, modal: "inventoryUpsert" })),
|
||||
});
|
||||
|
||||
export function JobsList({ bodyshop, refetch, loading, jobs, total }) {
|
||||
export function JobsList({
|
||||
bodyshop,
|
||||
refetch,
|
||||
loading,
|
||||
jobs,
|
||||
total,
|
||||
setInventoryUpsertContext,
|
||||
}) {
|
||||
const search = queryString.parse(useLocation().search);
|
||||
const { page, sortcolumn, sortorder } = search;
|
||||
const history = useHistory();
|
||||
@@ -30,6 +41,15 @@ export function JobsList({ bodyshop, refetch, loading, jobs, total }) {
|
||||
|
||||
sorter: true, //(a, b) => alphaSort(a.line_desc, b.line_desc),
|
||||
sortOrder: sortcolumn === "line_desc" && sortorder,
|
||||
render: (text, record) =>
|
||||
record.billline?.bill?.job ? (
|
||||
<div>
|
||||
<div>{text}</div>
|
||||
<strong>{`(${record.billline?.bill?.job?.v_model_yr} ${record.billline?.bill?.job?.v_make_desc} ${record.billline?.bill?.job?.v_model_desc})`}</strong>
|
||||
</div>
|
||||
) : (
|
||||
text
|
||||
),
|
||||
},
|
||||
{
|
||||
title: t("inventory.labels.frombillinvoicenumber"),
|
||||
@@ -39,7 +59,12 @@ export function JobsList({ bodyshop, refetch, loading, jobs, total }) {
|
||||
//sorter: true, // (a, b) => alphaSort(a.ownr_ln, b.ownr_ln),
|
||||
|
||||
//sortOrder: sortcolumn === "ownr_ln" && sortorder,
|
||||
render: (text, record) => record.billline?.bill?.invoice_number,
|
||||
render: (text, record) =>
|
||||
(
|
||||
(record.billline?.bill?.invoice_number || "") +
|
||||
" " +
|
||||
(record.manualinvoicenumber || "")
|
||||
).trim(),
|
||||
},
|
||||
{
|
||||
title: t("inventory.labels.fromvendor"),
|
||||
@@ -49,7 +74,12 @@ export function JobsList({ bodyshop, refetch, loading, jobs, total }) {
|
||||
//sorter: true, // (a, b) => alphaSort(a.ownr_ln, b.ownr_ln),
|
||||
|
||||
//sortOrder: sortcolumn === "ownr_ln" && sortorder,
|
||||
render: (text, record) => record.billline?.bill?.vendor?.name,
|
||||
render: (text, record) =>
|
||||
(
|
||||
(record.billline?.bill?.vendor?.name || "") +
|
||||
" " +
|
||||
(record.manualvendor || "")
|
||||
).trim(),
|
||||
},
|
||||
{
|
||||
title: t("billlines.fields.actual_price"),
|
||||
@@ -69,13 +99,49 @@ export function JobsList({ bodyshop, refetch, loading, jobs, total }) {
|
||||
<CurrencyFormatter>{record.actual_cost}</CurrencyFormatter>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: t("inventory.fields.comment"),
|
||||
dataIndex: "comment",
|
||||
key: "comment",
|
||||
},
|
||||
{
|
||||
title: t("inventory.labels.consumedbyjob"),
|
||||
dataIndex: "consumedbyjob",
|
||||
key: "consumedbyjob",
|
||||
|
||||
ellipsis: true,
|
||||
render: (text, record) => record.bill?.job?.ro_number,
|
||||
render: (text, record) =>
|
||||
record.bill?.job?.ro_number ? (
|
||||
<Link to={`/manage/jobs/${record.bill?.job?.id}`}>
|
||||
{record.bill?.job?.ro_number}
|
||||
</Link>
|
||||
) : (
|
||||
<InventoryBillRo inventoryline={record} />
|
||||
),
|
||||
},
|
||||
{
|
||||
title: t("general.labels.actions"),
|
||||
dataIndex: "actions",
|
||||
key: "actions",
|
||||
|
||||
ellipsis: true,
|
||||
render: (text, record) => (
|
||||
<Space wrap>
|
||||
<Button
|
||||
onClick={() => {
|
||||
setInventoryUpsertContext({
|
||||
actions: { refetch: refetch },
|
||||
context: {
|
||||
existingInventory: record,
|
||||
},
|
||||
});
|
||||
}}
|
||||
>
|
||||
<EditFilled />
|
||||
</Button>
|
||||
<InventoryLineDelete inventoryline={record} refetch={refetch} />
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
@@ -105,7 +171,16 @@ export function JobsList({ bodyshop, refetch, loading, jobs, total }) {
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
|
||||
<Button
|
||||
onClick={() => {
|
||||
setInventoryUpsertContext({
|
||||
actions: { refetch: refetch },
|
||||
context: {},
|
||||
});
|
||||
}}
|
||||
>
|
||||
<FileAddFilled />
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => {
|
||||
if (search.showall) delete search.showall;
|
||||
|
||||
@@ -11,7 +11,6 @@ import {
|
||||
} from "../../redux/application/application.actions";
|
||||
import AlertComponent from "../alert/alert.component";
|
||||
import InventoryListPaginated from "./inventory-list.component";
|
||||
import RbacWrapper from "../rbac-wrapper/rbac-wrapper.component";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
//bodyshop: selectBodyshop,
|
||||
@@ -52,15 +51,13 @@ export function InventoryList({ setBreadcrumbs, setSelectedHeader }) {
|
||||
|
||||
if (error) return <AlertComponent message={error.message} type="error" />;
|
||||
return (
|
||||
<RbacWrapper action="jobs:list-all">
|
||||
<InventoryListPaginated
|
||||
refetch={refetch}
|
||||
loading={loading}
|
||||
searchParams={searchParams}
|
||||
total={data ? data.search_inventory_aggregate.aggregate.count : 0}
|
||||
jobs={data ? data.search_inventory : []}
|
||||
/>
|
||||
</RbacWrapper>
|
||||
<InventoryListPaginated
|
||||
refetch={refetch}
|
||||
loading={loading}
|
||||
searchParams={searchParams}
|
||||
total={data ? data.search_inventory_aggregate.aggregate.count : 0}
|
||||
jobs={data ? data.search_inventory : []}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
import { Form, Input, Space } from "antd";
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { connect } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { selectInventoryUpsert } from "../../redux/modals/modals.selectors";
|
||||
import FormItemCurrency from "../form-items-formatted/currency-form-item.component";
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
inventoryUpsertModal: selectInventoryUpsert,
|
||||
});
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
//setUserLanguage: language => dispatch(setUserLanguage(language))
|
||||
});
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(NoteUpsertModalComponent);
|
||||
|
||||
export function NoteUpsertModalComponent({ form, inventoryUpsertModal }) {
|
||||
const { t } = useTranslation();
|
||||
const { existingInventory } = inventoryUpsertModal.context;
|
||||
|
||||
return (
|
||||
<Space wrap>
|
||||
<Form.Item
|
||||
label={t("billlines.fields.line_desc")}
|
||||
rules={[{ required: true }]}
|
||||
name="line_desc"
|
||||
>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
<Form.Item label={t("inventory.fields.comment")} name="comment">
|
||||
<Input />
|
||||
</Form.Item>
|
||||
|
||||
{!existingInventory && (
|
||||
<>
|
||||
<Form.Item
|
||||
label={t("inventory.fields.manualinvoicenumber")}
|
||||
name="manualinvoicenumber"
|
||||
>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label={t("inventory.fields.manualvendor")}
|
||||
name="manualvendor"
|
||||
>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
rules={[{ required: true }]}
|
||||
label={t("billlines.fields.actual_cost")}
|
||||
name="actual_cost"
|
||||
>
|
||||
<FormItemCurrency />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
rules={[{ required: true }]}
|
||||
label={t("billlines.fields.actual_price")}
|
||||
name="actual_price"
|
||||
>
|
||||
<FormItemCurrency />
|
||||
</Form.Item>
|
||||
</>
|
||||
)}
|
||||
</Space>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
import { useMutation } from "@apollo/client";
|
||||
import { Form, Modal, notification } from "antd";
|
||||
import React, { useEffect } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { connect } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { logImEXEvent } from "../../firebase/firebase.utils";
|
||||
import {
|
||||
INSERT_INVENTORY_LINE,
|
||||
UPDATE_INVENTORY_LINE,
|
||||
} from "../../graphql/inventory.queries";
|
||||
import { toggleModalVisible } from "../../redux/modals/modals.actions";
|
||||
import { selectInventoryUpsert } from "../../redux/modals/modals.selectors";
|
||||
import {
|
||||
selectBodyshop,
|
||||
selectCurrentUser,
|
||||
} from "../../redux/user/user.selectors";
|
||||
import InventoryUpsertModal from "./inventory-upsert-modal.component";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
bodyshop: selectBodyshop,
|
||||
currentUser: selectCurrentUser,
|
||||
inventoryUpsertModal: selectInventoryUpsert,
|
||||
});
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
toggleModalVisible: () => dispatch(toggleModalVisible("inventoryUpsert")),
|
||||
});
|
||||
|
||||
export function InventoryUpsertModalContainer({
|
||||
currentUser,
|
||||
bodyshop,
|
||||
inventoryUpsertModal,
|
||||
toggleModalVisible,
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
const [insertInventory] = useMutation(INSERT_INVENTORY_LINE);
|
||||
const [updateInventoryLine] = useMutation(UPDATE_INVENTORY_LINE);
|
||||
|
||||
const { visible, context, actions } = inventoryUpsertModal;
|
||||
const { existingInventory } = context;
|
||||
const { refetch } = actions;
|
||||
|
||||
const [form] = Form.useForm();
|
||||
|
||||
useEffect(() => {
|
||||
//Required to prevent infinite looping.
|
||||
if (existingInventory && visible) {
|
||||
form.setFieldsValue(existingInventory);
|
||||
} else if (!existingInventory && visible) {
|
||||
form.resetFields();
|
||||
}
|
||||
}, [existingInventory, form, visible]);
|
||||
|
||||
const handleFinish = async (formValues) => {
|
||||
const values = formValues;
|
||||
|
||||
if (existingInventory) {
|
||||
logImEXEvent("inventory_update");
|
||||
|
||||
updateInventoryLine({
|
||||
variables: {
|
||||
inventoryId: existingInventory.id,
|
||||
inventoryItem: values,
|
||||
},
|
||||
}).then((r) => {
|
||||
notification["success"]({
|
||||
message: t("inventory.successes.updated"),
|
||||
});
|
||||
});
|
||||
// if (refetch) refetch();
|
||||
toggleModalVisible();
|
||||
} else {
|
||||
logImEXEvent("inventory_insert");
|
||||
|
||||
await insertInventory({
|
||||
variables: {
|
||||
inventoryItem: { shopid: bodyshop.id, ...values },
|
||||
},
|
||||
update(cache, { data }) {
|
||||
cache.modify({
|
||||
fields: {
|
||||
inventory(existingInv) {
|
||||
return [...existingInv, data.insert_inventory_one];
|
||||
},
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
if (refetch) refetch();
|
||||
form.resetFields();
|
||||
toggleModalVisible();
|
||||
notification["success"]({
|
||||
message: t("inventory.successes.inserted"),
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Modal
|
||||
title={
|
||||
existingInventory
|
||||
? t("inventory.actions.edit")
|
||||
: t("inventory.actions.new")
|
||||
}
|
||||
visible={visible}
|
||||
okText={t("general.actions.save")}
|
||||
onOk={() => {
|
||||
form.submit();
|
||||
}}
|
||||
onCancel={() => {
|
||||
toggleModalVisible();
|
||||
}}
|
||||
destroyOnClose
|
||||
>
|
||||
<Form form={form} onFinish={handleFinish} layout="vertical">
|
||||
<InventoryUpsertModal form={form} />
|
||||
</Form>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(InventoryUpsertModalContainer);
|
||||
@@ -86,6 +86,7 @@ export default function JobBillsTotalComponent({
|
||||
|
||||
const totalPartsSublet = Dinero(totals.parts.parts.total)
|
||||
.add(Dinero(totals.parts.sublets.total))
|
||||
.add(Dinero(totals.additional.shipping))
|
||||
.add(Dinero(totals.additional.towing));
|
||||
|
||||
const discrepancy = totalPartsSublet.subtract(billTotals);
|
||||
|
||||
@@ -44,6 +44,7 @@ import JobCreateIOU from "../job-create-iou/job-create-iou.component";
|
||||
import JobLinesExpander from "./job-lines-expander.component";
|
||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||
import moment from "moment";
|
||||
import JobLineConvertToLabor from "../job-line-convert-to-labor/job-line-convert-to-labor.component";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
bodyshop: selectBodyshop,
|
||||
@@ -175,7 +176,7 @@ export function JobLinesComponent({
|
||||
state.sortedInfo.columnKey === "act_price" && state.sortedInfo.order,
|
||||
ellipsis: true,
|
||||
render: (text, record) => (
|
||||
<>
|
||||
<JobLineConvertToLabor jobline={record} job={job}>
|
||||
<CurrencyFormatter>
|
||||
{record.db_ref === "900510" || record.db_ref === "900511"
|
||||
? record.prt_dsmk_m
|
||||
@@ -188,7 +189,7 @@ export function JobLinesComponent({
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</>
|
||||
</JobLineConvertToLabor>
|
||||
),
|
||||
},
|
||||
{
|
||||
@@ -295,9 +296,9 @@ export function JobLinesComponent({
|
||||
dataIndex: "actions",
|
||||
key: "actions",
|
||||
render: (text, record) => (
|
||||
<div>
|
||||
<Space>
|
||||
{(record.manual_line || jobIsPrivate) && (
|
||||
<Space>
|
||||
<>
|
||||
<Button
|
||||
disabled={jobRO}
|
||||
onClick={() => {
|
||||
@@ -334,9 +335,9 @@ export function JobLinesComponent({
|
||||
>
|
||||
<DeleteFilled />
|
||||
</Button>
|
||||
</Space>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
@@ -0,0 +1,252 @@
|
||||
import { ClockCircleOutlined } from "@ant-design/icons";
|
||||
import { useApolloClient } from "@apollo/client";
|
||||
import {
|
||||
Button,
|
||||
Card,
|
||||
Form,
|
||||
notification,
|
||||
Popover,
|
||||
Select,
|
||||
Space,
|
||||
Tooltip,
|
||||
} from "antd";
|
||||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { logImEXEvent } from "../../firebase/firebase.utils";
|
||||
import {
|
||||
QUERY_JOB_LBR_ADJUSTMENTS,
|
||||
UPDATE_JOB,
|
||||
} from "../../graphql/jobs.queries";
|
||||
|
||||
import _ from "lodash";
|
||||
import { connect } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { UPDATE_JOB_LINE } from "../../graphql/jobs-lines.queries";
|
||||
import { insertAuditTrail } from "../../redux/application/application.actions";
|
||||
import AuditTrailMapping from "../../utils/AuditTrailMappings";
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
//currentUser: selectCurrentUser
|
||||
});
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
insertAuditTrail: ({ jobid, operation }) =>
|
||||
dispatch(insertAuditTrail({ jobid, operation })),
|
||||
});
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(JobLineConvertToLabor);
|
||||
|
||||
export function JobLineConvertToLabor({
|
||||
children,
|
||||
jobline,
|
||||
job,
|
||||
insertAuditTrail,
|
||||
...otherBtnProps
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [form] = Form.useForm();
|
||||
const [visibility, setVisibility] = useState(false);
|
||||
const client = useApolloClient();
|
||||
|
||||
const handleFinish = async (values) => {
|
||||
const { mod_lbr_ty } = values;
|
||||
logImEXEvent("job_convert_dollar_to_labor");
|
||||
|
||||
setLoading(true);
|
||||
|
||||
const existingAdjustments = await client.query({
|
||||
query: QUERY_JOB_LBR_ADJUSTMENTS,
|
||||
variables: {
|
||||
id: job.id,
|
||||
},
|
||||
});
|
||||
|
||||
const newAdjustments = _.cloneDeep(
|
||||
existingAdjustments.data.jobs_by_pk.lbr_adjustments
|
||||
);
|
||||
|
||||
newAdjustments[mod_lbr_ty] =
|
||||
(newAdjustments[mod_lbr_ty] || 0) +
|
||||
calculateAdjustment({ mod_lbr_ty, job, jobline });
|
||||
|
||||
const jobUpdate = client.mutate({
|
||||
mutation: UPDATE_JOB,
|
||||
variables: {
|
||||
jobId: job.id,
|
||||
job: { lbr_adjustments: newAdjustments },
|
||||
},
|
||||
});
|
||||
|
||||
const lineUpdate = client.mutate({
|
||||
mutation: UPDATE_JOB_LINE,
|
||||
variables: {
|
||||
lineId: jobline.id,
|
||||
line: { convertedtolbr: true },
|
||||
},
|
||||
});
|
||||
|
||||
if (!!jobUpdate.errors) {
|
||||
notification["error"]({
|
||||
message: t("jobs.errors.saving", {
|
||||
message: JSON.stringify(jobUpdate.errors),
|
||||
}),
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (!!lineUpdate.errors) {
|
||||
notification["error"]({
|
||||
message: t("joblines.errors.saving", {
|
||||
message: JSON.stringify(lineUpdate.errors),
|
||||
}),
|
||||
});
|
||||
return;
|
||||
}
|
||||
insertAuditTrail({
|
||||
jobid: job.id,
|
||||
operation: AuditTrailMapping.jobmodifylbradj({
|
||||
hours: calculateAdjustment({ mod_lbr_ty, job, jobline }).toFixed(1),
|
||||
mod_lbr_ty,
|
||||
}),
|
||||
});
|
||||
setLoading(false);
|
||||
setVisibility(false);
|
||||
};
|
||||
|
||||
const overlay = (
|
||||
<Card>
|
||||
<Form form={form} layout="vertical" onFinish={handleFinish}>
|
||||
<Form.Item
|
||||
label={t("joblines.fields.mod_lbr_ty")}
|
||||
name="mod_lbr_ty"
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
//message: t("general.validation.required"),
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Select allowClear optionFilterProp="children" showSearch>
|
||||
<Select.Option value="LAA">
|
||||
{t("joblines.fields.lbr_types.LAA")}
|
||||
</Select.Option>
|
||||
<Select.Option value="LAB">
|
||||
{t("joblines.fields.lbr_types.LAB")}
|
||||
</Select.Option>
|
||||
<Select.Option value="LAD">
|
||||
{t("joblines.fields.lbr_types.LAD")}
|
||||
</Select.Option>
|
||||
<Select.Option value="LAE">
|
||||
{t("joblines.fields.lbr_types.LAE")}
|
||||
</Select.Option>
|
||||
<Select.Option value="LAF">
|
||||
{t("joblines.fields.lbr_types.LAF")}
|
||||
</Select.Option>
|
||||
<Select.Option value="LAG">
|
||||
{t("joblines.fields.lbr_types.LAG")}
|
||||
</Select.Option>
|
||||
<Select.Option value="LAM">
|
||||
{t("joblines.fields.lbr_types.LAM")}
|
||||
</Select.Option>
|
||||
<Select.Option value="LAR">
|
||||
{t("joblines.fields.lbr_types.LAR")}
|
||||
</Select.Option>
|
||||
<Select.Option value="LAS">
|
||||
{t("joblines.fields.lbr_types.LAS")}
|
||||
</Select.Option>
|
||||
<Select.Option value="LAU">
|
||||
{t("joblines.fields.lbr_types.LAU")}
|
||||
</Select.Option>
|
||||
<Select.Option value="LA1">
|
||||
{t("joblines.fields.lbr_types.LA1")}
|
||||
</Select.Option>
|
||||
<Select.Option value="LA2">
|
||||
{t("joblines.fields.lbr_types.LA2")}
|
||||
</Select.Option>
|
||||
<Select.Option value="LA3">
|
||||
{t("joblines.fields.lbr_types.LA3")}
|
||||
</Select.Option>
|
||||
<Select.Option value="LA4">
|
||||
{t("joblines.fields.lbr_types.LA4")}
|
||||
</Select.Option>
|
||||
</Select>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item shouldUpdate>
|
||||
{() => {
|
||||
const { mod_lbr_ty } = form.getFieldsValue();
|
||||
return t("joblines.labels.adjustmenttobeadded", {
|
||||
adjustment: calculateAdjustment({
|
||||
mod_lbr_ty,
|
||||
job,
|
||||
jobline,
|
||||
}).toFixed(1),
|
||||
});
|
||||
}}
|
||||
</Form.Item>
|
||||
|
||||
<Space wrap>
|
||||
<Button
|
||||
type="primary"
|
||||
disabled={jobline.convertedtolbr}
|
||||
htmlType="submit"
|
||||
>
|
||||
{t("general.actions.save")}
|
||||
</Button>
|
||||
<Button onClick={() => setVisibility(false)}>
|
||||
{t("general.actions.cancel")}
|
||||
</Button>
|
||||
</Space>
|
||||
</Form>
|
||||
</Card>
|
||||
);
|
||||
|
||||
const handleClick = (e) => {
|
||||
setLoading(true);
|
||||
|
||||
form.setFieldsValue({
|
||||
// date: new moment(),
|
||||
// bodyhrs: Math.round(v.bodyhrs * 10) / 10,
|
||||
// painthrs: Math.round(v.painthrs * 10) / 10,
|
||||
});
|
||||
setVisibility(true);
|
||||
setLoading(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{children}
|
||||
{jobline.act_price !== 0 && (
|
||||
<Popover
|
||||
disabled={jobline.convertedtolbr}
|
||||
content={overlay}
|
||||
visible={visibility}
|
||||
placement="bottom"
|
||||
>
|
||||
<Tooltip title={t("joblines.actions.converttolabor")}>
|
||||
<Button
|
||||
type="link"
|
||||
disabled={jobline.convertedtolbr}
|
||||
loading={loading}
|
||||
onClick={handleClick}
|
||||
{...otherBtnProps}
|
||||
>
|
||||
<ClockCircleOutlined />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</Popover>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function calculateAdjustment({ mod_lbr_ty, job, jobline }) {
|
||||
if (!mod_lbr_ty) return 0;
|
||||
const rate = job[`rate_${mod_lbr_ty.toLowerCase()}`];
|
||||
|
||||
if (rate === 0 || rate === null || rate === undefined) return 0;
|
||||
const adj = jobline.act_price / job[`rate_${mod_lbr_ty.toLowerCase()}`];
|
||||
|
||||
return adj;
|
||||
}
|
||||
@@ -11,7 +11,7 @@ const mapDispatchToProps = (dispatch) => ({
|
||||
});
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(JobPartsQueueCount);
|
||||
|
||||
export function JobPartsQueueCount({ bodyshop, parts }) {
|
||||
export function JobPartsQueueCount({ bodyshop, parts, style }) {
|
||||
const partsStatus = useMemo(() => {
|
||||
if (!parts) return null;
|
||||
return parts.reduce(
|
||||
@@ -36,7 +36,7 @@ export function JobPartsQueueCount({ bodyshop, parts }) {
|
||||
if (!parts) return null;
|
||||
|
||||
return (
|
||||
<Row>
|
||||
<Row style={style}>
|
||||
<Col span={4}>
|
||||
<Tooltip title="Total">
|
||||
<Tag>{partsStatus.total}</Tag>
|
||||
|
||||
@@ -22,7 +22,8 @@ export default function JobReconciliationModalComponent({ job, bills }) {
|
||||
(j.part_type !== null && j.part_type !== "PAE") ||
|
||||
(j.line_desc &&
|
||||
j.line_desc.toLowerCase().includes("towing") &&
|
||||
j.lbr_op === "OP13")
|
||||
j.lbr_op === "OP13") ||
|
||||
j.db_ref === "936004" //ADD SHIPPING LINE.
|
||||
);
|
||||
|
||||
return (
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import i18next from "i18next";
|
||||
import _ from "lodash";
|
||||
|
||||
export const reconcileByAssocLine = (
|
||||
jobLines,
|
||||
jobLineState,
|
||||
@@ -73,7 +74,12 @@ export const reconcileByPrice = (
|
||||
|
||||
jobLines.forEach((jl) => {
|
||||
const matchingBillLineIds = billLines
|
||||
.filter((bl) => bl.actual_price === jl.act_price && bl.quantity === jl.part_qty && !jl.removed)
|
||||
.filter(
|
||||
(bl) =>
|
||||
bl.actual_price === jl.act_price &&
|
||||
bl.quantity === jl.part_qty &&
|
||||
!jl.removed
|
||||
)
|
||||
.map((bl) => bl.id);
|
||||
|
||||
if (matchingBillLineIds.length > 1) {
|
||||
|
||||
@@ -169,7 +169,7 @@ export default function ScoreboardAddButton({
|
||||
};
|
||||
|
||||
return (
|
||||
<Popover content={overlay} visible={visibility}>
|
||||
<Popover content={overlay} visible={visibility} placement="bottom">
|
||||
<Button
|
||||
loading={loading}
|
||||
disabled={disabled}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { LoadingOutlined } from "@ant-design/icons";
|
||||
import { useLazyQuery } from "@apollo/client";
|
||||
import { Empty, Select, Space, Tag } from "antd";
|
||||
import { Select, Space, Tag } from "antd";
|
||||
import _ from "lodash";
|
||||
import React, { forwardRef, useEffect } from "react";
|
||||
import React, { forwardRef, useState, useEffect } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import {
|
||||
SEARCH_JOBS_BY_ID_FOR_AUTOCOMPLETE,
|
||||
@@ -24,31 +23,35 @@ const JobSearchSelect = (
|
||||
ref
|
||||
) => {
|
||||
const { t } = useTranslation();
|
||||
const [theOptions, setTheOptions] = useState([]);
|
||||
const [callSearch, { loading, error, data }] = useLazyQuery(
|
||||
SEARCH_JOBS_FOR_AUTOCOMPLETE,
|
||||
{
|
||||
...(convertedOnly || notExported
|
||||
? {
|
||||
variables: {
|
||||
...(convertedOnly ? { isConverted: true } : {}),
|
||||
...(notExported ? { notExported: true } : {}),
|
||||
...(notInvoiced ? { notInvoiced: true } : {}),
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
}
|
||||
{}
|
||||
);
|
||||
|
||||
const [callIdSearch, { loading: idLoading, error: idError, data: idData }] =
|
||||
useLazyQuery(SEARCH_JOBS_BY_ID_FOR_AUTOCOMPLETE);
|
||||
|
||||
const executeSearch = (v) => {
|
||||
callSearch(v);
|
||||
if (v && v !== "") callSearch(v);
|
||||
};
|
||||
const debouncedExecuteSearch = _.debounce(executeSearch, 500);
|
||||
|
||||
const handleSearch = (value) => {
|
||||
debouncedExecuteSearch({ variables: { search: value } });
|
||||
debouncedExecuteSearch({
|
||||
variables: {
|
||||
search: value,
|
||||
...(convertedOnly || notExported
|
||||
? {
|
||||
variables: {
|
||||
...(convertedOnly ? { isConverted: true } : {}),
|
||||
...(notExported ? { notExported: true } : {}),
|
||||
...(notInvoiced ? { notInvoiced: true } : {}),
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
@@ -57,13 +60,17 @@ const JobSearchSelect = (
|
||||
}
|
||||
}, [restProps.value, callIdSearch]);
|
||||
|
||||
const theOptions = _.uniqBy(
|
||||
[
|
||||
...(idData && idData.jobs_by_pk ? [idData.jobs_by_pk] : []),
|
||||
...(data && data.search_jobs ? data.search_jobs : []),
|
||||
],
|
||||
"id"
|
||||
);
|
||||
useEffect(() => {
|
||||
setTheOptions(
|
||||
_.uniqBy(
|
||||
[
|
||||
...(idData && idData.jobs_by_pk ? [idData.jobs_by_pk] : []),
|
||||
...(data && data.search_jobs ? data.search_jobs : []),
|
||||
],
|
||||
"id"
|
||||
)
|
||||
);
|
||||
}, [data, idData]);
|
||||
|
||||
return (
|
||||
<div>
|
||||
@@ -77,7 +84,8 @@ const JobSearchSelect = (
|
||||
}}
|
||||
filterOption={false}
|
||||
onSearch={handleSearch}
|
||||
notFoundContent={loading ? <LoadingOutlined /> : <Empty />}
|
||||
loading={loading || idLoading}
|
||||
//notFoundContent={loading ? <LoadingOutlined /> : <Empty />}
|
||||
{...restProps}
|
||||
>
|
||||
{theOptions
|
||||
@@ -99,7 +107,6 @@ const JobSearchSelect = (
|
||||
))
|
||||
: null}
|
||||
</Select>
|
||||
{idLoading || loading ? <LoadingOutlined /> : null}
|
||||
{error ? <AlertComponent message={error.message} type="error" /> : null}
|
||||
{idError ? (
|
||||
<AlertComponent message={idError.message} type="error" />
|
||||
|
||||
@@ -6,12 +6,17 @@ import { useTranslation } from "react-i18next";
|
||||
|
||||
import { connect } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||
import {
|
||||
selectBodyshop,
|
||||
selectCurrentUser,
|
||||
} from "../../redux/user/user.selectors";
|
||||
import moment from "moment";
|
||||
import AuditTrailMapping from "../../utils/AuditTrailMappings";
|
||||
import { insertAuditTrail } from "../../redux/application/application.actions";
|
||||
import { INSERT_EXPORT_LOG } from "../../graphql/accounting.queries";
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
bodyshop: selectBodyshop,
|
||||
currentUser: selectCurrentUser,
|
||||
});
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
insertAuditTrail: ({ jobid, operation }) =>
|
||||
@@ -22,9 +27,15 @@ export default connect(
|
||||
mapDispatchToProps
|
||||
)(JobAdminMarkReexport);
|
||||
|
||||
export function JobAdminMarkReexport({ insertAuditTrail, bodyshop, job }) {
|
||||
export function JobAdminMarkReexport({
|
||||
insertAuditTrail,
|
||||
bodyshop,
|
||||
currentUser,
|
||||
job,
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [insertExportLog] = useMutation(INSERT_EXPORT_LOG);
|
||||
const [markJobForReexport] = useMutation(gql`
|
||||
mutation MARK_JOB_FOR_REEXPORT($jobId: uuid!) {
|
||||
update_jobs_by_pk(
|
||||
@@ -101,6 +112,20 @@ export function JobAdminMarkReexport({ insertAuditTrail, bodyshop, job }) {
|
||||
variables: { jobId: job.id, date_exported: moment() },
|
||||
});
|
||||
|
||||
await insertExportLog({
|
||||
variables: {
|
||||
logs: [
|
||||
{
|
||||
bodyshopid: bodyshop.id,
|
||||
jobid: job.id,
|
||||
successful: true,
|
||||
message: JSON.stringify([t("general.labels.markedexported")]),
|
||||
useremail: currentUser.email,
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
if (!result.errors) {
|
||||
notification["success"]({ message: t("jobs.successes.save") });
|
||||
insertAuditTrail({
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Form, Select } from "antd";
|
||||
import { Form, Select, Space, Tooltip } from "antd";
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { connect } from "react-redux";
|
||||
@@ -8,6 +8,7 @@ import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||
import LaborTypeFormItem from "../form-items-formatted/labor-type-form-item.component";
|
||||
import PartTypeFormItem from "../form-items-formatted/part-type-form-item.component";
|
||||
import ReadOnlyFormItem from "../form-items-formatted/read-only-form-item.component";
|
||||
import { WarningOutlined } from "@ant-design/icons";
|
||||
import "./jobs-close-lines.styles.scss";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
@@ -62,14 +63,23 @@ export function JobsCloseLines({ bodyshop, job, jobRO }) {
|
||||
</Form.Item>
|
||||
</td>
|
||||
<td>
|
||||
<Form.Item
|
||||
span={2}
|
||||
// label={t("joblines.fields.act_price")}
|
||||
key={`${index}act_price`}
|
||||
name={[field.name, "act_price"]}
|
||||
>
|
||||
<ReadOnlyFormItem type="currency" />
|
||||
</Form.Item>
|
||||
<Space>
|
||||
<Form.Item
|
||||
span={2}
|
||||
// label={t("joblines.fields.act_price")}
|
||||
key={`${index}act_price`}
|
||||
name={[field.name, "act_price"]}
|
||||
>
|
||||
<ReadOnlyFormItem type="currency" />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
noStyle
|
||||
key={`${index}convertedtolbr`}
|
||||
name={[field.name, "convertedtolbr"]}
|
||||
>
|
||||
<HasBeenConvertedTolabor />
|
||||
</Form.Item>
|
||||
</Space>
|
||||
</td>
|
||||
<td>
|
||||
<Form.Item
|
||||
@@ -192,3 +202,14 @@ export function JobsCloseLines({ bodyshop, job, jobRO }) {
|
||||
);
|
||||
}
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(JobsCloseLines);
|
||||
|
||||
const HasBeenConvertedTolabor = ({ value }) => {
|
||||
const { t } = useTranslation();
|
||||
console.log(value);
|
||||
if (!value) return null;
|
||||
return (
|
||||
<Tooltip title={t("joblines.labels.convertedtolabor")}>
|
||||
<WarningOutlined style={{ color: "tomato" }} />
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -217,21 +217,31 @@ export function JobsDetailHeader({ job, bodyshop, disabled }) {
|
||||
<JobsRelatedRos jobid={job.id} job={job} />
|
||||
</DataLabel>
|
||||
{job.vehicle && job.vehicle.notes && (
|
||||
<DataLabel label={t("vehicles.fields.notes")}>
|
||||
<span style={{ whiteSpace: "pre" }}>{job.vehicle.notes}</span>
|
||||
<DataLabel
|
||||
label={t("vehicles.fields.notes")}
|
||||
valueStyle={{ whiteSpace: "pre-wrap" }}
|
||||
>
|
||||
{job.vehicle.notes}
|
||||
</DataLabel>
|
||||
)}
|
||||
{job.vehicle && job.vehicle.v_paint_codes && (
|
||||
<DataLabel
|
||||
label={t("vehicles.fields.v_paint_codes", { number: "" })}
|
||||
>
|
||||
<span style={{ whiteSpace: "pre" }}>
|
||||
{Object.keys(job.vehicle.v_paint_codes)
|
||||
.filter(
|
||||
(key) =>
|
||||
job.vehicle.v_paint_codes[key] !== "" &&
|
||||
job.vehicle.v_paint_codes[key] !== null &&
|
||||
job.vehicle.v_paint_codes[key] !== undefined
|
||||
)
|
||||
.map((key, idx) => (
|
||||
<Tag key={idx}>{job.vehicle.v_paint_codes[key]}</Tag>
|
||||
))}
|
||||
</span>
|
||||
</DataLabel>
|
||||
)}
|
||||
{
|
||||
// job.vehicle && job.vehicle.v_paint_codes && (
|
||||
// <DataLabel label={t("vehicles.fields.v_paint_codes")}>
|
||||
// <span style={{ whiteSpace: "pre" }}>
|
||||
// {Object.keys(job.vehicle.v_paint_codes).map((key, idx) => (
|
||||
// <Tag key={idx}>{job.vehicle.v_paint_codes[key]}</Tag>
|
||||
// ))}
|
||||
// </span>
|
||||
// </DataLabel>
|
||||
// )
|
||||
}
|
||||
</div>
|
||||
</Card>
|
||||
</Col>
|
||||
|
||||
@@ -25,6 +25,7 @@ function JobsDocumentGalleryExternal({
|
||||
id: value.id,
|
||||
type: value.type,
|
||||
tags: [{ value: value.type, title: value.type }],
|
||||
size: value.size,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,24 @@ import React, { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { UPDATE_JOB } from "../../graphql/jobs.queries";
|
||||
|
||||
export default function LaborAllocationsAdjustmentEdit({
|
||||
import { connect } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { insertAuditTrail } from "../../redux/application/application.actions";
|
||||
import AuditTrailMapping from "../../utils/AuditTrailMappings";
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
//currentUser: selectCurrentUser
|
||||
});
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
insertAuditTrail: ({ jobid, operation }) =>
|
||||
dispatch(insertAuditTrail({ jobid, operation })),
|
||||
});
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(LaborAllocationsAdjustmentEdit);
|
||||
|
||||
export function LaborAllocationsAdjustmentEdit({
|
||||
insertAuditTrail,
|
||||
jobId,
|
||||
mod_lbr_ty,
|
||||
adjustments,
|
||||
@@ -51,6 +68,15 @@ export default function LaborAllocationsAdjustmentEdit({
|
||||
notification["success"]({
|
||||
message: t("jobs.successes.save"),
|
||||
});
|
||||
insertAuditTrail({
|
||||
jobid: jobId,
|
||||
operation: AuditTrailMapping.jobmodifylbradj({
|
||||
mod_lbr_ty: values.mod_lbr_ty,
|
||||
hours:
|
||||
values.hours -
|
||||
((adjustments && adjustments[mod_lbr_ty]) || 0).toFixed(1),
|
||||
}),
|
||||
});
|
||||
}
|
||||
setLoading(false);
|
||||
setVisible(false);
|
||||
|
||||
@@ -31,7 +31,7 @@ export default function OwnerFindModalContainer({
|
||||
|
||||
useEffect(() => {
|
||||
if (modalProps.visible && owner) {
|
||||
const s = OwnerNameDisplayFunction(owner);
|
||||
const s = OwnerNameDisplayFunction(owner, true);
|
||||
|
||||
setSearchText(s.trim());
|
||||
callSearchowners({ variables: { search: s.trim() } });
|
||||
|
||||
@@ -27,7 +27,7 @@ export function OwnerNameDisplay({ bodyshop, ownerObject }) {
|
||||
}`.trim();
|
||||
}
|
||||
|
||||
export function OwnerNameDisplayFunction(ownerObject) {
|
||||
export function OwnerNameDisplayFunction(ownerObject, forceFirstLast = false) {
|
||||
const emptyTest =
|
||||
ownerObject.ownr_fn + ownerObject.ownr_ln + ownerObject.ownr_co_nm;
|
||||
|
||||
@@ -36,7 +36,7 @@ export function OwnerNameDisplayFunction(ownerObject) {
|
||||
|
||||
const rdxStore = store.getState();
|
||||
|
||||
if (rdxStore.user.bodyshop.last_name_first)
|
||||
if (rdxStore.user.bodyshop.last_name_first && !forceFirstLast)
|
||||
return `${ownerObject.ownr_ln || ""}, ${ownerObject.ownr_fn || ""} ${
|
||||
ownerObject.ownr_co_nm || ""
|
||||
}`.trim();
|
||||
|
||||
@@ -124,6 +124,15 @@ export function PartsOrderModalComponent({
|
||||
<Checkbox />
|
||||
</Form.Item>
|
||||
)}
|
||||
{OEConnection.treatment === "on" && !isReturn && (
|
||||
<Form.Item
|
||||
name="is_quote"
|
||||
label={t("parts_orders.labels.is_quote")}
|
||||
valuePropName="checked"
|
||||
>
|
||||
<Checkbox />
|
||||
</Form.Item>
|
||||
)}
|
||||
</LayoutFormRow>
|
||||
<Divider orientation="left">
|
||||
{t("parts_orders.labels.inthisorder")}
|
||||
@@ -291,17 +300,32 @@ export function PartsOrderModalComponent({
|
||||
<Input.TextArea rows={3} />
|
||||
</Form.Item>
|
||||
|
||||
<Radio.Group
|
||||
defaultValue={sendType}
|
||||
onChange={(e) => setSendType(e.target.value)}
|
||||
>
|
||||
<Radio value={"none"}>{t("general.labels.none")}</Radio>
|
||||
<Radio value={"e"}>{t("parts_orders.labels.email")}</Radio>
|
||||
<Radio value={"p"}>{t("parts_orders.labels.print")}</Radio>
|
||||
{OEConnection.treatment === "on" && !isReturn && (
|
||||
<Radio value={"oec"}>{t("parts_orders.labels.oec")}</Radio>
|
||||
)}
|
||||
</Radio.Group>
|
||||
<Form.Item noStyle shouldUpdate>
|
||||
{() => {
|
||||
const is_quote = form.getFieldValue("is_quote");
|
||||
if (is_quote) setSendType("oec");
|
||||
return (
|
||||
<Radio.Group
|
||||
defaultValue={sendType}
|
||||
value={sendType}
|
||||
onChange={(e) => setSendType(e.target.value)}
|
||||
>
|
||||
<Radio disabled={is_quote} value={"none"}>
|
||||
{t("general.labels.none")}
|
||||
</Radio>
|
||||
<Radio disabled={is_quote} value={"e"}>
|
||||
{t("parts_orders.labels.email")}
|
||||
</Radio>
|
||||
<Radio disabled={is_quote} value={"p"}>
|
||||
{t("parts_orders.labels.print")}
|
||||
</Radio>
|
||||
{OEConnection.treatment === "on" && !isReturn && (
|
||||
<Radio value={"oec"}>{t("parts_orders.labels.oec")}</Radio>
|
||||
)}
|
||||
</Radio.Group>
|
||||
);
|
||||
}}
|
||||
</Form.Item>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -93,31 +93,53 @@ export function PartsOrderModalContainer({
|
||||
const [updateJobLines] = useMutation(UPDATE_JOB_LINE_STATUS);
|
||||
const [updateJob] = useMutation(UPDATE_JOB);
|
||||
|
||||
const handleFinish = async ({ removefrompartsqueue, ...values }) => {
|
||||
const handleFinish = async ({
|
||||
removefrompartsqueue,
|
||||
is_quote,
|
||||
...values
|
||||
}) => {
|
||||
logImEXEvent("parts_order_insert");
|
||||
setSaving(true);
|
||||
const insertResult = await insertPartOrder({
|
||||
variables: {
|
||||
po: [
|
||||
{
|
||||
...values,
|
||||
order_date: moment().format("YYYY-MM-DD"),
|
||||
orderedby: currentUser.email,
|
||||
jobid: jobId,
|
||||
user_email: currentUser.email,
|
||||
return: isReturn,
|
||||
status: bodyshop.md_order_statuses.default_ordered || "Ordered*",
|
||||
},
|
||||
],
|
||||
},
|
||||
refetchQueries: ["QUERY_PARTS_BILLS_BY_JOBID"],
|
||||
});
|
||||
if (!!insertResult.error) {
|
||||
notification["error"]({
|
||||
message: t("parts_orders.errors.creating"),
|
||||
description: JSON.stringify(insertResult.error),
|
||||
let insertResult;
|
||||
if (!is_quote) {
|
||||
insertResult = await insertPartOrder({
|
||||
variables: {
|
||||
po: [
|
||||
{
|
||||
...values,
|
||||
order_date: moment().format("YYYY-MM-DD"),
|
||||
orderedby: currentUser.email,
|
||||
jobid: jobId,
|
||||
user_email: currentUser.email,
|
||||
return: isReturn,
|
||||
status: bodyshop.md_order_statuses.default_ordered || "Ordered*",
|
||||
},
|
||||
],
|
||||
},
|
||||
refetchQueries: ["QUERY_PARTS_BILLS_BY_JOBID"],
|
||||
});
|
||||
if (!!insertResult.error) {
|
||||
notification["error"]({
|
||||
message: t("parts_orders.errors.creating"),
|
||||
description: JSON.stringify(insertResult.error),
|
||||
});
|
||||
return;
|
||||
}
|
||||
notification["success"]({
|
||||
message: values.isReturn
|
||||
? t("parts_orders.successes.return_created")
|
||||
: t("parts_orders.successes.created"),
|
||||
});
|
||||
insertAuditTrail({
|
||||
jobid: jobId,
|
||||
operation: isReturn
|
||||
? AuditTrailMapping.jobspartsreturn(
|
||||
insertResult.data.insert_parts_orders.returning[0].order_number
|
||||
)
|
||||
: AuditTrailMapping.jobspartsorder(
|
||||
insertResult.data.insert_parts_orders.returning[0].order_number
|
||||
),
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const jobLinesResult = await updateJobLines({
|
||||
@@ -127,6 +149,8 @@ export function PartsOrderModalContainer({
|
||||
.map((item) => item.job_line_id),
|
||||
status: isReturn
|
||||
? bodyshop.md_order_statuses.default_returned || "Returned*"
|
||||
: is_quote
|
||||
? bodyshop.md_order_statuses.default_quote || "Quote"
|
||||
: bodyshop.md_order_statuses.default_ordered || "Ordered*",
|
||||
},
|
||||
});
|
||||
@@ -142,17 +166,6 @@ export function PartsOrderModalContainer({
|
||||
});
|
||||
}
|
||||
|
||||
insertAuditTrail({
|
||||
jobid: jobId,
|
||||
operation: isReturn
|
||||
? AuditTrailMapping.jobspartsreturn(
|
||||
insertResult.data.insert_parts_orders.returning[0].order_number
|
||||
)
|
||||
: AuditTrailMapping.jobspartsorder(
|
||||
insertResult.data.insert_parts_orders.returning[0].order_number
|
||||
),
|
||||
});
|
||||
|
||||
if (!!jobLinesResult.errors) {
|
||||
notification["error"]({
|
||||
message: t("parts_orders.errors.creating"),
|
||||
@@ -160,12 +173,6 @@ export function PartsOrderModalContainer({
|
||||
});
|
||||
}
|
||||
|
||||
notification["success"]({
|
||||
message: values.isReturn
|
||||
? t("parts_orders.successes.return_created")
|
||||
: t("parts_orders.successes.created"),
|
||||
});
|
||||
|
||||
if (values.vendorid === bodyshop.inhousevendorid) {
|
||||
setBillEnterContext({
|
||||
actions: { refetch: refetch },
|
||||
|
||||
@@ -4,14 +4,15 @@ import React, { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { connect } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { INSERT_EXPORT_LOG } from "../../graphql/accounting.queries";
|
||||
import {
|
||||
selectAuthLevel,
|
||||
selectBodyshop,
|
||||
selectCurrentUser,
|
||||
} from "../../redux/user/user.selectors";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
bodyshop: selectBodyshop,
|
||||
authLevel: selectAuthLevel,
|
||||
currentUser: selectCurrentUser,
|
||||
});
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
//setUserLanguage: language => dispatch(setUserLanguage(language))
|
||||
@@ -23,6 +24,8 @@ export default connect(
|
||||
)(BillMarkSelectedExported);
|
||||
|
||||
export function BillMarkSelectedExported({
|
||||
bodyshop,
|
||||
currentUser,
|
||||
billids,
|
||||
disabled,
|
||||
loadingCallback,
|
||||
@@ -31,7 +34,7 @@ export function BillMarkSelectedExported({
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
const [insertExportLog] = useMutation(INSERT_EXPORT_LOG);
|
||||
const [updateBill] = useMutation(gql`
|
||||
mutation UPDATE_BILL($billIds: [uuid!]!) {
|
||||
update_bills(where: { id: { _in: $billIds } }, _set: { exported: true }) {
|
||||
@@ -49,9 +52,21 @@ export function BillMarkSelectedExported({
|
||||
loadingCallback(true);
|
||||
const result = await updateBill({
|
||||
variables: { billIds: billids },
|
||||
update(cache){
|
||||
|
||||
}
|
||||
update(cache) {},
|
||||
});
|
||||
|
||||
await insertExportLog({
|
||||
variables: {
|
||||
logs: billids.map((id) => {
|
||||
return {
|
||||
bodyshopid: bodyshop.id,
|
||||
billid: id,
|
||||
successful: true,
|
||||
message: JSON.stringify([t("general.labels.markedexported")]),
|
||||
useremail: currentUser.email,
|
||||
};
|
||||
}),
|
||||
},
|
||||
});
|
||||
|
||||
if (!result.errors) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import Icon from "@ant-design/icons";
|
||||
import { useMutation } from "@apollo/client";
|
||||
import { Button, Input, Popover } from "antd";
|
||||
import { Button, Input, Popover, Tooltip } from "antd";
|
||||
import React, { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { FaRegStickyNote } from "react-icons/fa";
|
||||
@@ -69,10 +69,11 @@ export default function ProductionListColumnComment({ record }) {
|
||||
cursor: "pointer",
|
||||
overflow: "hidden",
|
||||
textOverflow: "ellipsis",
|
||||
display: "inline-block",
|
||||
}}
|
||||
>
|
||||
<Icon component={FaRegStickyNote} style={{ marginRight: ".2rem" }} />
|
||||
{record.comment || " "}
|
||||
<Tooltip title={record.comment}>{record.comment || " "}</Tooltip>
|
||||
</div>
|
||||
</Popover>
|
||||
);
|
||||
|
||||
@@ -2,28 +2,28 @@ import { PauseCircleOutlined } from "@ant-design/icons";
|
||||
import { Space } from "antd";
|
||||
import i18n from "i18next";
|
||||
import moment from "moment";
|
||||
import React from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import CurrencyFormatter from "../../utils/CurrencyFormatter";
|
||||
import { TimeFormatter } from "../../utils/DateFormatter";
|
||||
import PhoneFormatter from "../../utils/PhoneFormatter";
|
||||
import { alphaSort, dateSort, statusSort } from "../../utils/sorters";
|
||||
import JobAltTransportChange from "../job-at-change/job-at-change.component";
|
||||
import JobPartsQueueCount from "../job-parts-queue-count/job-parts-queue-count.component";
|
||||
import OwnerNameDisplay from "../owner-name-display/owner-name-display.component";
|
||||
import ProductionSubletsManageComponent from "../production-sublets-manage/production-sublets-manage.component";
|
||||
import ProductionListColumnAlert from "./production-list-columns.alert.component";
|
||||
import ProductionListColumnBodyPriority from "./production-list-columns.bodypriority.component";
|
||||
import ProductionListColumnComment from "./production-list-columns.comment.component";
|
||||
import ProductionListDate from "./production-list-columns.date.component";
|
||||
import ProductionListColumnDetailPriority from "./production-list-columns.detailpriority.component";
|
||||
import ProductionListEmployeeAssignment from "./production-list-columns.empassignment.component";
|
||||
import ProductionListLastContacted from "./production-list-columns.lastcontacted.component";
|
||||
import ProductionListColumnPaintPriority from "./production-list-columns.paintpriority.component";
|
||||
import ProductionListColumnNote from "./production-list-columns.productionnote.component";
|
||||
import ProductionListColumnStatus from "./production-list-columns.status.component";
|
||||
import ProductionListColumnCategory from "./production-list-columns.status.category";
|
||||
import ProductionlistColumnTouchTime from "./prodution-list-columns.touchtime.component";
|
||||
import ProductionListColumnComment from "./production-list-columns.comment.component";
|
||||
import ProductionListColumnPartsReceived from "./production-list-columns.partsreceived.component";
|
||||
import OwnerNameDisplay from "../owner-name-display/owner-name-display.component";
|
||||
import JobPartsQueueCount from "../job-parts-queue-count/job-parts-queue-count.component";
|
||||
import ProductionListColumnNote from "./production-list-columns.productionnote.component";
|
||||
import ProductionListColumnCategory from "./production-list-columns.status.category";
|
||||
import ProductionListColumnStatus from "./production-list-columns.status.component";
|
||||
import ProductionlistColumnTouchTime from "./prodution-list-columns.touchtime.component";
|
||||
|
||||
const r = ({ technician, state, activeStatuses, bodyshop }) => {
|
||||
return [
|
||||
@@ -105,6 +105,16 @@ const r = ({ technician, state, activeStatuses, bodyshop }) => {
|
||||
<ProductionListDate record={record} field="actual_in" time />
|
||||
),
|
||||
},
|
||||
{
|
||||
title: i18n.t("jobs.fields.actual_in") + " (HH:MM)",
|
||||
dataIndex: "actual_in_time",
|
||||
key: "actual_in_time",
|
||||
ellipsis: true,
|
||||
|
||||
render: (text, record) => (
|
||||
<TimeFormatter>{record.actual_in}</TimeFormatter>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: i18n.t("jobs.fields.scheduled_completion"),
|
||||
dataIndex: "scheduled_completion",
|
||||
@@ -124,6 +134,16 @@ const r = ({ technician, state, activeStatuses, bodyshop }) => {
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: i18n.t("jobs.fields.scheduled_completion") + " (HH:MM)",
|
||||
dataIndex: "scheduled_completion_time",
|
||||
key: "scheduled_completion_time",
|
||||
ellipsis: true,
|
||||
|
||||
render: (text, record) => (
|
||||
<TimeFormatter>{record.scheduled_completion}</TimeFormatter>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: i18n.t("jobs.fields.date_last_contacted"),
|
||||
dataIndex: "date_last_contacted",
|
||||
@@ -176,6 +196,16 @@ const r = ({ technician, state, activeStatuses, bodyshop }) => {
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: i18n.t("jobs.fields.scheduled_delivery") + " (HH:MM)",
|
||||
dataIndex: "scheduled_delivery_time",
|
||||
key: "scheduled_delivery_time",
|
||||
ellipsis: true,
|
||||
|
||||
render: (text, record) => (
|
||||
<TimeFormatter>{record.scheduled_delivery}</TimeFormatter>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: i18n.t("jobs.fields.ins_co_nm"),
|
||||
dataIndex: "ins_co_nm",
|
||||
@@ -499,6 +529,27 @@ const r = ({ technician, state, activeStatuses, bodyshop }) => {
|
||||
<JobPartsQueueCount parts={record.joblines_status} record={record} />
|
||||
),
|
||||
},
|
||||
//Added as a place holder for St Claude. Not implemented as it requires another join for a field used by only 1 client.
|
||||
// {
|
||||
// title: i18n.t("vehicles.fields.v_paint_codes", { number: "" }),
|
||||
// dataIndex: "v_paint_codes",
|
||||
// key: "v_paint_codes",
|
||||
// render: (text, record) =>
|
||||
// record.vehicle?.v_paint_codes ? (
|
||||
// <span style={{ whiteSpace: "pre" }}>
|
||||
// {Object.keys(record.vehicle.v_paint_codes)
|
||||
// .filter(
|
||||
// (key) =>
|
||||
// record.vehicle.v_paint_codes[key] !== "" &&
|
||||
// record.vehicle.v_paint_codes[key] !== null &&
|
||||
// record.vehicle.v_paint_codes[key] !== undefined
|
||||
// )
|
||||
// .map((key, idx) => (
|
||||
// <Tag key={idx}>{record.vehicle.v_paint_codes[key]}</Tag>
|
||||
// ))}
|
||||
// </span>
|
||||
// ) : null,
|
||||
// },
|
||||
];
|
||||
};
|
||||
export default r;
|
||||
|
||||
@@ -50,50 +50,45 @@ export default function ProductionListDate({
|
||||
"production-completion-soon"));
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
<Dropdown
|
||||
//trigger={["click"]}
|
||||
visible={visible}
|
||||
style={{
|
||||
height: "19px",
|
||||
}}
|
||||
overlay={
|
||||
<Card
|
||||
style={{ padding: "1rem" }}
|
||||
<Dropdown
|
||||
//trigger={["click"]}
|
||||
visible={visible}
|
||||
style={{
|
||||
height: "19px",
|
||||
}}
|
||||
overlay={
|
||||
<Card style={{ padding: "1rem" }} onClick={(e) => e.stopPropagation()}>
|
||||
<FormDatePicker
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<FormDatePicker
|
||||
value={(record[field] && moment(record[field])) || null}
|
||||
onChange={handleChange}
|
||||
format="MM/DD/YYYY"
|
||||
isDateOnly={!time}
|
||||
/>
|
||||
{time && (
|
||||
<TimePicker
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
value={(record[field] && moment(record[field])) || null}
|
||||
onChange={handleChange}
|
||||
format="MM/DD/YYYY"
|
||||
isDateOnly={!time}
|
||||
minuteStep={15}
|
||||
format="hh:mm a"
|
||||
/>
|
||||
{time && (
|
||||
<TimePicker
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
value={(record[field] && moment(record[field])) || null}
|
||||
onChange={handleChange}
|
||||
minuteStep={15}
|
||||
format="hh:mm a"
|
||||
/>
|
||||
)}
|
||||
<Button onClick={() => setVisible(false)}>
|
||||
{t("general.actions.close")}
|
||||
</Button>
|
||||
</Card>
|
||||
}
|
||||
)}
|
||||
<Button onClick={() => setVisible(false)}>
|
||||
{t("general.actions.close")}
|
||||
</Button>
|
||||
</Card>
|
||||
}
|
||||
>
|
||||
<div
|
||||
onClick={() => setVisible(true)}
|
||||
style={{
|
||||
height: "19px",
|
||||
}}
|
||||
className={className}
|
||||
>
|
||||
<div
|
||||
onClick={() => setVisible(true)}
|
||||
style={{
|
||||
height: "19px",
|
||||
}}
|
||||
className={className}
|
||||
>
|
||||
<DateFormatter bordered={false}>{record[field]}</DateFormatter>
|
||||
</div>
|
||||
</Dropdown>
|
||||
</div>
|
||||
<DateFormatter bordered={false}>{record[field]}</DateFormatter>
|
||||
</div>
|
||||
</Dropdown>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -68,5 +68,6 @@ const ret = {
|
||||
"users:editaccess": 4,
|
||||
|
||||
"inventory:list": 1,
|
||||
"inventory:delete": 2,
|
||||
};
|
||||
export default ret;
|
||||
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||
import { DateTimeFormatter } from "../../utils/DateFormatter";
|
||||
import LoadingSkeleton from "../loading-skeleton/loading-skeleton.component";
|
||||
import OwnerNameDisplay from "../owner-name-display/owner-name-display.component";
|
||||
import ScheduleBlockDay from "../schedule-block-day/schedule-block-day.component";
|
||||
import ScheduleCalendarHeaderGraph from "./schedule-calendar-header-graph.component";
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
@@ -66,6 +67,9 @@ export function ScheduleCalendarHeaderComponent({
|
||||
<td>
|
||||
<Link to={`/manage/jobs/${j.id}`}>{j.ro_number}</Link>
|
||||
</td>
|
||||
<td>
|
||||
<OwnerNameDisplay ownerObject={j} />
|
||||
</td>
|
||||
<td>
|
||||
{`(${(
|
||||
j.labhrs.aggregate.sum.mod_lb_hrs +
|
||||
@@ -99,6 +103,9 @@ export function ScheduleCalendarHeaderComponent({
|
||||
<td>
|
||||
<Link to={`/manage/jobs/${j.id}`}>{j.ro_number}</Link>
|
||||
</td>
|
||||
<td>
|
||||
<OwnerNameDisplay ownerObject={j} />
|
||||
</td>
|
||||
<td>
|
||||
{`(${(
|
||||
j.labhrs.aggregate.sum.mod_lb_hrs +
|
||||
|
||||
@@ -26,7 +26,7 @@ export default function ScoreboardEntryEdit({ entry }) {
|
||||
return;
|
||||
} else {
|
||||
notification["success"]({
|
||||
message: t("scoredboard.successes.updated"),
|
||||
message: t("scoreboard.successes.updated"),
|
||||
});
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { Card } from "antd";
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { connect } from "react-redux";
|
||||
import {
|
||||
@@ -7,6 +6,7 @@ import {
|
||||
CartesianGrid,
|
||||
ComposedChart,
|
||||
Legend,
|
||||
ReferenceLine,
|
||||
ResponsiveContainer,
|
||||
Tooltip,
|
||||
XAxis,
|
||||
@@ -48,13 +48,15 @@ export function ScoreboardTicketsBar({ data, bodyshop }) {
|
||||
<YAxis strokeWidth={graphProps.strokeWidth} />
|
||||
<Tooltip />
|
||||
<Legend />
|
||||
{/* <Area
|
||||
type="monotone"
|
||||
name="Accumulated Hours"
|
||||
dataKey="accHrs"
|
||||
fill="lightgreen"
|
||||
stroke="green"
|
||||
/> */}
|
||||
<ReferenceLine
|
||||
y={
|
||||
bodyshop.scoreboard_target.dailyBodyTarget +
|
||||
bodyshop.scoreboard_target.dailyPaintTarget
|
||||
}
|
||||
label="Daily Target"
|
||||
stroke="red"
|
||||
strokeDasharray="3 3"
|
||||
/>
|
||||
{data &&
|
||||
data.employees.map((e, idx) => (
|
||||
<Bar
|
||||
@@ -64,16 +66,10 @@ export function ScoreboardTicketsBar({ data, bodyshop }) {
|
||||
stackId="productive"
|
||||
// barSize={20}
|
||||
fill={data.colors[idx]}
|
||||
/>
|
||||
>
|
||||
{/* <LabelList position="top" /> */}
|
||||
</Bar>
|
||||
))}
|
||||
|
||||
{/* <Line
|
||||
name="Target Hours"
|
||||
type="monotone"
|
||||
dataKey="accTargetHrs"
|
||||
stroke="#ff7300"
|
||||
strokeWidth={graphProps.strokeWidth}
|
||||
/> */}
|
||||
</ComposedChart>
|
||||
</ResponsiveContainer>
|
||||
</Card>
|
||||
|
||||
@@ -5,7 +5,7 @@ import moment from "moment";
|
||||
import queryString from "query-string";
|
||||
import React, { useMemo } from "react";
|
||||
import { useLocation } from "react-router-dom";
|
||||
import { QUERY_TIME_TICKETS_IN_RANGE } from "../../graphql/timetickets.queries";
|
||||
import { QUERY_TIME_TICKETS_IN_RANGE_SB } from "../../graphql/timetickets.queries";
|
||||
import AlertComponent from "../alert/alert.component";
|
||||
import LoadingSpinner from "../loading-spinner/loading-spinner.component";
|
||||
import * as Utils from "../scoreboard-targets-table/scoreboard-targets-table.util";
|
||||
@@ -59,7 +59,7 @@ export default function ScoreboardTimeTickets() {
|
||||
};
|
||||
}, []);
|
||||
|
||||
const { loading, error, data } = useQuery(QUERY_TIME_TICKETS_IN_RANGE, {
|
||||
const { loading, error, data } = useQuery(QUERY_TIME_TICKETS_IN_RANGE_SB, {
|
||||
variables: {
|
||||
start: startDate.format("YYYY-MM-DD"),
|
||||
end: endDate.format("YYYY-MM-DD"),
|
||||
@@ -216,7 +216,10 @@ export default function ScoreboardTimeTickets() {
|
||||
|
||||
ret2.push(r);
|
||||
});
|
||||
|
||||
roundObject(ret);
|
||||
roundObject(totals);
|
||||
roundObject(ret2);
|
||||
console.log(ret);
|
||||
return {
|
||||
fixed: ret,
|
||||
timeperiod: {
|
||||
@@ -299,3 +302,18 @@ function getColorArray(num) {
|
||||
// }
|
||||
// return result;
|
||||
}
|
||||
|
||||
function roundObject(inputObj) {
|
||||
for (var key of Object.keys(inputObj)) {
|
||||
if (typeof inputObj[key] === "number" && inputObj[key] !== 0) {
|
||||
inputObj[key] =
|
||||
inputObj[key] && inputObj[key].toFixed
|
||||
? inputObj[key].toFixed(1)
|
||||
: inputObj[key]; //Math.round(inputObj[key] * 100) / 100;
|
||||
} else if (Array.isArray(inputObj[key])) {
|
||||
inputObj[key].forEach((item) => roundObject(item));
|
||||
} else if (typeof inputObj[key] === "object") {
|
||||
roundObject(inputObj[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Card, Col, Row, Space, Statistic, Table } from "antd";
|
||||
import { Card, Col, Row, Statistic, Table, Typography } from "antd";
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { connect } from "react-redux";
|
||||
@@ -19,7 +19,7 @@ export default connect(
|
||||
|
||||
export function ScoreboardTicketsStats({ data, bodyshop }) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
console.log(data);
|
||||
const columns = [
|
||||
{
|
||||
title: t("employees.fields.employee_number"),
|
||||
@@ -68,31 +68,53 @@ export function ScoreboardTicketsStats({ data, bodyshop }) {
|
||||
return (
|
||||
<Card title={t("scoreboard.labels.productivestatistics")}>
|
||||
<Row gutter={[16, 16]}>
|
||||
<Col md={24} lg={6}>
|
||||
<Space wrap>
|
||||
<Statistic
|
||||
title={t("scoreboard.labels.lastweek")}
|
||||
value={data.totalLastWeek.toFixed(1)}
|
||||
/>
|
||||
<Statistic
|
||||
title={t("scoreboard.labels.thisweek")}
|
||||
value={data.totalThisWeek.toFixed(1)}
|
||||
/>
|
||||
<Statistic
|
||||
title={t("scoreboard.labels.lastmonth")}
|
||||
value={data.totalLastMonth.toFixed(1)}
|
||||
/>
|
||||
<Statistic
|
||||
title={t("scoreboard.labels.thismonth")}
|
||||
value={data.totalThisMonth.toFixed(1)}
|
||||
/>
|
||||
</Space>
|
||||
<Col md={24} lg={4}>
|
||||
<Row gutter={[16, 16]}>
|
||||
<Col span={12}>
|
||||
<Statistic
|
||||
title={t("scoreboard.labels.lastweek")}
|
||||
value={data.totalLastWeek}
|
||||
/>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Statistic
|
||||
title={t("scoreboard.labels.lastmonth")}
|
||||
value={data.totalLastMonth}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row gutter={[16, 16]}>
|
||||
<Col span={12}>
|
||||
<Statistic
|
||||
title={t("scoreboard.labels.thisweek")}
|
||||
value={data.totalThisWeek}
|
||||
/>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Statistic
|
||||
title={t("scoreboard.labels.thismonth")}
|
||||
value={data.totalThisMonth}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row gutter={[16, 16]}>
|
||||
<Col span={12}>
|
||||
<Statistic
|
||||
title={t("scoreboard.labels.totaloverperiod")}
|
||||
value={data.totalOverPeriod}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
<Typography.Text type="secondary">
|
||||
{t("scoreboard.labels.calendarperiod")}
|
||||
</Typography.Text>
|
||||
</Col>
|
||||
<Col md={24} lg={18}>
|
||||
<Col md={24} lg={20}>
|
||||
<Table
|
||||
columns={columns}
|
||||
dataSource={tableData}
|
||||
id="employee_number"
|
||||
scroll={{ y: "300px" }}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
@@ -2,9 +2,28 @@ import { Form, Input } from "antd";
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
|
||||
export default function ShopInfoOrderStatusComponent({ form }) {
|
||||
const { t } = useTranslation();
|
||||
import { connect } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||
import { useTreatments } from "@splitsoftware/splitio-react";
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
bodyshop: selectBodyshop,
|
||||
});
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
//setUserLanguage: language => dispatch(setUserLanguage(language))
|
||||
});
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(ShopInfoOrderStatusComponent);
|
||||
|
||||
export function ShopInfoOrderStatusComponent({ bodyshop, form }) {
|
||||
const { t } = useTranslation();
|
||||
const { OEConnection } = useTreatments(
|
||||
["OEConnection"],
|
||||
{},
|
||||
bodyshop.imexshopid
|
||||
);
|
||||
return (
|
||||
<LayoutFormRow header={t("bodyshop.labels.orderstatuses")}>
|
||||
<Form.Item
|
||||
@@ -56,6 +75,20 @@ export default function ShopInfoOrderStatusComponent({ form }) {
|
||||
>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
{OEConnection.treatment === "on" && (
|
||||
<Form.Item
|
||||
label={t("bodyshop.fields.statuses.default_quote")}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
//message: t("general.validation.required"),
|
||||
},
|
||||
]}
|
||||
name={["md_order_statuses", "default_quote"]}
|
||||
>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
)}
|
||||
</LayoutFormRow>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3,9 +3,28 @@ import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
|
||||
import RbacWrapper from "../rbac-wrapper/rbac-wrapper.component";
|
||||
export default function ShopInfoRbacComponent({ form }) {
|
||||
const { t } = useTranslation();
|
||||
import { useTreatments } from "@splitsoftware/splitio-react";
|
||||
import { connect } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
bodyshop: selectBodyshop,
|
||||
});
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
//setUserLanguage: language => dispatch(setUserLanguage(language))
|
||||
});
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(ShopInfoRbacComponent);
|
||||
|
||||
export function ShopInfoRbacComponent({ form, bodyshop }) {
|
||||
const { t } = useTranslation();
|
||||
const { Simple_Inventory } = useTreatments(
|
||||
["Simple_Inventory"],
|
||||
{},
|
||||
bodyshop && bodyshop.imexshopid
|
||||
);
|
||||
return (
|
||||
<RbacWrapper action="shop:rbac">
|
||||
<LayoutFormRow>
|
||||
@@ -633,18 +652,34 @@ export default function ShopInfoRbacComponent({ form }) {
|
||||
>
|
||||
<InputNumber />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label={t("bodyshop.fields.rbac.inventory.list")}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
//message: t("general.validation.required"),
|
||||
},
|
||||
]}
|
||||
name={["md_rbac", "inventory:list"]}
|
||||
>
|
||||
<InputNumber />
|
||||
</Form.Item>
|
||||
{Simple_Inventory.treatment === "on" && (
|
||||
<>
|
||||
<Form.Item
|
||||
label={t("bodyshop.fields.rbac.inventory.list")}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
//message: t("general.validation.required"),
|
||||
},
|
||||
]}
|
||||
name={["md_rbac", "inventory:list"]}
|
||||
>
|
||||
<InputNumber />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label={t("bodyshop.fields.rbac.inventory.delete")}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
//message: t("general.validation.required"),
|
||||
},
|
||||
]}
|
||||
name={["md_rbac", "inventory:delete"]}
|
||||
>
|
||||
<InputNumber />
|
||||
</Form.Item>
|
||||
</>
|
||||
)}
|
||||
</LayoutFormRow>
|
||||
</RbacWrapper>
|
||||
);
|
||||
|
||||
@@ -60,7 +60,10 @@ export function SignInComponent({
|
||||
<Form.Item
|
||||
name="email"
|
||||
rules={[
|
||||
{ required: true, message: t("general.validation.required") },
|
||||
{
|
||||
required: true,
|
||||
message: t("general.validation.required", { label: "Email" }),
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Input
|
||||
@@ -71,7 +74,10 @@ export function SignInComponent({
|
||||
<Form.Item
|
||||
name="password"
|
||||
rules={[
|
||||
{ required: true, message: t("general.validation.required") },
|
||||
{
|
||||
required: true,
|
||||
message: t("general.validation.required", { label: "Password" }),
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Input
|
||||
|
||||
@@ -11,13 +11,21 @@ import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||
import TechClockInComponent from "./tech-job-clock-in-form.component";
|
||||
import TechJobPrintTickets from "../tech-job-print-tickets/tech-job-print-tickets.component";
|
||||
import moment from "moment";
|
||||
import { setModalContext } from "../../redux/modals/modals.actions";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
technician: selectTechnician,
|
||||
bodyshop: selectBodyshop,
|
||||
});
|
||||
|
||||
export function TechClockInContainer({ technician, bodyshop }) {
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
setTimeTicketContext: (context) =>
|
||||
dispatch(setModalContext({ context: context, modal: "timeTicket" })),
|
||||
});
|
||||
export function TechClockInContainer({
|
||||
setTimeTicketContext,
|
||||
technician,
|
||||
bodyshop,
|
||||
}) {
|
||||
const [form] = Form.useForm();
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [insertTimeTicket] = useMutation(INSERT_NEW_TIME_TICKET, {
|
||||
@@ -75,6 +83,16 @@ export function TechClockInContainer({ technician, bodyshop }) {
|
||||
title={t("timetickets.labels.clockintojob")}
|
||||
extra={
|
||||
<Space wrap>
|
||||
<Button
|
||||
onClick={() => {
|
||||
setTimeTicketContext({
|
||||
actions: {},
|
||||
context: { timeticket: { employeeid: technician.id } },
|
||||
});
|
||||
}}
|
||||
>
|
||||
{t("timetickets.actions.enter")}
|
||||
</Button>
|
||||
<TechJobPrintTickets />
|
||||
<Button
|
||||
type="primary"
|
||||
@@ -92,4 +110,7 @@ export function TechClockInContainer({ technician, bodyshop }) {
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
export default connect(mapStateToProps, null)(TechClockInContainer);
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(TechClockInContainer);
|
||||
|
||||
@@ -43,9 +43,9 @@ export function TechLookupJobsDrawer({ bodyshop, setPrintCenterContext }) {
|
||||
xs: "100%",
|
||||
sm: "100%",
|
||||
md: "100%",
|
||||
lg: "70%",
|
||||
xl: "70%",
|
||||
xxl: "70%",
|
||||
lg: "100%",
|
||||
xl: "90%",
|
||||
xxl: "85%",
|
||||
};
|
||||
const drawerPercentage = selectedBreakpoint
|
||||
? bpoints[selectedBreakpoint[0]]
|
||||
|
||||
@@ -35,6 +35,7 @@ export function TimeTicketModalComponent({
|
||||
authLevel,
|
||||
employeeAutoCompleteOptions,
|
||||
isEdit,
|
||||
employeeSelectDisabled,
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
@@ -118,6 +119,7 @@ export function TimeTicketModalComponent({
|
||||
]}
|
||||
>
|
||||
<EmployeeSearchSelect
|
||||
disabled={employeeSelectDisabled}
|
||||
options={employeeAutoCompleteOptions}
|
||||
onSelect={(value) => {
|
||||
const emps =
|
||||
|
||||
@@ -244,6 +244,12 @@ export function TimeTicketModalContainer({
|
||||
employeeAutoCompleteOptions={
|
||||
EmployeeAutoCompleteData && EmployeeAutoCompleteData.employees
|
||||
}
|
||||
employeeSelectDisabled={
|
||||
timeTicketModal.context?.timeticket?.employeeid &&
|
||||
!timeTicketModal.context.id
|
||||
? true
|
||||
: false
|
||||
}
|
||||
/>
|
||||
</Form>
|
||||
</Modal>
|
||||
|
||||
@@ -146,7 +146,8 @@ const JobRelatedTicketsTable = ({
|
||||
title: t("employees.labels.name"),
|
||||
dataIndex: "empname",
|
||||
key: "empname",
|
||||
sorter: (a, b) => alphaSort(a.empname, b.empname),
|
||||
sorter: (a, b) =>
|
||||
alphaSort(a.item.employee.last_name, b.item.employee.last_name),
|
||||
sortOrder:
|
||||
state.sortedInfo.columnKey === "empname" && state.sortedInfo.order,
|
||||
render: (text, record) =>
|
||||
@@ -172,7 +173,9 @@ const JobRelatedTicketsTable = ({
|
||||
title: t("timetickets.fields.efficiency"),
|
||||
dataIndex: "total",
|
||||
key: "total",
|
||||
sorter: (a, b) => a.total - b.total,
|
||||
sorter: (a, b) =>
|
||||
(a.actHrs === 0 || !a.actHrs ? 0 : (a.prodHrs / a.actHrs) * 100) -
|
||||
(b.actHrs === 0 || !b.actHrs ? 0 : (b.prodHrs / b.actHrs) * 100),
|
||||
sortOrder:
|
||||
state.sortedInfo.columnKey === "total" && state.sortedInfo.order,
|
||||
render: (text, record) =>
|
||||
|
||||
@@ -324,6 +324,9 @@ export const QUERY_SCHEDULE_LOAD_DATA = gql`
|
||||
ro_number
|
||||
scheduled_completion
|
||||
actual_completion
|
||||
ownr_fn
|
||||
ownr_ln
|
||||
ownr_co_nm
|
||||
labhrs: joblines_aggregate(
|
||||
where: { mod_lbr_ty: { _neq: "LAR" }, removed: { _eq: false } }
|
||||
) {
|
||||
@@ -352,6 +355,9 @@ export const QUERY_SCHEDULE_LOAD_DATA = gql`
|
||||
id
|
||||
scheduled_in
|
||||
ro_number
|
||||
ownr_fn
|
||||
ownr_ln
|
||||
ownr_co_nm
|
||||
labhrs: joblines_aggregate(
|
||||
where: { mod_lbr_ty: { _neq: "LAR" }, removed: { _eq: false } }
|
||||
) {
|
||||
|
||||
@@ -80,6 +80,7 @@ export const QUERY_ALL_CC = gql`
|
||||
status
|
||||
vin
|
||||
year
|
||||
mileage
|
||||
cccontracts(
|
||||
where: { status: { _eq: "contracts.status.out" } }
|
||||
order_by: { contract_date: desc }
|
||||
|
||||
@@ -42,13 +42,20 @@ export const UPDATE_INVENTORY_LINES = gql`
|
||||
|
||||
export const QUERY_OUTSTANDING_INVENTORY = gql`
|
||||
query QUERY_OUTSTANDING_INVENTORY {
|
||||
inventory(where: { consumedbybillid: { _is_null: true } }) {
|
||||
inventory(
|
||||
where: { consumedbybillid: { _is_null: true } }
|
||||
order_by: { line_desc: asc }
|
||||
) {
|
||||
id
|
||||
actual_cost
|
||||
actual_price
|
||||
quantity
|
||||
billlineid
|
||||
line_desc
|
||||
comment
|
||||
manualinvoicenumber
|
||||
manualvendor
|
||||
consumedbybillid
|
||||
billline {
|
||||
bill {
|
||||
invoice_number
|
||||
@@ -80,6 +87,10 @@ export const QUERY_INVENTORY_PAGINATED = gql`
|
||||
line_desc
|
||||
actual_price
|
||||
actual_cost
|
||||
comment
|
||||
manualinvoicenumber
|
||||
manualvendor
|
||||
consumedbybillid
|
||||
bill {
|
||||
id
|
||||
invoice_number
|
||||
@@ -93,6 +104,12 @@ export const QUERY_INVENTORY_PAGINATED = gql`
|
||||
bill {
|
||||
id
|
||||
invoice_number
|
||||
job {
|
||||
id
|
||||
v_make_desc
|
||||
v_model_desc
|
||||
v_model_yr
|
||||
}
|
||||
vendor {
|
||||
id
|
||||
name
|
||||
@@ -110,3 +127,55 @@ export const QUERY_INVENTORY_PAGINATED = gql`
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const DELETE_INVENTORY_LINE = gql`
|
||||
mutation DELETE_INVENTORY_LINE($lineId: uuid!) {
|
||||
delete_inventory_by_pk(id: $lineId) {
|
||||
id
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const INSERT_INVENTORY_LINE = gql`
|
||||
mutation INSERT_INVENTORY_LINE($inventoryItem: inventory_insert_input!) {
|
||||
insert_inventory_one(object: $inventoryItem) {
|
||||
id
|
||||
line_desc
|
||||
consumedbybillid
|
||||
billlineid
|
||||
actual_price
|
||||
actual_cost
|
||||
comment
|
||||
manualinvoicenumber
|
||||
manualvendor
|
||||
bill {
|
||||
invoice_number
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const UPDATE_INVENTORY_LINE = gql`
|
||||
mutation UPDATE_INVENTORY_LINE(
|
||||
$inventoryId: uuid!
|
||||
$inventoryItem: inventory_set_input!
|
||||
) {
|
||||
update_inventory_by_pk(
|
||||
pk_columns: { id: $inventoryId }
|
||||
_set: $inventoryItem
|
||||
) {
|
||||
id
|
||||
line_desc
|
||||
consumedbybillid
|
||||
billlineid
|
||||
actual_price
|
||||
actual_cost
|
||||
comment
|
||||
manualinvoicenumber
|
||||
manualvendor
|
||||
bill {
|
||||
invoice_number
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -177,6 +177,7 @@ export const UPDATE_JOB_LINE = gql`
|
||||
location
|
||||
status
|
||||
removed
|
||||
convertedtolbr
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,6 +85,7 @@ export const QUERY_PARTS_QUEUE = gql`
|
||||
vehicleid
|
||||
ownerid
|
||||
queued_for_parts
|
||||
comment
|
||||
joblines_status {
|
||||
count
|
||||
part_type
|
||||
@@ -701,6 +702,7 @@ export const GET_JOB_BY_PK = gql`
|
||||
prt_dsmk_p
|
||||
prt_dsmk_m
|
||||
ioucreated
|
||||
convertedtolbr
|
||||
billlines(limit: 1, order_by: { bill: { date: desc } }) {
|
||||
id
|
||||
quantity
|
||||
@@ -1828,6 +1830,7 @@ export const QUERY_JOB_CLOSE_DETAILS = gql`
|
||||
ins_co_id
|
||||
dms_allocation
|
||||
id
|
||||
inproduction
|
||||
ded_amt
|
||||
ded_status
|
||||
depreciation_taxes
|
||||
@@ -1903,6 +1906,7 @@ export const QUERY_JOB_CLOSE_DETAILS = gql`
|
||||
profitcenter_labor
|
||||
profitcenter_part
|
||||
prt_dsmk_p
|
||||
convertedtolbr
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,41 @@ export const QUERY_TICKETS_BY_JOBID = gql`
|
||||
`;
|
||||
|
||||
export const QUERY_TIME_TICKETS_IN_RANGE = gql`
|
||||
query QUERY_TIME_TICKETS_IN_RANGE(
|
||||
query QUERY_TIME_TICKETS_IN_RANGE($start: date!, $end: date!) {
|
||||
timetickets(
|
||||
where: { date: { _gte: $start, _lte: $end } }
|
||||
order_by: { date: desc_nulls_first }
|
||||
) {
|
||||
actualhrs
|
||||
ciecacode
|
||||
clockoff
|
||||
clockon
|
||||
cost_center
|
||||
created_at
|
||||
date
|
||||
id
|
||||
rate
|
||||
productivehrs
|
||||
memo
|
||||
jobid
|
||||
flat_rate
|
||||
job {
|
||||
id
|
||||
ro_number
|
||||
}
|
||||
employeeid
|
||||
employee {
|
||||
id
|
||||
employee_number
|
||||
first_name
|
||||
last_name
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const QUERY_TIME_TICKETS_IN_RANGE_SB = gql`
|
||||
query QUERY_TIME_TICKETS_IN_RANGE_SB(
|
||||
$start: date!
|
||||
$end: date!
|
||||
$fixedStart: date!
|
||||
|
||||
@@ -48,6 +48,7 @@ export const socket = SocketIO(
|
||||
: window.location.origin,
|
||||
{
|
||||
path: "/ws",
|
||||
withCredentials: true,
|
||||
auth: async (callback) => {
|
||||
const token = auth.currentUser && (await auth.currentUser.getIdToken());
|
||||
callback({ token });
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
setSelectedHeader,
|
||||
} from "../../redux/application/application.actions";
|
||||
import InventoryList from "../../components/inventory-list/inventory-list.container";
|
||||
import InventoryUpsertModalContainer from "../../components/inventory-upsert-modal/inventory-upsert-modal.container";
|
||||
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
setBreadcrumbs: (breadcrumbs) => dispatch(setBreadcrumbs(breadcrumbs)),
|
||||
@@ -24,6 +25,7 @@ export function InventoryPage({ setBreadcrumbs, setSelectedHeader }) {
|
||||
|
||||
return (
|
||||
<RbacWrapper action="inventory:list">
|
||||
<InventoryUpsertModalContainer />
|
||||
<InventoryList />
|
||||
</RbacWrapper>
|
||||
);
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
PageHeader,
|
||||
InputNumber,
|
||||
Input,
|
||||
Switch,
|
||||
} from "antd";
|
||||
import React, { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
@@ -42,7 +43,7 @@ export function JobsCloseComponent({ job, bodyshop, jobRO }) {
|
||||
const [closeJob] = useMutation(UPDATE_JOB);
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
const handleFinish = async (values) => {
|
||||
const handleFinish = async ({ removefromproduction, ...values }) => {
|
||||
setLoading(true);
|
||||
const result = await client.mutate({
|
||||
mutation: generateJobLinesUpdatesForInvoicing(values.joblines),
|
||||
@@ -63,6 +64,7 @@ export function JobsCloseComponent({ job, bodyshop, jobRO }) {
|
||||
kmin: values.kmin,
|
||||
kmout: values.kmout,
|
||||
dms_allocation: values.dms_allocation,
|
||||
...(removefromproduction ? { inproduction: false } : {}),
|
||||
},
|
||||
},
|
||||
refetchQueries: ["QUERY_JOB_CLOSE_DETAILS"],
|
||||
@@ -248,6 +250,15 @@ export function JobsCloseComponent({ job, bodyshop, jobRO }) {
|
||||
onlyFuture={!!bodyshop.cdk_dealerid}
|
||||
/>
|
||||
</Form.Item>
|
||||
{!jobRO && job.inproduction && (
|
||||
<Form.Item
|
||||
label={t("jobs.actions.removefromproduction")}
|
||||
name="removefromproduction"
|
||||
valuePropName="checked"
|
||||
>
|
||||
<Switch />
|
||||
</Form.Item>
|
||||
)}
|
||||
{(bodyshop.cdk_dealerid || bodyshop.pbs_serialnumber) && (
|
||||
<Form.Item
|
||||
label={t("jobs.fields.kmin")}
|
||||
|
||||
@@ -24,6 +24,8 @@ import {
|
||||
selectBodyshop,
|
||||
selectInstanceConflict,
|
||||
} from "../../redux/user/user.selectors";
|
||||
import * as Sentry from "@sentry/react";
|
||||
|
||||
import "./manage.page.styles.scss";
|
||||
|
||||
const ManageRootPage = lazy(() =>
|
||||
@@ -407,7 +409,10 @@ export function Manage({ match, conflict, bodyshop }) {
|
||||
|
||||
<Content className="content-container">
|
||||
<PartnerPingComponent />
|
||||
<ErrorBoundary>{PageContent}</ErrorBoundary>
|
||||
<Sentry.ErrorBoundary fallback={<ErrorBoundary />} showDialog>
|
||||
{PageContent}
|
||||
</Sentry.ErrorBoundary>
|
||||
|
||||
<BackTop />
|
||||
<Footer>
|
||||
<div
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { SyncOutlined } from "@ant-design/icons";
|
||||
import { useQuery } from "@apollo/client";
|
||||
import { Button, Card, Input, Space, Table } from "antd";
|
||||
import _ from "lodash";
|
||||
import queryString from "query-string";
|
||||
import React, { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
@@ -12,11 +11,13 @@ import AlertComponent from "../../components/alert/alert.component";
|
||||
import JobPartsQueueCount from "../../components/job-parts-queue-count/job-parts-queue-count.component";
|
||||
import JobRemoveFromPartsQueue from "../../components/job-remove-from-parst-queue/job-remove-from-parts-queue.component";
|
||||
import OwnerNameDisplay from "../../components/owner-name-display/owner-name-display.component";
|
||||
import ProductionListColumnComment from "../../components/production-list-columns/production-list-columns.comment.component";
|
||||
import { QUERY_PARTS_QUEUE } from "../../graphql/jobs.queries";
|
||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||
import { onlyUnique } from "../../utils/arrayHelper";
|
||||
import { DateTimeFormatter, TimeAgoFormatter } from "../../utils/DateFormatter";
|
||||
import { alphaSort, dateSort } from "../../utils/sorters";
|
||||
import useLocalStorage from "../../utils/useLocalStorage";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
bodyshop: selectBodyshop,
|
||||
@@ -31,6 +32,7 @@ export function PartsQueuePageComponent({ bodyshop }) {
|
||||
statusFilters,
|
||||
} = searchParams;
|
||||
const history = useHistory();
|
||||
const [filter, setFilter] = useLocalStorage("filter_parts_queue", null);
|
||||
|
||||
const { loading, error, data, refetch } = useQuery(QUERY_PARTS_QUEUE, {
|
||||
fetchPolicy: "network-only",
|
||||
@@ -92,13 +94,7 @@ export function PartsQueuePageComponent({ bodyshop }) {
|
||||
// searchParams.page = pagination.current;
|
||||
searchParams.sortcolumn = sorter.columnKey;
|
||||
searchParams.sortorder = sorter.order;
|
||||
if (filters.status) {
|
||||
searchParams.statusFilters = JSON.stringify(
|
||||
_.flattenDeep(filters.status)
|
||||
);
|
||||
} else {
|
||||
delete searchParams.statusFilters;
|
||||
}
|
||||
setFilter(filters);
|
||||
history.push({ search: queryString.stringify(searchParams) });
|
||||
};
|
||||
|
||||
@@ -235,15 +231,36 @@ export function PartsQueuePageComponent({ bodyshop }) {
|
||||
dataIndex: "partsstatus",
|
||||
key: "partsstatus",
|
||||
render: (text, record) => (
|
||||
<JobPartsQueueCount parts={record.joblines_status} />
|
||||
<JobPartsQueueCount
|
||||
style={{ minWidth: "10rem" }}
|
||||
parts={record.joblines_status}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: t("jobs.fields.comment"),
|
||||
dataIndex: "comment",
|
||||
key: "comment",
|
||||
render: (text, record) => <ProductionListColumnComment record={record} />,
|
||||
},
|
||||
{
|
||||
title: t("jobs.fields.queued_for_parts"),
|
||||
dataIndex: "queued_for_parts",
|
||||
key: "queued_for_parts",
|
||||
sorter: (a, b) => a.queued_for_parts - b.queued_for_parts,
|
||||
sortOrder: sortcolumn === "queued_for_parts" && sortorder,
|
||||
filteredValue: filter?.queued_for_parts || null,
|
||||
filters: [
|
||||
{
|
||||
text: "Queued",
|
||||
value: true,
|
||||
},
|
||||
{
|
||||
text: "Unqueued",
|
||||
value: false,
|
||||
},
|
||||
],
|
||||
onFilter: (value, record) => record.queued_for_parts === value,
|
||||
render: (text, record) => (
|
||||
<JobRemoveFromPartsQueue
|
||||
checked={record.queued_for_parts}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import Icon, { BarsOutlined } from "@ant-design/icons";
|
||||
import Icon, { FieldTimeOutlined } from "@ant-design/icons";
|
||||
import { Tabs } from "antd";
|
||||
import React, { useEffect } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
@@ -70,7 +70,7 @@ export function ScoreboardContainer({ setBreadcrumbs, setSelectedHeader }) {
|
||||
<Tabs.TabPane
|
||||
tab={
|
||||
<span>
|
||||
<BarsOutlined />
|
||||
<FieldTimeOutlined />
|
||||
{t("scoreboard.labels.timetickets")}
|
||||
</span>
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ export const getJobMedia = (jobid) => ({
|
||||
});
|
||||
|
||||
export const getBillMedia = ({ jobid, invoice_number }) => {
|
||||
console.log("in the action");
|
||||
return {
|
||||
type: MediaActionTypes.GET_MEDIA_FOR_BILL,
|
||||
payload: { jobid, invoice_number },
|
||||
|
||||
@@ -23,6 +23,7 @@ const INITIAL_STATE = {
|
||||
reportCenter: { ...baseModal },
|
||||
partsReceive: { ...baseModal },
|
||||
contractFinder: { ...baseModal },
|
||||
inventoryUpsert: { ...baseModal },
|
||||
ca_bc_eftTableConvert: { ...baseModal },
|
||||
};
|
||||
|
||||
|
||||
@@ -70,6 +70,10 @@ export const selectContractFinder = createSelector(
|
||||
[selectModals],
|
||||
(modals) => modals.contractFinder
|
||||
);
|
||||
export const selectInventoryUpsert = createSelector(
|
||||
[selectModals],
|
||||
(modals) => modals.inventoryUpsert
|
||||
);
|
||||
|
||||
export const selectCaBcEtfTableConvert = createSelector(
|
||||
[selectModals],
|
||||
|
||||
@@ -103,7 +103,7 @@
|
||||
"jobimported": "Job imported.",
|
||||
"jobinproductionchange": "Job production status set to {{inproduction}}",
|
||||
"jobioucreated": "IOU Created.",
|
||||
"jobmodifylbradj": "Labor adjustments modified.",
|
||||
"jobmodifylbradj": "Labor adjustments modified {{mod_lbr_ty}} / {{hours}}.",
|
||||
"jobnoteadded": "Note added to job.",
|
||||
"jobnotedeleted": "Note deleted from job.",
|
||||
"jobnoteupdated": "Note updated on job.",
|
||||
@@ -136,6 +136,9 @@
|
||||
"other": "-- Not On Estimate --",
|
||||
"reconciled": "Reconciled!",
|
||||
"unreconciled": "Unreconciled"
|
||||
},
|
||||
"validation": {
|
||||
"atleastone": "At least one bill line must be entered."
|
||||
}
|
||||
},
|
||||
"bills": {
|
||||
@@ -147,6 +150,7 @@
|
||||
"errors": {
|
||||
"creating": "Error adding bill. {{error}}",
|
||||
"deleting": "Error deleting bill. {{error}}",
|
||||
"existinginventoryline": "This bill cannot be deleted as it is tied to items in inventory.",
|
||||
"exporting": "Error exporting payable(s). {{error}}",
|
||||
"exporting-partner": "Unable to connect to ImEX Partner. Please ensure it is running and logged in.",
|
||||
"invalidro": "Not a valid RO.",
|
||||
@@ -207,6 +211,7 @@
|
||||
"reexport": "Bill marked for re-export."
|
||||
},
|
||||
"validation": {
|
||||
"inventoryquantity": "Quantity must be greater than or equal to what has been added to inventory ({{number}}).",
|
||||
"manualinhouse": "Manual posting to the in house vendor is restricted. ",
|
||||
"unique_invoice_number": "This invoice number has already been entered for this vendor."
|
||||
}
|
||||
@@ -352,6 +357,10 @@
|
||||
"employees": {
|
||||
"page": "Employees -> List"
|
||||
},
|
||||
"inventory": {
|
||||
"delete": "Inventory -> Delete",
|
||||
"list": "Inventory -> List"
|
||||
},
|
||||
"jobs": {
|
||||
"admin": "Jobs -> Admin",
|
||||
"available-list": "Jobs -> Available List",
|
||||
@@ -496,6 +505,7 @@
|
||||
"default_imported": "Default Imported Status",
|
||||
"default_invoiced": "Default Invoiced Status",
|
||||
"default_ordered": "Default Ordered Status",
|
||||
"default_quote": "Default Quote Status",
|
||||
"default_received": "Default Received Status",
|
||||
"default_returned": "Default Returned",
|
||||
"default_scheduled": "Default Scheduled Status",
|
||||
@@ -955,7 +965,8 @@
|
||||
},
|
||||
"errors": {
|
||||
"fcm": "You must allow notification permissions to have real time messaging. Click to try again.",
|
||||
"notfound": "No record was found."
|
||||
"notfound": "No record was found.",
|
||||
"sizelimit": "The selected items exceed the size limit."
|
||||
},
|
||||
"itemtypes": {
|
||||
"contract": "CC Contract",
|
||||
@@ -988,6 +999,7 @@
|
||||
"loadingapp": "Loading $t(titles.app)",
|
||||
"loadingshop": "Loading shop data...",
|
||||
"loggingin": "Authorizing...",
|
||||
"markedexported": "Manually marked as exported.",
|
||||
"message": "Message",
|
||||
"monday": "Monday",
|
||||
"na": "N/A",
|
||||
@@ -1072,13 +1084,22 @@
|
||||
"inventory": {
|
||||
"actions": {
|
||||
"addtoinventory": "Add to Inventory",
|
||||
"consumefrominventory": "Consume from Inventory?"
|
||||
"addtoro": "Add to RO",
|
||||
"consumefrominventory": "Consume from Inventory?",
|
||||
"edit": "Edit Inventory LIne",
|
||||
"new": "New Inventory Line"
|
||||
},
|
||||
"errors": {
|
||||
"inserting": "Error inserting inventory item. {{error}}"
|
||||
},
|
||||
"fields": {
|
||||
"comment": "Comment",
|
||||
"manualinvoicenumber": "Invoice Number",
|
||||
"manualvendor": "Vendor"
|
||||
},
|
||||
"labels": {
|
||||
"consumedbyjob": "Consumed by Job",
|
||||
"deleteconfirm": "Are you sure you want to delete this from inventory? The associated bill will not be modified or deleted. ",
|
||||
"frombillinvoicenumber": "Original Bill Invoice Number",
|
||||
"fromvendor": "Original Bill Vendor",
|
||||
"inventory": "Inventory",
|
||||
@@ -1086,11 +1107,14 @@
|
||||
"showavailable": "Show Only Available Inventory"
|
||||
},
|
||||
"successes": {
|
||||
"inserted": "Added line to inventory."
|
||||
"deleted": "Inventory lined deleted.",
|
||||
"inserted": "Added line to inventory.",
|
||||
"updated": "Inventory line updated."
|
||||
}
|
||||
},
|
||||
"joblines": {
|
||||
"actions": {
|
||||
"converttolabor": "Convert amount to Labor.",
|
||||
"new": "New Line"
|
||||
},
|
||||
"errors": {
|
||||
@@ -1156,7 +1180,9 @@
|
||||
"unq_seq": "Seq #"
|
||||
},
|
||||
"labels": {
|
||||
"adjustmenttobeadded": "Adjustment to be added: {{adjustment}}",
|
||||
"billref": "Latest Bill",
|
||||
"convertedtolabor": "This line has been converted to labor. Ensure you adjust the profit center for the amount accordingly.",
|
||||
"edit": "Edit Line",
|
||||
"ioucreated": "IOU",
|
||||
"new": "New Line",
|
||||
@@ -1994,6 +2020,7 @@
|
||||
"confirmdelete": "Are you sure you want to delete this item? It cannot be recovered. Job line statuses will not be updated and may require manual review. ",
|
||||
"email": "Send by Email",
|
||||
"inthisorder": "Parts in this Order",
|
||||
"is_quote": "Parts Quote?",
|
||||
"mark_as_received": "Mark as Received?",
|
||||
"newpartsorder": "New Parts Order",
|
||||
"notyetordered": "This part has not yet been ordered.",
|
||||
@@ -2361,6 +2388,7 @@
|
||||
"job_costing_ro_date_summary": "Job Costing by RO - Summary",
|
||||
"job_costing_ro_estimator": "Job Costing by Estimator",
|
||||
"job_costing_ro_ins_co": "Job Costing by RO Source",
|
||||
"jobs_reconcile": "Parts/Sublet/Labor Reconciliation",
|
||||
"lag_time": "Lag Time",
|
||||
"open_orders": "Open Orders by Date",
|
||||
"open_orders_csr": "Open Orders by CSR",
|
||||
@@ -2424,6 +2452,7 @@
|
||||
},
|
||||
"labels": {
|
||||
"asoftodaytarget": "As of Today",
|
||||
"calendarperiod": "Periods based on calendar weeks/months.",
|
||||
"dailyactual": "Actual (D)",
|
||||
"dailytarget": "Daily",
|
||||
"jobs": "Jobs",
|
||||
@@ -2437,7 +2466,7 @@
|
||||
"thisweek": "This Week",
|
||||
"timetickets": "Timetickets",
|
||||
"todateactual": "Actual (MTD)",
|
||||
"totaloverperiod": "Total Period",
|
||||
"totaloverperiod": "Total over Selected Dates",
|
||||
"weeklyactual": "Actual (W)",
|
||||
"weeklytarget": "Weekly",
|
||||
"workingdays": "Working Days / Month"
|
||||
@@ -2448,11 +2477,6 @@
|
||||
"updated": "Scoreboard updated."
|
||||
}
|
||||
},
|
||||
"scoredboard": {
|
||||
"successes": {
|
||||
"updated": "Scoreboard entry updated."
|
||||
}
|
||||
},
|
||||
"tech": {
|
||||
"fields": {
|
||||
"employeeid": "Employee ID",
|
||||
@@ -2654,6 +2678,7 @@
|
||||
"users": {
|
||||
"errors": {
|
||||
"signinerror": {
|
||||
"auth/user-disabled": "User account disabled. ",
|
||||
"auth/user-not-found": "A user with this email does not exist.",
|
||||
"auth/wrong-password": "The email and password combination you provided is incorrect."
|
||||
}
|
||||
|
||||
@@ -136,6 +136,9 @@
|
||||
"other": "",
|
||||
"reconciled": "",
|
||||
"unreconciled": ""
|
||||
},
|
||||
"validation": {
|
||||
"atleastone": ""
|
||||
}
|
||||
},
|
||||
"bills": {
|
||||
@@ -147,6 +150,7 @@
|
||||
"errors": {
|
||||
"creating": "",
|
||||
"deleting": "",
|
||||
"existinginventoryline": "",
|
||||
"exporting": "",
|
||||
"exporting-partner": "",
|
||||
"invalidro": "",
|
||||
@@ -207,6 +211,7 @@
|
||||
"reexport": ""
|
||||
},
|
||||
"validation": {
|
||||
"inventoryquantity": "",
|
||||
"manualinhouse": "",
|
||||
"unique_invoice_number": ""
|
||||
}
|
||||
@@ -352,6 +357,10 @@
|
||||
"employees": {
|
||||
"page": ""
|
||||
},
|
||||
"inventory": {
|
||||
"delete": "",
|
||||
"list": ""
|
||||
},
|
||||
"jobs": {
|
||||
"admin": "",
|
||||
"available-list": "",
|
||||
@@ -496,6 +505,7 @@
|
||||
"default_imported": "",
|
||||
"default_invoiced": "",
|
||||
"default_ordered": "",
|
||||
"default_quote": "",
|
||||
"default_received": "",
|
||||
"default_returned": "",
|
||||
"default_scheduled": "",
|
||||
@@ -955,7 +965,8 @@
|
||||
},
|
||||
"errors": {
|
||||
"fcm": "",
|
||||
"notfound": ""
|
||||
"notfound": "",
|
||||
"sizelimit": ""
|
||||
},
|
||||
"itemtypes": {
|
||||
"contract": "",
|
||||
@@ -988,6 +999,7 @@
|
||||
"loadingapp": "Cargando $t(titles.app)",
|
||||
"loadingshop": "Cargando datos de la tienda ...",
|
||||
"loggingin": "Iniciando sesión ...",
|
||||
"markedexported": "",
|
||||
"message": "",
|
||||
"monday": "",
|
||||
"na": "N / A",
|
||||
@@ -1072,13 +1084,22 @@
|
||||
"inventory": {
|
||||
"actions": {
|
||||
"addtoinventory": "",
|
||||
"consumefrominventory": ""
|
||||
"addtoro": "",
|
||||
"consumefrominventory": "",
|
||||
"edit": "",
|
||||
"new": ""
|
||||
},
|
||||
"errors": {
|
||||
"inserting": ""
|
||||
},
|
||||
"fields": {
|
||||
"comment": "",
|
||||
"manualinvoicenumber": "",
|
||||
"manualvendor": ""
|
||||
},
|
||||
"labels": {
|
||||
"consumedbyjob": "",
|
||||
"deleteconfirm": "",
|
||||
"frombillinvoicenumber": "",
|
||||
"fromvendor": "",
|
||||
"inventory": "",
|
||||
@@ -1086,11 +1107,14 @@
|
||||
"showavailable": ""
|
||||
},
|
||||
"successes": {
|
||||
"inserted": ""
|
||||
"deleted": "",
|
||||
"inserted": "",
|
||||
"updated": ""
|
||||
}
|
||||
},
|
||||
"joblines": {
|
||||
"actions": {
|
||||
"converttolabor": "",
|
||||
"new": ""
|
||||
},
|
||||
"errors": {
|
||||
@@ -1156,7 +1180,9 @@
|
||||
"unq_seq": "Seq #"
|
||||
},
|
||||
"labels": {
|
||||
"adjustmenttobeadded": "",
|
||||
"billref": "",
|
||||
"convertedtolabor": "",
|
||||
"edit": "Línea de edición",
|
||||
"ioucreated": "",
|
||||
"new": "Nueva línea",
|
||||
@@ -1994,6 +2020,7 @@
|
||||
"confirmdelete": "",
|
||||
"email": "Enviar por correo electrónico",
|
||||
"inthisorder": "Partes en este pedido",
|
||||
"is_quote": "",
|
||||
"mark_as_received": "",
|
||||
"newpartsorder": "",
|
||||
"notyetordered": "",
|
||||
@@ -2361,6 +2388,7 @@
|
||||
"job_costing_ro_date_summary": "",
|
||||
"job_costing_ro_estimator": "",
|
||||
"job_costing_ro_ins_co": "",
|
||||
"jobs_reconcile": "",
|
||||
"lag_time": "",
|
||||
"open_orders": "",
|
||||
"open_orders_csr": "",
|
||||
@@ -2424,6 +2452,7 @@
|
||||
},
|
||||
"labels": {
|
||||
"asoftodaytarget": "",
|
||||
"calendarperiod": "",
|
||||
"dailyactual": "",
|
||||
"dailytarget": "",
|
||||
"jobs": "",
|
||||
@@ -2448,11 +2477,6 @@
|
||||
"updated": ""
|
||||
}
|
||||
},
|
||||
"scoredboard": {
|
||||
"successes": {
|
||||
"updated": ""
|
||||
}
|
||||
},
|
||||
"tech": {
|
||||
"fields": {
|
||||
"employeeid": "",
|
||||
@@ -2654,6 +2678,7 @@
|
||||
"users": {
|
||||
"errors": {
|
||||
"signinerror": {
|
||||
"auth/user-disabled": "",
|
||||
"auth/user-not-found": "",
|
||||
"auth/wrong-password": ""
|
||||
}
|
||||
|
||||
@@ -136,6 +136,9 @@
|
||||
"other": "",
|
||||
"reconciled": "",
|
||||
"unreconciled": ""
|
||||
},
|
||||
"validation": {
|
||||
"atleastone": ""
|
||||
}
|
||||
},
|
||||
"bills": {
|
||||
@@ -147,6 +150,7 @@
|
||||
"errors": {
|
||||
"creating": "",
|
||||
"deleting": "",
|
||||
"existinginventoryline": "",
|
||||
"exporting": "",
|
||||
"exporting-partner": "",
|
||||
"invalidro": "",
|
||||
@@ -207,6 +211,7 @@
|
||||
"reexport": ""
|
||||
},
|
||||
"validation": {
|
||||
"inventoryquantity": "",
|
||||
"manualinhouse": "",
|
||||
"unique_invoice_number": ""
|
||||
}
|
||||
@@ -352,6 +357,10 @@
|
||||
"employees": {
|
||||
"page": ""
|
||||
},
|
||||
"inventory": {
|
||||
"delete": "",
|
||||
"list": ""
|
||||
},
|
||||
"jobs": {
|
||||
"admin": "",
|
||||
"available-list": "",
|
||||
@@ -496,6 +505,7 @@
|
||||
"default_imported": "",
|
||||
"default_invoiced": "",
|
||||
"default_ordered": "",
|
||||
"default_quote": "",
|
||||
"default_received": "",
|
||||
"default_returned": "",
|
||||
"default_scheduled": "",
|
||||
@@ -955,7 +965,8 @@
|
||||
},
|
||||
"errors": {
|
||||
"fcm": "",
|
||||
"notfound": ""
|
||||
"notfound": "",
|
||||
"sizelimit": ""
|
||||
},
|
||||
"itemtypes": {
|
||||
"contract": "",
|
||||
@@ -988,6 +999,7 @@
|
||||
"loadingapp": "Chargement de $t(titles.app)",
|
||||
"loadingshop": "Chargement des données de la boutique ...",
|
||||
"loggingin": "Vous connecter ...",
|
||||
"markedexported": "",
|
||||
"message": "",
|
||||
"monday": "",
|
||||
"na": "N / A",
|
||||
@@ -1072,13 +1084,22 @@
|
||||
"inventory": {
|
||||
"actions": {
|
||||
"addtoinventory": "",
|
||||
"consumefrominventory": ""
|
||||
"addtoro": "",
|
||||
"consumefrominventory": "",
|
||||
"edit": "",
|
||||
"new": ""
|
||||
},
|
||||
"errors": {
|
||||
"inserting": ""
|
||||
},
|
||||
"fields": {
|
||||
"comment": "",
|
||||
"manualinvoicenumber": "",
|
||||
"manualvendor": ""
|
||||
},
|
||||
"labels": {
|
||||
"consumedbyjob": "",
|
||||
"deleteconfirm": "",
|
||||
"frombillinvoicenumber": "",
|
||||
"fromvendor": "",
|
||||
"inventory": "",
|
||||
@@ -1086,11 +1107,14 @@
|
||||
"showavailable": ""
|
||||
},
|
||||
"successes": {
|
||||
"inserted": ""
|
||||
"deleted": "",
|
||||
"inserted": "",
|
||||
"updated": ""
|
||||
}
|
||||
},
|
||||
"joblines": {
|
||||
"actions": {
|
||||
"converttolabor": "",
|
||||
"new": ""
|
||||
},
|
||||
"errors": {
|
||||
@@ -1156,7 +1180,9 @@
|
||||
"unq_seq": "Seq #"
|
||||
},
|
||||
"labels": {
|
||||
"adjustmenttobeadded": "",
|
||||
"billref": "",
|
||||
"convertedtolabor": "",
|
||||
"edit": "Ligne d'édition",
|
||||
"ioucreated": "",
|
||||
"new": "Nouvelle ligne",
|
||||
@@ -1994,6 +2020,7 @@
|
||||
"confirmdelete": "",
|
||||
"email": "Envoyé par email",
|
||||
"inthisorder": "Pièces dans cette commande",
|
||||
"is_quote": "",
|
||||
"mark_as_received": "",
|
||||
"newpartsorder": "",
|
||||
"notyetordered": "",
|
||||
@@ -2361,6 +2388,7 @@
|
||||
"job_costing_ro_date_summary": "",
|
||||
"job_costing_ro_estimator": "",
|
||||
"job_costing_ro_ins_co": "",
|
||||
"jobs_reconcile": "",
|
||||
"lag_time": "",
|
||||
"open_orders": "",
|
||||
"open_orders_csr": "",
|
||||
@@ -2424,6 +2452,7 @@
|
||||
},
|
||||
"labels": {
|
||||
"asoftodaytarget": "",
|
||||
"calendarperiod": "",
|
||||
"dailyactual": "",
|
||||
"dailytarget": "",
|
||||
"jobs": "",
|
||||
@@ -2448,11 +2477,6 @@
|
||||
"updated": ""
|
||||
}
|
||||
},
|
||||
"scoredboard": {
|
||||
"successes": {
|
||||
"updated": ""
|
||||
}
|
||||
},
|
||||
"tech": {
|
||||
"fields": {
|
||||
"employeeid": "",
|
||||
@@ -2654,6 +2678,7 @@
|
||||
"users": {
|
||||
"errors": {
|
||||
"signinerror": {
|
||||
"auth/user-disabled": "",
|
||||
"auth/user-not-found": "",
|
||||
"auth/wrong-password": ""
|
||||
}
|
||||
|
||||
@@ -18,7 +18,8 @@ const AuditTrailMapping = {
|
||||
i18n.t("audit_trail.messages.jobspartsorder", { order_number }),
|
||||
jobspartsreturn: (order_number) =>
|
||||
i18n.t("audit_trail.messages.jobspartsreturn", { order_number }),
|
||||
jobmodifylbradj: () => i18n.t("audit_trail.messages.jobmodifylbradj", {}),
|
||||
jobmodifylbradj: ({ mod_lbr_ty, hours }) =>
|
||||
i18n.t("audit_trail.messages.jobmodifylbradj", { mod_lbr_ty, hours }),
|
||||
billposted: (invoice_number) =>
|
||||
i18n.t("audit_trail.messages.billposted", { invoice_number }),
|
||||
billupdated: (invoice_number) =>
|
||||
|
||||
@@ -17,6 +17,11 @@ export function DateTimeFormatter(props) {
|
||||
)
|
||||
: null;
|
||||
}
|
||||
export function TimeFormatter(props) {
|
||||
return props.children
|
||||
? moment(props.children).format(props.format ? props.format : "hh:mm a")
|
||||
: null;
|
||||
}
|
||||
|
||||
export function TimeAgoFormatter(props) {
|
||||
const m = moment(props.children);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { gql } from "@apollo/client";
|
||||
import { notification } from "antd";
|
||||
import axios from "axios";
|
||||
import jsreport from "jsreport-browser-client-dist";
|
||||
import jsreport from "@jsreport/browser-client";
|
||||
import _ from "lodash";
|
||||
import moment from "moment";
|
||||
import { auth } from "../firebase/firebase.utils";
|
||||
@@ -9,7 +9,9 @@ import { setEmailOptions } from "../redux/email/email.actions";
|
||||
import { store } from "../redux/store";
|
||||
import client from "../utils/GraphQLClient";
|
||||
import { TemplateList } from "./TemplateConstants";
|
||||
|
||||
const server = process.env.REACT_APP_REPORTS_SERVER_URL;
|
||||
|
||||
jsreport.serverUrl = server;
|
||||
|
||||
const Templates = TemplateList();
|
||||
@@ -21,6 +23,10 @@ export default async function RenderTemplate(
|
||||
renderAsExcel = false,
|
||||
renderAsText = false
|
||||
) {
|
||||
if (window.jsr3) {
|
||||
jsreport.serverUrl = "https://reports3.test.imex.online/";
|
||||
}
|
||||
|
||||
//Query assets that match the template name. Must be in format <<templateName>>.query
|
||||
let { contextData, useShopSpecificTemplate } = await fetchContextData(
|
||||
templateObject
|
||||
@@ -69,7 +75,7 @@ export default async function RenderTemplate(
|
||||
};
|
||||
|
||||
try {
|
||||
const render = await jsreport.renderAsync(reportRequest);
|
||||
const render = await jsreport.render(reportRequest);
|
||||
|
||||
if (!renderAsHtml) {
|
||||
render.download(
|
||||
@@ -80,18 +86,41 @@ export default async function RenderTemplate(
|
||||
} else {
|
||||
let pdf;
|
||||
if (bodyshop.attach_pdf_to_email) {
|
||||
const pdfRequest = _.cloneDeep(reportRequest);
|
||||
pdfRequest.template.recipe = "chrome-pdf";
|
||||
const pdfRender = await jsreport.renderAsync(pdfRequest);
|
||||
pdf = pdfRender.toDataURI();
|
||||
const pdfRequest = _.cloneDeep(reportRequest); //Updates to spread in the header details.
|
||||
pdfRequest.template = {
|
||||
...pdfRequest.template,
|
||||
...{
|
||||
recipe: "chrome-pdf",
|
||||
...(!ignoreCustomMargins && {
|
||||
chrome: {
|
||||
marginTop:
|
||||
bodyshop.logo_img_path &&
|
||||
bodyshop.logo_img_path.headerMargin &&
|
||||
bodyshop.logo_img_path.headerMargin > 36
|
||||
? bodyshop.logo_img_path.headerMargin
|
||||
: "36px",
|
||||
marginBottom:
|
||||
bodyshop.logo_img_path &&
|
||||
bodyshop.logo_img_path.footerMargin &&
|
||||
bodyshop.logo_img_path.footerMargin > 50
|
||||
? bodyshop.logo_img_path.footerMargin
|
||||
: "50px",
|
||||
},
|
||||
}),
|
||||
},
|
||||
};
|
||||
|
||||
const pdfRender = await jsreport.render(pdfRequest);
|
||||
pdf = await pdfRender.toDataURI();
|
||||
}
|
||||
const html = await render.toString();
|
||||
return new Promise((resolve, reject) => {
|
||||
resolve({
|
||||
pdf,
|
||||
filename:
|
||||
Templates[templateObject.name] &&
|
||||
Templates[templateObject.name].title,
|
||||
html: render.toString(),
|
||||
html,
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -130,6 +159,9 @@ export async function RenderTemplates(
|
||||
// (template) => template.name === item.templateObject.name
|
||||
// );
|
||||
// });
|
||||
if (window.jsr3) {
|
||||
jsreport.serverUrl = "https://reports3.test.imex.online/";
|
||||
}
|
||||
|
||||
unsortedTemplatesAndData.sort(function (a, b) {
|
||||
return (
|
||||
@@ -220,13 +252,11 @@ export async function RenderTemplates(
|
||||
};
|
||||
|
||||
try {
|
||||
const render = await jsreport.renderAsync(reportRequest);
|
||||
const render = await jsreport.render(reportRequest);
|
||||
if (!renderAsHtml) {
|
||||
render.download("Speed Print");
|
||||
} else {
|
||||
return new Promise((resolve, reject) => {
|
||||
resolve(render.toString());
|
||||
});
|
||||
return render.toString();
|
||||
}
|
||||
} catch (error) {
|
||||
notification["error"]({ message: JSON.stringify(error) });
|
||||
|
||||
@@ -1534,6 +1534,18 @@ export const TemplateList = (type, context) => {
|
||||
},
|
||||
group: "purchases",
|
||||
},
|
||||
jobs_reconcile: {
|
||||
title: i18n.t("reportcenter.templates.jobs_reconcile"),
|
||||
subject: i18n.t("reportcenter.templates.jobs_reconcile"),
|
||||
key: "jobs_reconcile",
|
||||
//idtype: "vendor",
|
||||
disabled: false,
|
||||
rangeFilter: {
|
||||
object: i18n.t("reportcenter.labels.objects.jobs"),
|
||||
field: i18n.t("jobs.fields.date_invoiced"),
|
||||
},
|
||||
group: "jobs",
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
...(!type || type === "courtesycarcontract"
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
export default async function FcmHandler({ client, payload }) {
|
||||
console.log("Handling payload type", payload);
|
||||
switch (payload.type) {
|
||||
case "messaging-inbound":
|
||||
client.cache.modify({
|
||||
@@ -24,9 +23,9 @@ export default async function FcmHandler({ client, payload }) {
|
||||
updated_at(oldupdated0) {
|
||||
return new Date();
|
||||
},
|
||||
messages_aggregate(cached) {
|
||||
return { aggregate: { count: cached.aggregate.count + 1 } };
|
||||
},
|
||||
// messages_aggregate(cached) {
|
||||
// return { aggregate: { count: cached.aggregate.count + 1 } };
|
||||
// },
|
||||
},
|
||||
});
|
||||
break;
|
||||
|
||||
40
client/src/utils/useLocalStorage.js
Normal file
40
client/src/utils/useLocalStorage.js
Normal file
@@ -0,0 +1,40 @@
|
||||
import { useState } from "react";
|
||||
|
||||
export default function useLocalStorage(key, initialValue) {
|
||||
// State to store our value
|
||||
// Pass initial state function to useState so logic is only executed once
|
||||
const [storedValue, setStoredValue] = useState(() => {
|
||||
if (typeof window === "undefined") {
|
||||
return initialValue;
|
||||
}
|
||||
try {
|
||||
// Get from local storage by key
|
||||
const item = window.localStorage.getItem(key);
|
||||
// Parse stored json or if none return initialValue
|
||||
return item ? JSON.parse(item) : initialValue;
|
||||
} catch (error) {
|
||||
// If error also return initialValue
|
||||
console.log(error);
|
||||
return initialValue;
|
||||
}
|
||||
});
|
||||
// Return a wrapped version of useState's setter function that ...
|
||||
// ... persists the new value to localStorage.
|
||||
const setValue = (value) => {
|
||||
try {
|
||||
// Allow value to be a function so we have same API as useState
|
||||
const valueToStore =
|
||||
value instanceof Function ? value(storedValue) : value;
|
||||
// Save state
|
||||
setStoredValue(valueToStore);
|
||||
// Save to local storage
|
||||
if (typeof window !== "undefined") {
|
||||
window.localStorage.setItem(key, JSON.stringify(valueToStore));
|
||||
}
|
||||
} catch (error) {
|
||||
// A more advanced implementation would handle the error case
|
||||
console.log(error);
|
||||
}
|
||||
};
|
||||
return [storedValue, setValue];
|
||||
}
|
||||
540
client/yarn.lock
540
client/yarn.lock
@@ -36,10 +36,10 @@
|
||||
lodash "^4.17.21"
|
||||
resize-observer-polyfill "^1.5.0"
|
||||
|
||||
"@apollo/client@^3.6.2":
|
||||
version "3.6.2"
|
||||
resolved "https://registry.yarnpkg.com/@apollo/client/-/client-3.6.2.tgz#0418bfa6358dd117894c8af396706cfa2b186032"
|
||||
integrity sha512-DNWyl+NNU2VsfHtXwOr4rV9hnQFPkl2/dNXeouhk9q7bXCWdEh3K8YTt/frULGVKbQjtnlPmz8C+LFI/JZ2N3w==
|
||||
"@apollo/client@^3.6.6":
|
||||
version "3.6.6"
|
||||
resolved "https://registry.yarnpkg.com/@apollo/client/-/client-3.6.6.tgz#3fb1f5b11da9a64b51b5a86b62450bee034e7f41"
|
||||
integrity sha512-AzNLN043wy0bDTTR9wzKYSu+I1IT2Ox3+vWckxgIt88Jfw5jHBvumf3lXE1JlgvbFCTiKS/Sa66AadQXWMVBRQ==
|
||||
dependencies:
|
||||
"@graphql-typed-document-node/core" "^3.1.1"
|
||||
"@wry/context" "^0.6.0"
|
||||
@@ -50,10 +50,9 @@
|
||||
optimism "^0.16.1"
|
||||
prop-types "^15.7.2"
|
||||
symbol-observable "^4.0.0"
|
||||
ts-invariant "^0.10.0"
|
||||
ts-invariant "^0.10.3"
|
||||
tslib "^2.3.0"
|
||||
use-sync-external-store "^1.0.0"
|
||||
zen-observable-ts "^1.2.0"
|
||||
zen-observable-ts "^1.2.5"
|
||||
|
||||
"@asseinfo/react-kanban@^2.2.0":
|
||||
version "2.2.0"
|
||||
@@ -1106,10 +1105,10 @@
|
||||
dependencies:
|
||||
regenerator-runtime "^0.13.4"
|
||||
|
||||
"@babel/runtime@^7.17.9":
|
||||
version "7.17.9"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.9.tgz#d19fbf802d01a8cb6cf053a64e472d42c434ba72"
|
||||
integrity sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg==
|
||||
"@babel/runtime@^7.18.3":
|
||||
version "7.18.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.18.3.tgz#c7b654b57f6f63cf7f8b418ac9ca04408c4579f4"
|
||||
integrity sha512-38Y8f7YUhce/K7RMwTp7m0uCumpv9hZkitCbBClqQIow1qSbCvGkcegKOXpEWCQLfWmevgRiWokZ1GkpfhbZug==
|
||||
dependencies:
|
||||
regenerator-runtime "^0.13.4"
|
||||
|
||||
@@ -1333,12 +1332,12 @@
|
||||
"@firebase/util" "1.6.0"
|
||||
tslib "^2.1.0"
|
||||
|
||||
"@firebase/app-compat@0.1.25":
|
||||
version "0.1.25"
|
||||
resolved "https://registry.yarnpkg.com/@firebase/app-compat/-/app-compat-0.1.25.tgz#4ba8b9209cd956e31a3418343db4a21016d7673d"
|
||||
integrity sha512-FdCnYwIM3R+OuRE7nrAdVT5oNlvSAHQHN1ictB/gjCFs58lXMCe0DCIRDrA7zxaOFIKeWPtx35ZNXv3EdPFNpQ==
|
||||
"@firebase/app-compat@0.1.26":
|
||||
version "0.1.26"
|
||||
resolved "https://registry.yarnpkg.com/@firebase/app-compat/-/app-compat-0.1.26.tgz#46ca3ea0929a28b6d894f6d4fd8d49a0fe2b66ca"
|
||||
integrity sha512-i5UTq1HZAHuhe7RNjgFSezbow4jVxc2oe3Gndsv+Hdut92f8L0AyssOtdU2iOylLlxbTijewAXXui4FAUzXubw==
|
||||
dependencies:
|
||||
"@firebase/app" "0.7.24"
|
||||
"@firebase/app" "0.7.25"
|
||||
"@firebase/component" "0.5.14"
|
||||
"@firebase/logger" "0.3.2"
|
||||
"@firebase/util" "1.6.0"
|
||||
@@ -1349,10 +1348,10 @@
|
||||
resolved "https://registry.yarnpkg.com/@firebase/app-types/-/app-types-0.7.0.tgz#c9e16d1b8bed1a991840b8d2a725fb58d0b5899f"
|
||||
integrity sha512-6fbHQwDv2jp/v6bXhBw2eSRbNBpxHcd1NBF864UksSMVIqIyri9qpJB1Mn6sGZE+bnDsSQBC5j2TbMxYsJQkQg==
|
||||
|
||||
"@firebase/app@0.7.24":
|
||||
version "0.7.24"
|
||||
resolved "https://registry.yarnpkg.com/@firebase/app/-/app-0.7.24.tgz#bfdfcbf6145d5d1e8e3fcda7a2044a0a510bf476"
|
||||
integrity sha512-HIbAhayEykbCez1Rl6pmzAWbIx63Mc9+t3ngWKqZdkMnBNAAJvYaUdx7Krus7O9XHUKNw/gzBUETAEYt93jusA==
|
||||
"@firebase/app@0.7.25":
|
||||
version "0.7.25"
|
||||
resolved "https://registry.yarnpkg.com/@firebase/app/-/app-0.7.25.tgz#a5ee629d7f957579d5b25105c70316886a75cfc3"
|
||||
integrity sha512-OemDA3NZS1oEbAPFlWHeVI8Od26ZHAXUivUWFYIsYrw+YjS7FloltwyHB06Q8LQyPJIBPubGkEuzNTHz32EDCQ==
|
||||
dependencies:
|
||||
"@firebase/component" "0.5.14"
|
||||
"@firebase/logger" "0.3.2"
|
||||
@@ -1360,17 +1359,17 @@
|
||||
idb "7.0.1"
|
||||
tslib "^2.1.0"
|
||||
|
||||
"@firebase/auth-compat@0.2.14":
|
||||
version "0.2.14"
|
||||
resolved "https://registry.yarnpkg.com/@firebase/auth-compat/-/auth-compat-0.2.14.tgz#ea7dcc38121ce2f2cc9a687830025c8c67d356d8"
|
||||
integrity sha512-1KSNItrTQzky2d0GVCum6d7Hdj9pfNh9aGTN0uJPNk+th9XHBCy0El8Wx5yk0miiyB3h1evWAXdgnIyNs4kTEQ==
|
||||
"@firebase/auth-compat@0.2.15":
|
||||
version "0.2.15"
|
||||
resolved "https://registry.yarnpkg.com/@firebase/auth-compat/-/auth-compat-0.2.15.tgz#dbd04173657fdf525d9da89433b64cd3c658a1c4"
|
||||
integrity sha512-Kl8pujKWVBJ+76h4tRsS5xI9Dvk8MVSP6eN82rnEgmCxiUsnVj5Adb/WzvS3p4/l++4mRSAEnlIVxZ2Pyaeirg==
|
||||
dependencies:
|
||||
"@firebase/auth" "0.20.1"
|
||||
"@firebase/auth" "0.20.2"
|
||||
"@firebase/auth-types" "0.11.0"
|
||||
"@firebase/component" "0.5.14"
|
||||
"@firebase/util" "1.6.0"
|
||||
node-fetch "2.6.7"
|
||||
selenium-webdriver " 4.1.1"
|
||||
selenium-webdriver "4.1.2"
|
||||
tslib "^2.1.0"
|
||||
|
||||
"@firebase/auth-interop-types@0.1.6":
|
||||
@@ -1383,16 +1382,16 @@
|
||||
resolved "https://registry.yarnpkg.com/@firebase/auth-types/-/auth-types-0.11.0.tgz#b9c73c60ca07945b3bbd7a097633e5f78fa9e886"
|
||||
integrity sha512-q7Bt6cx+ySj9elQHTsKulwk3+qDezhzRBFC9zlQ1BjgMueUOnGMcvqmU0zuKlQ4RhLSH7MNAdBV2znVaoN3Vxw==
|
||||
|
||||
"@firebase/auth@0.20.1":
|
||||
version "0.20.1"
|
||||
resolved "https://registry.yarnpkg.com/@firebase/auth/-/auth-0.20.1.tgz#a0a4cac5c73f3e496a6444d17ec4e1e63f33233c"
|
||||
integrity sha512-rffEVZOkcQbQG3zcyhgbJFrE3xIDYtaEIIio5/bMCukitIx0n8okKhb0XKXJ/LGO3zZFRwWh4tyU53t6tHB9uQ==
|
||||
"@firebase/auth@0.20.2":
|
||||
version "0.20.2"
|
||||
resolved "https://registry.yarnpkg.com/@firebase/auth/-/auth-0.20.2.tgz#fbd080a1ae279f81615cf03960fd6b9769f615c6"
|
||||
integrity sha512-anv2dhHXnlHSuXDuXIoCm/w/JJ+SiQ1TAKgNVYlhfq+yvx9Op8CxfTqcfBwfbIZ1gizw4PNLuk82m8KelsKl6Q==
|
||||
dependencies:
|
||||
"@firebase/component" "0.5.14"
|
||||
"@firebase/logger" "0.3.2"
|
||||
"@firebase/util" "1.6.0"
|
||||
node-fetch "2.6.7"
|
||||
selenium-webdriver " 4.1.1"
|
||||
selenium-webdriver "4.1.2"
|
||||
tslib "^2.1.0"
|
||||
|
||||
"@firebase/component@0.5.14":
|
||||
@@ -1919,6 +1918,11 @@
|
||||
"@types/yargs" "^16.0.0"
|
||||
chalk "^4.0.0"
|
||||
|
||||
"@jsreport/browser-client@^3.1.0":
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@jsreport/browser-client/-/browser-client-3.1.0.tgz#a84011087ca8a29a6dc6a852fa05ffaf1983a679"
|
||||
integrity sha512-ZElwn2KRIzkUzAyD5UKGxULZUhokWuPOlMzrmiur4WirqH3yoiHlOJEdnRGkjjE/fhZzCR8gBFZ/TuOW/fsOIw==
|
||||
|
||||
"@nodelib/fs.scandir@2.1.5":
|
||||
version "2.1.5"
|
||||
resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5"
|
||||
@@ -2105,14 +2109,14 @@
|
||||
estree-walker "^1.0.1"
|
||||
picomatch "^2.2.2"
|
||||
|
||||
"@sentry/browser@6.19.7":
|
||||
version "6.19.7"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-6.19.7.tgz#a40b6b72d911b5f1ed70ed3b4e7d4d4e625c0b5f"
|
||||
integrity sha512-oDbklp4O3MtAM4mtuwyZLrgO1qDVYIujzNJQzXmi9YzymJCuzMLSRDvhY83NNDCRxf0pds4DShgYeZdbSyKraA==
|
||||
"@sentry/browser@7.1.1":
|
||||
version "7.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-7.1.1.tgz#2d1fe4a81e0d9679aa73c5ae69a0958e4e42b422"
|
||||
integrity sha512-5AQvStZ+nOP/yxsBmeMZpeGLVtuOgnCNvswKd/c1CJwNw7bDmCE4TQeNKp1C3Gb7lSdBk8ViwUKn0ZpoVQ5MTw==
|
||||
dependencies:
|
||||
"@sentry/core" "6.19.7"
|
||||
"@sentry/types" "6.19.7"
|
||||
"@sentry/utils" "6.19.7"
|
||||
"@sentry/core" "7.1.1"
|
||||
"@sentry/types" "7.1.1"
|
||||
"@sentry/utils" "7.1.1"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@sentry/cli@^1.74.4":
|
||||
@@ -2128,69 +2132,57 @@
|
||||
proxy-from-env "^1.1.0"
|
||||
which "^2.0.2"
|
||||
|
||||
"@sentry/core@6.19.7":
|
||||
version "6.19.7"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/core/-/core-6.19.7.tgz#156aaa56dd7fad8c89c145be6ad7a4f7209f9785"
|
||||
integrity sha512-tOfZ/umqB2AcHPGbIrsFLcvApdTm9ggpi/kQZFkej7kMphjT+SGBiQfYtjyg9jcRW+ilAR4JXC9BGKsdEQ+8Vw==
|
||||
"@sentry/core@7.1.1":
|
||||
version "7.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.1.1.tgz#85f73f8037eec61e37549998de03a6d3d3c635b5"
|
||||
integrity sha512-SADdAoG5u1LTJhPN5KPtn5HHmH6r0mr6h2LokuZnhj6/okrAuCIIKOb6Fh8jV7j2VuABvew8+FjJHORxi7D/3Q==
|
||||
dependencies:
|
||||
"@sentry/hub" "6.19.7"
|
||||
"@sentry/minimal" "6.19.7"
|
||||
"@sentry/types" "6.19.7"
|
||||
"@sentry/utils" "6.19.7"
|
||||
"@sentry/hub" "7.1.1"
|
||||
"@sentry/types" "7.1.1"
|
||||
"@sentry/utils" "7.1.1"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@sentry/hub@6.19.7":
|
||||
version "6.19.7"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-6.19.7.tgz#58ad7776bbd31e9596a8ec46365b45cd8b9cfd11"
|
||||
integrity sha512-y3OtbYFAqKHCWezF0EGGr5lcyI2KbaXW2Ik7Xp8Mu9TxbSTuwTe4rTntwg8ngPjUQU3SUHzgjqVB8qjiGqFXCA==
|
||||
"@sentry/hub@7.1.1":
|
||||
version "7.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-7.1.1.tgz#d6aa54e7bd20a71cebd602701dd29d5d581d391a"
|
||||
integrity sha512-ASsRVjYDIii6ZTf36JnIYKHWBQBk0P42Tgq324MpyPgaeVDg3saBcyXO5iAtWvY6Vmdi2H4JCVDoir2Zz3Me1w==
|
||||
dependencies:
|
||||
"@sentry/types" "6.19.7"
|
||||
"@sentry/utils" "6.19.7"
|
||||
"@sentry/types" "7.1.1"
|
||||
"@sentry/utils" "7.1.1"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@sentry/minimal@6.19.7":
|
||||
version "6.19.7"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-6.19.7.tgz#b3ee46d6abef9ef3dd4837ebcb6bdfd01b9aa7b4"
|
||||
integrity sha512-wcYmSJOdvk6VAPx8IcmZgN08XTXRwRtB1aOLZm+MVHjIZIhHoBGZJYTVQS/BWjldsamj2cX3YGbGXNunaCfYJQ==
|
||||
"@sentry/react@^7.1.1":
|
||||
version "7.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/react/-/react-7.1.1.tgz#13d63384d1a8c916b96ea79b74fc419ba967fb6a"
|
||||
integrity sha512-Z7cZvXHIWxg7OhOSy4InhrRgQPRNtHsyOkIAHkgwW32JYOGTg1HdqQ5mFUxQLejhU/YqsxVjTK4CI58FATykLw==
|
||||
dependencies:
|
||||
"@sentry/hub" "6.19.7"
|
||||
"@sentry/types" "6.19.7"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@sentry/react@^6.19.7":
|
||||
version "6.19.7"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/react/-/react-6.19.7.tgz#58cc2d6da20f7d3b0df40638dfbbbc86c9c85caf"
|
||||
integrity sha512-VzJeBg/v41jfxUYPkH2WYrKjWc4YiMLzDX0f4Zf6WkJ4v3IlDDSkX6DfmWekjTKBho6wiMkSNy2hJ1dHfGZ9jA==
|
||||
dependencies:
|
||||
"@sentry/browser" "6.19.7"
|
||||
"@sentry/minimal" "6.19.7"
|
||||
"@sentry/types" "6.19.7"
|
||||
"@sentry/utils" "6.19.7"
|
||||
"@sentry/browser" "7.1.1"
|
||||
"@sentry/types" "7.1.1"
|
||||
"@sentry/utils" "7.1.1"
|
||||
hoist-non-react-statics "^3.3.2"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@sentry/tracing@^6.19.7":
|
||||
version "6.19.7"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-6.19.7.tgz#54bb99ed5705931cd33caf71da347af769f02a4c"
|
||||
integrity sha512-ol4TupNnv9Zd+bZei7B6Ygnr9N3Gp1PUrNI761QSlHtPC25xXC5ssSD3GMhBgyQrcvpuRcCFHVNNM97tN5cZiA==
|
||||
"@sentry/tracing@^7.1.1":
|
||||
version "7.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-7.1.1.tgz#8996c0913803d3c4a103388c9c0dd2410cca8478"
|
||||
integrity sha512-MJ+EPGfvPlgbJOcZRoIl6+Oi0oRE2nIi/HP2BPJSKGxXFi2Y09bcZUwfxOH8fkUa465jOGBFdCm+sXcbyExvuw==
|
||||
dependencies:
|
||||
"@sentry/hub" "6.19.7"
|
||||
"@sentry/minimal" "6.19.7"
|
||||
"@sentry/types" "6.19.7"
|
||||
"@sentry/utils" "6.19.7"
|
||||
"@sentry/hub" "7.1.1"
|
||||
"@sentry/types" "7.1.1"
|
||||
"@sentry/utils" "7.1.1"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@sentry/types@6.19.7":
|
||||
version "6.19.7"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/types/-/types-6.19.7.tgz#c6b337912e588083fc2896eb012526cf7cfec7c7"
|
||||
integrity sha512-jH84pDYE+hHIbVnab3Hr+ZXr1v8QABfhx39KknxqKWr2l0oEItzepV0URvbEhB446lk/S/59230dlUUIBGsXbg==
|
||||
"@sentry/types@7.1.1":
|
||||
version "7.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.1.1.tgz#63aa68e7be36d63cc305d01af9119a4cdb186ae3"
|
||||
integrity sha512-5N1UMd2SqvUXprcIUMyDEju3H9lJY2oWfWQBGo0lG6Amn/lGAPAYlchg+4vQCLutDQMyd8K9zPwcbKn4u6gHdw==
|
||||
|
||||
"@sentry/utils@6.19.7":
|
||||
version "6.19.7"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-6.19.7.tgz#6edd739f8185fd71afe49cbe351c1bbf5e7b7c79"
|
||||
integrity sha512-z95ECmE3i9pbWoXQrD/7PgkBAzJYR+iXtPuTkpBjDKs86O3mT+PXOT3BAn79w2wkn7/i3vOGD2xVr1uiMl26dA==
|
||||
"@sentry/utils@7.1.1":
|
||||
version "7.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.1.1.tgz#7174a1439f8970510207fa7587385119397e1718"
|
||||
integrity sha512-DPRHDf3InfyVgmxToE4Z+AATAR4OVm+wsXDLFGGyncR91CE1x4wLQKOcAJJwX3F0Hz1VHENfmx1DvyYTHOrC/A==
|
||||
dependencies:
|
||||
"@sentry/types" "6.19.7"
|
||||
"@sentry/types" "7.1.1"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@sentry/webpack-plugin@^1.18.9":
|
||||
@@ -2243,17 +2235,17 @@
|
||||
shallowequal "^1.1.0"
|
||||
unfetch "^4.2.0"
|
||||
|
||||
"@stripe/react-stripe-js@^1.8.0":
|
||||
version "1.8.0"
|
||||
resolved "https://registry.yarnpkg.com/@stripe/react-stripe-js/-/react-stripe-js-1.8.0.tgz#b07f1d95e75fe93ac5c33346539ec0972298957d"
|
||||
integrity sha512-WtF2mIWJKnyAaZledC48NfynFckEseCPG8tybwFgisFxHvLPKrArlLISJOi2cjIY20DkMAkSkdlEljXifJi0ZA==
|
||||
"@stripe/react-stripe-js@^1.8.1":
|
||||
version "1.8.1"
|
||||
resolved "https://registry.yarnpkg.com/@stripe/react-stripe-js/-/react-stripe-js-1.8.1.tgz#b646e3a8775dbb0432e234c6e1d67b19c4c0462d"
|
||||
integrity sha512-8TpHu87zWSX/PhMMIC2C0jYXKl53kdiHz7bDSfLDs2oIynbV5L9cyoCZ1NuTllrNvFtd28fOqPc4IikZYRRDew==
|
||||
dependencies:
|
||||
prop-types "^15.7.2"
|
||||
|
||||
"@stripe/stripe-js@^1.29.0":
|
||||
version "1.29.0"
|
||||
resolved "https://registry.yarnpkg.com/@stripe/stripe-js/-/stripe-js-1.29.0.tgz#f41e46aee711d1eabcb3bbc77376016a250ec962"
|
||||
integrity sha512-OsUxk0VLlum8E2d6onlEdKuQcvLMs7qTrOXCnl/BGV3fAm65qr6h3e1IZ5AX4lgUlPRrzRcddSOA5DvkKKYLvg==
|
||||
"@stripe/stripe-js@^1.31.0":
|
||||
version "1.31.0"
|
||||
resolved "https://registry.yarnpkg.com/@stripe/stripe-js/-/stripe-js-1.31.0.tgz#2920bdddc3eabb5734f9ca794824e25b378533ac"
|
||||
integrity sha512-drlXsNvd/s9S1+Ghja0aDB81N3Wr/6iRAZ7MOzKv7AtKxVdvGpOwESw3z1lHl/Wx/rvPpA7whKdB3W2CnVSArw==
|
||||
|
||||
"@surma/rollup-plugin-off-main-thread@^1.1.1":
|
||||
version "1.4.2"
|
||||
@@ -2366,12 +2358,12 @@
|
||||
"@svgr/plugin-svgo" "^5.5.0"
|
||||
loader-utils "^2.0.0"
|
||||
|
||||
"@tanem/react-nprogress@^5.0.0":
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@tanem/react-nprogress/-/react-nprogress-5.0.0.tgz#5da9b9f5719f40192dea7d7157fe5fa0da64061e"
|
||||
integrity sha512-ReHCykV4pRIiXsPvbIwZ7Qrxx+940W5AdPsrXeFJlxBWUa9HEMtjXxwwvCoFbnlDF1ZziNvriAvgD/rneM9v3g==
|
||||
"@tanem/react-nprogress@^5.0.1":
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@tanem/react-nprogress/-/react-nprogress-5.0.1.tgz#338249e907c805e51ab9e6c712ee59130f190f93"
|
||||
integrity sha512-Q6nVFs4EP88L8b/oVS5MJgEfF7NaWfQ5sGuNXVvxtzPn6EmfCsunG5Oj5pZdpDH0MFSRMvd9cfuL/WpW+S+bvg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.17.9"
|
||||
"@babel/runtime" "^7.18.3"
|
||||
hoist-non-react-statics "^3.3.2"
|
||||
|
||||
"@testing-library/cypress@^8.0.2":
|
||||
@@ -2464,42 +2456,6 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.3.3.tgz#85bc74ba782fb7aa3a514d11767832b0e3bc6803"
|
||||
integrity sha512-LKVP3cgXBT9RYj+t+9FDKwS5tdI+rPBXaNSkma7hvqy35lc7mAokC2zsqWJH0LaqIt3B962nuYI77hsJoT1gow==
|
||||
|
||||
"@types/d3-color@^2":
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/d3-color/-/d3-color-2.0.3.tgz#8bc4589073c80e33d126345542f588056511fe82"
|
||||
integrity sha512-+0EtEjBfKEDtH9Rk3u3kLOUXM5F+iZK+WvASPb0MhIZl8J8NUvGeZRwKCXl+P3HkYx5TdU4YtcibpqHkSR9n7w==
|
||||
|
||||
"@types/d3-interpolate@^2.0.0":
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/d3-interpolate/-/d3-interpolate-2.0.2.tgz#78eddf7278b19e48e8652603045528d46897aba0"
|
||||
integrity sha512-lElyqlUfIPyWG/cD475vl6msPL4aMU7eJvx1//Q177L8mdXoVPFl1djIESF2FKnc0NyaHvQlJpWwKJYwAhUoCw==
|
||||
dependencies:
|
||||
"@types/d3-color" "^2"
|
||||
|
||||
"@types/d3-path@^2":
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/d3-path/-/d3-path-2.0.1.tgz#ca03dfa8b94d8add97ad0cd97e96e2006b4763cb"
|
||||
integrity sha512-6K8LaFlztlhZO7mwsZg7ClRsdLg3FJRzIIi6SZXDWmmSJc2x8dd2VkESbLXdk3p8cuvz71f36S0y8Zv2AxqvQw==
|
||||
|
||||
"@types/d3-scale@^3.0.0":
|
||||
version "3.3.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/d3-scale/-/d3-scale-3.3.2.tgz#18c94e90f4f1c6b1ee14a70f14bfca2bd1c61d06"
|
||||
integrity sha512-gGqr7x1ost9px3FvIfUMi5XA/F/yAf4UkUDtdQhpH92XCT0Oa7zkkRzY61gPVJq+DxpHn/btouw5ohWkbBsCzQ==
|
||||
dependencies:
|
||||
"@types/d3-time" "^2"
|
||||
|
||||
"@types/d3-shape@^2.0.0":
|
||||
version "2.1.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/d3-shape/-/d3-shape-2.1.3.tgz#35d397b9e687abaa0de82343b250b9897b8cacf3"
|
||||
integrity sha512-HAhCel3wP93kh4/rq+7atLdybcESZ5bRHDEZUojClyZWsRuEMo3A52NGYJSh48SxfxEU6RZIVbZL2YFZ2OAlzQ==
|
||||
dependencies:
|
||||
"@types/d3-path" "^2"
|
||||
|
||||
"@types/d3-time@^2":
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/d3-time/-/d3-time-2.1.1.tgz#743fdc821c81f86537cbfece07093ac39b4bc342"
|
||||
integrity sha512-9MVYlmIgmRR31C5b4FVSWtuMmBHh2mOWQYfl7XAYOa8dsnb7iEmUmRSWSFgXFtkjxO65d7hTUHQC+RhR/9IWFg==
|
||||
|
||||
"@types/eslint@^7.28.2":
|
||||
version "7.29.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-7.29.0.tgz#e56ddc8e542815272720bb0b4ccc2aff9c3e1c78"
|
||||
@@ -3048,10 +3004,10 @@ accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7:
|
||||
mime-types "~2.1.24"
|
||||
negotiator "0.6.2"
|
||||
|
||||
ace-builds@^1.4.14:
|
||||
version "1.4.14"
|
||||
resolved "https://registry.yarnpkg.com/ace-builds/-/ace-builds-1.4.14.tgz#2c41ccbccdd09e665d3489f161a20baeb3a3c852"
|
||||
integrity sha512-NBOQlm9+7RBqRqZwimpgquaLeTJFayqb9UEPtTkpC3TkkwDnlsT/TwsCC0svjt9kEZ6G9mH5AEOHSz6Q/HrzQQ==
|
||||
ace-builds@^1.5.3:
|
||||
version "1.5.3"
|
||||
resolved "https://registry.yarnpkg.com/ace-builds/-/ace-builds-1.5.3.tgz#05f81d3464a9ea19696e5e6fd0f924d37dab442f"
|
||||
integrity sha512-WN5BKR2aTSuBmisO8jo3Fytk6sOmJGki82v/Boeic81IgYN8pFHNkXq2anDF0XkmfDWMqLbRoW9sjc/GtKzQbQ==
|
||||
|
||||
acorn-globals@^6.0.0:
|
||||
version "6.0.0"
|
||||
@@ -3210,10 +3166,10 @@ ansi-styles@^5.0.0:
|
||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b"
|
||||
integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==
|
||||
|
||||
antd@^4.20.5:
|
||||
version "4.20.5"
|
||||
resolved "https://registry.yarnpkg.com/antd/-/antd-4.20.5.tgz#ac6a35f8ed2703dc94ac4661d5d10a88912be457"
|
||||
integrity sha512-43bV1y9pXsccMBmThEPnk0FdPPl5oqEZs8wneKEtdUm6RusmAHxxWnWGgoqdVsEP2ASRDcwyhECTLu2oPw88ug==
|
||||
antd@^4.21.0:
|
||||
version "4.21.0"
|
||||
resolved "https://registry.yarnpkg.com/antd/-/antd-4.21.0.tgz#44e65d08528b28664d3ef00a539964c2133f3338"
|
||||
integrity sha512-p8R5scejlWjAIF/NoJ5JF5OMjLbAlCA7u85cNwbtRQOP+14KQDXZyHMT4C5oc9nhz7xxD/Bry6HhPkUmsRuP7Q==
|
||||
dependencies:
|
||||
"@ant-design/colors" "^6.0.0"
|
||||
"@ant-design/icons" "^4.7.0"
|
||||
@@ -3225,36 +3181,36 @@ antd@^4.20.5:
|
||||
lodash "^4.17.21"
|
||||
memoize-one "^6.0.0"
|
||||
moment "^2.29.2"
|
||||
rc-cascader "~3.5.0"
|
||||
rc-cascader "~3.6.0"
|
||||
rc-checkbox "~2.3.0"
|
||||
rc-collapse "~3.1.0"
|
||||
rc-dialog "~8.8.1"
|
||||
rc-collapse "~3.3.0"
|
||||
rc-dialog "~8.8.2"
|
||||
rc-drawer "~4.4.2"
|
||||
rc-dropdown "~3.5.0"
|
||||
rc-dropdown "~4.0.0"
|
||||
rc-field-form "~1.26.1"
|
||||
rc-image "~5.6.0"
|
||||
rc-input "~0.0.1-alpha.5"
|
||||
rc-input-number "~7.3.0"
|
||||
rc-mentions "~1.7.0"
|
||||
rc-menu "~9.5.5"
|
||||
rc-mentions "~1.8.0"
|
||||
rc-menu "~9.6.0"
|
||||
rc-motion "^2.5.1"
|
||||
rc-notification "~4.6.0"
|
||||
rc-pagination "~3.1.9"
|
||||
rc-picker "~2.6.4"
|
||||
rc-progress "~3.2.1"
|
||||
rc-pagination "~3.1.16"
|
||||
rc-picker "~2.6.8"
|
||||
rc-progress "~3.3.2"
|
||||
rc-rate "~2.9.0"
|
||||
rc-resize-observer "^1.2.0"
|
||||
rc-segmented "~2.1.0 "
|
||||
rc-segmented "~2.1.0"
|
||||
rc-select "~14.1.1"
|
||||
rc-slider "~10.0.0"
|
||||
rc-steps "~4.1.0"
|
||||
rc-switch "~3.2.0"
|
||||
rc-table "~7.24.0"
|
||||
rc-tabs "~11.13.0"
|
||||
rc-tabs "~11.16.0"
|
||||
rc-textarea "~0.3.0"
|
||||
rc-tooltip "~5.1.1"
|
||||
rc-tree "~5.5.0"
|
||||
rc-tree-select "~5.3.0"
|
||||
rc-tree "~5.6.4"
|
||||
rc-tree-select "~5.4.0"
|
||||
rc-trigger "^5.2.10"
|
||||
rc-upload "~4.3.0"
|
||||
rc-util "^5.20.0"
|
||||
@@ -6630,20 +6586,20 @@ find-up@^3.0.0:
|
||||
dependencies:
|
||||
locate-path "^3.0.0"
|
||||
|
||||
firebase@^9.8.1:
|
||||
version "9.8.1"
|
||||
resolved "https://registry.yarnpkg.com/firebase/-/firebase-9.8.1.tgz#502e186078d69d72ab8d4f1b5befa287e0858276"
|
||||
integrity sha512-VyM+3ijzB1Q24b9v6HzVOB0bXNy0a/maOZlmv2P8M29VXfrS/npo6zntNiOEtcjrCoItZIuWFH4oDGiYkPHxbg==
|
||||
firebase@^9.8.2:
|
||||
version "9.8.2"
|
||||
resolved "https://registry.yarnpkg.com/firebase/-/firebase-9.8.2.tgz#ce2b8a6d41036b323d963280c345b03f4bd4df52"
|
||||
integrity sha512-cVPpiR18vsLuGWAAVkVhNO6mYsEgYBqawvMI2zxKo2FCtneyBgMwOyWKI8VyCmL5ze5p5QJTPjkoatM6rZkd0Q==
|
||||
dependencies:
|
||||
"@firebase/analytics" "0.7.9"
|
||||
"@firebase/analytics-compat" "0.1.10"
|
||||
"@firebase/app" "0.7.24"
|
||||
"@firebase/app" "0.7.25"
|
||||
"@firebase/app-check" "0.5.8"
|
||||
"@firebase/app-check-compat" "0.2.8"
|
||||
"@firebase/app-compat" "0.1.25"
|
||||
"@firebase/app-compat" "0.1.26"
|
||||
"@firebase/app-types" "0.7.0"
|
||||
"@firebase/auth" "0.20.1"
|
||||
"@firebase/auth-compat" "0.2.14"
|
||||
"@firebase/auth" "0.20.2"
|
||||
"@firebase/auth-compat" "0.2.15"
|
||||
"@firebase/database" "0.13.0"
|
||||
"@firebase/database-compat" "0.2.0"
|
||||
"@firebase/firestore" "3.4.9"
|
||||
@@ -7412,10 +7368,10 @@ i18next-browser-languagedetector@^6.1.4:
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.14.6"
|
||||
|
||||
i18next@^21.8.2:
|
||||
version "21.8.2"
|
||||
resolved "https://registry.yarnpkg.com/i18next/-/i18next-21.8.2.tgz#b2d9fd7feafc1a9929651c24a5c17ba703552bbc"
|
||||
integrity sha512-H/oQvA/OXcqurXHemlyDwdIzr9GHYg5/xBuDeFXTXJGMOJFH0ke1wgbsDjFFk2noD4cJfzicVPpUtp39Z+OzgQ==
|
||||
i18next@^21.8.9:
|
||||
version "21.8.9"
|
||||
resolved "https://registry.yarnpkg.com/i18next/-/i18next-21.8.9.tgz#c79edd5bba61e0a0d5b43a93d52e2d13a526de82"
|
||||
integrity sha512-PY9a/8ADVmnju1tETeglbbVQi+nM5pcJQWm9kvKMTE3GPgHHtpDsHy5HQ/hccz2/xtW7j3vuso23JdQSH0EttA==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.17.2"
|
||||
|
||||
@@ -8721,12 +8677,12 @@ json5@^2.1.2:
|
||||
dependencies:
|
||||
minimist "^1.2.5"
|
||||
|
||||
jsoneditor@^9.7.4:
|
||||
version "9.7.4"
|
||||
resolved "https://registry.yarnpkg.com/jsoneditor/-/jsoneditor-9.7.4.tgz#00ddbd99950f8551e0d5e5d0bb9c69584beabda4"
|
||||
integrity sha512-Ln+WdNKLwaqaA64RgI8SI5PRA5RpcVougDNF9ILVzgyj3gDY9ev4WIQcgjoEoQC3Ymml3V7scQ08sDKiNSjo9Q==
|
||||
jsoneditor@^9.8.0:
|
||||
version "9.8.0"
|
||||
resolved "https://registry.yarnpkg.com/jsoneditor/-/jsoneditor-9.8.0.tgz#08db81ccf6f6e9fdff8691e42c4fb62d3efdd6ad"
|
||||
integrity sha512-q1ekwYizbSAny0/UAEOzLviVCyBS5XFGwM/EUNf9KnfB1MRSDmJDWjt4lAqMVz1TUV5O/l3J4/WzUSLQh2tZjw==
|
||||
dependencies:
|
||||
ace-builds "^1.4.14"
|
||||
ace-builds "^1.5.3"
|
||||
ajv "^6.12.6"
|
||||
javascript-natural-sort "^0.7.1"
|
||||
jmespath "^0.16.0"
|
||||
@@ -8901,10 +8857,10 @@ levn@~0.3.0:
|
||||
prelude-ls "~1.1.2"
|
||||
type-check "~0.3.2"
|
||||
|
||||
libphonenumber-js@^1.9.53:
|
||||
version "1.9.53"
|
||||
resolved "https://registry.yarnpkg.com/libphonenumber-js/-/libphonenumber-js-1.9.53.tgz#f4f3321f8fb0ee62952c2a8df4711236d2626088"
|
||||
integrity sha512-3cuMrA2CY3TbKVC0wKye5dXYgxmVVi4g13gzotprQSguFHMqf0pIrMM2Z6ZtMsSWqvtIqi5TuQhGjMhxz0O9Mw==
|
||||
libphonenumber-js@^1.10.6:
|
||||
version "1.10.6"
|
||||
resolved "https://registry.yarnpkg.com/libphonenumber-js/-/libphonenumber-js-1.10.6.tgz#a453efe9d692cc9457abb20a712dec34472a7164"
|
||||
integrity sha512-CIjT100/SmntsUjsLVs2t3ufeN4KdNXUxhD07tH153pdbaCWuAjv0jK/gPuywR3IImB/U/MQM+x9RfhMs5XZiA==
|
||||
|
||||
lie@~3.3.0:
|
||||
version "3.3.0"
|
||||
@@ -10233,10 +10189,10 @@ performance-now@^2.1.0:
|
||||
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
|
||||
integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
|
||||
|
||||
phone@^3.1.17:
|
||||
version "3.1.17"
|
||||
resolved "https://registry.yarnpkg.com/phone/-/phone-3.1.17.tgz#4cf6e8f3738ba35d5261979c98823005af459792"
|
||||
integrity sha512-62vV6eQGP15iGzCPS+ugaEzuvxz6qWBUlKnrAqzKtGUMT3HlLD7vpoi9NA+Ty7M3KvnKI+idddOgufqu1XAeEA==
|
||||
phone@^3.1.20:
|
||||
version "3.1.20"
|
||||
resolved "https://registry.yarnpkg.com/phone/-/phone-3.1.20.tgz#8b7b326c182ce70eaf7884eae3eee0cd6e7ee7b3"
|
||||
integrity sha512-RR23OELEPPMWX3fz//ajrElna+9Y10iqBTL6W1SXHeQPnvpVd8ey2tYYcIH8lB70QL3QiTMDiSIwaINcde6SOw==
|
||||
|
||||
picocolors@^0.2.1:
|
||||
version "0.2.1"
|
||||
@@ -11332,16 +11288,16 @@ rc-align@^4.0.0:
|
||||
rc-util "^5.3.0"
|
||||
resize-observer-polyfill "^1.5.1"
|
||||
|
||||
rc-cascader@~3.5.0:
|
||||
version "3.5.0"
|
||||
resolved "https://registry.yarnpkg.com/rc-cascader/-/rc-cascader-3.5.0.tgz#a49b632bc2d0c8ef31b212c8ddd0bea346e64877"
|
||||
integrity sha512-rpXnWCfvk7Frh2dBzMoA0c7i0nn6aJU7L2NZo8R8pNkrT0sKgytQSpdtPWP+Pq8IkvwbEd8BU8Z8OnOljcqgZg==
|
||||
rc-cascader@~3.6.0:
|
||||
version "3.6.0"
|
||||
resolved "https://registry.yarnpkg.com/rc-cascader/-/rc-cascader-3.6.0.tgz#7db0d373edf4c276bba4b68b7de57fad1486c908"
|
||||
integrity sha512-p9qwt8E8ZICzPIzyfXF5y7/lbJhRowFj8YhWpdytMomHUZ568duFNwA4H5QVqdC6hg/HIV1YEawOE5jlxSpeww==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.12.5"
|
||||
array-tree-filter "^2.1.0"
|
||||
classnames "^2.3.1"
|
||||
rc-select "~14.1.0"
|
||||
rc-tree "~5.5.0"
|
||||
rc-tree "~5.6.3"
|
||||
rc-util "^5.6.1"
|
||||
|
||||
rc-checkbox@~2.3.0:
|
||||
@@ -11352,10 +11308,10 @@ rc-checkbox@~2.3.0:
|
||||
"@babel/runtime" "^7.10.1"
|
||||
classnames "^2.2.1"
|
||||
|
||||
rc-collapse@~3.1.0:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/rc-collapse/-/rc-collapse-3.1.2.tgz#76028a811b845d03d9460ccc409c7ea8ad09db14"
|
||||
integrity sha512-HujcKq7mghk/gVKeI6EjzTbb8e19XUZpakrYazu1MblEZ3Hu3WBMSN4A3QmvbF6n1g7x6lUlZvsHZ5shABWYOQ==
|
||||
rc-collapse@~3.3.0:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/rc-collapse/-/rc-collapse-3.3.0.tgz#ecde33a06ca53c6c672c6a46c701052b88723950"
|
||||
integrity sha512-nkxjhpYAAwEVbBvZ/qoatLecD0PpRtQ5ja9G+FP1QmsWhs/4VCruhjvRdSpMn9vfluKUnePe3PEy8eeqTeuE0g==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.10.1"
|
||||
classnames "2.x"
|
||||
@@ -11363,7 +11319,7 @@ rc-collapse@~3.1.0:
|
||||
rc-util "^5.2.1"
|
||||
shallowequal "^1.1.0"
|
||||
|
||||
rc-dialog@~8.8.0, rc-dialog@~8.8.1:
|
||||
rc-dialog@~8.8.0:
|
||||
version "8.8.1"
|
||||
resolved "https://registry.yarnpkg.com/rc-dialog/-/rc-dialog-8.8.1.tgz#cd8897fbee1de0eab6d237a6abe1e4db8d09dd72"
|
||||
integrity sha512-7M1WKZCjfIABKEaJVskdYvb80z+RX7I11PeSjPVfLOOaJAmIepvDEd0alBtOZvOL3fZFWlMs4JVZtp9LZgONxA==
|
||||
@@ -11373,6 +11329,16 @@ rc-dialog@~8.8.0, rc-dialog@~8.8.1:
|
||||
rc-motion "^2.3.0"
|
||||
rc-util "^5.21.0"
|
||||
|
||||
rc-dialog@~8.8.2:
|
||||
version "8.8.2"
|
||||
resolved "https://registry.yarnpkg.com/rc-dialog/-/rc-dialog-8.8.2.tgz#2212c63b940cf0ca46f961803f83007966cc6582"
|
||||
integrity sha512-n1waqBDDKqCCcPCDGycahfawF00WqgtXTXUwxrLStUpfQAo7nzkAvTq9voT78X2qN83UYvrMg1TWCuTueBp+sg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.10.1"
|
||||
classnames "^2.2.6"
|
||||
rc-motion "^2.3.0"
|
||||
rc-util "^5.21.0"
|
||||
|
||||
rc-drawer@~4.4.2:
|
||||
version "4.4.3"
|
||||
resolved "https://registry.yarnpkg.com/rc-drawer/-/rc-drawer-4.4.3.tgz#2094937a844e55dc9644236a2d9fba79c344e321"
|
||||
@@ -11382,14 +11348,14 @@ rc-drawer@~4.4.2:
|
||||
classnames "^2.2.6"
|
||||
rc-util "^5.7.0"
|
||||
|
||||
rc-dropdown@~3.5.0:
|
||||
version "3.5.2"
|
||||
resolved "https://registry.yarnpkg.com/rc-dropdown/-/rc-dropdown-3.5.2.tgz#2f1f4eeb36c07fb67cd599c0cb8e861da3de5527"
|
||||
integrity sha512-Ty4LsXjkspZuFJSRx3blCLLCDicXM5qds6F1odgEa+jcjC+OJKHQGnvE4FqtoljPaqWm4wG78pbgXH6Ddh2DkA==
|
||||
rc-dropdown@~4.0.0:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/rc-dropdown/-/rc-dropdown-4.0.1.tgz#f65d9d3d89750241057db59d5a75e43cd4576b68"
|
||||
integrity sha512-OdpXuOcme1rm45cR0Jzgfl1otzmU4vuBVb+etXM8vcaULGokAKVpKlw8p6xzspG7jGd/XxShvq+N3VNEfk/l5g==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.10.1"
|
||||
"@babel/runtime" "^7.18.3"
|
||||
classnames "^2.2.6"
|
||||
rc-trigger "^5.0.4"
|
||||
rc-trigger "^5.3.1"
|
||||
rc-util "^5.17.0"
|
||||
|
||||
rc-field-form@~1.26.1:
|
||||
@@ -11429,22 +11395,22 @@ rc-input@~0.0.1-alpha.5:
|
||||
classnames "^2.2.1"
|
||||
rc-util "^5.18.1"
|
||||
|
||||
rc-mentions@~1.7.0:
|
||||
version "1.7.1"
|
||||
resolved "https://registry.yarnpkg.com/rc-mentions/-/rc-mentions-1.7.1.tgz#480ad04af4460ee01b6ccd9137fcea23067aa9be"
|
||||
integrity sha512-JbCS9bTqt6BYN2vfTPythlScLuc42rIlX85n7975RnkfawXlJjskHOlR3o8EpD4asl4KuA2jKTy0dj39DtSVqg==
|
||||
rc-mentions@~1.8.0:
|
||||
version "1.8.0"
|
||||
resolved "https://registry.yarnpkg.com/rc-mentions/-/rc-mentions-1.8.0.tgz#4c0c41605064303f7aedec47d4d07e0bbfcc2dc3"
|
||||
integrity sha512-ch7yfMMvx2UXy+EvE4axm0Vp6VlVZ30WLrZtLtV/Eb1ty7rQQRzNzCwAHAMyw6tNKTMs9t9sF68AVjAzQ0rvJw==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.10.1"
|
||||
classnames "^2.2.6"
|
||||
rc-menu "~9.5.1"
|
||||
rc-menu "~9.6.0"
|
||||
rc-textarea "^0.3.0"
|
||||
rc-trigger "^5.0.4"
|
||||
rc-util "^5.0.1"
|
||||
|
||||
rc-menu@~9.5.1, rc-menu@~9.5.5:
|
||||
version "9.5.5"
|
||||
resolved "https://registry.yarnpkg.com/rc-menu/-/rc-menu-9.5.5.tgz#aa2f151d4191ed089dc1a8141fe365c9b77d61a9"
|
||||
integrity sha512-wj2y2BAKwSMyWXO3RBf9sNN5V+DFWxFl45Ma6qQEHA5nwwh7p07bNgc6AAJc+L1+LAz+rWz3AU8PYyT17hMHCw==
|
||||
rc-menu@~9.6.0:
|
||||
version "9.6.0"
|
||||
resolved "https://registry.yarnpkg.com/rc-menu/-/rc-menu-9.6.0.tgz#3263a729a81ae49cfdadee112e97d3c702922829"
|
||||
integrity sha512-d26waws42U/rVwW/+rOE2FN9pX6wUc9bDy38vVQYoie6gE85auWIpl5oChGlnW6nE2epnTwUsgWl8ipOPgmnUA==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.10.1"
|
||||
classnames "2.x"
|
||||
@@ -11492,18 +11458,18 @@ rc-overflow@^1.0.0, rc-overflow@^1.2.0:
|
||||
rc-resize-observer "^1.0.0"
|
||||
rc-util "^5.5.1"
|
||||
|
||||
rc-pagination@~3.1.9:
|
||||
version "3.1.14"
|
||||
resolved "https://registry.yarnpkg.com/rc-pagination/-/rc-pagination-3.1.14.tgz#1f7d0342edb80dca0989e4ddbe937b1d4657d88d"
|
||||
integrity sha512-tcugvxrtPiVU00Uh0IwC8NIUlxa4KtA9pXcaMNJdSHeO2uQqVkHEwllsULTAWRF3zRV2ozo2weP/DRKIUrX+Zg==
|
||||
rc-pagination@~3.1.16:
|
||||
version "3.1.16"
|
||||
resolved "https://registry.yarnpkg.com/rc-pagination/-/rc-pagination-3.1.16.tgz#b0082108cf027eded18ed61d818d31897c343e81"
|
||||
integrity sha512-GFcHXJ7XxeJDf9B+ndP4PRDt46maSSgYhiwofBMiIGKIlBhJ0wfu8DMCEvaWJJLpI2u4Gb6zF1dHpiqPFrosPg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.10.1"
|
||||
classnames "^2.2.1"
|
||||
|
||||
rc-picker@~2.6.4:
|
||||
version "2.6.5"
|
||||
resolved "https://registry.yarnpkg.com/rc-picker/-/rc-picker-2.6.5.tgz#a7cf8eb0723ec81e379c784c4b798b7fe076dd8c"
|
||||
integrity sha512-4pcg0PgEz4YXBfdwMuHIKaRWaADm3k3g0NtoPIgeGM+VVeOBdUowTx0YSXnT8mQEXcE9lWXX+ZX3biAzQwDM1w==
|
||||
rc-picker@~2.6.8:
|
||||
version "2.6.9"
|
||||
resolved "https://registry.yarnpkg.com/rc-picker/-/rc-picker-2.6.9.tgz#2f2f82c5340adbe3b30875a25e015c120eb88c9c"
|
||||
integrity sha512-yH3UYXCADf7REtOAB5cwe1cyFKtB0p204RCN8JdZGG4uuSOZ1IPTkk/GJS6HOpxspZeJCLGzzajuQMDwck9dsw==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.10.1"
|
||||
classnames "^2.2.1"
|
||||
@@ -11514,10 +11480,10 @@ rc-picker@~2.6.4:
|
||||
rc-util "^5.4.0"
|
||||
shallowequal "^1.1.0"
|
||||
|
||||
rc-progress@~3.2.1:
|
||||
version "3.2.4"
|
||||
resolved "https://registry.yarnpkg.com/rc-progress/-/rc-progress-3.2.4.tgz#4036acdae2566438545bc4df2203248babaf7549"
|
||||
integrity sha512-M9WWutRaoVkPUPIrTpRIDpX0SPSrVHzxHdCRCbeoBFrd9UFWTYNWRlHsruJM5FH1AZI+BwB4wOJUNNylg/uFSw==
|
||||
rc-progress@~3.3.2:
|
||||
version "3.3.3"
|
||||
resolved "https://registry.yarnpkg.com/rc-progress/-/rc-progress-3.3.3.tgz#eb9bffbacab1534f2542f9f6861ce772254362b1"
|
||||
integrity sha512-MDVNVHzGanYtRy2KKraEaWeZLri2ZHWIRyaE1a9MQ2MuJ09m+Wxj5cfcaoaR6z5iRpHpA59YeUxAlpML8N4PJw==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.10.1"
|
||||
classnames "^2.2.6"
|
||||
@@ -11572,7 +11538,7 @@ rc-scroll-anim@^2.7.6:
|
||||
react-lifecycles-compat "^3.0.4"
|
||||
tween-functions "1.x"
|
||||
|
||||
"rc-segmented@~2.1.0 ":
|
||||
rc-segmented@~2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/rc-segmented/-/rc-segmented-2.1.0.tgz#0e0afe646c1a0e44a0e18785f518c42633ec8efc"
|
||||
integrity sha512-hUlonro+pYoZcwrH6Vm56B2ftLfQh046hrwif/VwLIw1j3zGt52p5mREBwmeVzXnSwgnagpOpfafspzs1asjGw==
|
||||
@@ -11635,15 +11601,15 @@ rc-table@~7.24.0:
|
||||
rc-util "^5.14.0"
|
||||
shallowequal "^1.1.0"
|
||||
|
||||
rc-tabs@~11.13.0:
|
||||
version "11.13.0"
|
||||
resolved "https://registry.yarnpkg.com/rc-tabs/-/rc-tabs-11.13.0.tgz#083eed578f8ad02dc0d462d73da487fe32e3a573"
|
||||
integrity sha512-aUw1Pq0B1a2zGX4o/m3yrQycZcCLgDp6gKwn8IAU07q148RRONsVGxi0oLVVe5SE51kOB+j0bk1RX43ZBdZNgA==
|
||||
rc-tabs@~11.16.0:
|
||||
version "11.16.0"
|
||||
resolved "https://registry.yarnpkg.com/rc-tabs/-/rc-tabs-11.16.0.tgz#12447069ea1dc480c729e1e40661cfbd46ac4efe"
|
||||
integrity sha512-CIDPv3lHaXSHTJevmFP2eHoD3Hq9psfKbOZYf6D4FYPACloNGHpz44y3RGeJgataQ7omFLrGBm3dOBMUki87tA==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.11.2"
|
||||
classnames "2.x"
|
||||
rc-dropdown "~3.5.0"
|
||||
rc-menu "~9.5.1"
|
||||
rc-dropdown "~4.0.0"
|
||||
rc-menu "~9.6.0"
|
||||
rc-resize-observer "^1.0.0"
|
||||
rc-util "^5.5.0"
|
||||
|
||||
@@ -11665,27 +11631,27 @@ rc-tooltip@^5.0.1, rc-tooltip@~5.1.1:
|
||||
"@babel/runtime" "^7.11.2"
|
||||
rc-trigger "^5.0.0"
|
||||
|
||||
rc-tree-select@~5.3.0:
|
||||
version "5.3.0"
|
||||
resolved "https://registry.yarnpkg.com/rc-tree-select/-/rc-tree-select-5.3.0.tgz#6edd19d1066ad2bfa212f043c3ff701b93828026"
|
||||
integrity sha512-UN6CUBulmch+CsihnJ73+DtWijEB1hVTC8sdVxq6E0teVAkHQZUvDj+cwZShtShAKvWwXy73PZ1hIHEUrmVcKw==
|
||||
rc-tree-select@~5.4.0:
|
||||
version "5.4.0"
|
||||
resolved "https://registry.yarnpkg.com/rc-tree-select/-/rc-tree-select-5.4.0.tgz#c94b961aca68689f5ee3a43e33881cf693d195ef"
|
||||
integrity sha512-reRbOqC7Ic/nQocJAJeCl4n6nJUY3NoqiwRXKvhjgZJU7NGr9vIccXEsY+Lghkw5UMpPoxGsIJB0jiAvM18XYA==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.10.1"
|
||||
classnames "2.x"
|
||||
rc-select "~14.1.0"
|
||||
rc-tree "~5.5.0"
|
||||
rc-tree "~5.6.1"
|
||||
rc-util "^5.16.1"
|
||||
|
||||
rc-tree@~5.5.0:
|
||||
version "5.5.0"
|
||||
resolved "https://registry.yarnpkg.com/rc-tree/-/rc-tree-5.5.0.tgz#ba7c8aea2ad29f40a9c7168e490300f7a50c0f22"
|
||||
integrity sha512-vpKeFsDyj7weik8UPseCTaSNAPt939qn1dQd8goSbRDajbjJEja0v/WFXyRhOiF1HLemNTfqMz4MYc9qlqyNXg==
|
||||
rc-tree@~5.6.1, rc-tree@~5.6.3, rc-tree@~5.6.4:
|
||||
version "5.6.5"
|
||||
resolved "https://registry.yarnpkg.com/rc-tree/-/rc-tree-5.6.5.tgz#1947337fc48f3fe20fabaafb1aed3e4ff1ce71b4"
|
||||
integrity sha512-Bnyen46B251APyRZ9D/jYeTnSqbSEvK2AkU5B4vWkNYgUJNPrxO+VMgcDRedP/8N7YcsgdDT9hxqVvNOq7oCAQ==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.10.1"
|
||||
classnames "2.x"
|
||||
rc-motion "^2.0.1"
|
||||
rc-util "^5.16.1"
|
||||
rc-virtual-list "^3.4.2"
|
||||
rc-virtual-list "^3.4.8"
|
||||
|
||||
rc-trigger@^5.0.0, rc-trigger@^5.0.4, rc-trigger@^5.1.2, rc-trigger@^5.2.10:
|
||||
version "5.2.10"
|
||||
@@ -11698,6 +11664,17 @@ rc-trigger@^5.0.0, rc-trigger@^5.0.4, rc-trigger@^5.1.2, rc-trigger@^5.2.10:
|
||||
rc-motion "^2.0.0"
|
||||
rc-util "^5.5.0"
|
||||
|
||||
rc-trigger@^5.3.1:
|
||||
version "5.3.1"
|
||||
resolved "https://registry.yarnpkg.com/rc-trigger/-/rc-trigger-5.3.1.tgz#acafadf3eaf384e7f466c303bfa0f34c8137d7b8"
|
||||
integrity sha512-5gaFbDkYSefZ14j2AdzucXzlWgU2ri5uEjkHvsf1ynRhdJbKxNOnw4PBZ9+FVULNGFiDzzlVF8RJnR9P/xrnKQ==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.18.3"
|
||||
classnames "^2.2.6"
|
||||
rc-align "^4.0.0"
|
||||
rc-motion "^2.0.0"
|
||||
rc-util "^5.19.2"
|
||||
|
||||
rc-tween-one@^1.2.5:
|
||||
version "1.8.1"
|
||||
resolved "https://registry.yarnpkg.com/rc-tween-one/-/rc-tween-one-1.8.1.tgz#5b3b464b9bf2c369efc16c816cccf57bc16ae253"
|
||||
@@ -11749,6 +11726,15 @@ rc-util@^5.17.0, rc-util@^5.18.1:
|
||||
react-is "^16.12.0"
|
||||
shallowequal "^1.1.0"
|
||||
|
||||
rc-util@^5.19.2:
|
||||
version "5.21.5"
|
||||
resolved "https://registry.yarnpkg.com/rc-util/-/rc-util-5.21.5.tgz#6e2a5699f820ba915f43f11a4b7dfb0b0672d0fa"
|
||||
integrity sha512-ip7HqX37Cy/RDl9MlrFp+FbcKnsWZ22sF5MS5eSpYLtg5MpC0TMqGb5ukBatoOhgjnLL+eJGR6e7YAJ/dhK09A==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.18.3"
|
||||
react-is "^16.12.0"
|
||||
shallowequal "^1.1.0"
|
||||
|
||||
rc-util@^5.20.0, rc-util@^5.20.1, rc-util@^5.21.0:
|
||||
version "5.21.4"
|
||||
resolved "https://registry.yarnpkg.com/rc-util/-/rc-util-5.21.4.tgz#61e24ad297f679ca0796b618a3ef30eca959d904"
|
||||
@@ -11767,14 +11753,14 @@ rc-virtual-list@^3.2.0:
|
||||
rc-resize-observer "^1.0.0"
|
||||
rc-util "^5.0.7"
|
||||
|
||||
rc-virtual-list@^3.4.2:
|
||||
version "3.4.4"
|
||||
resolved "https://registry.yarnpkg.com/rc-virtual-list/-/rc-virtual-list-3.4.4.tgz#be42832edecdcffc56260df131e437a2e0473bca"
|
||||
integrity sha512-Zb2h0B+ZhA/aysZNEUkQYaqx0hd8hq7WMIUegII+1KfFjh99GtHZ4ZMWB+SlpdVadskKJZzUWWzIq5N1mE6AVg==
|
||||
rc-virtual-list@^3.4.8:
|
||||
version "3.4.8"
|
||||
resolved "https://registry.yarnpkg.com/rc-virtual-list/-/rc-virtual-list-3.4.8.tgz#c24c10c6940546b7e2a5e9809402c6716adfd26c"
|
||||
integrity sha512-qSN+Rv4i/E7RCTvTMr1uZo7f3crJJg/5DekoCagydo9zsXrxj07zsFSxqizqW+ldGA16lwa8So/bIbV9Ofjddg==
|
||||
dependencies:
|
||||
classnames "^2.2.6"
|
||||
rc-resize-observer "^1.0.0"
|
||||
rc-util "^5.0.7"
|
||||
rc-util "^5.15.0"
|
||||
|
||||
react-app-polyfill@^2.0.0:
|
||||
version "2.0.0"
|
||||
@@ -11879,10 +11865,10 @@ react-dom@^17.0.2:
|
||||
object-assign "^4.1.1"
|
||||
scheduler "^0.20.2"
|
||||
|
||||
react-drag-listview@^0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/react-drag-listview/-/react-drag-listview-0.2.0.tgz#b672d1d98ec98a642472c678af2cbfa7e513e277"
|
||||
integrity sha512-YHVxC71QIfakFFGA3ejpPe3fcQYomXBA5M3Z2nEBs7JScfc+dx3kq4xB8dzPHy240lI5213nemoogiL7ZCNsEg==
|
||||
react-drag-listview@^0.2.1:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/react-drag-listview/-/react-drag-listview-0.2.1.tgz#922fa3c37ed4d84f2a349a93b01a623ac565f7dc"
|
||||
integrity sha512-LFR/14CpmiieITCywfe2rxAg1szAqsynpqgquSgirT9cansDwJdpqAVEjzIRSEql/DRIYTvBYLvMI/HJcVeU4w==
|
||||
dependencies:
|
||||
babel-runtime "^6.26.0"
|
||||
prop-types "^15.5.8"
|
||||
@@ -11924,19 +11910,19 @@ react-grid-layout@^1.3.4:
|
||||
react-draggable "^4.0.0"
|
||||
react-resizable "^3.0.4"
|
||||
|
||||
react-i18next@^11.16.9:
|
||||
version "11.16.9"
|
||||
resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-11.16.9.tgz#890cdac0c49120e075d6c520b43dbad3f91bd2df"
|
||||
integrity sha512-euXxWvcEAvsY7ZVkwx9ztCq4butqtsGHEkpkuo0RMj8Ru09IF9o2KxCyN+zyv51Nr0aBh/elaTIiR6fMb8YfVg==
|
||||
react-i18next@^11.17.0:
|
||||
version "11.17.0"
|
||||
resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-11.17.0.tgz#44a0689dac7903352733e40303b743fa465eb797"
|
||||
integrity sha512-ewq2S4bVUTRqOMAdM/XvzCn9xUPIryzeBQRghmJ8lC6VI/8Kp7z1GwoLyt8j7GB2ywhN2SjPk7LU4sHzVeu7aw==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.14.5"
|
||||
html-escaper "^2.0.2"
|
||||
html-parse-stringify "^3.0.1"
|
||||
|
||||
react-icons@^4.3.1:
|
||||
version "4.3.1"
|
||||
resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-4.3.1.tgz#2fa92aebbbc71f43d2db2ed1aed07361124e91ca"
|
||||
integrity sha512-cB10MXLTs3gVuXimblAdI71jrJx8njrJZmNMEMC+sQu5B/BIOmlsAjskdqpn81y8UBVEGuHODd7/ci5DvoSzTQ==
|
||||
react-icons@^4.4.0:
|
||||
version "4.4.0"
|
||||
resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-4.4.0.tgz#a13a8a20c254854e1ec9aecef28a95cdf24ef703"
|
||||
integrity sha512-fSbvHeVYo/B5/L4VhB7sBA1i2tS8MkT0Hb9t2H1AVPkwGfVHLJCqyr2Py9dKMxsyM63Eng1GkdZfbWj+Fmv8Rg==
|
||||
|
||||
react-images@^0.5.16:
|
||||
version "0.5.19"
|
||||
@@ -12265,14 +12251,11 @@ recharts-scale@^0.4.4:
|
||||
dependencies:
|
||||
decimal.js-light "^2.4.1"
|
||||
|
||||
recharts@^2.1.9:
|
||||
version "2.1.9"
|
||||
resolved "https://registry.yarnpkg.com/recharts/-/recharts-2.1.9.tgz#a52d411a7d822d118f7754cfc9c50db8fab46fb9"
|
||||
integrity sha512-VozH5uznUvGqD7n224FGj7cmMAenlS0HPCs+7r2HeeHiQK6un6z0CTZfWVAB860xbcr4m+BN/EGMPZmYWd34Rg==
|
||||
recharts@^2.1.10:
|
||||
version "2.1.10"
|
||||
resolved "https://registry.yarnpkg.com/recharts/-/recharts-2.1.10.tgz#4253f4354fcb9328a162f66d7c5c8d33ef7741db"
|
||||
integrity sha512-me6c8m2Gs88X/nuM2gDSTDIhpSLNMbiTrlE4Cu53hjZNegT3g3xLlTrbYSAQuBCFWuWJAZXCmEuMr6AwizLyaA==
|
||||
dependencies:
|
||||
"@types/d3-interpolate" "^2.0.0"
|
||||
"@types/d3-scale" "^3.0.0"
|
||||
"@types/d3-shape" "^2.0.0"
|
||||
classnames "^2.2.5"
|
||||
d3-interpolate "^2.0.0"
|
||||
d3-scale "^3.0.0"
|
||||
@@ -12477,10 +12460,10 @@ requires-port@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
|
||||
integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=
|
||||
|
||||
reselect@^4.1.5:
|
||||
version "4.1.5"
|
||||
resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.1.5.tgz#852c361247198da6756d07d9296c2b51eddb79f6"
|
||||
integrity sha512-uVdlz8J7OO+ASpBYoz1Zypgx0KasCY20H+N8JD13oUMtPvSHQuscrHop4KbXrbsBcdB9Ds7lVK7eRkBIfO43vQ==
|
||||
reselect@^4.1.6:
|
||||
version "4.1.6"
|
||||
resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.1.6.tgz#19ca2d3d0b35373a74dc1c98692cdaffb6602656"
|
||||
integrity sha512-ZovIuXqto7elwnxyXbBtCPo9YFEr3uJqj2rRbcOOog1bmu2Ag85M4hixSwFWyaBMKXNgvPaJ9OSu9SkBPIeJHQ==
|
||||
|
||||
resize-observer-polyfill@^1.5.0, resize-observer-polyfill@^1.5.1:
|
||||
version "1.5.1"
|
||||
@@ -12828,10 +12811,10 @@ select-hose@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca"
|
||||
integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=
|
||||
|
||||
"selenium-webdriver@ 4.1.1":
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-4.1.1.tgz#da083177d811f36614950e809e2982570f67d02e"
|
||||
integrity sha512-Fr9e9LC6zvD6/j7NO8M1M/NVxFX67abHcxDJoP5w2KN/Xb1SyYLjMVPGgD14U2TOiKe4XKHf42OmFw9g2JgCBQ==
|
||||
selenium-webdriver@4.1.2:
|
||||
version "4.1.2"
|
||||
resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-4.1.2.tgz#d463b4335632d2ea41a9e988e435a55dc41f5314"
|
||||
integrity sha512-e4Ap8vQvhipgBB8Ry9zBiKGkU6kHKyNnWiavGGLKkrdW81Zv7NVMtFOL/j3yX0G8QScM7XIXijKssNd4EUxSOw==
|
||||
dependencies:
|
||||
jszip "^3.6.0"
|
||||
tmp "^0.2.1"
|
||||
@@ -13088,10 +13071,10 @@ snapdragon@^0.8.1:
|
||||
source-map-resolve "^0.5.0"
|
||||
use "^3.1.0"
|
||||
|
||||
socket.io-client@^4.5.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-4.5.0.tgz#3858b6183bab31c5c4eaf3efd0fa50840ebb4504"
|
||||
integrity sha512-HW61c1G7OrYGxaI79WRn17+b03iBCdvhBj4iqyXHBoL5M8w2MSO/vChsjA93knG4GYEai1/vbXWJna9dzxXtSg==
|
||||
socket.io-client@^4.5.1:
|
||||
version "4.5.1"
|
||||
resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-4.5.1.tgz#cab8da71976a300d3090414e28c2203a47884d84"
|
||||
integrity sha512-e6nLVgiRYatS+AHXnOnGi4ocOpubvOUCGhyWw8v+/FxW8saHkinG6Dfhi9TU0Kt/8mwJIAASxvw6eujQmjdZVA==
|
||||
dependencies:
|
||||
"@socket.io/component-emitter" "~3.1.0"
|
||||
debug "~4.3.2"
|
||||
@@ -13961,7 +13944,7 @@ tryer@^1.0.1:
|
||||
resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8"
|
||||
integrity sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==
|
||||
|
||||
ts-invariant@^0.10.0:
|
||||
ts-invariant@^0.10.3:
|
||||
version "0.10.3"
|
||||
resolved "https://registry.yarnpkg.com/ts-invariant/-/ts-invariant-0.10.3.tgz#3e048ff96e91459ffca01304dbc7f61c1f642f6c"
|
||||
integrity sha512-uivwYcQaxAucv1CzRp2n/QdYPo4ILf9VXgH19zEIjFx2EJufV16P0JtJVpYHy89DItG6Kwj2oIUjrcK5au+4tQ==
|
||||
@@ -14335,11 +14318,6 @@ use-memo-one@^1.1.1:
|
||||
resolved "https://registry.yarnpkg.com/use-memo-one/-/use-memo-one-1.1.2.tgz#0c8203a329f76e040047a35a1197defe342fab20"
|
||||
integrity sha512-u2qFKtxLsia/r8qG0ZKkbytbztzRb317XCkT7yP8wxL0tZ/CzK2G+WWie5vWvpyeP7+YoPIwbJoIHJ4Ba4k0oQ==
|
||||
|
||||
use-sync-external-store@^1.0.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.1.0.tgz#3343c3fe7f7e404db70f8c687adf5c1652d34e82"
|
||||
integrity sha512-SEnieB2FPKEVne66NpXPd1Np4R1lTNKfjuy3XdIoPQKYBAFdzbzSZlSn1KJZUiihQLQC5Znot4SBz1EOTBwQAQ==
|
||||
|
||||
use@^3.1.0:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f"
|
||||
@@ -15196,10 +15174,10 @@ yocto-queue@^0.1.0:
|
||||
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
|
||||
integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
|
||||
|
||||
zen-observable-ts@^1.2.0:
|
||||
version "1.2.3"
|
||||
resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-1.2.3.tgz#c2f5ccebe812faf0cfcde547e6004f65b1a6d769"
|
||||
integrity sha512-hc/TGiPkAWpByykMwDcem3SdUgA4We+0Qb36bItSuJC9xD0XVBZoFHYoadAomDSNf64CG8Ydj0Qb8Od8BUWz5g==
|
||||
zen-observable-ts@^1.2.5:
|
||||
version "1.2.5"
|
||||
resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-1.2.5.tgz#6c6d9ea3d3a842812c6e9519209365a122ba8b58"
|
||||
integrity sha512-QZWQekv6iB72Naeake9hS1KxHlotfRpe+WGNbNx5/ta+R3DNjVO2bswf63gXlWDcs+EMd7XY8HfVQyP1X6T4Zg==
|
||||
dependencies:
|
||||
zen-observable "0.8.15"
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
Must set the environment variables using:
|
||||
|
||||
firebase functions:config:set auth.graphql_endpoint="https://bodyshop-dev-db.herokuapp.com/v1/graphql" auth.hasura_secret_admin_key="Dev-BodyShopApp!"
|
||||
firebase functions:config:set auth.graphql_endpoint="https://db.development.bodyshop.app/v1/graphql" auth.hasura_secret_admin_key="Dev-BodyShopApp!"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
version: 2
|
||||
endpoint: https://bodyshop-dev-db.herokuapp.com
|
||||
endpoint: https://db.development.bodyshop.app
|
||||
admin_secret: Dev-BodyShopApp!
|
||||
metadata_directory: metadata
|
||||
actions:
|
||||
|
||||
@@ -2166,11 +2166,14 @@
|
||||
- actual_cost
|
||||
- actual_price
|
||||
- billlineid
|
||||
- comment
|
||||
- consumedbybillid
|
||||
- created_at
|
||||
- id
|
||||
- joblineid
|
||||
- line_desc
|
||||
- manualinvoicenumber
|
||||
- manualvendor
|
||||
- quantity
|
||||
- shopid
|
||||
- updated_at
|
||||
@@ -2182,11 +2185,14 @@
|
||||
- actual_cost
|
||||
- actual_price
|
||||
- billlineid
|
||||
- comment
|
||||
- consumedbybillid
|
||||
- created_at
|
||||
- id
|
||||
- joblineid
|
||||
- line_desc
|
||||
- manualinvoicenumber
|
||||
- manualvendor
|
||||
- quantity
|
||||
- shopid
|
||||
- updated_at
|
||||
@@ -2207,11 +2213,14 @@
|
||||
- actual_cost
|
||||
- actual_price
|
||||
- billlineid
|
||||
- comment
|
||||
- consumedbybillid
|
||||
- created_at
|
||||
- id
|
||||
- joblineid
|
||||
- line_desc
|
||||
- manualinvoicenumber
|
||||
- manualvendor
|
||||
- quantity
|
||||
- shopid
|
||||
- updated_at
|
||||
@@ -2225,6 +2234,18 @@
|
||||
- active:
|
||||
_eq: true
|
||||
check: null
|
||||
delete_permissions:
|
||||
- role: user
|
||||
permission:
|
||||
filter:
|
||||
bodyshop:
|
||||
associations:
|
||||
_and:
|
||||
- user:
|
||||
authid:
|
||||
_eq: X-Hasura-User-Id
|
||||
- active:
|
||||
_eq: true
|
||||
- table:
|
||||
schema: public
|
||||
name: ioevents
|
||||
@@ -2363,6 +2384,7 @@
|
||||
- bett_tax
|
||||
- bett_type
|
||||
- cert_part
|
||||
- convertedtolbr
|
||||
- created_at
|
||||
- db_hrs
|
||||
- db_price
|
||||
@@ -2426,6 +2448,7 @@
|
||||
- bett_tax
|
||||
- bett_type
|
||||
- cert_part
|
||||
- convertedtolbr
|
||||
- created_at
|
||||
- db_hrs
|
||||
- db_price
|
||||
@@ -2500,6 +2523,7 @@
|
||||
- bett_tax
|
||||
- bett_type
|
||||
- cert_part
|
||||
- convertedtolbr
|
||||
- created_at
|
||||
- db_hrs
|
||||
- db_price
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
-- Could not auto-generate a down migration.
|
||||
-- Please write an appropriate down migration for the SQL below:
|
||||
-- alter table "public"."inventory" add column "manualinvoicenumber" text
|
||||
-- null;
|
||||
@@ -0,0 +1,2 @@
|
||||
alter table "public"."inventory" add column "manualinvoicenumber" text
|
||||
null;
|
||||
@@ -0,0 +1,4 @@
|
||||
-- Could not auto-generate a down migration.
|
||||
-- Please write an appropriate down migration for the SQL below:
|
||||
-- alter table "public"."inventory" add column "comment" text
|
||||
-- null;
|
||||
@@ -0,0 +1,2 @@
|
||||
alter table "public"."inventory" add column "comment" text
|
||||
null;
|
||||
@@ -0,0 +1,4 @@
|
||||
-- Could not auto-generate a down migration.
|
||||
-- Please write an appropriate down migration for the SQL below:
|
||||
-- alter table "public"."inventory" add column "manualvendor" text
|
||||
-- null;
|
||||
@@ -0,0 +1,2 @@
|
||||
alter table "public"."inventory" add column "manualvendor" text
|
||||
null;
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TABLE "public"."inventory" ALTER COLUMN "quantity" drop default;
|
||||
@@ -0,0 +1 @@
|
||||
alter table "public"."inventory" alter column "quantity" set default '1';
|
||||
@@ -0,0 +1,4 @@
|
||||
-- Could not auto-generate a down migration.
|
||||
-- Please write an appropriate down migration for the SQL below:
|
||||
-- alter table "public"."joblines" add column "convertedtolbr" boolean
|
||||
-- not null default 'false';
|
||||
@@ -0,0 +1,2 @@
|
||||
alter table "public"."joblines" add column "convertedtolbr" boolean
|
||||
not null default 'false';
|
||||
4940
package-lock.json
generated
4940
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
20
server.js
20
server.js
@@ -36,6 +36,8 @@ const io = new Server(server, {
|
||||
"https://www.imex.online",
|
||||
],
|
||||
methods: ["GET", "POST"],
|
||||
credentials: true,
|
||||
exposedHeaders: ["set-cookie"],
|
||||
},
|
||||
});
|
||||
exports.io = io;
|
||||
@@ -48,7 +50,7 @@ app.use(bodyParser.json({ limit: "50mb" }));
|
||||
app.use(bodyParser.urlencoded({ limit: "50mb", extended: true }));
|
||||
//app.use(enforce.HTTPS({ trustProtoHeader: true }));
|
||||
app.use(
|
||||
cors()
|
||||
cors({ credentials: true, exposedHeaders: ["set-cookie"] })
|
||||
// cors({
|
||||
// credentials: true,
|
||||
// origin: [
|
||||
@@ -155,7 +157,21 @@ app.post(
|
||||
fb.unsubscribe
|
||||
);
|
||||
app.post("/adm/updateuser", fb.validateFirebaseIdToken, fb.updateUser);
|
||||
app.post("/adm/getuser", fb.validateFirebaseIdToken, fb.getUser);
|
||||
app.post("/adm/createuser", fb.validateFirebaseIdToken, fb.createUser);
|
||||
const adm = require("./server/admin/adminops");
|
||||
app.post(
|
||||
"/adm/createassociation",
|
||||
fb.validateFirebaseIdToken,
|
||||
fb.validateAdmin,
|
||||
adm.createAssociation
|
||||
);
|
||||
app.post(
|
||||
"/adm/createshop",
|
||||
fb.validateFirebaseIdToken,
|
||||
fb.validateAdmin,
|
||||
adm.createShop
|
||||
);
|
||||
|
||||
//Stripe Processing
|
||||
var stripe = require("./server/stripe/payment");
|
||||
@@ -214,7 +230,7 @@ server.listen(port, (error) => {
|
||||
if (error) throw error;
|
||||
logger.log(
|
||||
`[${process.env.NODE_ENV || "DEVELOPMENT"}] Server running on port ${port}`,
|
||||
"DEBUG",
|
||||
"INFO",
|
||||
"api"
|
||||
);
|
||||
});
|
||||
|
||||
@@ -179,7 +179,6 @@ exports.default = async (req, res) => {
|
||||
ret.push({ paymentid: payment.id, success: true });
|
||||
} catch (error) {
|
||||
logger.log("qbo-payment-create-error", "ERROR", req.user.email, {
|
||||
|
||||
error:
|
||||
(error && error.authResponse && error.authResponse.body) ||
|
||||
(error && error.message),
|
||||
@@ -217,7 +216,10 @@ exports.default = async (req, res) => {
|
||||
res.status(200).json(ret);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
logger.log("qbo-payment-create-error", "ERROR", req.user.email, { error: error.message, stack: error.stack });
|
||||
logger.log("qbo-payment-create-error", "ERROR", req.user.email, {
|
||||
error: error.message,
|
||||
stack: error.stack,
|
||||
});
|
||||
res.status(400).json(error);
|
||||
}
|
||||
};
|
||||
@@ -240,7 +242,7 @@ async function InsertPayment(
|
||||
|
||||
if (invoices && invoices.length !== 1) {
|
||||
throw new Error(
|
||||
`More than 1 invoice with DocNumber ${payment.ro_number} found.`
|
||||
`More than 1 invoice with DocNumber ${payment.job.ro_number} found.`
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -211,7 +211,7 @@ async function QueryInsuranceCo(oauthClient, qbo_realmId, req, job) {
|
||||
qbo_realmId,
|
||||
"query",
|
||||
`select * From Customer where DisplayName = '${StandardizeName(
|
||||
job.ins_co_nm
|
||||
job.ins_co_nm.trim()
|
||||
)}'`
|
||||
),
|
||||
method: "POST",
|
||||
@@ -239,7 +239,7 @@ async function InsertInsuranceCo(oauthClient, qbo_realmId, req, job, bodyshop) {
|
||||
const insCo = bodyshop.md_ins_cos.find((i) => i.name === job.ins_co_nm);
|
||||
|
||||
const Customer = {
|
||||
DisplayName: job.ins_co_nm,
|
||||
DisplayName: job.ins_co_nm.trim(),
|
||||
BillWithParent: true,
|
||||
BillAddr: {
|
||||
City: job.ownr_city,
|
||||
@@ -269,6 +269,7 @@ async function InsertInsuranceCo(oauthClient, qbo_realmId, req, job, bodyshop) {
|
||||
}
|
||||
}
|
||||
exports.InsertInsuranceCo = InsertInsuranceCo;
|
||||
|
||||
async function QueryOwner(oauthClient, qbo_realmId, req, job) {
|
||||
const ownerName = generateOwnerTier(job, true, null);
|
||||
const result = await oauthClient.makeApiCall({
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user