cloudcommerce 0.2.3 → 0.3.0

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 (149) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/ecomplus-stores/monocard/functions/ssr/package.json +0 -2
  3. package/ecomplus-stores/tia-sonia/functions/ssr/package.json +0 -2
  4. package/package.json +6 -6
  5. package/packages/api/package.json +1 -1
  6. package/packages/apps/correios/package.json +2 -2
  7. package/packages/apps/custom-payment/package.json +1 -1
  8. package/packages/apps/custom-shipping/package.json +1 -1
  9. package/packages/apps/datafrete/package.json +2 -2
  10. package/packages/apps/discounts/package.json +1 -1
  11. package/packages/apps/emails/package.json +1 -1
  12. package/packages/apps/fb-conversions/package.json +1 -1
  13. package/packages/apps/frenet/package.json +2 -2
  14. package/packages/apps/galaxpay/package.json +2 -2
  15. package/packages/apps/google-analytics/package.json +2 -2
  16. package/packages/apps/infinitepay/package.json +2 -2
  17. package/packages/apps/jadlog/package.json +2 -2
  18. package/packages/apps/loyalty-points/package.json +1 -1
  19. package/packages/apps/melhor-envio/CHANGELOG.md +1 -0
  20. package/packages/apps/melhor-envio/README.md +1 -0
  21. package/packages/apps/melhor-envio/events.js +1 -0
  22. package/packages/apps/melhor-envio/lib/functions-lib/database.d.ts +18 -0
  23. package/packages/apps/melhor-envio/lib/functions-lib/database.js +115 -0
  24. package/packages/apps/melhor-envio/lib/functions-lib/database.js.map +1 -0
  25. package/packages/apps/melhor-envio/lib/functions-lib/events-to-melhor-envio.d.ts +7 -0
  26. package/packages/apps/melhor-envio/lib/functions-lib/events-to-melhor-envio.js +112 -0
  27. package/packages/apps/melhor-envio/lib/functions-lib/events-to-melhor-envio.js.map +1 -0
  28. package/packages/apps/melhor-envio/lib/functions-lib/new-label.d.ts +42 -0
  29. package/packages/apps/melhor-envio/lib/functions-lib/new-label.js +185 -0
  30. package/packages/apps/melhor-envio/lib/functions-lib/new-label.js.map +1 -0
  31. package/packages/apps/melhor-envio/lib/functions-lib/order-is-valid.d.ts +5 -0
  32. package/packages/apps/melhor-envio/lib/functions-lib/order-is-valid.js +40 -0
  33. package/packages/apps/melhor-envio/lib/functions-lib/order-is-valid.js.map +1 -0
  34. package/packages/apps/melhor-envio/lib/functions-lib/tracking-codes.d.ts +2 -0
  35. package/packages/apps/melhor-envio/lib/functions-lib/tracking-codes.js +164 -0
  36. package/packages/apps/melhor-envio/lib/functions-lib/tracking-codes.js.map +1 -0
  37. package/packages/apps/melhor-envio/lib/index.d.ts +1 -0
  38. package/packages/apps/melhor-envio/lib/index.js +2 -0
  39. package/packages/apps/melhor-envio/lib/index.js.map +1 -0
  40. package/packages/apps/melhor-envio/lib/melhor-envio-events.d.ts +6 -0
  41. package/packages/apps/melhor-envio/lib/melhor-envio-events.js +17 -0
  42. package/packages/apps/melhor-envio/lib/melhor-envio-events.js.map +1 -0
  43. package/packages/apps/melhor-envio/lib/melhor-envio.d.ts +2 -0
  44. package/packages/apps/melhor-envio/lib/melhor-envio.js +6 -0
  45. package/packages/apps/melhor-envio/lib/melhor-envio.js.map +1 -0
  46. package/packages/apps/melhor-envio/lib-mjs/calculate-melhor-envio.mjs +341 -0
  47. package/packages/apps/melhor-envio/lib-mjs/functions/client-melhor-envio.mjs +14 -0
  48. package/packages/apps/melhor-envio/lib-mjs/functions/error-handling.mjs +62 -0
  49. package/packages/apps/melhor-envio/lib-mjs/functions/new-shipment.mjs +119 -0
  50. package/packages/apps/melhor-envio/package.json +36 -0
  51. package/packages/apps/melhor-envio/src/functions-lib/database.ts +140 -0
  52. package/packages/apps/melhor-envio/src/functions-lib/events-to-melhor-envio.ts +137 -0
  53. package/packages/apps/melhor-envio/src/functions-lib/new-label.ts +214 -0
  54. package/packages/apps/melhor-envio/src/functions-lib/order-is-valid.ts +51 -0
  55. package/packages/apps/melhor-envio/src/functions-lib/tracking-codes.ts +191 -0
  56. package/packages/apps/melhor-envio/src/index.ts +1 -0
  57. package/packages/apps/melhor-envio/src/melhor-envio-events.ts +24 -0
  58. package/packages/apps/melhor-envio/src/melhor-envio.ts +7 -0
  59. package/packages/apps/melhor-envio/tsconfig.json +6 -0
  60. package/packages/apps/mercadopago/package.json +2 -2
  61. package/packages/apps/pagarme/package.json +2 -2
  62. package/packages/apps/paghiper/package.json +3 -3
  63. package/packages/apps/pix/package.json +2 -2
  64. package/packages/apps/tiny-erp/package.json +2 -2
  65. package/packages/cli/package.json +1 -1
  66. package/packages/config/package.json +1 -1
  67. package/packages/emails/package.json +3 -3
  68. package/packages/events/lib/firebase.js +2 -0
  69. package/packages/events/lib/firebase.js.map +1 -1
  70. package/packages/events/package.json +2 -1
  71. package/packages/events/src/firebase.ts +2 -0
  72. package/packages/firebase/lib/config.d.ts +4 -0
  73. package/packages/firebase/lib/config.js +7 -0
  74. package/packages/firebase/lib/config.js.map +1 -1
  75. package/packages/firebase/package.json +2 -2
  76. package/packages/firebase/src/config.ts +8 -0
  77. package/packages/i18n/lib/en_us/i19buyTogether.txt +1 -0
  78. package/packages/i18n/lib/en_us/i19buyTogetherWith.txt +1 -0
  79. package/packages/i18n/lib/en_us/i19report.txt +1 -0
  80. package/packages/i18n/lib/en_us/i19toggleMenu.txt +1 -0
  81. package/packages/i18n/lib/en_us/i19uponRequest.txt +1 -0
  82. package/packages/i18n/lib/en_us/i19usedPoints.txt +1 -0
  83. package/packages/i18n/lib/en_us.d.ts +6 -0
  84. package/packages/i18n/lib/en_us.js +6 -0
  85. package/packages/i18n/lib/en_us.js.map +1 -1
  86. package/packages/i18n/lib/pt_br/i19buyTogether.txt +1 -0
  87. package/packages/i18n/lib/pt_br/i19buyTogetherWith.txt +1 -0
  88. package/packages/i18n/lib/pt_br/i19report.txt +1 -0
  89. package/packages/i18n/lib/pt_br/i19toggleMenu.txt +1 -0
  90. package/packages/i18n/lib/pt_br/i19uponRequest.txt +1 -0
  91. package/packages/i18n/lib/pt_br/i19usedPoints.txt +1 -0
  92. package/packages/i18n/lib/pt_br.d.ts +6 -0
  93. package/packages/i18n/lib/pt_br.js +6 -0
  94. package/packages/i18n/lib/pt_br.js.map +1 -1
  95. package/packages/i18n/package.json +1 -1
  96. package/packages/i18n/src/en_us.ts +6 -0
  97. package/packages/i18n/src/pt_br.ts +6 -0
  98. package/packages/modules/lib/firebase/call-app-module.js +5 -0
  99. package/packages/modules/lib/firebase/call-app-module.js.map +1 -1
  100. package/packages/modules/package.json +3 -2
  101. package/packages/modules/src/firebase/call-app-module.ts +5 -0
  102. package/packages/passport/package.json +1 -1
  103. package/packages/ssr/package.json +3 -4
  104. package/packages/storefront/.eslintrc.cjs +1 -1
  105. package/packages/storefront/astro.config.mjs +8 -1
  106. package/packages/storefront/dist/client/_astro/PitchBar.209c6645.js +1 -0
  107. package/packages/storefront/dist/client/_astro/Prices.6fbcb5ac.js +1 -0
  108. package/packages/storefront/dist/client/_astro/Prices.vue_vue_type_script_setup_true_lang.44f23680.js +1 -0
  109. package/packages/storefront/dist/client/_astro/ProductCard.ee5eee91.js +1 -0
  110. package/packages/storefront/dist/client/_astro/ShopHeader.b801c785.js +1 -0
  111. package/packages/storefront/dist/client/_astro/_...slug_.32968ccf.css +1 -0
  112. package/packages/storefront/dist/client/_astro/client.5a46cc02.js +1 -0
  113. package/packages/storefront/dist/client/_astro/index.844a4059.js +1 -0
  114. package/packages/storefront/dist/client/_astro/{modules-info.dde776b4.js → modules-info.d9373e21.js} +1 -1
  115. package/packages/storefront/dist/client/_astro/runtime-core.esm-bundler.f04cee62.js +1 -0
  116. package/packages/storefront/dist/client/_astro/runtime-dom.esm-bundler.00313542.js +1 -0
  117. package/packages/storefront/dist/client/_astro/server.60de185d.css +1 -0
  118. package/packages/storefront/dist/client/_astro/use-component-variant.58788b6e.js +1 -0
  119. package/packages/storefront/dist/client/fallback/index.html +13 -7
  120. package/packages/storefront/dist/client/sw.js +1 -1
  121. package/packages/storefront/dist/server/chunks/pages/{all.c27193d6.mjs → all.23de4e5c.mjs} +444 -186
  122. package/packages/storefront/dist/server/chunks/{prerender.89f63027.mjs → prerender.f40361a3.mjs} +0 -0
  123. package/packages/storefront/dist/server/entry.mjs +39 -4452
  124. package/packages/storefront/package.json +4 -5
  125. package/packages/storefront/src/lib/assets/base.css +16 -11
  126. package/packages/storefront/src/lib/components/Carousel.vue +52 -82
  127. package/packages/storefront/src/lib/components/Drawer.vue +103 -0
  128. package/packages/storefront/src/lib/components/PitchBar.vue +16 -11
  129. package/packages/storefront/src/lib/components/Prices.vue +5 -5
  130. package/packages/storefront/src/lib/components/ShopHeader.vue +82 -0
  131. package/packages/storefront/src/lib/components/StickyHeader.vue +71 -43
  132. package/packages/storefront/src/lib/components/globals/Fade.vue +10 -14
  133. package/packages/storefront/src/lib/composables/use-component-variant.ts +6 -2
  134. package/packages/storefront/src/lib/composables/use-prices.ts +4 -2
  135. package/packages/storefront/src/lib/layouts/BaseBody.astro +1 -0
  136. package/packages/storefront/src/lib/layouts/PagesHeader.astro +28 -13
  137. package/packages/storefront/tailwind.config.cjs +4 -0
  138. package/packages/storefront/uno.config.cjs +1 -1
  139. package/packages/types/package.json +1 -1
  140. package/packages/storefront/dist/client/_astro/PitchBar.f3579a5b.js +0 -1
  141. package/packages/storefront/dist/client/_astro/Prices.8e5cead5.js +0 -1
  142. package/packages/storefront/dist/client/_astro/Prices.vue_vue_type_script_setup_true_lang.b8cbeb54.js +0 -1
  143. package/packages/storefront/dist/client/_astro/ProductCard.6d8b6d86.js +0 -1
  144. package/packages/storefront/dist/client/_astro/StickyHeader.7b0f3963.js +0 -1
  145. package/packages/storefront/dist/client/_astro/_...slug_.97285eba.css +0 -1
  146. package/packages/storefront/dist/client/_astro/client.3e777d4c.js +0 -1
  147. package/packages/storefront/dist/client/_astro/runtime-core.esm-bundler.7cf33881.js +0 -1
  148. package/packages/storefront/dist/client/_astro/runtime-dom.esm-bundler.1a4c7407.js +0 -1
  149. package/packages/storefront/dist/client/_astro/server.4d9646d8.css +0 -1
@@ -0,0 +1,140 @@
1
+ import { getFirestore, Timestamp } from 'firebase-admin/firestore';
2
+ import logger from 'firebase-functions/logger';
3
+
4
+ const firestoreColl = 'melhorEnvioTracking';
5
+
6
+ export type Lable = {
7
+ id: string,
8
+ labelId: string,
9
+ status: string,
10
+ resourceId: string,
11
+ createdAt: Timestamp,
12
+ updateAt?: string,
13
+ };
14
+
15
+ const searchLabel = async (resourceId: string): Promise<Lable | null> => new Promise(
16
+ (resolve, reject) => {
17
+ getFirestore().doc(`${firestoreColl}/${resourceId}`)
18
+ .get()
19
+ .then((documentSnapshot) => {
20
+ if (documentSnapshot && documentSnapshot.exists) {
21
+ const data = documentSnapshot.data() as Lable;
22
+ if (data) {
23
+ resolve(data);
24
+ } else {
25
+ resolve(null);
26
+ }
27
+ } else {
28
+ resolve(null);
29
+ }
30
+ })
31
+ .catch((err: any) => {
32
+ reject(err);
33
+ });
34
+ },
35
+ );
36
+
37
+ const saveLabel = (
38
+ labelId: string,
39
+ status: string,
40
+ resourceId: string,
41
+ ) => new Promise((resolve) => {
42
+ const documentRef = getFirestore().doc(`${firestoreColl}/${resourceId}`);
43
+ if (documentRef) {
44
+ documentRef.set({
45
+ id: resourceId,
46
+ labelId,
47
+ status,
48
+ resourceId,
49
+ createdAt: Timestamp.now(),
50
+ }).then(() => resolve(true))
51
+ .catch(logger.error);
52
+ }
53
+ });
54
+
55
+ const getAllLabels = (): Promise<Lable[]> => new Promise((resolve, reject) => {
56
+ getFirestore().collection(firestoreColl).get()
57
+ .then((docsRef) => {
58
+ if (docsRef.size > 0) {
59
+ const list: Lable[] = [];
60
+ docsRef.forEach((documentSnapshot) => {
61
+ if (documentSnapshot && documentSnapshot.exists) {
62
+ const data = documentSnapshot.data() as Lable;
63
+ list.push(data);
64
+ }
65
+ });
66
+ resolve(list);
67
+ } else {
68
+ const err = new Error('No label');
69
+ reject(err);
70
+ }
71
+ })
72
+ .catch(reject);
73
+ });
74
+
75
+ const updateLabel = async (
76
+ status: string,
77
+ labelId: string,
78
+ ): Promise<boolean> => new Promise((resolve, reject) => {
79
+ getFirestore().collection(firestoreColl)
80
+ .where('labelId', '==', labelId)
81
+ .get()
82
+ .then((docsRef) => {
83
+ if (docsRef.size > 0) {
84
+ docsRef.forEach(async (documentSnapshot) => {
85
+ if (documentSnapshot && documentSnapshot.exists) {
86
+ const documentRef = documentSnapshot.ref;
87
+ await documentRef.set({
88
+ status,
89
+ updateAt: new Date().toISOString(),
90
+ }, { merge: true });
91
+ }
92
+ });
93
+ }
94
+ resolve(true);
95
+ })
96
+ .catch(reject);
97
+ });
98
+
99
+ const deleteLabel = async (id: string): Promise<boolean> => new Promise((resolve, reject) => {
100
+ getFirestore().doc(`${firestoreColl}/${id}`)
101
+ .get()
102
+ .then(async (documentSnapshot) => {
103
+ if (documentSnapshot && documentSnapshot.exists) {
104
+ const data = documentSnapshot.data();
105
+ if (data) {
106
+ await documentSnapshot.ref.delete();
107
+ resolve(true);
108
+ }
109
+ }
110
+ resolve(false);
111
+ })
112
+ .catch(reject);
113
+ });
114
+
115
+ const clearLabels = async (): Promise<boolean> => new Promise((resolve, reject) => {
116
+ const deadline = new Date();
117
+ deadline.setMonth(deadline.getMonth() - 2);
118
+
119
+ getFirestore().collection(firestoreColl)
120
+ .where('createdAt', '<=', deadline)
121
+ .get()
122
+ .then((docsRef) => {
123
+ docsRef.docs.forEach((doc) => {
124
+ doc.ref.delete();
125
+ });
126
+ resolve(true);
127
+ })
128
+ .catch(reject);
129
+ });
130
+
131
+ const db = {
132
+ searchLabel,
133
+ saveLabel,
134
+ getAllLabels,
135
+ updateLabel,
136
+ deleteLabel,
137
+ clearLabels,
138
+ };
139
+
140
+ export default db;
@@ -0,0 +1,137 @@
1
+ import type { Orders } from '@cloudcommerce/types';
2
+ import logger from 'firebase-functions/logger';
3
+ import api from '@cloudcommerce/api';
4
+ import meClient from '../../lib-mjs/functions/client-melhor-envio.mjs';
5
+ import errorHandling from '../../lib-mjs/functions/error-handling.mjs';
6
+ import db from './database';
7
+ import orderIsValid from './order-is-valid';
8
+ import newLabel from './new-label';
9
+
10
+ const ECHO_SKIP = (msg?: string) => logger.warn(msg || 'SKIP');
11
+
12
+ const metafieldName = 'melhor_envio_label_id';
13
+
14
+ const handleApiEvent = async ({
15
+ evName,
16
+ apiEvent,
17
+ apiDoc,
18
+ app,
19
+ }) => {
20
+ const resourceId = apiEvent.resource_id;
21
+ logger.info('>> ', resourceId, ' - Action: ', apiEvent.action);
22
+ const key = `${evName}_${resourceId}`;
23
+ const appData = { ...app.data, ...app.hidden_data };
24
+ if (
25
+ Array.isArray(appData.ignore_events)
26
+ && appData.ignore_events.includes(evName)
27
+ ) {
28
+ logger.info('>> ', key, ' - Ignored event');
29
+ return null;
30
+ }
31
+ logger.info(`> Webhook ${resourceId} [${evName}] => ${apiDoc}`);
32
+
33
+ try {
34
+ const trackingCode = await db.searchLabel(resourceId);
35
+ if (!trackingCode) {
36
+ const accessToken = appData.access_token;
37
+ const { sandbox } = appData;
38
+ if (!accessToken) {
39
+ ECHO_SKIP('>> Melhor Envio token not found');
40
+ return null;
41
+ }
42
+
43
+ const order = apiDoc as Orders;
44
+ if (!appData.enabled_label_purchase || !orderIsValid(order, appData)) {
45
+ ECHO_SKIP();
46
+ return null;
47
+ }
48
+ const merchantData = await meClient(accessToken, sandbox).get('/')
49
+ .then(({ data }) => data);
50
+
51
+ const label = newLabel(order, appData, merchantData);
52
+ // logger.log(`>> Comprando etiquetas #${storeId} ${order._id}`);
53
+ const { data } = await meClient(accessToken, sandbox).post('/cart', label);
54
+ if (data) {
55
+ logger.log(`>> Etiqueta inserida no carrinho com sucesso #${data.id}`);
56
+ if (appData.enabled_label_checkout) {
57
+ await meClient(accessToken, sandbox).post('/shipment/checkout', { orders: [data.id] });
58
+ }
59
+
60
+ // logger.log(`>> Carrinho finalizado com sucesso #${data.id}`);
61
+ await db.saveLabel(data.id, data.status, resourceId);
62
+
63
+ // logger.log(`>> Etiquetas salvas no db para futuros rastreio #${storeId} ${resourceId}`);
64
+ // updates hidden_metafields with the generated tag id
65
+ const bodyHiddenMetaField = {
66
+ namespace: 'app-melhor-envio',
67
+ field: metafieldName,
68
+ value: data.id,
69
+ } as any; // TODO: type amount
70
+ await api.post(`orders/${resourceId}/hidden_metafields`, bodyHiddenMetaField);
71
+
72
+ if (typeof data.tracking === 'string' && data.tracking.length) {
73
+ let shippingLine = order.shipping_lines?.find(({ app: application }) => application
74
+ && application.service_code && application.service_code.startsWith('ME'));
75
+
76
+ if (!shippingLine && order.shipping_lines) {
77
+ [shippingLine] = order.shipping_lines;
78
+ }
79
+ if (shippingLine) {
80
+ const trackingCodes = shippingLine.tracking_codes || [];
81
+ trackingCodes.push({
82
+ code: data.tracking,
83
+ link: `https://www.melhorrastreio.com.br/rastreio/${data.tracking}`,
84
+ });
85
+
86
+ await api.patch(
87
+ `orders/${resourceId}/shipping_lines/${shippingLine._id}`,
88
+ { tracking_codes: trackingCodes },
89
+ );
90
+
91
+ logger.log(`>> 'hidden_metafields' do pedido ${order._id} atualizado com sucesso!`);
92
+ // done
93
+ return null;
94
+ }
95
+ }
96
+ }
97
+ }
98
+ ECHO_SKIP();
99
+ return null;
100
+ } catch (err: any) {
101
+ if (err.response && err.isAxiosError) {
102
+ const { data } = err.response;
103
+
104
+ if (data) {
105
+ // update order hidden_metafields
106
+ const bodyHiddenMetaField = {
107
+ namespace: 'app-melhor-envio',
108
+ field: 'melhor_envio_label_error',
109
+ value: JSON.stringify(data).substring(0, 255),
110
+ } as any;
111
+
112
+ await api.post(`orders/${resourceId}/hidden_metafields`, bodyHiddenMetaField);
113
+
114
+ if (
115
+ data.error
116
+ === 'Os documentos (CPFs) dos participantes do frete não podem ser iguais'
117
+ || data.error.startsWith('Seu saldo de R$ ')
118
+ ) {
119
+ // ignoring known ME/merchant errors
120
+ logger.warn(`ME: ${data.error}`);
121
+ return null;
122
+ }
123
+ }
124
+
125
+ logger.error('BuyLabelErr:', JSON.stringify({
126
+ data,
127
+ status: err.response.status,
128
+ config: err.response.config,
129
+ }, null, 4));
130
+ } else {
131
+ errorHandling(err);
132
+ }
133
+ return err;
134
+ }
135
+ };
136
+
137
+ export default handleApiEvent;
@@ -0,0 +1,214 @@
1
+ import type { Orders } from '@cloudcommerce/types';
2
+
3
+ export default (
4
+ order: Orders,
5
+ appConfig: { [x: string]: any },
6
+ merchantData: { [x: string]: any },
7
+ ) => {
8
+ const {
9
+ firstname, lastname, phone, email, address,
10
+ } = merchantData;
11
+ const from: { [x: string]: any } = {
12
+ name: `${firstname} ${lastname}`,
13
+ phone: (phone && phone.phone) || '',
14
+ email,
15
+ };
16
+ if (merchantData.company_document) {
17
+ from.company_document = merchantData.company_document;
18
+ }
19
+ if (merchantData.document) {
20
+ const field = merchantData.document.length > 11 ? 'company_document' : 'document';
21
+ from[field] = merchantData.document;
22
+ }
23
+ if (address) {
24
+ if (typeof address === 'string') {
25
+ from.address = address;
26
+ } else {
27
+ [
28
+ 'address',
29
+ 'complement',
30
+ 'number',
31
+ 'district',
32
+ 'postal_code',
33
+ 'city',
34
+ 'state_abbr',
35
+ 'country_id',
36
+ ].forEach((field) => {
37
+ from[field] = address[field] || '';
38
+ });
39
+ if (typeof address.city === 'object') {
40
+ from.city = address.city.city || '';
41
+ if (address.city.state) {
42
+ from.state_abbr = address.city.state.state_abbr || '';
43
+ from.country_id = (address.city.state.country && address.city.state.country.id) || '';
44
+ }
45
+ }
46
+ }
47
+ }
48
+
49
+ const shippingLine = (order.shipping_lines && order.shipping_lines[0]);
50
+ // || {};
51
+ const buyer = order.buyers && order.buyers[0];
52
+ const to = {
53
+ email: '',
54
+ };
55
+
56
+ if (buyer && buyer.main_email) {
57
+ to.email = buyer.main_email;
58
+ if (buyer.registry_type === 'j') {
59
+ Object.assign(to, { company_document: buyer.doc_number || '' });
60
+ } else {
61
+ Object.assign(to, { document: buyer.doc_number || '' });
62
+ }
63
+ if (buyer.phones && buyer.phones[0]) {
64
+ Object.assign(to, { phone: buyer.phones[0].number });
65
+ }
66
+ }
67
+
68
+ if (shippingLine?.to) {
69
+ const {
70
+ name,
71
+ street,
72
+ complement,
73
+ number,
74
+ borough,
75
+ city,
76
+ zip,
77
+ } = shippingLine.to;
78
+
79
+ Object.assign(to, {
80
+ name,
81
+ address: street || '',
82
+ complement,
83
+ number,
84
+ district: borough || '',
85
+ city,
86
+ state_abbr: shippingLine.to.province_code || '',
87
+ country_id: shippingLine.to.country_code || 'BR',
88
+ postal_code: zip || '',
89
+ note: shippingLine.to.near_to || '',
90
+ });
91
+ }
92
+
93
+ let physicalWeight = 0;
94
+ if (shippingLine?.package) {
95
+ const { weight } = shippingLine.package;
96
+ if (weight && weight.value) {
97
+ switch (weight.unit) {
98
+ case 'kg':
99
+ physicalWeight = weight.value;
100
+ break;
101
+ case 'g':
102
+ physicalWeight = weight.value / 1000;
103
+ break;
104
+ case 'mg':
105
+ physicalWeight = weight.value / 1000000;
106
+ break;
107
+ default:
108
+ break;
109
+ }
110
+ }
111
+ }
112
+
113
+ const getDimensions = (side: string) => {
114
+ const dimensions = shippingLine?.package && shippingLine.package.dimensions;
115
+ if (dimensions && dimensions[side]) {
116
+ const dimension = dimensions[side];
117
+ if (dimension && dimension.unit) {
118
+ let dimensionValue = 0;
119
+ switch (dimension.unit) {
120
+ case 'cm':
121
+ dimensionValue = dimension.value;
122
+ break;
123
+ case 'm':
124
+ dimensionValue = dimension.value * 100;
125
+ break;
126
+ case 'mm':
127
+ dimensionValue = dimension.value / 10;
128
+ break;
129
+ default:
130
+ break;
131
+ }
132
+ return dimensionValue;
133
+ }
134
+ }
135
+ return 0;
136
+ };
137
+
138
+ const products: {
139
+ name: string
140
+ quantity: number
141
+ unitary_value: number
142
+ }[] = [];
143
+
144
+ let insuranceValue = 0;
145
+ if (order.items) {
146
+ order.items.forEach((item) => {
147
+ products.push({
148
+ name: item.name || item.product_id,
149
+ quantity: item.quantity,
150
+ unitary_value: item.price,
151
+ });
152
+ insuranceValue += item.final_price || item.price;
153
+ });
154
+ }
155
+
156
+ const options = {
157
+ insurance_value: insuranceValue,
158
+ receipt: (appConfig.receipt),
159
+ own_hand: (appConfig.own_hand),
160
+ collect: false,
161
+ reverse: false,
162
+ platform: 'E-Com Plus',
163
+ tags: [
164
+ {
165
+ tag: `Etiqueta referente ao pedido: #${order.number}`,
166
+ },
167
+ {
168
+ tag: 'order_id',
169
+ url: order._id,
170
+ },
171
+ ],
172
+ };
173
+
174
+ // https://docs.menv.io/?version=latest#9a8f308b-4872-4268-b402-e1b0d64d1f1c
175
+ if (appConfig.enabled_non_commercial) {
176
+ Object.assign(options, { non_commercial: true });
177
+ }
178
+
179
+ const invoices = shippingLine?.invoices;
180
+ if (invoices && Array.isArray(invoices) && invoices[0].number) {
181
+ Object.assign(options, {
182
+ invoice: {
183
+ number: invoices[0].number,
184
+ key: invoices[0].access_key,
185
+ },
186
+ });
187
+ }
188
+
189
+ const label = {
190
+ from,
191
+ to,
192
+ package: {
193
+ weight: physicalWeight,
194
+ width: getDimensions('width'),
195
+ height: getDimensions('height'),
196
+ length: getDimensions('length'),
197
+ },
198
+ products,
199
+ options,
200
+ };
201
+
202
+ if (shippingLine?.app && shippingLine.app.service_code) {
203
+ Object.assign(label, {
204
+ service: parseInt(shippingLine.app.service_code.replace('ME ', ''), 10),
205
+ });
206
+ }
207
+ if (appConfig.jadlog_agency) {
208
+ Object.assign(label, {
209
+ agency: appConfig.jadlog_agency,
210
+ });
211
+ }
212
+
213
+ return label;
214
+ };
@@ -0,0 +1,51 @@
1
+ import type { Orders } from '@cloudcommerce/types';
2
+
3
+ export default (order: Orders, appConfig: { [x: string]: any; }) => {
4
+ if (!order.fulfillment_status || !order.shipping_lines) {
5
+ return false;
6
+ }
7
+
8
+ // check if the shipping calculation was done with the app-melhor-envio
9
+ const isByMelhorEnvio = Boolean(order.shipping_lines.find((shippingLine) => {
10
+ return shippingLine.custom_fields && shippingLine.custom_fields.find(({ field }) => {
11
+ return field === 'by_melhor_envio';
12
+ });
13
+ }));
14
+
15
+ // checks if the non-commercial shipping option is enabled
16
+ const isNonCommercial = () => (appConfig.enabled_non_commercial);
17
+
18
+ // checks if order is ready to ship by last
19
+ // entry in fulfillments instead of checking fulfillment_status
20
+
21
+ const isReadyForShipping = () => {
22
+ const current = order.fulfillment_status?.current;
23
+ return (current && current === 'ready_for_shipping');
24
+ };
25
+
26
+ // check if nf was issued for the order
27
+ const hasInvoice = () => {
28
+ return Boolean(order.shipping_lines?.find(({ invoices }) => {
29
+ return invoices && invoices[0] && invoices[0].number;
30
+ }));
31
+ };
32
+
33
+ const hasLabelBuyIt = () => {
34
+ if (order.hidden_metafields) {
35
+ return order.hidden_metafields
36
+ .find(({ field }) => field === 'melhor_envio_label_id');
37
+ }
38
+
39
+ return false;
40
+ };
41
+
42
+ if (!isByMelhorEnvio || !isReadyForShipping() || hasLabelBuyIt()) {
43
+ return false;
44
+ }
45
+
46
+ if (isNonCommercial() || hasInvoice()) {
47
+ return true;
48
+ }
49
+
50
+ return false;
51
+ };