@controleonline/ui-common 1.2.70

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (203) hide show
  1. package/.github/agents/developer.agent.md +30 -0
  2. package/.github/agents/devops.agent.md +30 -0
  3. package/.github/agents/qa.agent.md +30 -0
  4. package/.github/agents/security.agent.md +30 -0
  5. package/.github/workflows/npmjs.yml +35 -0
  6. package/.github/workflows/pull-request-checks.yml +19 -0
  7. package/.scrutinizer.yml +24 -0
  8. package/FUNDING.yml +1 -0
  9. package/package.json +28 -0
  10. package/src/api/fetch.js +74 -0
  11. package/src/api/index.js +155 -0
  12. package/src/api/localDB.js +131 -0
  13. package/src/api/queue.js +66 -0
  14. package/src/react/assets/tap.mp3 +0 -0
  15. package/src/react/components/AddImportModal.js +157 -0
  16. package/src/react/components/AddImportModal.styles.js +81 -0
  17. package/src/react/components/BackgroundRuntimeBridge.js +219 -0
  18. package/src/react/components/BottomNavigationBar.config.js +238 -0
  19. package/src/react/components/BottomNavigationBar.js +120 -0
  20. package/src/react/components/BottomNavigationBar.styles.js +110 -0
  21. package/src/react/components/CategoryForm.js +572 -0
  22. package/src/react/components/CategoryForm.styles.js +334 -0
  23. package/src/react/components/ConfirmModal.js +24 -0
  24. package/src/react/components/ConfirmModal.styles.js +43 -0
  25. package/src/react/components/ContextHelpButton.js +69 -0
  26. package/src/react/components/ContextHelpButton.styles.js +62 -0
  27. package/src/react/components/DefaultProvider.native.js +848 -0
  28. package/src/react/components/DefaultProvider.styles.js +21 -0
  29. package/src/react/components/DefaultProvider.web.js +909 -0
  30. package/src/react/components/DeliveryPushBridge.native.js +314 -0
  31. package/src/react/components/DeliveryPushBridge.web.js +5 -0
  32. package/src/react/components/DeviceAlertSoundService.js +499 -0
  33. package/src/react/components/EntityLogContent.js +909 -0
  34. package/src/react/components/EntityLogContent.styles.js +400 -0
  35. package/src/react/components/EventBus.js +12 -0
  36. package/src/react/components/KioskModeBridge.js +65 -0
  37. package/src/react/components/LauncherModeBridge.js +47 -0
  38. package/src/react/components/LinkedOrderProductsTab.js +388 -0
  39. package/src/react/components/LinkedOrderProductsTab.styles.js +180 -0
  40. package/src/react/components/ManagerPushBridge.native.js +345 -0
  41. package/src/react/components/MessageService.js +314 -0
  42. package/src/react/components/Paywall/Google.js +89 -0
  43. package/src/react/components/PrintService.js +778 -0
  44. package/src/react/components/ProductCatalogCacheService.js +45 -0
  45. package/src/react/components/RemoteCheckoutService.js +292 -0
  46. package/src/react/components/RuntimeBottomNavigationBar.js +151 -0
  47. package/src/react/components/RuntimeInfoFooter.js +214 -0
  48. package/src/react/components/RuntimeInfoFooter.styles.js +56 -0
  49. package/src/react/components/SystemErrorToast.js +29 -0
  50. package/src/react/components/SystemErrorToast.styles.js +38 -0
  51. package/src/react/components/TouchFeedbackProvider.js +65 -0
  52. package/src/react/components/UnifiedPaymentBar.js +155 -0
  53. package/src/react/components/UnifiedPaymentBar.styles.js +174 -0
  54. package/src/react/components/WebsocketListener.native.js +487 -0
  55. package/src/react/components/WebsocketListener.web.js +102 -0
  56. package/src/react/components/inputs/IdInput.js +49 -0
  57. package/src/react/components/inputs/IdInput.styles.js +26 -0
  58. package/src/react/components/inputs/InvoiceDueDateFilterInput.js +74 -0
  59. package/src/react/components/inputs/InvoiceDueDateFilterInput.styles.js +34 -0
  60. package/src/react/components/inputs/InvoiceDueDateRangeFilterInput.js +115 -0
  61. package/src/react/components/inputs/InvoiceDueDateRangeFilterInput.styles.js +39 -0
  62. package/src/react/components/lists/CategoriesList.js +56 -0
  63. package/src/react/components/lists/PaymentTypeList.js +55 -0
  64. package/src/react/components/lists/ReceiverList.js +56 -0
  65. package/src/react/components/lists/SelectList.styles.js +18 -0
  66. package/src/react/components/lists/StatusList.js +55 -0
  67. package/src/react/components/lists/WalletList.js +54 -0
  68. package/src/react/components/radio/Spotify.js +144 -0
  69. package/src/react/components/radio/Spotify.styles.js +32 -0
  70. package/src/react/components/radio/YouTube.js +82 -0
  71. package/src/react/components/radio/YouTube.styles.js +16 -0
  72. package/src/react/components/toastConfig.js +16 -0
  73. package/src/react/config/deviceConfigBootstrap.js +571 -0
  74. package/src/react/index.js +4 -0
  75. package/src/react/localStorage.js +30 -0
  76. package/src/react/pages/EntityLogPage.js +124 -0
  77. package/src/react/pages/EntityLogPage.styles.js +17 -0
  78. package/src/react/pages/GenericLogPage.js +760 -0
  79. package/src/react/pages/GenericLogPage.styles.js +401 -0
  80. package/src/react/pages/Imports.js +361 -0
  81. package/src/react/pages/Imports.styles.js +223 -0
  82. package/src/react/pages/SettingsPage/PaymentTypesByWalletTab.js +462 -0
  83. package/src/react/pages/SettingsPage/index.js +1171 -0
  84. package/src/react/pages/SettingsPage/index.styles.js +122 -0
  85. package/src/react/print/jobs.js +147 -0
  86. package/src/react/print/providers/local.js +53 -0
  87. package/src/react/print/providers/remote.js +81 -0
  88. package/src/react/print/selection.js +296 -0
  89. package/src/react/print/usePrintButtonController.js +474 -0
  90. package/src/react/router/routes.js +42 -0
  91. package/src/react/services/NetworkPrinterService.native.js +391 -0
  92. package/src/react/services/NetworkPrinterService.web.js +15 -0
  93. package/src/react/stores/index.js +128 -0
  94. package/src/react/stores/storeErrorBridge.js +36 -0
  95. package/src/react/utils/backgroundRuntimeRegistration.js +69 -0
  96. package/src/react/utils/cashPayment.js +87 -0
  97. package/src/react/utils/commercialDocumentOrders.js +269 -0
  98. package/src/react/utils/dateRangeFilter.js +264 -0
  99. package/src/react/utils/deviceRuntime.js +193 -0
  100. package/src/react/utils/entityDisplay.js +231 -0
  101. package/src/react/utils/entityLog.js +649 -0
  102. package/src/react/utils/fileUrl.js +102 -0
  103. package/src/react/utils/frontendDebugLog.js +45 -0
  104. package/src/react/utils/googleMapsConfig.js +49 -0
  105. package/src/react/utils/importStatus.js +100 -0
  106. package/src/react/utils/invoiceDueDateMessages.js +14 -0
  107. package/src/react/utils/invoicePresentation.js +46 -0
  108. package/src/react/utils/logSettings.js +143 -0
  109. package/src/react/utils/maintenanceSettings.js +53 -0
  110. package/src/react/utils/managerOrderNotifications.js +523 -0
  111. package/src/react/utils/mapNavigation.js +76 -0
  112. package/src/react/utils/menuCatalogConfig.js +8 -0
  113. package/src/react/utils/menuCatalogDownload.js +157 -0
  114. package/src/react/utils/networkCameraDevices.js +175 -0
  115. package/src/react/utils/networkDeviceProfiles.js +135 -0
  116. package/src/react/utils/normalizedCatalogDownload.js +157 -0
  117. package/src/react/utils/notificationNavigation.js +94 -0
  118. package/src/react/utils/notificationSound.js +42 -0
  119. package/src/react/utils/paymentDevices.js +397 -0
  120. package/src/react/utils/paymentGatewayExecution.js +91 -0
  121. package/src/react/utils/paymentOptions.js +88 -0
  122. package/src/react/utils/peopleDisplay.js +39 -0
  123. package/src/react/utils/printerDevices.js +465 -0
  124. package/src/react/utils/remotePayment.js +61 -0
  125. package/src/react/utils/runtimeFooter.js +475 -0
  126. package/src/react/utils/runtimeLanguage.js +50 -0
  127. package/src/react/utils/runtimeMenu.js +224 -0
  128. package/src/react/utils/screenMetrics.js +30 -0
  129. package/src/react/utils/shopConfig.js +294 -0
  130. package/src/react/utils/shopFranchises.js +114 -0
  131. package/src/react/utils/socketRuntimePipeline.js +454 -0
  132. package/src/react/utils/spoolAckTracker.js +77 -0
  133. package/src/react/utils/storeColumns.js +427 -0
  134. package/src/react/utils/systemErrorChannel.js +109 -0
  135. package/src/react/utils/systemErrorMessage.js +67 -0
  136. package/src/react/utils/toastPresentation.js +53 -0
  137. package/src/react/utils/websocketSharedRuntime.js +826 -0
  138. package/src/store/acl/getters.js +4 -0
  139. package/src/store/acl/index.js +19 -0
  140. package/src/store/acl/mutation_types.js +4 -0
  141. package/src/store/acl/mutations.js +17 -0
  142. package/src/store/address/city.js +22 -0
  143. package/src/store/categories/category_file/index.js +25 -0
  144. package/src/store/categories/index.js +93 -0
  145. package/src/store/configs/customActions.js +131 -0
  146. package/src/store/configs/index.js +25 -0
  147. package/src/store/connections/customActions.js +26 -0
  148. package/src/store/connections/index.js +124 -0
  149. package/src/store/device/index.js +22 -0
  150. package/src/store/device_config/customActions.js +190 -0
  151. package/src/store/device_config/index.js +28 -0
  152. package/src/store/entity_log/customActions.js +63 -0
  153. package/src/store/entity_log/index.js +25 -0
  154. package/src/store/extra/data.js +85 -0
  155. package/src/store/extra/fields.js +88 -0
  156. package/src/store/file/actions.js +27 -0
  157. package/src/store/file/index.js +24 -0
  158. package/src/store/imports/index.js +88 -0
  159. package/src/store/print/customActions.js +251 -0
  160. package/src/store/print/index.js +28 -0
  161. package/src/store/printer/customActions.js +54 -0
  162. package/src/store/printer/index.js +26 -0
  163. package/src/store/runtime_debug/customActions.js +71 -0
  164. package/src/store/runtime_debug/index.js +30 -0
  165. package/src/store/status/index.js +65 -0
  166. package/src/store/timezones/index.js +43 -0
  167. package/src/store/websocket/customActions.js +24 -0
  168. package/src/store/websocket/index.js +28 -0
  169. package/src/tests/react/components/LauncherModeBridge.test.js +93 -0
  170. package/src/tests/react/config/deviceConfigBootstrap.test.js +337 -0
  171. package/src/tests/react/print/localPrintProvider.test.js +45 -0
  172. package/src/tests/react/utils/backgroundRuntimeRegistration.test.js +123 -0
  173. package/src/tests/react/utils/cashPayment.test.js +41 -0
  174. package/src/tests/react/utils/dateRangeFilter.test.mjs +29 -0
  175. package/src/tests/react/utils/entityDisplay.test.js +18 -0
  176. package/src/tests/react/utils/googleMapsConfig.test.js +32 -0
  177. package/src/tests/react/utils/importStatus.test.js +85 -0
  178. package/src/tests/react/utils/invoicePresentation.test.mjs +40 -0
  179. package/src/tests/react/utils/managerOrderNotifications.test.js +127 -0
  180. package/src/tests/react/utils/mapNavigation.test.js +58 -0
  181. package/src/tests/react/utils/notificationNavigation.test.js +39 -0
  182. package/src/tests/react/utils/notificationSound.test.js +27 -0
  183. package/src/tests/react/utils/paymentDevices.test.js +88 -0
  184. package/src/tests/react/utils/runtimeFooter.test.js +429 -0
  185. package/src/tests/react/utils/runtimeLanguage.test.js +80 -0
  186. package/src/tests/react/utils/runtimeMenu.test.js +174 -0
  187. package/src/tests/react/utils/shopFranchises.test.js +82 -0
  188. package/src/tests/react/utils/socketRuntimePipeline.test.js +124 -0
  189. package/src/tests/react/utils/spoolAckTracker.test.js +40 -0
  190. package/src/tests/react/utils/storeErrorBridge.test.js +66 -0
  191. package/src/tests/react/utils/systemErrorChannel.test.js +58 -0
  192. package/src/tests/react/utils/systemErrorMessage.test.js +59 -0
  193. package/src/tests/react/utils/toastPresentation.test.js +75 -0
  194. package/src/tests/react/utils/translate.test.mjs +396 -0
  195. package/src/tests/react/utils/websocketSharedRuntime.test.js +245 -0
  196. package/src/utils/apiEntryPoint.js +31 -0
  197. package/src/utils/appDomain.js +50 -0
  198. package/src/utils/config.js +14 -0
  199. package/src/utils/formatter.js +419 -0
  200. package/src/utils/integrationConfigs.js +79 -0
  201. package/src/utils/methods.js +23 -0
  202. package/src/utils/oauth.js +42 -0
  203. package/src/utils/translate.js +620 -0
@@ -0,0 +1,94 @@
1
+ const queuedNotificationRequests = [];
2
+ const queuedNotificationKeys = new Set();
3
+ let notificationNavigationHandler = null;
4
+
5
+ const normalizeText = value => String(value || '').trim();
6
+
7
+ const normalizeParams = params => {
8
+ if (!params || typeof params !== 'object' || Array.isArray(params)) {
9
+ return {};
10
+ }
11
+
12
+ return params;
13
+ };
14
+
15
+ const buildRequestKey = ({routeName, params}) => {
16
+ try {
17
+ return `${normalizeText(routeName)}::${JSON.stringify(normalizeParams(params))}`;
18
+ } catch {
19
+ return `${normalizeText(routeName)}::fallback`;
20
+ }
21
+ };
22
+
23
+ export const setNotificationNavigationHandler = handler => {
24
+ notificationNavigationHandler =
25
+ typeof handler === 'function' ? handler : null;
26
+
27
+ return () => {
28
+ if (notificationNavigationHandler === handler) {
29
+ notificationNavigationHandler = null;
30
+ }
31
+ };
32
+ };
33
+
34
+ export const flushNotificationNavigationQueue = () => {
35
+ if (typeof notificationNavigationHandler !== 'function') {
36
+ return false;
37
+ }
38
+
39
+ let handledAny = false;
40
+ const remainingRequests = [];
41
+
42
+ while (queuedNotificationRequests.length > 0) {
43
+ const request = queuedNotificationRequests.shift();
44
+ if (!request) {
45
+ continue;
46
+ }
47
+
48
+ try {
49
+ const handled =
50
+ notificationNavigationHandler(request.routeName, request.params) !== false;
51
+
52
+ if (handled) {
53
+ queuedNotificationKeys.delete(request.key);
54
+ handledAny = true;
55
+ } else {
56
+ remainingRequests.push(request);
57
+ }
58
+ } catch {
59
+ remainingRequests.push(request);
60
+ }
61
+ }
62
+
63
+ queuedNotificationRequests.push(...remainingRequests);
64
+ return handledAny;
65
+ };
66
+
67
+ export const queueNotificationNavigation = (routeName, params = {}) => {
68
+ const normalizedRouteName = normalizeText(routeName);
69
+ if (!normalizedRouteName) {
70
+ return false;
71
+ }
72
+
73
+ const request = {
74
+ routeName: normalizedRouteName,
75
+ params: normalizeParams(params),
76
+ };
77
+ request.key = buildRequestKey(request);
78
+
79
+ if (queuedNotificationKeys.has(request.key)) {
80
+ return false;
81
+ }
82
+
83
+ queuedNotificationKeys.add(request.key);
84
+ queuedNotificationRequests.push(request);
85
+ flushNotificationNavigationQueue();
86
+
87
+ return true;
88
+ };
89
+
90
+ export const clearNotificationNavigationQueue = () => {
91
+ queuedNotificationRequests.splice(0, queuedNotificationRequests.length);
92
+ queuedNotificationKeys.clear();
93
+ };
94
+
@@ -0,0 +1,42 @@
1
+ /*
2
+ * Regra do fallback de audio operacional
3
+ * - O som padrao dos alertas e `caixa.m4a`.
4
+ * - Quando nao houver URL customizada, este helper precisa resolver o asset
5
+ * empacotado para manter o aviso sonoro dos novos pedidos.
6
+ */
7
+
8
+ const DEFAULT_NOTIFICATION_SOUND_FILE = 'caixa.m4a';
9
+
10
+ let defaultNotificationSoundSource = null;
11
+
12
+ try {
13
+ // O asset fica empacotado no app e serve como fallback quando nao ha URL customizada.
14
+ defaultNotificationSoundSource = require('@controleonline/../../src/assets/sound/caixa.m4a');
15
+ } catch {
16
+ defaultNotificationSoundSource = null;
17
+ }
18
+
19
+ const normalizeText = value => String(value || '').trim();
20
+
21
+ const resolveNotificationSoundSource = (
22
+ soundUrl,
23
+ fallbackSource = defaultNotificationSoundSource,
24
+ ) => {
25
+ if (typeof soundUrl === 'number') {
26
+ return soundUrl;
27
+ }
28
+
29
+ if (soundUrl && typeof soundUrl === 'object') {
30
+ return soundUrl;
31
+ }
32
+
33
+ const normalizedSoundUrl = normalizeText(soundUrl);
34
+
35
+ return normalizedSoundUrl || fallbackSource;
36
+ };
37
+
38
+ export {
39
+ DEFAULT_NOTIFICATION_SOUND_FILE,
40
+ defaultNotificationSoundSource as DEFAULT_NOTIFICATION_SOUND_SOURCE,
41
+ resolveNotificationSoundSource,
42
+ };
@@ -0,0 +1,397 @@
1
+ import {Platform} from 'react-native';
2
+
3
+ export const PAYMENT_GATEWAY_CIELO = 'cielo';
4
+ export const PAYMENT_GATEWAY_INFINITE_PAY = 'infinite-pay';
5
+ export const PAYMENT_GATEWAYS = [
6
+ PAYMENT_GATEWAY_CIELO,
7
+ PAYMENT_GATEWAY_INFINITE_PAY,
8
+ ];
9
+ export const POS_GATEWAY_CONFIG_KEY = 'pos-gateway';
10
+ export const PDV_PRINTER_ENABLED_CONFIG_KEY = 'printer-enabled';
11
+ export const ORDER_PAYMENT_DEVICES_CONFIG_KEY = 'order-payment-devices';
12
+ export const ORDER_PAYMENT_DEVICE_CONFIG_KEY = 'order-payment-device';
13
+ export const ORDER_PAYMENT_DEVICE_CHANGE_ALLOWED_CONFIG_KEY =
14
+ 'order-payment-device-change-allowed';
15
+ export const ORDER_CHARGE_ON_DELIVERY_ENABLED_CONFIG_KEY =
16
+ 'order-charge-on-delivery-enabled';
17
+ export const PAYMENT_TYPE_IDS_CONFIG_KEY = 'payment-type-ids';
18
+
19
+ const parseJsonValue = (value, fallback) => {
20
+ if (value === null || value === undefined || value === '') {
21
+ return fallback;
22
+ }
23
+
24
+ if (typeof value === 'string') {
25
+ try {
26
+ return JSON.parse(value);
27
+ } catch {
28
+ return fallback;
29
+ }
30
+ }
31
+
32
+ return value;
33
+ };
34
+
35
+ export const normalizeDeviceId = value => String(value || '').trim();
36
+ export const normalizeEntityId = value =>
37
+ String(value?.id || value || '')
38
+ .replace(/\D/g, '')
39
+ .trim();
40
+
41
+ export const normalizeDeviceIds = value => {
42
+ const parsed = parseJsonValue(value, []);
43
+
44
+ if (Array.isArray(parsed)) {
45
+ return parsed.map(normalizeDeviceId).filter(Boolean);
46
+ }
47
+
48
+ const singleId = normalizeDeviceId(parsed);
49
+ return singleId ? [singleId] : [];
50
+ };
51
+
52
+ const normalizeDevicePaymentIds = value => {
53
+ if (value === null || value === undefined || value === '') {
54
+ return [];
55
+ }
56
+
57
+ let parsed = value;
58
+
59
+ if (typeof parsed === 'string') {
60
+ const trimmed = parsed.trim();
61
+
62
+ if (trimmed.startsWith('[') || trimmed.startsWith('{')) {
63
+ try {
64
+ parsed = JSON.parse(trimmed);
65
+ } catch {
66
+ parsed = trimmed;
67
+ }
68
+ } else {
69
+ parsed = trimmed;
70
+ }
71
+ }
72
+
73
+ const rawValues = Array.isArray(parsed)
74
+ ? parsed
75
+ : typeof parsed === 'string'
76
+ ? parsed.split(/[,\n;]/)
77
+ : [parsed];
78
+
79
+ return [...new Set(
80
+ rawValues
81
+ .map(walletValue =>
82
+ normalizeEntityId(
83
+ walletValue?.['@id'] || walletValue?.id || walletValue,
84
+ ),
85
+ )
86
+ .filter(Boolean),
87
+ )];
88
+ };
89
+
90
+ export const normalizePaymentTypeIds = normalizeDevicePaymentIds;
91
+
92
+ const resolveWalletPaymentTypeWalletId = walletPaymentType =>
93
+ normalizeEntityId(
94
+ walletPaymentType?.wallet?.['@id'] ||
95
+ walletPaymentType?.wallet?.id ||
96
+ walletPaymentType?.wallet ||
97
+ walletPaymentType?.walletId ||
98
+ walletPaymentType?.wallet_id,
99
+ );
100
+
101
+ const resolveWalletPaymentTypeId = walletPaymentType =>
102
+ normalizeEntityId(
103
+ walletPaymentType?.['@id'] || walletPaymentType?.id,
104
+ );
105
+
106
+ const parseConfigsObject = value => {
107
+ if (!value) {
108
+ return {};
109
+ }
110
+
111
+ if (typeof value === 'string') {
112
+ try {
113
+ const parsed = JSON.parse(value);
114
+ return parsed && typeof parsed === 'object' ? parsed : {};
115
+ } catch {
116
+ return {};
117
+ }
118
+ }
119
+
120
+ return typeof value === 'object' ? value : {};
121
+ };
122
+
123
+ const resolveConfigsSource = value => {
124
+ if (
125
+ value &&
126
+ typeof value === 'object' &&
127
+ !Array.isArray(value) &&
128
+ Object.prototype.hasOwnProperty.call(value, 'configs')
129
+ ) {
130
+ return value.configs;
131
+ }
132
+
133
+ return value;
134
+ };
135
+
136
+ export const normalizePaymentGateway = value => {
137
+ const rawGateway = String(value || '')
138
+ .trim()
139
+ .toLowerCase();
140
+
141
+ if (!rawGateway) {
142
+ return '';
143
+ }
144
+
145
+ const compactGateway = rawGateway.replace(/[\s_]/g, '-');
146
+ if (compactGateway === 'infinitepay') {
147
+ return PAYMENT_GATEWAY_INFINITE_PAY;
148
+ }
149
+ if (compactGateway === PAYMENT_GATEWAY_INFINITE_PAY) {
150
+ return PAYMENT_GATEWAY_INFINITE_PAY;
151
+ }
152
+ if (compactGateway === PAYMENT_GATEWAY_CIELO) {
153
+ return PAYMENT_GATEWAY_CIELO;
154
+ }
155
+
156
+ return compactGateway;
157
+ };
158
+
159
+ const normalizeDeviceType = value =>
160
+ String(value || '')
161
+ .trim()
162
+ .toUpperCase();
163
+
164
+ const isTruthyValue = value =>
165
+ value === true || value === '1' || value === 1 || value === 'true';
166
+
167
+ const resolveDeviceConfigDevice = deviceConfig => {
168
+ const nestedDevice = deviceConfig?.device;
169
+ if (nestedDevice && typeof nestedDevice === 'object') {
170
+ return nestedDevice;
171
+ }
172
+ if (typeof nestedDevice === 'string') {
173
+ return {device: nestedDevice};
174
+ }
175
+ return {};
176
+ };
177
+
178
+ const getDeviceConfigDeviceId = deviceConfig => {
179
+ const device = resolveDeviceConfigDevice(deviceConfig);
180
+ return normalizeDeviceId(
181
+ device?.device || deviceConfig?.deviceId || deviceConfig?.device_id || '',
182
+ );
183
+ };
184
+
185
+ const getDeviceConfigType = deviceConfig =>
186
+ normalizeDeviceType(deviceConfig?.type || deviceConfig?.device?.type);
187
+
188
+ export const filterDeviceConfigsByCompany = (deviceConfigs, companyId) => {
189
+ const normalizedCompanyId = normalizeEntityId(companyId);
190
+
191
+ return (Array.isArray(deviceConfigs) ? deviceConfigs : []).filter(
192
+ deviceConfig =>
193
+ !normalizedCompanyId ||
194
+ normalizeEntityId(deviceConfig?.people?.id || deviceConfig?.people) ===
195
+ normalizedCompanyId,
196
+ );
197
+ };
198
+
199
+ export const getPaymentGatewayFromConfigs = configs =>
200
+ normalizePaymentGateway(
201
+ parseConfigsObject(resolveConfigsSource(configs))?.[POS_GATEWAY_CONFIG_KEY],
202
+ );
203
+
204
+ export const getPaymentGateway = deviceConfig =>
205
+ getPaymentGatewayFromConfigs(deviceConfig);
206
+
207
+ export const isLocalCieloPrintCapableDeviceConfig = deviceConfig =>
208
+ getDeviceConfigType(deviceConfig) === 'PDV' &&
209
+ getPaymentGateway(deviceConfig) === PAYMENT_GATEWAY_CIELO;
210
+
211
+ export const isPdvPrinterEnabled = configs => {
212
+ const parsedConfigs = parseConfigsObject(resolveConfigsSource(configs));
213
+ const printerEnabled = parsedConfigs?.[PDV_PRINTER_ENABLED_CONFIG_KEY];
214
+
215
+ if (
216
+ printerEnabled === undefined ||
217
+ printerEnabled === null ||
218
+ printerEnabled === ''
219
+ ) {
220
+ return true;
221
+ }
222
+
223
+ return isTruthyValue(printerEnabled);
224
+ };
225
+
226
+ export const isOrderChargeOnDeliveryEnabled = configs =>
227
+ isTruthyValue(
228
+ parseConfigsObject(resolveConfigsSource(configs))?.[
229
+ ORDER_CHARGE_ON_DELIVERY_ENABLED_CONFIG_KEY
230
+ ],
231
+ );
232
+
233
+ export const isOrderPaymentDeviceChangeAllowed = configs =>
234
+ isTruthyValue(
235
+ parseConfigsObject(resolveConfigsSource(configs))?.[
236
+ ORDER_PAYMENT_DEVICE_CHANGE_ALLOWED_CONFIG_KEY
237
+ ],
238
+ );
239
+
240
+ export const resolveConfiguredPaymentTypeIds = configs => {
241
+ // The allowlist is keyed by wallet_payment_type id so the same payment type
242
+ // can stay independent across different wallets.
243
+ const parsedConfigs = parseConfigsObject(resolveConfigsSource(configs));
244
+ const configuredPaymentTypeIds = normalizePaymentTypeIds(
245
+ parsedConfigs?.[PAYMENT_TYPE_IDS_CONFIG_KEY],
246
+ );
247
+
248
+ return configuredPaymentTypeIds;
249
+ };
250
+
251
+ export const resolveDevicePaymentTypeIds = resolveConfiguredPaymentTypeIds;
252
+
253
+ export const filterWalletPaymentTypesByAllowedIds = (
254
+ walletPaymentTypes,
255
+ allowedPaymentTypeIds,
256
+ ) => {
257
+ const allowedPaymentTypeIdSet = new Set(
258
+ normalizePaymentTypeIds(allowedPaymentTypeIds),
259
+ );
260
+
261
+ if (allowedPaymentTypeIdSet.size === 0) {
262
+ return [];
263
+ }
264
+
265
+ return (Array.isArray(walletPaymentTypes) ? walletPaymentTypes : []).filter(
266
+ walletPaymentType =>
267
+ allowedPaymentTypeIdSet.has(
268
+ resolveWalletPaymentTypeId(walletPaymentType),
269
+ ),
270
+ );
271
+ };
272
+
273
+ export const groupWalletPaymentTypesByWalletId = walletPaymentTypes =>
274
+ (Array.isArray(walletPaymentTypes) ? walletPaymentTypes : []).reduce(
275
+ (grouped, walletPaymentType) => {
276
+ const walletId = resolveWalletPaymentTypeWalletId(walletPaymentType);
277
+
278
+ if (!walletId) {
279
+ grouped.__unassigned = grouped.__unassigned || [];
280
+ grouped.__unassigned.push(walletPaymentType);
281
+ return grouped;
282
+ }
283
+
284
+ if (!grouped[walletId]) {
285
+ grouped[walletId] = [];
286
+ }
287
+
288
+ grouped[walletId].push(walletPaymentType);
289
+ return grouped;
290
+ },
291
+ {},
292
+ );
293
+
294
+ export const isPaymentGateway = gateway => PAYMENT_GATEWAYS.includes(gateway);
295
+
296
+ export const isPaymentCapableDeviceConfig = deviceConfig =>
297
+ isPaymentGateway(getPaymentGateway(deviceConfig));
298
+
299
+ export const isRemotePaymentCapableDeviceConfig = deviceConfig =>
300
+ getDeviceConfigType(deviceConfig) === 'PDV' &&
301
+ isPaymentCapableDeviceConfig(deviceConfig);
302
+
303
+ export const getPaymentDeviceLabel = deviceConfig =>
304
+ resolveDeviceConfigDevice(deviceConfig)?.alias ||
305
+ resolveDeviceConfigDevice(deviceConfig)?.name ||
306
+ resolveDeviceConfigDevice(deviceConfig)?.device ||
307
+ 'Device sem nome';
308
+
309
+ export const getPaymentGatewayLabel = gateway => {
310
+ if (gateway === PAYMENT_GATEWAY_CIELO) return 'Cielo';
311
+ if (gateway === PAYMENT_GATEWAY_INFINITE_PAY) return 'Infinite Pay';
312
+ return 'Gateway nao configurado';
313
+ };
314
+
315
+ export const getCompanyPaymentDeviceOptions = deviceConfigs =>
316
+ (Array.isArray(deviceConfigs) ? deviceConfigs : [])
317
+ .filter(isRemotePaymentCapableDeviceConfig)
318
+ .map(deviceConfig => ({
319
+ alias: getPaymentDeviceLabel(deviceConfig),
320
+ deviceId: getDeviceConfigDeviceId(deviceConfig),
321
+ gateway: getPaymentGateway(deviceConfig),
322
+ gatewayLabel: getPaymentGatewayLabel(getPaymentGateway(deviceConfig)),
323
+ config: deviceConfig,
324
+ }))
325
+ .filter(option => option.deviceId);
326
+
327
+ export const resolveConfiguredRemotePaymentDeviceIds = ({
328
+ deviceConfig,
329
+ companyConfigs,
330
+ }) => {
331
+ const configuredCompanyDeviceIds = normalizeDeviceIds(
332
+ companyConfigs?.[ORDER_PAYMENT_DEVICES_CONFIG_KEY],
333
+ );
334
+
335
+ if (configuredCompanyDeviceIds.length > 0) {
336
+ return configuredCompanyDeviceIds;
337
+ }
338
+
339
+ const configs = parseConfigsObject(deviceConfig?.configs);
340
+ const preferredDeviceId = normalizeDeviceId(
341
+ configs?.[ORDER_PAYMENT_DEVICE_CONFIG_KEY],
342
+ );
343
+
344
+ return preferredDeviceId ? [preferredDeviceId] : [];
345
+ };
346
+
347
+ export const resolveRemotePaymentDeviceOptions = ({
348
+ deviceConfig,
349
+ deviceConfigs,
350
+ companyConfigs,
351
+ }) => {
352
+ const currentDeviceId = getDeviceConfigDeviceId(deviceConfig);
353
+ const availableOptions = getCompanyPaymentDeviceOptions(deviceConfigs).filter(
354
+ option => option.deviceId !== currentDeviceId,
355
+ );
356
+ const configuredDeviceIds = resolveConfiguredRemotePaymentDeviceIds({
357
+ deviceConfig,
358
+ companyConfigs,
359
+ });
360
+
361
+ if (!configuredDeviceIds.length) {
362
+ return availableOptions;
363
+ }
364
+
365
+ const availableOptionsMap = new Map(
366
+ availableOptions.map(option => [option.deviceId, option]),
367
+ );
368
+
369
+ const configuredOptions = configuredDeviceIds
370
+ .map(deviceId => availableOptionsMap.get(deviceId))
371
+ .filter(Boolean);
372
+
373
+ return configuredOptions.length > 0 ? configuredOptions : availableOptions;
374
+ };
375
+
376
+ export const supportsLocalCardPayment = ({deviceConfig, platform = Platform.OS}) =>
377
+ platform !== 'web' && isPaymentCapableDeviceConfig(deviceConfig);
378
+
379
+ export const buildWalletIdsForGateway = ({
380
+ gateway,
381
+ companyConfigs,
382
+ includeCashWallet = true,
383
+ }) => {
384
+ const walletIds = [];
385
+ const gatewayWallet = companyConfigs?.[`pos-${gateway}-wallet`];
386
+ const cashWallet = companyConfigs?.['pos-cash-wallet'];
387
+
388
+ if (gatewayWallet) {
389
+ walletIds.push(gatewayWallet);
390
+ }
391
+
392
+ if (includeCashWallet && cashWallet) {
393
+ walletIds.push(cashWallet);
394
+ }
395
+
396
+ return walletIds;
397
+ };
@@ -0,0 +1,91 @@
1
+ import {runCieloCheckoutPayment} from '@controleonline/ui-orders/src/react/services/Cielo/Checkout';
2
+ import {runInfinitePayCheckoutPayment} from '@controleonline/ui-orders/src/react/services/InfinitePay/Checkout';
3
+
4
+ import {
5
+ PAYMENT_GATEWAY_CIELO,
6
+ PAYMENT_GATEWAY_INFINITE_PAY,
7
+ } from './paymentDevices';
8
+
9
+ export const normalizeGatewayPaymentError = (
10
+ error,
11
+ fallback = 'Nao foi possivel concluir o pagamento.',
12
+ ) => {
13
+ if (typeof error === 'string' && error.trim()) {
14
+ return error;
15
+ }
16
+
17
+ if (typeof error?.message === 'string' && error.message.trim()) {
18
+ return error.message;
19
+ }
20
+
21
+ if (typeof error?.result === 'string' && error.result.trim()) {
22
+ return error.result;
23
+ }
24
+
25
+ if (typeof error?.error === 'string' && error.error.trim()) {
26
+ return error.error;
27
+ }
28
+
29
+ try {
30
+ const serialized = JSON.stringify(error);
31
+ return serialized && serialized !== '{}' ? serialized : fallback;
32
+ } catch {
33
+ return fallback;
34
+ }
35
+ };
36
+
37
+ export const runConfiguredGatewayPayment = async ({
38
+ gateway = '',
39
+ installments = null,
40
+ order = null,
41
+ orderProducts = [],
42
+ payment = null,
43
+ total = 0,
44
+ }) => {
45
+ const resolvedTotal = Number(total || 0);
46
+
47
+ if (!payment?.paymentCode) {
48
+ throw new Error('Meio de pagamento sem codigo de gateway.');
49
+ }
50
+
51
+ if (resolvedTotal <= 0) {
52
+ throw new Error('Informe um valor de pagamento valido.');
53
+ }
54
+
55
+ if (gateway === PAYMENT_GATEWAY_CIELO) {
56
+ const {response, paidAmount} = await runCieloCheckoutPayment({
57
+ orderProducts,
58
+ payment,
59
+ total: resolvedTotal,
60
+ });
61
+
62
+ if (!response?.success) {
63
+ throw new Error(normalizeGatewayPaymentError(response?.result));
64
+ }
65
+
66
+ return {
67
+ paidAmount,
68
+ response,
69
+ };
70
+ }
71
+
72
+ if (gateway === PAYMENT_GATEWAY_INFINITE_PAY) {
73
+ const {response, paidAmount} = await runInfinitePayCheckoutPayment({
74
+ installments,
75
+ order,
76
+ payment,
77
+ total: resolvedTotal,
78
+ });
79
+
80
+ if (!response?.success || response?.code === 1 || response?.code === 2) {
81
+ throw response;
82
+ }
83
+
84
+ return {
85
+ paidAmount,
86
+ response,
87
+ };
88
+ }
89
+
90
+ throw new Error('Gateway de pagamento indisponível neste equipamento.');
91
+ };
@@ -0,0 +1,88 @@
1
+ const normalizeText = value =>
2
+ String(value || '')
3
+ .trim()
4
+ .toLowerCase();
5
+
6
+ const normalizeEntityId = value => {
7
+ if (!value) {
8
+ return '';
9
+ }
10
+
11
+ if (typeof value === 'object') {
12
+ return normalizeEntityId(value?.['@id'] || value?.id);
13
+ }
14
+
15
+ return String(value).replace(/\D+/g, '').trim();
16
+ };
17
+
18
+ export const getPaymentOptionId = payment =>
19
+ normalizeEntityId(
20
+ payment?.paymentType?.['@id'] ||
21
+ payment?.paymentType?.id ||
22
+ payment?.paymentType ||
23
+ payment?.id,
24
+ );
25
+
26
+ export const getPaymentOptionWalletId = payment =>
27
+ normalizeEntityId(
28
+ payment?.wallet?.['@id'] ||
29
+ payment?.wallet?.id ||
30
+ payment?.wallet,
31
+ );
32
+
33
+ export const getInvoiceDestinationWalletId = invoice =>
34
+ normalizeEntityId(
35
+ invoice?.destinationWallet?.['@id'] ||
36
+ invoice?.destinationWallet?.id ||
37
+ invoice?.destinationWallet,
38
+ );
39
+
40
+ export const getPaymentOptionLabel = payment =>
41
+ String(
42
+ payment?.paymentType?.paymentType ||
43
+ payment?.paymentType?.name ||
44
+ payment?.paymentCode ||
45
+ 'Pagamento',
46
+ ).trim() || 'Pagamento';
47
+
48
+ export const getPaymentOptionWalletLabel = payment =>
49
+ String(
50
+ payment?.wallet?.wallet ||
51
+ '',
52
+ ).trim();
53
+
54
+ export const isIntegratedPaymentOption = payment =>
55
+ normalizeText(payment?.paymentCode) !== '';
56
+
57
+ export const detectPaymentOptionKind = payment => {
58
+ const text = normalizeText(
59
+ `${getPaymentOptionLabel(payment)} ${getPaymentOptionWalletLabel(payment)} ${payment?.paymentCode || ''}`,
60
+ );
61
+
62
+ if (text.includes('pix')) return 'pix';
63
+
64
+ if (
65
+ text.includes('cart') ||
66
+ text.includes('credito') ||
67
+ text.includes('credit') ||
68
+ text.includes('debito') ||
69
+ text.includes('debit')
70
+ ) {
71
+ return 'card';
72
+ }
73
+
74
+ if (
75
+ text.includes('dinh') ||
76
+ text.includes('cash') ||
77
+ text.includes('espec') ||
78
+ text.includes('moeda') ||
79
+ text.includes('papel')
80
+ ) {
81
+ return 'cash';
82
+ }
83
+
84
+ return 'other';
85
+ };
86
+
87
+ export const isCashPaymentOption = payment =>
88
+ detectPaymentOptionKind(payment) === 'cash';