@controleonline/ui-common 1.2.71 → 1.2.76

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 (150) hide show
  1. package/.github/actions/workers/manager/action.yml +147 -0
  2. package/.github/actions/workers/qa/action.yml +44 -0
  3. package/.github/actions/workers/security/action.yml +44 -0
  4. package/.github/actions/workers/technical-documenter/action.yml +51 -0
  5. package/.github/workflows/manager-worker.yml +168 -0
  6. package/.github/workflows/publish-npm.yml +45 -0
  7. package/.gitmodules +3 -0
  8. package/AGENTS.md +6 -0
  9. package/README.md +14 -0
  10. package/package.json +3 -2
  11. package/src/api/fetch.js +1 -1
  12. package/src/api/index.js +92 -22
  13. package/src/react/components/AddImportModal.js +94 -110
  14. package/src/react/components/BottomNavigationBar.config.js +211 -231
  15. package/src/react/components/CategoryForm.js +52 -35
  16. package/src/react/components/DefaultProvider.native.js +131 -95
  17. package/src/react/components/DefaultProvider.web.js +148 -74
  18. package/src/react/components/NetworkPrinterPreviewModal.js +249 -0
  19. package/src/react/components/NetworkPrinterPreviewModal.styles.js +159 -0
  20. package/src/react/components/RuntimeInfoFooter.js +164 -104
  21. package/src/react/components/RuntimeInfoFooter.styles.js +3 -0
  22. package/src/react/components/UnifiedPaymentBar.js +7 -4
  23. package/src/react/components/UserAvatar.js +160 -0
  24. package/src/react/components/integrations/IntegrationHero/index.js +48 -0
  25. package/src/react/components/integrations/IntegrationHero/styles.js +57 -0
  26. package/src/react/components/integrations/IntegrationTabs/index.js +89 -0
  27. package/src/react/components/integrations/IntegrationTabs/styles.js +44 -0
  28. package/src/react/config/deviceConfigBootstrap.js +5 -3
  29. package/src/react/pages/Connections.js +229 -0
  30. package/src/react/pages/Connections.styles.js +222 -0
  31. package/src/react/pages/DeviceDetailPage.js +2865 -0
  32. package/src/react/pages/DeviceDetailPage.styles.js +308 -0
  33. package/src/react/pages/Devices/currentDevice.js +194 -0
  34. package/src/react/pages/Devices/deviceTypes/DeviceGroupCard.js +257 -0
  35. package/src/react/pages/Devices/deviceTypes/all.js +23 -0
  36. package/src/react/pages/Devices/deviceTypes/device.js +25 -0
  37. package/src/react/pages/Devices/deviceTypes/deviceListHelpers.js +178 -0
  38. package/src/react/pages/Devices/deviceTypes/display.js +26 -0
  39. package/src/react/pages/Devices/deviceTypes/index.js +145 -0
  40. package/src/react/pages/Devices/deviceTypes/ipCamera.js +35 -0
  41. package/src/react/pages/Devices/deviceTypes/pdv.js +88 -0
  42. package/src/react/pages/Devices/deviceTypes/printer.js +37 -0
  43. package/src/react/pages/Devices/deviceTypes/shared.js +453 -0
  44. package/src/react/pages/Devices/deviceTypes/useDeviceNetworkConnectivity.js +145 -0
  45. package/src/react/pages/Devices.js +183 -0
  46. package/src/react/pages/Devices.styles.js +353 -0
  47. package/src/react/pages/Food99IntegrationPage/components/Food99CatalogTab.js +219 -0
  48. package/src/react/pages/Food99IntegrationPage/components/Food99OverviewTab.js +134 -0
  49. package/src/react/pages/Food99IntegrationPage/components/Food99PreviewModal.js +173 -0
  50. package/src/react/pages/Food99IntegrationPage/components/Food99ProductCard.js +1 -0
  51. package/src/react/pages/Food99IntegrationPage/components/Food99QuickWalletModal.js +181 -0
  52. package/src/react/pages/Food99IntegrationPage/components/Food99SettingsTab.js +306 -0
  53. package/src/react/pages/Food99IntegrationPage/components/Food99StoreTab.js +417 -0
  54. package/src/react/pages/Food99IntegrationPage/index.js +1530 -0
  55. package/src/react/pages/Food99IntegrationPage/styles.js +792 -0
  56. package/src/react/pages/Food99IntegrationPage/utils.js +155 -0
  57. package/src/react/pages/Food99IntegrationPage.js +1 -0
  58. package/src/react/pages/Food99IntegrationPage.styles.js +1 -0
  59. package/src/react/pages/GenericLogPage.js +42 -167
  60. package/src/react/pages/IFoodIntegrationPage/components/IFoodCatalogTab.js +8 -0
  61. package/src/react/pages/IFoodIntegrationPage/components/IFoodOperationsTab.js +420 -0
  62. package/src/react/pages/IFoodIntegrationPage/components/IFoodOverviewTab.js +118 -0
  63. package/src/react/pages/IFoodIntegrationPage/components/IFoodPreviewModal.js +103 -0
  64. package/src/react/pages/IFoodIntegrationPage/components/IFoodProductCard.js +1 -0
  65. package/src/react/pages/IFoodIntegrationPage/components/IFoodStoreTab.js +150 -0
  66. package/src/react/pages/IFoodIntegrationPage/index.js +1298 -0
  67. package/src/react/pages/IFoodIntegrationPage/styles.js +764 -0
  68. package/src/react/pages/IFoodIntegrationPage/utils.js +91 -0
  69. package/src/react/pages/IFoodIntegrationPage.js +1 -0
  70. package/src/react/pages/IFoodIntegrationPage.styles.js +1 -0
  71. package/src/react/pages/Imports.js +214 -166
  72. package/src/react/pages/IntegrationConfigPage.js +744 -0
  73. package/src/react/pages/IntegrationConfigPage.styles.js +269 -0
  74. package/src/react/pages/Integrations.js +299 -0
  75. package/src/react/pages/Integrations.styles.js +130 -0
  76. package/src/react/pages/ManagerOrderNotificationsPage.js +642 -0
  77. package/src/react/pages/MarketplaceIntegrationPage/components/MarketplaceProductCard.js +205 -0
  78. package/src/react/pages/MarketplaceIntegrationPage/components/RemoteMarketplaceMenuTab.js +335 -0
  79. package/src/react/pages/MarketplaceIntegrationPage/index.js +60 -0
  80. package/src/react/pages/MarketplaceIntegrationPage/utils.js +137 -0
  81. package/src/react/pages/MercadoLivreIntegrationPage.js +538 -0
  82. package/src/react/pages/PrinterDeviceDetailPage.js +1916 -0
  83. package/src/react/pages/PrinterDeviceDetailPage.styles.js +223 -0
  84. package/src/react/pages/PrinterDeviceFormPage.js +521 -0
  85. package/src/react/pages/PrinterDeviceFormPage.styles.js +159 -0
  86. package/src/react/pages/WhatsAppConnectionPage.js +459 -0
  87. package/src/react/pages/WhatsAppConnectionPage.styles.js +284 -0
  88. package/src/react/pages/integrationsCatalog.js +399 -0
  89. package/src/react/services/Cielo/Cielo.js +193 -193
  90. package/src/react/utils/categoryContexts.js +46 -0
  91. package/src/react/utils/entityDisplay.js +222 -217
  92. package/src/react/utils/fileUrl.js +39 -20
  93. package/src/react/utils/integrationPage.js +16 -0
  94. package/src/react/utils/runtimeFooter.js +40 -22
  95. package/src/react/utils/runtimeLanguage.js +50 -9
  96. package/src/react/utils/runtimeMenu.js +191 -131
  97. package/src/react/utils/runtimeZoom.js +43 -0
  98. package/src/react/utils/shopConfig.js +27 -15
  99. package/src/react/utils/shopFranchises.js +126 -1
  100. package/src/react/utils/storeColumns.js +23 -4
  101. package/src/react/utils/userAvatar.js +104 -0
  102. package/src/store/categories/index.js +48 -20
  103. package/src/store/device_config/index.js +62 -21
  104. package/src/store/entity_log/index.js +22 -1
  105. package/src/store/imports/customActions.js +51 -0
  106. package/src/store/imports/index.js +89 -88
  107. package/src/store/status/index.js +11 -11
  108. package/src/store/themes/index.js +22 -0
  109. package/src/store/timezones/index.js +3 -1
  110. package/src/tests/browser/manager/connections.spec.js +143 -0
  111. package/src/tests/browser/manager/devices-current.spec.js +343 -0
  112. package/src/tests/browser/manager/mercado-livre-integration.spec.js +268 -0
  113. package/src/tests/react/api/deviceHeaders.test.js +114 -0
  114. package/src/tests/react/components/AddImportModal.test.js +166 -0
  115. package/src/tests/react/components/BottomNavigationBar.config.test.js +20 -0
  116. package/src/tests/react/components/UserAvatar.test.js +52 -0
  117. package/src/tests/react/pages/DevicePickerStyles.test.js +47 -0
  118. package/src/tests/react/pages/Devices/deviceListHelpers.test.js +39 -0
  119. package/src/tests/react/pages/DevicesCurrentDevice.test.js +198 -0
  120. package/src/tests/react/pages/connectionsHelpers.test.js +34 -0
  121. package/src/tests/react/pages/mercadoLivreIntegrationPageContract.test.mjs +16 -0
  122. package/src/tests/react/services/Cielo.test.js +190 -190
  123. package/src/tests/react/store/categoriesOrdering.test.js +26 -0
  124. package/src/tests/react/utils/appDomain.test.js +62 -0
  125. package/src/tests/react/utils/entityDisplay.test.js +2 -2
  126. package/src/tests/react/utils/fileUrl.test.js +3 -3
  127. package/src/tests/react/utils/formatter.test.mjs +33 -0
  128. package/src/tests/react/utils/runtimeFooter.test.js +29 -4
  129. package/src/tests/react/utils/runtimeLanguage.test.js +79 -9
  130. package/src/tests/react/utils/runtimeMenu.test.js +198 -134
  131. package/src/tests/react/utils/runtimeZoom.test.js +38 -0
  132. package/src/tests/react/utils/shopConfig.test.js +10 -9
  133. package/src/tests/react/utils/shopFranchises.test.js +43 -0
  134. package/src/tests/react/utils/translate.discovery.test.mjs +170 -0
  135. package/src/tests/react/utils/translate.test.helpers.mjs +152 -0
  136. package/src/tests/react/utils/translate.test.mjs +141 -349
  137. package/src/tests/react/utils/userAvatar.test.js +63 -0
  138. package/src/utils/appDomain.js +15 -4
  139. package/src/utils/formatter.js +104 -16
  140. package/src/utils/integrationConfigs.js +80 -80
  141. package/src/utils/translate.js +222 -438
  142. package/src/utils/translateDiscovery.js +96 -0
  143. package/src/utils/translateNormalize.js +33 -0
  144. package/src/utils/translatePending.js +92 -0
  145. package/src/utils/translateStorage.js +142 -0
  146. package/.github/agents/developer.agent.md +0 -30
  147. package/.github/agents/devops.agent.md +0 -30
  148. package/.github/agents/qa.agent.md +0 -30
  149. package/.github/agents/security.agent.md +0 -30
  150. package/.github/workflows/npmjs.yml +0 -35
@@ -1,193 +1,193 @@
1
- import Cielo from '@controleonline-rn/react-native-cielo-payment';
2
- import {env} from '@env';
3
- import {api} from '@controleonline/ui-common/src/api';
4
- import {getAllStores} from '@store';
5
- import {
6
- DEFAULT_CIELO_CONFIG,
7
- resolveCieloConfig,
8
- } from '@controleonline/ui-common/src/utils/integrationConfigs';
9
-
10
- const isConfigMap = value =>
11
- value && typeof value === 'object' && !Array.isArray(value);
12
-
13
- const normalizeEntityId = value =>
14
- String(value?.id || value?.['@id'] || value || '')
15
- .replace(/\D+/g, '')
16
- .trim();
17
-
18
- const extractCollectionItems = response => {
19
- if (Array.isArray(response)) return response;
20
- if (Array.isArray(response?.member)) return response.member;
21
- if (Array.isArray(response?.['hydra:member'])) return response['hydra:member'];
22
- return [];
23
- };
24
-
25
- const hasRequiredCieloConfig = config =>
26
- Boolean(
27
- String(config?.ACCESS_TOKEN || '').trim() &&
28
- String(config?.CLIENT_ID || '').trim() &&
29
- String(config?.EMAIL || '').trim(),
30
- );
31
-
32
- const hasExpectedMerchantCode = (result, expectedMerchantCode) => {
33
- if (!expectedMerchantCode) return true;
34
-
35
- const payments = Array.isArray(result?.payments) ? result.payments : [];
36
-
37
- return (
38
- payments.length > 0 &&
39
- payments.every(
40
- payment => String(payment?.merchantCode || '').trim() === expectedMerchantCode,
41
- )
42
- );
43
- };
44
-
45
- let technicalCieloConfigCache = DEFAULT_CIELO_CONFIG;
46
- let technicalCieloConfigCompanyId = '';
47
- let technicalCieloConfigPromise = null;
48
-
49
- const resolveRuntimeCompanyConfigs = () => {
50
- const stores = getAllStores();
51
- const peopleStore = stores?.people?.getters || {};
52
- const configsStore = stores?.configs?.getters || {};
53
-
54
- if (isConfigMap(configsStore.items)) {
55
- return configsStore.items;
56
- }
57
-
58
- if (isConfigMap(peopleStore.currentCompany?.configs)) {
59
- return peopleStore.currentCompany.configs;
60
- }
61
-
62
- if (isConfigMap(peopleStore.defaultCompany?.configs)) {
63
- return peopleStore.defaultCompany.configs;
64
- }
65
-
66
- return {};
67
- };
68
-
69
- const resolveDefaultCompanyId = () => {
70
- const stores = getAllStores();
71
- const peopleStore = stores?.people?.getters || {};
72
-
73
- return normalizeEntityId(
74
- peopleStore.defaultCompany?.id || peopleStore.defaultCompany?.['@id'],
75
- );
76
- };
77
-
78
- const loadTechnicalCieloConfig = async () => {
79
- const defaultCompanyId = resolveDefaultCompanyId();
80
-
81
- if (!defaultCompanyId) {
82
- return DEFAULT_CIELO_CONFIG;
83
- }
84
-
85
- if (
86
- technicalCieloConfigCompanyId === defaultCompanyId &&
87
- hasRequiredCieloConfig(technicalCieloConfigCache)
88
- ) {
89
- return technicalCieloConfigCache;
90
- }
91
-
92
- if (technicalCieloConfigPromise) {
93
- return technicalCieloConfigPromise;
94
- }
95
-
96
- technicalCieloConfigPromise = api
97
- .fetch('/configs', {
98
- params: {
99
- configKey: 'CIELO',
100
- people: '/people/' + defaultCompanyId,
101
- visibility: 'private',
102
- },
103
- })
104
- .then(response => {
105
- const item = extractCollectionItems(response)[0];
106
- technicalCieloConfigCompanyId = defaultCompanyId;
107
- technicalCieloConfigCache = resolveCieloConfig(
108
- item?.configKey ? {[item.configKey]: item?.configValue} : {},
109
- );
110
-
111
- return technicalCieloConfigCache;
112
- })
113
- .catch(() => DEFAULT_CIELO_CONFIG)
114
- .finally(() => {
115
- technicalCieloConfigPromise = null;
116
- });
117
-
118
- return technicalCieloConfigPromise;
119
- };
120
-
121
- const resolveRuntimeCieloConfig = async () => {
122
- const runtimeConfig = resolveCieloConfig(resolveRuntimeCompanyConfigs());
123
- const technicalConfig = hasRequiredCieloConfig(runtimeConfig)
124
- ? DEFAULT_CIELO_CONFIG
125
- : await loadTechnicalCieloConfig();
126
-
127
- return {
128
- ACCESS_TOKEN:
129
- runtimeConfig.ACCESS_TOKEN ||
130
- technicalConfig.ACCESS_TOKEN ||
131
- env?.CIELO?.ACCESS_TOKEN ||
132
- '',
133
- CLIENT_ID:
134
- runtimeConfig.CLIENT_ID ||
135
- technicalConfig.CLIENT_ID ||
136
- env?.CIELO?.CLIENT_ID ||
137
- '',
138
- EMAIL: runtimeConfig.EMAIL || technicalConfig.EMAIL || env?.CIELO?.EMAIL || '',
139
- MERCHANT_CODE:
140
- runtimeConfig.MERCHANT_CODE ||
141
- technicalConfig.MERCHANT_CODE ||
142
- env?.CIELO?.MERCHANT_CODE ||
143
- '',
144
- };
145
- };
146
-
147
- class CieloService {
148
- async payment(paymentCode, items, orderPrice) {
149
- const cieloConfig = await resolveRuntimeCieloConfig();
150
-
151
- if (
152
- !cieloConfig.ACCESS_TOKEN ||
153
- !cieloConfig.CLIENT_ID ||
154
- !cieloConfig.EMAIL
155
- ) {
156
- throw new Error('Configuracao da Cielo incompleta.');
157
- }
158
-
159
- const json = {
160
- accessToken: cieloConfig.ACCESS_TOKEN,
161
- clientID: cieloConfig.CLIENT_ID,
162
- email: cieloConfig.EMAIL,
163
- installments: 0,
164
- items: items,
165
- paymentCode: paymentCode,
166
- value: orderPrice,
167
- };
168
-
169
- if (cieloConfig.MERCHANT_CODE) {
170
- json.merchantCode = cieloConfig.MERCHANT_CODE;
171
- }
172
-
173
- const response = await Cielo.payment(JSON.stringify(json));
174
-
175
- const result = response.success
176
- ? JSON.parse(response.result)
177
- : response.result;
178
- const hasValidMerchantCode = hasExpectedMerchantCode(
179
- result,
180
- cieloConfig.MERCHANT_CODE,
181
- );
182
-
183
- return {
184
- success: response.success && hasValidMerchantCode,
185
- code: response.code,
186
- result: hasValidMerchantCode
187
- ? result
188
- : 'Pagamento processado em estabelecimento Cielo diferente do configurado.',
189
- };
190
- }
191
- }
192
-
193
- export default CieloService;
1
+ import Cielo from '@controleonline-rn/react-native-cielo-payment';
2
+ import {env} from '@env';
3
+ import {api} from '@controleonline/ui-common/src/api';
4
+ import {getAllStores} from '@store';
5
+ import {
6
+ DEFAULT_CIELO_CONFIG,
7
+ resolveCieloConfig,
8
+ } from '@controleonline/ui-common/src/utils/integrationConfigs';
9
+
10
+ const isConfigMap = value =>
11
+ value && typeof value === 'object' && !Array.isArray(value);
12
+
13
+ const normalizeEntityId = value =>
14
+ String(value?.id || value?.['@id'] || value || '')
15
+ .replace(/\D+/g, '')
16
+ .trim();
17
+
18
+ const extractCollectionItems = response => {
19
+ if (Array.isArray(response)) return response;
20
+ if (Array.isArray(response?.member)) return response.member;
21
+ if (Array.isArray(response?.['hydra:member'])) return response['hydra:member'];
22
+ return [];
23
+ };
24
+
25
+ const hasRequiredCieloConfig = config =>
26
+ Boolean(
27
+ String(config?.ACCESS_TOKEN || '').trim() &&
28
+ String(config?.CLIENT_ID || '').trim() &&
29
+ String(config?.EMAIL || '').trim(),
30
+ );
31
+
32
+ const hasExpectedMerchantCode = (result, expectedMerchantCode) => {
33
+ if (!expectedMerchantCode) return true;
34
+
35
+ const payments = Array.isArray(result?.payments) ? result.payments : [];
36
+
37
+ return (
38
+ payments.length > 0 &&
39
+ payments.every(
40
+ payment => String(payment?.merchantCode || '').trim() === expectedMerchantCode,
41
+ )
42
+ );
43
+ };
44
+
45
+ let technicalCieloConfigCache = DEFAULT_CIELO_CONFIG;
46
+ let technicalCieloConfigCompanyId = '';
47
+ let technicalCieloConfigPromise = null;
48
+
49
+ const resolveRuntimeCompanyConfigs = () => {
50
+ const stores = getAllStores();
51
+ const peopleStore = stores?.people?.getters || {};
52
+ const configsStore = stores?.configs?.getters || {};
53
+
54
+ if (isConfigMap(configsStore.items)) {
55
+ return configsStore.items;
56
+ }
57
+
58
+ if (isConfigMap(peopleStore.currentCompany?.configs)) {
59
+ return peopleStore.currentCompany.configs;
60
+ }
61
+
62
+ if (isConfigMap(peopleStore.defaultCompany?.configs)) {
63
+ return peopleStore.defaultCompany.configs;
64
+ }
65
+
66
+ return {};
67
+ };
68
+
69
+ const resolveDefaultCompanyId = () => {
70
+ const stores = getAllStores();
71
+ const peopleStore = stores?.people?.getters || {};
72
+
73
+ return normalizeEntityId(
74
+ peopleStore.defaultCompany?.id || peopleStore.defaultCompany?.['@id'],
75
+ );
76
+ };
77
+
78
+ const loadTechnicalCieloConfig = async () => {
79
+ const defaultCompanyId = resolveDefaultCompanyId();
80
+
81
+ if (!defaultCompanyId) {
82
+ return DEFAULT_CIELO_CONFIG;
83
+ }
84
+
85
+ if (
86
+ technicalCieloConfigCompanyId === defaultCompanyId &&
87
+ hasRequiredCieloConfig(technicalCieloConfigCache)
88
+ ) {
89
+ return technicalCieloConfigCache;
90
+ }
91
+
92
+ if (technicalCieloConfigPromise) {
93
+ return technicalCieloConfigPromise;
94
+ }
95
+
96
+ technicalCieloConfigPromise = api
97
+ .fetch('/configs', {
98
+ params: {
99
+ configKey: 'CIELO',
100
+ people: '/people/' + defaultCompanyId,
101
+ visibility: 'private',
102
+ },
103
+ })
104
+ .then(response => {
105
+ const item = extractCollectionItems(response)[0];
106
+ technicalCieloConfigCompanyId = defaultCompanyId;
107
+ technicalCieloConfigCache = resolveCieloConfig(
108
+ item?.configKey ? {[item.configKey]: item?.configValue} : {},
109
+ );
110
+
111
+ return technicalCieloConfigCache;
112
+ })
113
+ .catch(() => DEFAULT_CIELO_CONFIG)
114
+ .finally(() => {
115
+ technicalCieloConfigPromise = null;
116
+ });
117
+
118
+ return technicalCieloConfigPromise;
119
+ };
120
+
121
+ const resolveRuntimeCieloConfig = async () => {
122
+ const runtimeConfig = resolveCieloConfig(resolveRuntimeCompanyConfigs());
123
+ const technicalConfig = hasRequiredCieloConfig(runtimeConfig)
124
+ ? DEFAULT_CIELO_CONFIG
125
+ : await loadTechnicalCieloConfig();
126
+
127
+ return {
128
+ ACCESS_TOKEN:
129
+ runtimeConfig.ACCESS_TOKEN ||
130
+ technicalConfig.ACCESS_TOKEN ||
131
+ env?.CIELO?.ACCESS_TOKEN ||
132
+ '',
133
+ CLIENT_ID:
134
+ runtimeConfig.CLIENT_ID ||
135
+ technicalConfig.CLIENT_ID ||
136
+ env?.CIELO?.CLIENT_ID ||
137
+ '',
138
+ EMAIL: runtimeConfig.EMAIL || technicalConfig.EMAIL || env?.CIELO?.EMAIL || '',
139
+ MERCHANT_CODE:
140
+ runtimeConfig.MERCHANT_CODE ||
141
+ technicalConfig.MERCHANT_CODE ||
142
+ env?.CIELO?.MERCHANT_CODE ||
143
+ '',
144
+ };
145
+ };
146
+
147
+ class CieloService {
148
+ async payment(paymentCode, items, orderPrice) {
149
+ const cieloConfig = await resolveRuntimeCieloConfig();
150
+
151
+ if (
152
+ !cieloConfig.ACCESS_TOKEN ||
153
+ !cieloConfig.CLIENT_ID ||
154
+ !cieloConfig.EMAIL
155
+ ) {
156
+ throw new Error('Configuracao da Cielo incompleta.');
157
+ }
158
+
159
+ const json = {
160
+ accessToken: cieloConfig.ACCESS_TOKEN,
161
+ clientID: cieloConfig.CLIENT_ID,
162
+ email: cieloConfig.EMAIL,
163
+ installments: 0,
164
+ items: items,
165
+ paymentCode: paymentCode,
166
+ value: orderPrice,
167
+ };
168
+
169
+ if (cieloConfig.MERCHANT_CODE) {
170
+ json.merchantCode = cieloConfig.MERCHANT_CODE;
171
+ }
172
+
173
+ const response = await Cielo.payment(JSON.stringify(json));
174
+
175
+ const result = response.success
176
+ ? JSON.parse(response.result)
177
+ : response.result;
178
+ const hasValidMerchantCode = hasExpectedMerchantCode(
179
+ result,
180
+ cieloConfig.MERCHANT_CODE,
181
+ );
182
+
183
+ return {
184
+ success: response.success && hasValidMerchantCode,
185
+ code: response.code,
186
+ result: hasValidMerchantCode
187
+ ? result
188
+ : 'Pagamento processado em estabelecimento Cielo diferente do configurado.',
189
+ };
190
+ }
191
+ }
192
+
193
+ export default CieloService;
@@ -0,0 +1,46 @@
1
+ const DOCUMENT_CATEGORY_CONTEXTS = {
2
+ proposal: 'proposal-category',
3
+ contract: 'contract-category',
4
+ email: 'email-category',
5
+ menu: 'menu-category',
6
+ };
7
+
8
+ export const normalizeCategoryContext = value => String(value || '').trim();
9
+
10
+ export const getCategoryContextForDocument = documentContext => {
11
+ const normalizedContext = normalizeCategoryContext(documentContext);
12
+ if (!normalizedContext) {
13
+ return '';
14
+ }
15
+
16
+ return DOCUMENT_CATEGORY_CONTEXTS[normalizedContext] || `${normalizedContext}-category`;
17
+ };
18
+
19
+ export const getCategoryContextCandidates = documentContext => {
20
+ const normalizedContext = normalizeCategoryContext(documentContext);
21
+ if (!normalizedContext) {
22
+ return [];
23
+ }
24
+
25
+ const preferredContext = getCategoryContextForDocument(normalizedContext);
26
+ const legacyContext = `${normalizedContext}-model`;
27
+
28
+ if (preferredContext === legacyContext) {
29
+ return [preferredContext];
30
+ }
31
+
32
+ return [preferredContext, legacyContext];
33
+ };
34
+
35
+ export const humanizeCategoryContext = value => {
36
+ const normalizedContext = normalizeCategoryContext(value);
37
+ if (!normalizedContext) {
38
+ return 'Sem contexto';
39
+ }
40
+
41
+ return normalizedContext
42
+ .split(/[-_]+/)
43
+ .filter(Boolean)
44
+ .map(part => part.charAt(0).toUpperCase() + part.slice(1))
45
+ .join(' ');
46
+ };