cloudcommerce 0.0.59 → 0.0.60

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 (135) hide show
  1. package/.eslintrc.cjs +2 -0
  2. package/CHANGELOG.md +23 -0
  3. package/package.json +9 -8
  4. package/packages/api/lib/api.d.ts +5036 -0
  5. package/packages/api/lib/{index.js → api.js} +16 -10
  6. package/packages/api/lib/api.js.map +1 -0
  7. package/packages/api/lib/types.d.ts +1 -0
  8. package/packages/api/package.json +3 -3
  9. package/packages/api/src/{index.ts → api.ts} +21 -17
  10. package/packages/api/src/types.ts +1 -0
  11. package/packages/api/tests/index.test.ts +2 -2
  12. package/packages/apps/discounts/lib/discounts.js +1 -1
  13. package/packages/apps/discounts/lib/discounts.js.map +1 -1
  14. package/packages/apps/discounts/{lib-cjs/apply-discount.cjs → lib-mjs/apply-discount.mjs} +7 -9
  15. package/packages/apps/discounts/{lib-cjs/helpers.cjs → lib-mjs/helpers.mjs} +2 -2
  16. package/packages/apps/discounts/package.json +1 -1
  17. package/packages/apps/discounts/src/discounts.ts +1 -1
  18. package/packages/apps/tiny-erp/lib/event-to-tiny.js +111 -0
  19. package/packages/apps/tiny-erp/lib/event-to-tiny.js.map +1 -0
  20. package/packages/apps/tiny-erp/lib/index.js +2 -0
  21. package/packages/apps/tiny-erp/lib/index.js.map +1 -0
  22. package/packages/apps/tiny-erp/lib/integration/after-tiny-queue.js +79 -0
  23. package/packages/apps/tiny-erp/lib/integration/after-tiny-queue.js.map +1 -0
  24. package/packages/apps/tiny-erp/lib/integration/export-order-to-tiny.js +81 -0
  25. package/packages/apps/tiny-erp/lib/integration/export-order-to-tiny.js.map +1 -0
  26. package/packages/apps/tiny-erp/lib/integration/export-product-to-tiny.js +58 -0
  27. package/packages/apps/tiny-erp/lib/integration/export-product-to-tiny.js.map +1 -0
  28. package/packages/apps/tiny-erp/lib/integration/helpers/format-tiny-date.js +7 -0
  29. package/packages/apps/tiny-erp/lib/integration/helpers/format-tiny-date.js.map +1 -0
  30. package/packages/apps/tiny-erp/lib/integration/import-order-from-tiny.js +94 -0
  31. package/packages/apps/tiny-erp/lib/integration/import-order-from-tiny.js.map +1 -0
  32. package/packages/apps/tiny-erp/lib/integration/import-product-from-tiny.js +169 -0
  33. package/packages/apps/tiny-erp/lib/integration/import-product-from-tiny.js.map +1 -0
  34. package/packages/apps/tiny-erp/lib/integration/parsers/order-from-tiny.js +46 -0
  35. package/packages/apps/tiny-erp/lib/integration/parsers/order-from-tiny.js.map +1 -0
  36. package/packages/apps/tiny-erp/lib/integration/parsers/order-to-tiny.js +193 -0
  37. package/packages/apps/tiny-erp/lib/integration/parsers/order-to-tiny.js.map +1 -0
  38. package/packages/apps/tiny-erp/lib/integration/parsers/product-from-tiny.js +199 -0
  39. package/packages/apps/tiny-erp/lib/integration/parsers/product-from-tiny.js.map +1 -0
  40. package/packages/apps/tiny-erp/lib/integration/parsers/product-to-tiny.js +129 -0
  41. package/packages/apps/tiny-erp/lib/integration/parsers/product-to-tiny.js.map +1 -0
  42. package/packages/apps/tiny-erp/lib/integration/parsers/status-from-tiny.js +34 -0
  43. package/packages/apps/tiny-erp/lib/integration/parsers/status-from-tiny.js.map +1 -0
  44. package/packages/apps/tiny-erp/lib/integration/parsers/status-to-tiny.js +39 -0
  45. package/packages/apps/tiny-erp/lib/integration/parsers/status-to-tiny.js.map +1 -0
  46. package/packages/apps/tiny-erp/lib/integration/post-tiny-erp.js +47 -0
  47. package/packages/apps/tiny-erp/lib/integration/post-tiny-erp.js.map +1 -0
  48. package/packages/apps/tiny-erp/lib/tiny-erp.js +17 -0
  49. package/packages/apps/tiny-erp/lib/tiny-erp.js.map +1 -0
  50. package/packages/apps/tiny-erp/lib/tiny-webhook.js +135 -0
  51. package/packages/apps/tiny-erp/lib/tiny-webhook.js.map +1 -0
  52. package/packages/apps/tiny-erp/package.json +13 -6
  53. package/packages/apps/tiny-erp/src/event-to-tiny.ts +129 -0
  54. package/packages/apps/tiny-erp/src/index.ts +1 -0
  55. package/packages/apps/tiny-erp/src/integration/after-tiny-queue.ts +80 -0
  56. package/packages/apps/tiny-erp/src/integration/export-order-to-tiny.ts +86 -0
  57. package/packages/apps/tiny-erp/src/integration/export-product-to-tiny.ts +60 -0
  58. package/packages/apps/tiny-erp/src/integration/helpers/format-tiny-date.ts +6 -0
  59. package/packages/apps/tiny-erp/src/integration/import-order-from-tiny.ts +104 -0
  60. package/packages/apps/tiny-erp/src/integration/import-product-from-tiny.ts +174 -0
  61. package/packages/apps/tiny-erp/src/integration/parsers/order-from-tiny.ts +49 -0
  62. package/packages/apps/tiny-erp/src/integration/parsers/order-to-tiny.ts +205 -0
  63. package/packages/apps/tiny-erp/src/integration/parsers/product-from-tiny.ts +215 -0
  64. package/packages/apps/tiny-erp/src/integration/parsers/product-to-tiny.ts +138 -0
  65. package/packages/apps/tiny-erp/src/integration/parsers/status-from-tiny.ts +35 -0
  66. package/packages/apps/tiny-erp/src/integration/parsers/status-to-tiny.ts +42 -0
  67. package/packages/apps/tiny-erp/src/integration/post-tiny-erp.ts +52 -0
  68. package/packages/apps/tiny-erp/src/tiny-erp.ts +23 -0
  69. package/packages/apps/tiny-erp/src/tiny-webhook.ts +143 -0
  70. package/packages/cli/package.json +1 -1
  71. package/packages/events/lib/firebase.js +2 -26
  72. package/packages/events/lib/firebase.js.map +1 -1
  73. package/packages/events/lib/index.js +1 -1
  74. package/packages/events/lib/index.js.map +1 -1
  75. package/packages/events/package.json +1 -1
  76. package/packages/events/src/firebase.ts +2 -28
  77. package/packages/events/src/index.ts +1 -1
  78. package/packages/firebase/lib/config.d.ts +2 -2
  79. package/packages/firebase/lib/config.js +7 -5
  80. package/packages/firebase/lib/config.js.map +1 -1
  81. package/packages/firebase/lib/const.d.ts +2 -0
  82. package/packages/firebase/lib/const.js +6 -0
  83. package/packages/firebase/lib/const.js.map +1 -0
  84. package/packages/firebase/lib/handlers/check-store-events.js +50 -27
  85. package/packages/firebase/lib/handlers/check-store-events.js.map +1 -1
  86. package/packages/firebase/lib/helpers/pubsub.d.ts +9 -0
  87. package/packages/firebase/lib/helpers/pubsub.js +32 -0
  88. package/packages/firebase/lib/helpers/pubsub.js.map +1 -0
  89. package/packages/firebase/lib/helpers/update-app-data.d.ts +9 -0
  90. package/packages/firebase/lib/helpers/update-app-data.js +45 -0
  91. package/packages/firebase/lib/helpers/update-app-data.js.map +1 -0
  92. package/packages/firebase/lib/index.d.ts +1 -2
  93. package/packages/firebase/lib/index.js +1 -6
  94. package/packages/firebase/lib/index.js.map +1 -1
  95. package/packages/firebase/lib/init.d.ts +2 -0
  96. package/packages/firebase/lib/init.js +9 -0
  97. package/packages/firebase/lib/init.js.map +1 -0
  98. package/packages/firebase/package.json +5 -2
  99. package/packages/firebase/src/config.ts +9 -6
  100. package/packages/firebase/src/const.ts +5 -0
  101. package/packages/firebase/src/handlers/check-store-events.ts +56 -33
  102. package/packages/firebase/src/helpers/pubsub.ts +52 -0
  103. package/packages/firebase/src/helpers/update-app-data.ts +49 -0
  104. package/packages/firebase/src/index.ts +1 -7
  105. package/packages/firebase/src/init.ts +9 -0
  106. package/packages/modules/lib/firebase/handle-module.js +4 -5
  107. package/packages/modules/lib/firebase/handle-module.js.map +1 -1
  108. package/packages/modules/lib/firebase/serve-modules-api.js +2 -2
  109. package/packages/modules/lib/firebase/serve-modules-api.js.map +1 -1
  110. package/packages/modules/lib/firebase.js +2 -7
  111. package/packages/modules/lib/firebase.js.map +1 -1
  112. package/packages/modules/package.json +1 -1
  113. package/packages/modules/src/firebase/handle-module.ts +2 -5
  114. package/packages/modules/src/firebase/serve-modules-api.ts +2 -6
  115. package/packages/modules/src/firebase.ts +2 -7
  116. package/packages/passport/lib/firebase/handle-passport.js +12 -10
  117. package/packages/passport/lib/firebase/handle-passport.js.map +1 -1
  118. package/packages/passport/lib/firebase/serve-passport-api.js +2 -2
  119. package/packages/passport/lib/firebase/serve-passport-api.js.map +1 -1
  120. package/packages/passport/lib/firebase.js +2 -7
  121. package/packages/passport/lib/firebase.js.map +1 -1
  122. package/packages/passport/package.json +1 -1
  123. package/packages/passport/src/firebase/handle-passport.ts +10 -19
  124. package/packages/passport/src/firebase/serve-passport-api.ts +0 -2
  125. package/packages/passport/src/firebase.ts +1 -7
  126. package/packages/ssr/lib/firebase.js +1 -4
  127. package/packages/ssr/lib/firebase.js.map +1 -1
  128. package/packages/ssr/package.json +1 -1
  129. package/packages/ssr/src/firebase.ts +1 -4
  130. package/packages/storefront/package.json +4 -4
  131. package/packages/types/index.ts +18 -3
  132. package/packages/types/package.json +1 -1
  133. package/packages/api/lib/index.d.ts +0 -9974
  134. package/packages/api/lib/index.js.map +0 -1
  135. package/packages/apps/tiny-erp/src/firebase.ts +0 -0
@@ -0,0 +1,49 @@
1
+ import postTiny from '../post-tiny-erp';
2
+
3
+ export default (tinyOrder, shippingLines) => new Promise((resolve, reject) => {
4
+ const partialOrder: Record<string, any> = {};
5
+ if (tinyOrder.obs_interna) {
6
+ partialOrder.staff_notes = tinyOrder.obs_interna;
7
+ }
8
+
9
+ if (shippingLines && shippingLines.length) {
10
+ const shippingLine = shippingLines[0];
11
+ if (
12
+ (tinyOrder.codigo_rastreamento || tinyOrder.url_rastreamento)
13
+ && (!shippingLine.tracking_codes || !shippingLine.tracking_codes.length)
14
+ ) {
15
+ let link;
16
+ if (tinyOrder.url_rastreamento) {
17
+ link = tinyOrder.url_rastreamento;
18
+ }
19
+ const tracking = {
20
+ code: String(tinyOrder.codigo_rastreamento)
21
+ || link.replace(/^https?:\/\/[^/]+/, '').replace(/^[^?]+\?/, '').substring(0, 70),
22
+ link,
23
+ };
24
+ shippingLine.tracking_codes = [tracking];
25
+ partialOrder.shipping_lines = shippingLines;
26
+ }
27
+
28
+ if (tinyOrder.id_nota_fiscal > 0) {
29
+ if (!shippingLine.invoices) {
30
+ shippingLine.invoices = [];
31
+ }
32
+ postTiny('/nota.fiscal.obter.php', { id: tinyOrder.id_nota_fiscal })
33
+ .then((tinyInvoice) => {
34
+ const number = String(tinyInvoice.nota_fiscal.numero);
35
+ if (number && !shippingLine.invoices.find((invoice) => invoice.number === number)) {
36
+ shippingLine.invoices.push({
37
+ number,
38
+ serial_number: String(tinyInvoice.nota_fiscal.serie),
39
+ });
40
+ }
41
+ partialOrder.shipping_lines = shippingLines;
42
+ resolve(partialOrder);
43
+ })
44
+ .catch(reject);
45
+ return;
46
+ }
47
+ }
48
+ resolve(partialOrder);
49
+ });
@@ -0,0 +1,205 @@
1
+ import type { Orders } from '@cloudcommerce/types';
2
+ import ecomUtils from '@ecomplus/utils';
3
+ import formatDate from '../helpers/format-tiny-date';
4
+ import parseStatus from './status-to-tiny';
5
+
6
+ export default (order: Orders, appData) => {
7
+ const orderRef = String(order.number) || order._id;
8
+ const tinyOrder: Record<string, any> = {
9
+ numero_pedido_ecommerce: orderRef,
10
+ data_pedido: formatDate(new Date(order.opened_at || order.created_at)),
11
+ ecommerce: 'E-Com Plus',
12
+ situacao: parseStatus(order),
13
+ itens: [],
14
+ };
15
+
16
+ const buyer = order.buyers && order.buyers[0];
17
+ const shippingLine = order.shipping_lines && order.shipping_lines[0];
18
+ const transaction = order.transactions && order.transactions[0];
19
+ const shippingAddress = shippingLine && shippingLine.to;
20
+ const billingAddress = transaction && transaction.billing_address;
21
+
22
+ const parseAddress = (address, tinyObject) => {
23
+ [
24
+ ['street', 'endereco', 50],
25
+ ['number', 'numero', 10],
26
+ ['complement', 'complemento', 50],
27
+ ['borough', 'bairro', 30],
28
+ ['zip', 'cep', 10],
29
+ ['city', 'cidade', 30],
30
+ ['province_code', 'uf', 30],
31
+ ].forEach(([addressField, tinyField, maxLength]) => {
32
+ if (address[addressField]) {
33
+ tinyObject[tinyField] = String(address[addressField])
34
+ .substring(0, maxLength as number);
35
+ }
36
+ });
37
+ };
38
+
39
+ if (buyer) {
40
+ const tinyCustomer: Record<string, any> = {
41
+ codigo: buyer._id,
42
+ nome: (buyer.corporate_name || ecomUtils.fullName(buyer)).substring(0, 30)
43
+ || `Comprador de #${orderRef}`,
44
+ tipo_pessoa: buyer.registry_type === 'j' ? 'J' : 'F',
45
+ };
46
+ if (buyer.display_name) {
47
+ tinyCustomer.nome_fantasia = buyer.display_name.substring(0, 30);
48
+ }
49
+ if (buyer.doc_number && buyer.doc_number.length <= 18) {
50
+ tinyCustomer.cpf_cnpj = buyer.doc_number;
51
+ }
52
+ if (buyer.inscription_number && buyer.inscription_number.length <= 18) {
53
+ tinyCustomer.ie = buyer.inscription_number;
54
+ }
55
+ if (buyer.main_email && buyer.main_email.length <= 50) {
56
+ tinyCustomer.email = buyer.main_email;
57
+ }
58
+ if (shippingAddress) {
59
+ parseAddress(billingAddress || shippingAddress, tinyCustomer);
60
+ }
61
+ const phone = buyer.phones && buyer.phones[0];
62
+ if (phone) {
63
+ tinyCustomer.fone = phone.country_code ? `+${phone.country_code} ` : '';
64
+ tinyCustomer.fone += phone.number;
65
+ }
66
+ tinyOrder.cliente = tinyCustomer;
67
+ } else {
68
+ tinyOrder.cliente = {
69
+ nome: `Comprador de #${orderRef}`,
70
+ };
71
+ }
72
+
73
+ if (shippingAddress && billingAddress) {
74
+ tinyOrder.endereco_entrega = {};
75
+ parseAddress(shippingAddress, tinyOrder.endereco_entrega);
76
+ if (shippingAddress.name) {
77
+ tinyOrder.endereco_entrega.nome_destinatario = shippingAddress.name.substring(0, 60);
78
+ }
79
+ }
80
+
81
+ if (order.items) {
82
+ order.items.forEach((item) => {
83
+ if (item.quantity) {
84
+ const itemRef = (item.sku || item._id || Math.random().toString()).substring(0, 30);
85
+ tinyOrder.itens.push({
86
+ item: {
87
+ codigo: itemRef,
88
+ descricao: item.name ? item.name.substring(0, 120) : itemRef,
89
+ unidade: 'UN',
90
+ quantidade: item.quantity,
91
+ valor_unitario: ecomUtils.price(item),
92
+ },
93
+ });
94
+ }
95
+ });
96
+ }
97
+
98
+ if (order.payment_method_label) {
99
+ tinyOrder.meio_pagamento = order.payment_method_label;
100
+ }
101
+ if (transaction) {
102
+ switch (transaction.payment_method.code) {
103
+ case 'credit_card':
104
+ tinyOrder.forma_pagamento = 'credito';
105
+ break;
106
+ case 'banking_billet':
107
+ tinyOrder.forma_pagamento = 'boleto';
108
+ break;
109
+ case 'account_deposit':
110
+ tinyOrder.forma_pagamento = 'deposito';
111
+ break;
112
+ case 'online_debit':
113
+ case 'debit_card':
114
+ case 'balance_on_intermediary':
115
+ tinyOrder.forma_pagamento = 'debito';
116
+ break;
117
+ default:
118
+ tinyOrder.forma_pagamento = 'multiplas';
119
+ }
120
+ if (!tinyOrder.meio_pagamento && transaction.payment_method.name) {
121
+ tinyOrder.meio_pagamento = transaction.payment_method.name.substring(0, 100);
122
+ }
123
+ }
124
+
125
+ if (order.shipping_method_label) {
126
+ tinyOrder.forma_frete = order.shipping_method_label;
127
+ }
128
+ if (shippingLine) {
129
+ tinyOrder.forma_envio = 'X';
130
+ if (shippingLine.app) {
131
+ const { carrier } = shippingLine.app;
132
+ if (carrier) {
133
+ if (/correios/i.test(carrier)) {
134
+ tinyOrder.forma_envio = 'C';
135
+ } else if (/b2w/i.test(carrier)) {
136
+ tinyOrder.forma_envio = 'B';
137
+ } else if (/mercado envios/i.test(carrier)) {
138
+ tinyOrder.forma_envio = 'M';
139
+ } else {
140
+ tinyOrder.forma_envio = 'T';
141
+ }
142
+ }
143
+ if (
144
+ (!tinyOrder.forma_envio || tinyOrder.forma_envio === 'X' || tinyOrder.forma_envio === 'T')
145
+ && shippingLine.app.service_name && /(pac|sedex)/i.test(shippingLine.app.service_name)
146
+ ) {
147
+ tinyOrder.forma_envio = 'C';
148
+ }
149
+ if (!tinyOrder.forma_frete && shippingLine.app.label) {
150
+ tinyOrder.forma_frete = shippingLine.app.label;
151
+ }
152
+ }
153
+ } else {
154
+ tinyOrder.forma_envio = 'S';
155
+ }
156
+
157
+ const { amount } = order;
158
+ if (amount) {
159
+ if (typeof amount.freight === 'number') {
160
+ tinyOrder.valor_frete = amount.freight;
161
+ if (amount.tax) {
162
+ tinyOrder.valor_frete += amount.tax;
163
+ }
164
+ if (amount.extra) {
165
+ tinyOrder.valor_frete += amount.extra;
166
+ }
167
+ }
168
+ if (amount.discount) {
169
+ tinyOrder.valor_desconto = amount.discount;
170
+ }
171
+ }
172
+
173
+ if (order.notes) {
174
+ tinyOrder.obs = order.notes.substring(0, 100);
175
+ }
176
+ if (order.extra_discount && order.extra_discount.discount_coupon) {
177
+ tinyOrder.obs = `${(tinyOrder.obs || '')} - ${order.extra_discount.discount_coupon}`
178
+ .substring(0, 100);
179
+ }
180
+ if (order.staff_notes) {
181
+ tinyOrder.obs_internas = order.staff_notes.substring(0, 100);
182
+ }
183
+
184
+ if (appData.tiny_order_data && typeof appData.tiny_order_data === 'object') {
185
+ Object.keys(appData.tiny_order_data).forEach((field) => {
186
+ let value = appData.tiny_order_data[field];
187
+ switch (value) {
188
+ case undefined:
189
+ case '':
190
+ case null:
191
+ break;
192
+ default:
193
+ if (typeof value === 'string') {
194
+ value = value.trim();
195
+ if (value) {
196
+ tinyOrder[field] = value;
197
+ }
198
+ } else {
199
+ tinyOrder[field] = value;
200
+ }
201
+ }
202
+ });
203
+ }
204
+ return tinyOrder;
205
+ };
@@ -0,0 +1,215 @@
1
+ import type { Products } from '@cloudcommerce/types';
2
+ import logger from 'firebase-functions/lib/logger';
3
+ import axios from 'axios';
4
+ import FormData from 'form-data';
5
+ import ecomUtils from '@ecomplus/utils';
6
+ import getEnv from '@cloudcommerce/firebase/lib/env';
7
+
8
+ const removeAccents = (str: string) => str.replace(/áàãâÁÀÃÂ/g, 'a')
9
+ .replace(/éêÉÊ/g, 'e')
10
+ .replace(/óõôÓÕÔ/g, 'o')
11
+ .replace(/íÍ/g, 'e')
12
+ .replace(/úÚ/g, 'u')
13
+ .replace(/çÇ/g, 'c');
14
+
15
+ const tryImageUpload = (originImgUrl: string, product: Products) => new Promise((resolve) => {
16
+ const {
17
+ storeId,
18
+ apiAuth: {
19
+ authenticationId,
20
+ apiKey,
21
+ },
22
+ } = getEnv();
23
+ axios.get(originImgUrl, {
24
+ responseType: 'arraybuffer',
25
+ }).then(({ data }) => {
26
+ const form = new FormData();
27
+ form.append('file', Buffer.from(data), originImgUrl.replace(/.*\/([^/]+)$/, '$1'));
28
+
29
+ return axios.post(`https://apx-storage.e-com.plus/${storeId}/api/v1/upload.json`, form, {
30
+ headers: {
31
+ ...form.getHeaders(),
32
+ 'X-Store-ID': storeId,
33
+ 'X-My-ID': authenticationId,
34
+ 'X-API-Key': apiKey,
35
+ },
36
+ }).then(({ data, status }) => {
37
+ if (data.picture) {
38
+ Object.keys(data.picture).forEach((imgSize) => {
39
+ if (data.picture[imgSize]) {
40
+ if (!data.picture[imgSize].url) {
41
+ delete data.picture[imgSize];
42
+ return;
43
+ }
44
+ if (data.picture[imgSize].size !== undefined) {
45
+ delete data.picture[imgSize].size;
46
+ }
47
+ data.picture[imgSize].alt = `${product.name} (${imgSize})`;
48
+ }
49
+ });
50
+ if (Object.keys(data.picture).length) {
51
+ return resolve({
52
+ _id: ecomUtils.randomObjectId(),
53
+ ...data.picture,
54
+ });
55
+ }
56
+ }
57
+ const err: any = new Error('Unexpected Storage API response');
58
+ err.response = { data, status };
59
+ throw err;
60
+ });
61
+ })
62
+
63
+ .catch((err) => {
64
+ logger.error(err);
65
+ resolve({
66
+ _id: ecomUtils.randomObjectId(),
67
+ normal: {
68
+ url: originImgUrl,
69
+ alt: product.name,
70
+ },
71
+ });
72
+ });
73
+ }).then((picture) => {
74
+ if (product && product.pictures) {
75
+ // @ts-ignore
76
+ product.pictures.push(picture);
77
+ }
78
+ return picture;
79
+ });
80
+
81
+ export default (tinyProduct, isNew = true) => new Promise((resolve) => {
82
+ const sku = tinyProduct.codigo || String(tinyProduct.id);
83
+ const name = (tinyProduct.nome || sku).trim();
84
+ const product: Omit<Products, '_id'| 'store_id' | 'created_at' | 'updated_at'> = {
85
+ available: tinyProduct.situacao === 'A',
86
+ sku,
87
+ name,
88
+ cost_price: tinyProduct.preco_custo,
89
+ price: tinyProduct.preco_promocional || tinyProduct.preco,
90
+ base_price: tinyProduct.preco,
91
+ body_html: tinyProduct.descricao_complementar,
92
+ };
93
+
94
+ if (isNew) {
95
+ product.slug = removeAccents(name.toLowerCase())
96
+ .replace(/\s+/g, '-')
97
+ .replace(/[^a-z0-9-_./]/g, '');
98
+ if (!/[a-z0-9]/.test(product.slug.charAt(0))) {
99
+ product.slug = `p-${product.slug}`;
100
+ }
101
+ }
102
+ if (tinyProduct.garantia) {
103
+ product.warranty = tinyProduct.garantia;
104
+ }
105
+ if (tinyProduct.unidade_por_caixa) {
106
+ product.min_quantity = Number(tinyProduct.unidade_por_caixa);
107
+ }
108
+ if (tinyProduct.ncm) {
109
+ product.mpn = [tinyProduct.ncm];
110
+ }
111
+ const validateGtin = (gtin) => {
112
+ return typeof gtin === 'string' && /^([0-9]{8}|[0-9]{12,14})$/.test(gtin);
113
+ };
114
+ if (validateGtin(tinyProduct.gtin)) {
115
+ product.gtin = [tinyProduct.gtin];
116
+ if (validateGtin(tinyProduct.gtin_embalagem)) {
117
+ product.gtin.push(tinyProduct.gtin_embalagem);
118
+ }
119
+ }
120
+
121
+ const weight = tinyProduct.peso_bruto || tinyProduct.peso_liquido;
122
+ if (weight > 0) {
123
+ product.weight = {
124
+ unit: 'kg',
125
+ value: parseFloat(weight),
126
+ };
127
+ }
128
+ [
129
+ ['largura', 'width'],
130
+ ['altura', 'height'],
131
+ ['comprimento', 'length'],
132
+ ].forEach(([lado, side]) => {
133
+ const dimension = tinyProduct[`${lado}_embalagem`] || tinyProduct[`${lado}Embalagem`];
134
+ if (dimension > 0) {
135
+ if (!product.dimensions) {
136
+ product.dimensions = {};
137
+ }
138
+ product.dimensions[side] = {
139
+ unit: 'cm',
140
+ value: parseFloat(dimension),
141
+ };
142
+ }
143
+ });
144
+
145
+ if (isNew) {
146
+ if (Array.isArray(tinyProduct.variacoes) && tinyProduct.variacoes.length) {
147
+ product.variations = [];
148
+ tinyProduct.variacoes.forEach(({ variacao }) => {
149
+ const { codigo, preco, grade } = variacao;
150
+ if (grade && typeof grade === 'object') {
151
+ const specifications = {};
152
+ const specTexts: string[] = [];
153
+ Object.keys(grade).forEach((tipo) => {
154
+ if (grade[tipo]) {
155
+ const gridId = removeAccents(tipo.toLowerCase())
156
+ .replace(/\s+/g, '_')
157
+ .replace(/[^a-z0-9_]/g, '')
158
+ .substring(0, 30)
159
+ .padStart(2, 'i');
160
+ const spec: Record<string, string> = {
161
+ text: grade[tipo],
162
+ };
163
+ specTexts.push(spec.text);
164
+ if (gridId !== 'colors') {
165
+ spec.value = removeAccents(spec.text.toLowerCase()).substring(0, 100);
166
+ }
167
+ specifications[gridId] = [spec];
168
+ }
169
+ });
170
+
171
+ if (specTexts.length) {
172
+ product.variations?.push({
173
+ _id: ecomUtils.randomObjectId(),
174
+ name: `${name} / ${specTexts.join(' / ')}`.substring(0, 100),
175
+ sku: codigo,
176
+ specifications,
177
+ price: parseFloat(preco || 0),
178
+ });
179
+ }
180
+ }
181
+ });
182
+ }
183
+
184
+ if (Array.isArray(tinyProduct.imagens_externas)) {
185
+ product.pictures = [];
186
+ tinyProduct.imagens_externas.forEach((imagemExterna) => {
187
+ if (imagemExterna.imagem_externa) {
188
+ const { url } = imagemExterna.imagem_externa;
189
+ if (url) {
190
+ product.pictures?.push({
191
+ normal: { url },
192
+ _id: ecomUtils.randomObjectId(),
193
+ });
194
+ }
195
+ }
196
+ });
197
+ }
198
+
199
+ if (tinyProduct.anexos) {
200
+ if (!product.pictures) {
201
+ product.pictures = [];
202
+ }
203
+ const promises: Promise<any>[] = [];
204
+ tinyProduct.anexos.forEach(({ anexo }) => {
205
+ if (typeof anexo === 'string' && anexo.startsWith('http')) {
206
+ promises.push(tryImageUpload(anexo, product as Products));
207
+ }
208
+ });
209
+ Promise.all(promises).then(() => resolve(product));
210
+ return;
211
+ }
212
+ }
213
+
214
+ resolve(product);
215
+ });
@@ -0,0 +1,138 @@
1
+ /* eslint-disable no-nested-ternary */
2
+ import type { Products } from '@cloudcommerce/types';
3
+ import ecomUtils from '@ecomplus/utils';
4
+
5
+ export default async (product: Products, originalTinyProduct, appData) => {
6
+ const hasVariations = product.variations && product.variations.length;
7
+ const tinyProduct: Record<string, any> = {
8
+ sequencia: 1,
9
+ origem: 0,
10
+ situacao: product.available && product.visible ? 'A' : 'I',
11
+ tipo: 'P',
12
+ classe_produto: hasVariations ? 'V' : 'S',
13
+ codigo: product.sku,
14
+ nome: ecomUtils.name(product, 'pt_br').substring(0, 120),
15
+ unidade: originalTinyProduct && originalTinyProduct.unidade
16
+ ? originalTinyProduct.unidade
17
+ : product.measurement && product.measurement.unit !== 'oz' && product.measurement.unit !== 'ct'
18
+ ? product.measurement.unit.substring(0, 3).toUpperCase()
19
+ : 'UN',
20
+ };
21
+
22
+ if (ecomUtils.onPromotion(product)) {
23
+ tinyProduct.preco = product.base_price;
24
+ tinyProduct.preco_promocional = ecomUtils.price(product);
25
+ } else {
26
+ tinyProduct.preco = product.price;
27
+ }
28
+ if (product.cost_price) {
29
+ tinyProduct.preco_custo = product.cost_price;
30
+ }
31
+ if (product.min_quantity) {
32
+ tinyProduct.unidade_por_caixa = product.min_quantity < 1000
33
+ ? String(product.min_quantity) : '999';
34
+ }
35
+
36
+ if (product.short_description) {
37
+ tinyProduct.descricao_complementar = product.short_description;
38
+ }
39
+ if (product.warranty) {
40
+ tinyProduct.garantia = product.warranty.substring(0, 20);
41
+ }
42
+
43
+ if (product.mpn && product.mpn.length) {
44
+ [tinyProduct.ncm] = product.mpn;
45
+ }
46
+ if (product.gtin && product.gtin.length) {
47
+ [tinyProduct.gtin] = product.gtin;
48
+ if (product.gtin[1]) {
49
+ // eslint-disable-next-line prefer-destructuring
50
+ tinyProduct.gtin_embalagem = product.gtin[1];
51
+ }
52
+ }
53
+
54
+ if (product.weight && product.weight.value) {
55
+ tinyProduct.peso_bruto = product.weight.value;
56
+ if (product.weight.unit === 'mg') {
57
+ tinyProduct.peso_bruto /= 1000000;
58
+ } else if (product.weight.unit === 'g') {
59
+ tinyProduct.peso_bruto /= 1000;
60
+ }
61
+ }
62
+ const { dimensions } = product;
63
+ if (dimensions) {
64
+ Object.keys(dimensions).forEach((side) => {
65
+ if (dimensions[side] && dimensions[side].value) {
66
+ let field = side === 'width' ? 'largura'
67
+ : side === 'height' ? 'altura'
68
+ : 'comprimento';
69
+ field += '_embalagem';
70
+ tinyProduct[field] = dimensions[side].value;
71
+ if (dimensions[side].unit === 'mm') {
72
+ tinyProduct[field] *= 0.1;
73
+ } else if (dimensions[side].unit === 'm') {
74
+ tinyProduct[field] *= 100;
75
+ }
76
+ }
77
+ });
78
+ }
79
+
80
+ if (product.brands && product.brands.length) {
81
+ tinyProduct.marca = product.brands[0].name;
82
+ }
83
+ if (product.category_tree) {
84
+ tinyProduct.categoria = product.category_tree.replace(/\s?>\s?/g, ' >> ');
85
+ } else if (product.categories && product.categories.length) {
86
+ tinyProduct.categoria = product.categories.map(({ name }) => name).join(' >> ');
87
+ }
88
+
89
+ if (product.pictures && product.pictures.length) {
90
+ tinyProduct.anexos = [];
91
+ product.pictures.forEach(({ zoom, big, normal }) => {
92
+ const img = (zoom || big || normal) as { url: string };
93
+ if (img) {
94
+ tinyProduct.anexos.push({
95
+ anexo: img.url,
96
+ });
97
+ }
98
+ });
99
+ }
100
+
101
+ if (originalTinyProduct) {
102
+ tinyProduct.id = originalTinyProduct.id;
103
+ if (!appData.update_price) {
104
+ ['preco', 'preco_promocional', 'preco_custo'].forEach((field) => {
105
+ if (typeof originalTinyProduct[field] === 'number') {
106
+ tinyProduct[field] = originalTinyProduct[field];
107
+ }
108
+ });
109
+ }
110
+ } else {
111
+ tinyProduct.estoque_atual = product.quantity || 0;
112
+ }
113
+
114
+ if (hasVariations) {
115
+ tinyProduct.variacoes = [];
116
+ product.variations?.forEach((variation, i) => {
117
+ const tinyVariation: Record<string, any> = {
118
+ codigo: variation.sku || `${product.sku}-${(i + 1)}`,
119
+ grade: {},
120
+ };
121
+ if (!originalTinyProduct) {
122
+ tinyVariation.estoque_atual = variation.quantity || 0;
123
+ }
124
+ Object.keys(variation.specifications).forEach((gridId) => {
125
+ const gridOptions = variation.specifications[gridId];
126
+ if (gridOptions && gridOptions.length) {
127
+ gridOptions.forEach(({ text }, i) => {
128
+ tinyVariation.grade[i === 0 ? gridId : `${gridId}_${(i + 1)}`] = text;
129
+ });
130
+ }
131
+ });
132
+ tinyProduct.variacoes.push({
133
+ variacao: tinyVariation,
134
+ });
135
+ });
136
+ }
137
+ return tinyProduct;
138
+ };
@@ -0,0 +1,35 @@
1
+ import type { Orders } from '@cloudcommerce/types';
2
+
3
+ export default (situacao: string) => {
4
+ let financialStatus: Exclude<Orders['financial_status'], undefined>['current'] | undefined;
5
+ let fulfillmentStatus: Exclude<Orders['fulfillment_status'], undefined>['current'] | undefined;
6
+ switch (situacao) {
7
+ case 'aprovado':
8
+ financialStatus = 'paid';
9
+ break;
10
+ case 'preparando_envio':
11
+ case 'preparando envio':
12
+ fulfillmentStatus = 'in_separation';
13
+ break;
14
+ case 'faturado':
15
+ case 'faturado (atendido)':
16
+ case 'atendido':
17
+ fulfillmentStatus = 'invoice_issued';
18
+ break;
19
+ case 'pronto_envio':
20
+ case 'pronto para envio':
21
+ fulfillmentStatus = 'ready_for_shipping';
22
+ break;
23
+ case 'enviado':
24
+ fulfillmentStatus = 'shipped';
25
+ break;
26
+ case 'entregue':
27
+ fulfillmentStatus = 'delivered';
28
+ break;
29
+ case 'cancelado':
30
+ financialStatus = 'voided';
31
+ break;
32
+ default:
33
+ }
34
+ return { financialStatus, fulfillmentStatus };
35
+ };
@@ -0,0 +1,42 @@
1
+ import type { Orders } from '@cloudcommerce/types';
2
+
3
+ export default (order: Orders) => {
4
+ const financialStatus = order.financial_status && order.financial_status.current;
5
+ switch (financialStatus) {
6
+ case 'pending':
7
+ case 'under_analysis':
8
+ case 'unknown':
9
+ case 'authorized':
10
+ case 'partially_paid':
11
+ return 'aberto';
12
+ case 'voided':
13
+ case 'refunded':
14
+ case 'in_dispute':
15
+ case 'unauthorized':
16
+ return 'cancelado';
17
+ default:
18
+ }
19
+
20
+ switch (order.fulfillment_status && order.fulfillment_status.current) {
21
+ case 'in_production':
22
+ case 'in_separation':
23
+ return 'preparando_envio';
24
+ case 'invoice_issued':
25
+ return 'faturado';
26
+ case 'ready_for_shipping':
27
+ return 'pronto_envio';
28
+ case 'shipped':
29
+ case 'partially_shipped':
30
+ return 'enviado';
31
+ case 'delivered':
32
+ return 'entregue';
33
+ case 'returned':
34
+ return 'cancelado';
35
+ default:
36
+ }
37
+
38
+ if (financialStatus === 'paid') {
39
+ return 'aprovado';
40
+ }
41
+ return 'aberto';
42
+ };