npm-pkg-hook 1.9.8 → 1.10.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.
package/package.json CHANGED
@@ -47,5 +47,5 @@
47
47
  "rm": "rm -rf node_modules package-lock.json && npm i",
48
48
  "test": "echo \"Error: no test specified\" && exit 1"
49
49
  },
50
- "version": "1.9.8"
50
+ "version": "1.10.0"
51
51
  }
@@ -54,7 +54,7 @@ export class GenerateReport {
54
54
  */
55
55
  GenExcelReportFileName (type) {
56
56
  const fileNames = {
57
- 1: 'report.xlsx'
57
+ 1: `report_${new Date().toISOString().replace(/[:.]/g, '-')}.xlsx`
58
58
  }
59
59
 
60
60
  return fileNames[type] ? fileNames[type] : null
@@ -5,6 +5,8 @@ import { CREATE_ONE_EMPLOYEE_STORE_AND_USER } from './queries'
5
5
  /**
6
6
  * Custom hook to handle the createOneEmployeeStoreAndUser mutation.
7
7
  *
8
+ * @param
9
+ * @param {Object}
8
10
  * @returns {{
9
11
  * createEmployeeStoreAndUser: (input: IEmployeeStore) => Promise<void>,
10
12
  * loading: boolean,
@@ -23,15 +25,29 @@ export const useCreateEmployeeStoreAndUser = ({
23
25
  onCompleted = () => {
24
26
  return {
25
27
  }
28
+ },
29
+ onError = () => {
30
+ return {
31
+ }
26
32
  }
27
33
  } = {}) => {
28
34
  const [createEmployeeStoreAndUserMutation, { loading, error, data }] = useMutation(CREATE_ONE_EMPLOYEE_STORE_AND_USER, {
35
+ onError: () => {
36
+ sendNotification({
37
+ description: 'Error creando empleado',
38
+ title: 'Error',
39
+ backgroundColor: 'error'
40
+ })
41
+ },
29
42
  onCompleted: (response) => {
30
43
  console.log(response)
31
44
  const { createOneEmployeeStoreAndUser } = response ?? {}
32
45
  const { message, success } = createOneEmployeeStoreAndUser ?? {}
46
+ if (success === false) {
47
+ onError(response)
48
+ }
33
49
  if (success) {
34
- onCompleted()
50
+ onCompleted(response)
35
51
  }
36
52
  sendNotification({
37
53
  description: message,
@@ -60,8 +60,8 @@ export const useFormTools = ({
60
60
  }
61
61
  if (errSub) {
62
62
  sendNotification({
63
- title: 'Completa los campos requeridos',
64
- description: 'Error',
63
+ description: 'Completa los campos requeridos',
64
+ title: 'Error',
65
65
  backgroundColor: 'error'
66
66
  })
67
67
  }
@@ -585,6 +585,7 @@ export const GET_ONE_PRODUCTS_FOOD = gql`
585
585
  fId
586
586
  pName
587
587
  ProPrice
588
+ ProBarCode
588
589
  ProDescuento
589
590
  ValueDelivery
590
591
  ProUniDisponibles
@@ -1,17 +1,21 @@
1
1
  import { useMutation } from '@apollo/client'
2
2
  import { UPDATE_MULTIPLE_PRODUCTS } from './queries'
3
- import { CATEGORY_EMPTY, RandomCode } from '../../utils/index'
3
+ import { CATEGORY_EMPTY } from '../../utils/index'
4
4
  import { useCategoriesProduct } from '../useCategoriesProduct'
5
5
 
6
6
  export const useUpdateMultipleProducts = ({
7
7
  sendNotification = () => { }
8
8
  }) => {
9
- const [updateMultipleProducts, { data, loading, error }] = useMutation(UPDATE_MULTIPLE_PRODUCTS)
9
+ const [updateMultipleProducts, {
10
+ data,
11
+ loading,
12
+ error
13
+ }] = useMutation(UPDATE_MULTIPLE_PRODUCTS)
10
14
  const [dataCategoriesProducts] = useCategoriesProduct()
11
15
  const findEmptyCategory = dataCategoriesProducts?.find(category => category.pName === CATEGORY_EMPTY)
12
16
  const updateProducts = async (products) => {
17
+ console.log("🚀 ~ updateProducts ~ products:", products)
13
18
  const newProducts = products.map(product => {
14
- const code = RandomCode(9)
15
19
  return {
16
20
  idStore: '',
17
21
  ProPrice: product.PRECIO_AL_PUBLICO,
@@ -19,12 +23,14 @@ export const useUpdateMultipleProducts = ({
19
23
  ValueDelivery: 0,
20
24
  ProDescription: product.DESCRIPCION,
21
25
  pName: product.NOMBRE,
22
- pCode: code,
26
+ pCode: product.pCode,
23
27
  carProId: findEmptyCategory?.carProId ?? null,
24
28
  pState: 1,
25
29
  sTateLogistic: 1,
26
30
  ProStar: 0,
27
- ProImage: 'https:http://localhost:8080',
31
+ ProImage: null,
32
+ vat: product['IMPUESTO (%)'],
33
+ ProBarCode: product.CODIGO_DE_BARRAS,
28
34
  ProHeight: null,
29
35
  ProWeight: '',
30
36
  ProOutstanding: 0,
@@ -0,0 +1 @@
1
+ export * from './parseNumber'
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Parses a formatted number (string or number) and converts it into a float with two decimal places.
3
+ * @param {string|number} value - The number to parse (e.g., "1.500,00", "1500.00", 1500).
4
+ * @returns {string} Parsed number as a string in the format "1500.00".
5
+ * @throws Will throw an error if the input is not a valid formatted number.
6
+ */
7
+ export const parseNumber = (value) => {
8
+ // Convert value to string if it's a number
9
+ const stringValue = typeof value === 'number' ? value.toString() : value
10
+
11
+ if (typeof stringValue !== 'string') {
12
+ throw new Error('Input must be a string or number')
13
+ }
14
+
15
+ // Remove thousands separators and adjust decimal separator
16
+ const sanitizedValue = stringValue
17
+ .replace(/\./g, '') // Removes thousands separators (.)
18
+ .replace(',', '.') // Changes comma to period for decimal
19
+
20
+ // Parse the sanitized value as a float
21
+ const parsedNumber = parseFloat(sanitizedValue)
22
+ if (isNaN(parsedNumber)) {
23
+ throw new Error('Invalid number format')
24
+ }
25
+
26
+ // Format the number with two decimal places
27
+ return parsedNumber.toFixed(2)
28
+ }
29
+
30
+ // Example usage:
31
+ console.log(parseNumber('1.500,00')) // "1500.00"
32
+ console.log(parseNumber('1500.00')) // "1500.00"
33
+ console.log(parseNumber('1,500.50')) // "1500.50"
34
+ console.log(parseNumber('500')) // "500.00"
35
+ console.log(parseNumber('0,50')) // "0.50"
36
+ console.log(parseNumber(1500)) // "1500.00"
37
+ console.log(parseNumber(1500.5)) // "1500.50"
@@ -0,0 +1,65 @@
1
+ export const validateProductDataExcel = (product, productIndex) => {
2
+ const expectedHeaders = [
3
+ {
4
+ name: 'NOMBRE',
5
+ required: true,
6
+ type: 'string'
7
+ },
8
+ {
9
+ name: 'PRECIO_AL_PUBLICO',
10
+ required: false,
11
+ type: 'number'
12
+ },
13
+ {
14
+ name: 'VALOR_DE_COMPRA',
15
+ required: false,
16
+ type: 'number'
17
+ },
18
+ {
19
+ name: 'CANTIDAD',
20
+ required: true,
21
+ type: 'number'
22
+ },
23
+ {
24
+ name: 'DESCRIPCION',
25
+ required: true,
26
+ type: 'string'
27
+ },
28
+ {
29
+ name: 'DESCUENTO',
30
+ required: false,
31
+ type: 'number'
32
+ },
33
+ {
34
+ name: 'CATEGORIA',
35
+ required: false,
36
+ type: 'string'
37
+ },
38
+ {
39
+ name: 'CODIGO_DE_BARRAS',
40
+ required: false,
41
+ type: 'string'
42
+ },
43
+ {
44
+ name: 'IMPUESTO (%)',
45
+ required: false,
46
+ type: 'number'
47
+ }
48
+ ]
49
+
50
+ const errors = []
51
+
52
+ // Validar encabezados requeridos
53
+ expectedHeaders.forEach(({ name, required, type }) => {
54
+ if (required && !(name in product)) {
55
+ errors.push(`Producto ${productIndex + 1}: Faltan la columna requerida: ${name}.`)
56
+ } else if (product[name] !== undefined) {
57
+ const isValidType = typeof product[name] === type || (type === 'number' && typeof product[name] === 'number' && !isNaN(product[name]))
58
+ if (!isValidType) {
59
+ errors.push(`Producto ${productIndex + 1}: El campo ${name} debe ser de tipo ${type}.`)
60
+ }
61
+ }
62
+ })
63
+
64
+ return errors // Retorna todos los errores encontrados
65
+ }
@@ -1,15 +1,25 @@
1
1
  import { useState } from 'react'
2
2
  import * as XLSX from 'xlsx'
3
+ import { RandomCode } from '../../utils'
4
+ import { validateProductDataExcel } from './helpers/validateProductDataExcel'
3
5
 
4
- export const useUploadProducts = () => {
5
- const [data, setData] = useState([])
6
+ const STEPS = {
7
+ UPLOAD_FILE: 0,
8
+ UPLOAD_PRODUCTS: 1
9
+ }
6
10
 
7
- const [active, setActive] = useState(0)
8
- const [overActive, setOverActive] = useState(0)
11
+ export const useUploadProducts = ({
12
+ sendNotification = () => { return null }
13
+ } = {}) => {
14
+ const [data, setData] = useState([])
15
+ const [isLoading, setIsLoading] = useState(false)
16
+ const [active, setActive] = useState(STEPS.UPLOAD_FILE)
17
+ const [overActive, setOverActive] = useState(STEPS.UPLOAD_FILE)
9
18
 
10
19
  const handleOverActive = (index) => {
11
20
  setOverActive(index)
12
21
  }
22
+
13
23
  const readExcelFile = (file) => {
14
24
  return new Promise((resolve, reject) => {
15
25
  const reader = new FileReader()
@@ -27,17 +37,383 @@ export const useUploadProducts = () => {
27
37
  }
28
38
 
29
39
  const onChangeFiles = async (files) => {
30
- const filePromises = Array.from(files).map(file => readExcelFile(file))
31
- const data = await Promise.all(filePromises)
32
- setData(data.flat())
40
+ setIsLoading(true) // Activa el loader al inicio
41
+ try {
42
+ const filePromises = Array.from(files).map(file => readExcelFile(file))
43
+ const newData = await Promise.all(filePromises)
44
+
45
+ const newProducts = newData.flat().map((product, index) => {
46
+ const PRECIO_AL_PUBLICO = isNaN(product.PRECIO_AL_PUBLICO) ? 0.00 : product.PRECIO_AL_PUBLICO
47
+ const VALOR_DE_COMPRA = isNaN(product.VALOR_DE_COMPRA) ? 0.00 : product.VALOR_DE_COMPRA
48
+ const validationErrors = validateProductDataExcel(product, index)
49
+
50
+ const code = RandomCode(9)
51
+ return {
52
+ ...product,
53
+ CANTIDAD: isNaN(product.CANTIDAD) ? 1 : product.CANTIDAD,
54
+ ORIGINAL_CANTIDAD: isNaN(product.CANTIDAD) ? 1 : product.CANTIDAD,
55
+ free: false,
56
+ product: product?.DESCRIPCION,
57
+ pCode: code,
58
+ editing: false,
59
+ PRECIO_AL_PUBLICO,
60
+ VALOR_DE_COMPRA,
61
+ errors: validationErrors.length > 0 ? validationErrors : null
62
+ }
63
+ })
64
+
65
+ // Notificación de errores
66
+ newProducts.forEach(product => {
67
+ if (product.errors) {
68
+ // Enviar una notificación por cada error encontrado
69
+ product.errors.forEach(error => {
70
+ sendNotification({
71
+ description: error,
72
+ title: 'Error',
73
+ backgroundColor: 'error'
74
+ })
75
+ })
76
+ }
77
+ })
78
+
79
+ // Validar el número total de productos antes de actualizar el estado
80
+ setData(prevData => {
81
+ const currentLength = prevData.length
82
+ const totalProducts = currentLength + newProducts.length
83
+
84
+ if (totalProducts > 100) {
85
+ sendNotification({
86
+ description: 'Cannot add more products. You have reached the 100-product limit.',
87
+ title: 'Error',
88
+ backgroundColor: 'error'
89
+ })
90
+
91
+ // Calcular la cantidad de productos que se pueden agregar sin exceder el límite
92
+ const remainingSlots = 100 - currentLength
93
+ const productsToAdd = newProducts.slice(0, remainingSlots)
94
+ return [...prevData, ...productsToAdd]
95
+ } else {
96
+ // Agregar todos los nuevos productos si no se excede el límite
97
+ return [...prevData, ...newProducts]
98
+ }
99
+ })
100
+ } catch (error) {
101
+ sendNotification({
102
+ description: 'Un error ha ocurrido mientras se cargaba el archivo de productos.',
103
+ title: 'Error',
104
+ backgroundColor: 'error'
105
+ })
106
+ } finally {
107
+ setIsLoading(false)
108
+ }
109
+ }
110
+
111
+ const handleSetActive = (index) => {
112
+ if (typeof index !== 'number' || index < 0 || index >= Object.keys(STEPS).length) {
113
+ sendNotification({
114
+ description: 'Invalid step index',
115
+ title: 'Error',
116
+ backgroundColor: 'error'
117
+ })
118
+ return
119
+ }
120
+ if (active === STEPS.UPLOAD_FILE && Boolean(!data.length)) return setActive(0)
121
+ if (active === STEPS.UPLOAD_FILE && Boolean(data.length)) return setActive(STEPS.UPLOAD_PRODUCTS)
33
122
  }
34
123
 
124
+ const updateProductQuantity = (index, quantityChange) => {
125
+ // Validar el índice
126
+ if (index < 0 || index >= data.length) {
127
+ console.warn('Invalid product index:', index)
128
+ return
129
+ }
130
+
131
+ const newData = [...data]
132
+ const newQuantity = newData[index].CANTIDAD + quantityChange
133
+
134
+ // Actualizar la cantidad solo si es mayor o igual a 0
135
+ if (newQuantity < 0) {
136
+ console.warn('Quantity cannot be negative, no update performed.')
137
+ return // No permitir cantidades negativas
138
+ }
139
+
140
+ // Actualizar la cantidad
141
+ newData[index].CANTIDAD = newQuantity
142
+ newData[index].ORIGINAL_CANTIDAD = newQuantity
143
+ // Eliminar el producto si la nueva cantidad es 0
144
+ if (newData[index].CANTIDAD === 0) {
145
+ newData.splice(index, 1)
146
+
147
+ // Verificar si no quedan más productos
148
+ if (newData.length === 0) {
149
+ setActive(STEPS.UPLOAD_FILE) // Restablecer el estado activo a 0 si no hay productos
150
+ }
151
+ }
152
+
153
+ setData(newData)
154
+ }
155
+ /**
156
+ * Toggle the 'free' status of a specific product in the data array.
157
+ * Performs validation to ensure the product index is valid.
158
+ *
159
+ * @param {number} productIndex - The index of the product to update.
160
+ */
161
+ const handleCheckFree = (productIndex) => {
162
+ setData((prevData) => {
163
+ // Validar que el índice es un número válido
164
+ if (typeof productIndex !== 'number' || productIndex < 0 || productIndex >= prevData.length) {
165
+ console.warn('Invalid product index:', productIndex)
166
+ return prevData // Retorna el estado anterior si el índice es inválido
167
+ }
168
+
169
+ // Validar que el producto existe y que tiene la propiedad 'free'
170
+ const product = prevData[productIndex]
171
+ if (!product || typeof product.free === 'undefined') {
172
+ console.warn('Product or "free" property not found for index:', productIndex)
173
+ return prevData // Retorna el estado anterior si no se encuentra el producto
174
+ }
175
+
176
+ // Evitar cambios innecesarios si el estado de 'free' no cambia
177
+ const updatedFreeStatus = !product.free
178
+ if (product.free === updatedFreeStatus) {
179
+ console.info('Product "free" status is already:', updatedFreeStatus)
180
+ return prevData // No actualiza si el estado es el mismo
181
+ }
182
+
183
+ // Crear una nueva copia de los datos actualizando solo el producto específico
184
+ return prevData.map((product, index) =>
185
+ index === productIndex
186
+ ? {
187
+ ...product,
188
+ free: updatedFreeStatus,
189
+ PRECIO_AL_PUBLICO: updatedFreeStatus ? 0 : product.oldPrice,
190
+ oldPrice: product.PRECIO_AL_PUBLICO
191
+ }
192
+ : product
193
+ )
194
+ })
195
+ }
196
+ const handleCleanAllProducts = () => {
197
+ setData([])
198
+ setActive(STEPS.UPLOAD_FILE)
199
+ }
200
+ /**
201
+ * Toggle the 'editing' status of a specific product in the data array.
202
+ * Validates the product index and only updates if necessary.
203
+ *
204
+ * @param {number} productIndex - The index of the product to update.
205
+ */
206
+ const handleToggleEditingStatus = (productIndex) => {
207
+ setData((prevData) => {
208
+ // Validar que el índice es un número válido
209
+ if (typeof productIndex !== 'number' || productIndex < 0 || productIndex >= prevData.length) {
210
+ sendNotification({
211
+ description: `Invalid product index: ${productIndex}`,
212
+ title: 'Error',
213
+ backgroundColor: 'error'
214
+ })
215
+ return prevData // Retorna el estado anterior si el índice es inválido
216
+ }
217
+
218
+ // Validar que el producto existe y tiene la propiedad 'editing'
219
+ const product = prevData[productIndex]
220
+ if (!product || typeof product.editing === 'undefined') {
221
+ sendNotification({
222
+ description: `Product or "editing" property not found for index: ${productIndex}`,
223
+ title: 'Error',
224
+ backgroundColor: 'error'
225
+ })
226
+ return prevData // Retorna el estado anterior si no se encuentra el producto
227
+ }
228
+
229
+ // Evitar cambios innecesarios si el estado de 'editing' no cambia
230
+ const updatedEditingStatus = !product.editing
231
+ if (product.editing === updatedEditingStatus) {
232
+ sendNotification({
233
+ description: `Product "editing" status is already: ${updatedEditingStatus}`,
234
+ title: 'Info',
235
+ backgroundColor: 'info'
236
+ })
237
+ return prevData // No actualiza si el estado es el mismo
238
+ }
239
+
240
+ // Crear una nueva copia de los datos actualizando solo el producto específico
241
+ return prevData.map((product, index) => {
242
+ console.log(index === productIndex)
243
+ return index === productIndex
244
+ ? {
245
+ ...product,
246
+ editing: updatedEditingStatus
247
+ }
248
+ : product
249
+ }
250
+ )
251
+ })
252
+ }
253
+
254
+ /**
255
+ * Confirm and update the quantity of a product in the data array.
256
+ * Only updates when the button is clicked.
257
+ *
258
+ * @param {number} productIndex - The index of the product to update.
259
+ */
260
+ const handleSuccessUpdateQuantity = (productIndex) => {
261
+ const product = data[productIndex]
262
+ setData((prevData) => {
263
+ // Validar que `CANTIDAD` sea un número entero
264
+ const product = prevData[productIndex]
265
+ if (!Number.isInteger(product?.CANTIDAD)) {
266
+ sendNotification({
267
+ description: 'La cantidad debe ser un valor entero.',
268
+ title: 'Error',
269
+ backgroundColor: 'error'
270
+ })
271
+ return prevData // Retorna el estado anterior si `CANTIDAD` no es entero
272
+ }
273
+
274
+ // Crear una copia actualizada de prevData donde se actualiza `CANTIDAD` si es necesario
275
+ const updatedData = prevData.map((product, index) =>
276
+ index === productIndex
277
+ ? { ...product, editing: false, ORIGINAL_CANTIDAD: product.CANTIDAD } // Actualización o cambio de estado
278
+ : product
279
+ )
280
+
281
+ // Filtrar productos con CANTIDAD mayor a 0
282
+ const filteredData = updatedData.filter(product => product.CANTIDAD > 0)
283
+
284
+ // Cambiar el estado a `STEPS.UPLOAD_FILE` si no quedan productos
285
+ if (filteredData.length === 0) {
286
+ setActive(STEPS.UPLOAD_FILE)
287
+ }
288
+
289
+ return filteredData
290
+ })
291
+ if (product.CANTIDAD !== data[productIndex].ORIGINAL_CANTIDAD) {
292
+ sendNotification({
293
+ description: `Cantidad actualizada con éxito para el producto ${product.NOMBRE} #${productIndex}.`,
294
+ title: 'Éxito',
295
+ backgroundColor: 'success'
296
+ })
297
+ }
298
+ }
299
+
300
+ const handleChangeQuantity = (event, productIndex) => {
301
+ const { value } = event.target
302
+ setData((prevData) => {
303
+ if (typeof productIndex !== 'number' || productIndex < 0 || productIndex >= prevData.length) {
304
+ console.warn('Invalid product index:', productIndex)
305
+ return prevData // Retorna el estado anterior si el índice es inválido
306
+ }
307
+
308
+ // Obtener la cantidad temporal para el producto
309
+ const newQuantity = value
310
+ if (isNaN(newQuantity) || newQuantity < 0) {
311
+ console.warn('Quantity must be a valid non-negative number.')
312
+ return prevData // Retorna sin cambios si la cantidad no es válida
313
+ }
314
+
315
+ // Actualiza el array `data` con la nueva cantidad
316
+ return prevData.map((product, index) =>
317
+ index === productIndex
318
+ ? { ...product, CANTIDAD: newQuantity }
319
+ : product
320
+ )
321
+ })
322
+ }
323
+ /**
324
+ * Restore the 'CANTIDAD' value to 'ORIGINAL_CANTIDAD' for a specific product.
325
+ * Validates the product index and only updates if necessary.
326
+ *
327
+ * @param {number} productIndex - The index of the product to restore quantity for.
328
+ */
329
+ const handleCancelUpdateQuantity = (productIndex) => {
330
+ setData((prevData) => {
331
+ // Validar que el índice es un número válido
332
+ if (typeof productIndex !== 'number' || productIndex < 0 || productIndex >= prevData.length) {
333
+ console.warn('Invalid product index:', productIndex)
334
+ return prevData // Retorna el estado anterior si el índice es inválido
335
+ }
336
+
337
+ // Validar que el producto existe y tiene las propiedades 'CANTIDAD' y 'ORIGINAL_CANTIDAD'
338
+ const product = prevData[productIndex]
339
+ if (!product || typeof product.ORIGINAL_CANTIDAD === 'undefined') {
340
+ console.warn('Product or "ORIGINAL_CANTIDAD" property not found for index:', productIndex)
341
+ return prevData // Retorna el estado anterior si no se encuentra el producto o propiedad
342
+ }
343
+
344
+ // Crear una nueva copia de los datos actualizando solo el producto específico
345
+ return prevData.map((product, index) =>
346
+ index === productIndex
347
+ ? { ...product, CANTIDAD: product.ORIGINAL_CANTIDAD, editing: false }
348
+ : product
349
+ )
350
+ })
351
+ }
352
+ /**
353
+ * Filters products with a quantity of 0 or less from the data array.
354
+ * Sends a notification if any products are found with invalid quantities.
355
+ */
356
+ const filterInvalidQuantityProducts = () => {
357
+ setData((prevData) => {
358
+ // Filtrar productos con `CANTIDAD` mayor a 0
359
+ const validProducts = prevData.filter(product => product.CANTIDAD > 0)
360
+
361
+ // Notificar si hubo productos con cantidad no válida
362
+ if (validProducts.length < prevData.length) {
363
+ sendNotification({
364
+ description: 'Some products had a quantity of 0 or less and were removed.',
365
+ title: 'Invalid Products Removed',
366
+ backgroundColor: 'warning'
367
+ })
368
+ }
369
+
370
+ return validProducts
371
+ })
372
+ }
373
+
374
+ /**
375
+ * Compares uploaded products against response data to determine which were successfully uploaded.
376
+ * @param {Array} data - Original array of products with their details.
377
+ * @param {Array} response - Array of response objects from the `updateProducts` function.
378
+ * @returns {Object} Object containing arrays of successfully and unsuccessfully uploaded products.
379
+ */
380
+ const getUploadResults = (data, response) => {
381
+ const uploadedCodes = new Set(
382
+ response
383
+ .filter((product) => product.success)
384
+ .map((product) => product.data.pCode)
385
+ )
386
+
387
+ const successfullyUploaded = data.filter((product) =>
388
+ uploadedCodes.has(product.pCode)
389
+ )
390
+
391
+ const failedUploads = data.filter(
392
+ (product) => !uploadedCodes.has(product.pCode)
393
+ )
394
+
395
+ return {
396
+ successfullyUploaded,
397
+ failedUploads
398
+ }
399
+ }
35
400
  return {
36
401
  active,
402
+ STEPS,
403
+ isLoading,
37
404
  data,
38
405
  overActive,
39
406
  handleOverActive,
407
+ handleCheckFree,
408
+ getUploadResults,
40
409
  onChangeFiles,
41
- setActive
410
+ handleChangeQuantity,
411
+ handleCancelUpdateQuantity,
412
+ handleToggleEditingStatus,
413
+ filterInvalidQuantityProducts,
414
+ handleSuccessUpdateQuantity,
415
+ updateProductQuantity,
416
+ handleCleanAllProducts,
417
+ setActive: handleSetActive
42
418
  }
43
419
  }