npm-pkg-hook 1.9.9 → 1.10.1
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 +1 -1
- package/src/hooks/useProductsFood/queriesStore.js +1 -0
- package/src/hooks/useSales/index.js +151 -36
- package/src/hooks/useUpdateMultipleProducts/index.js +2 -0
- package/src/hooks/useUploadProducts/helpers/validateProductDataExcel.js +65 -0
- package/src/hooks/useUploadProducts/index.js +46 -14
package/package.json
CHANGED
|
@@ -59,8 +59,8 @@ export const initializer = (initialValue = initialState) => {
|
|
|
59
59
|
export const useSales = ({
|
|
60
60
|
disabled = false,
|
|
61
61
|
router,
|
|
62
|
-
sendNotification = (
|
|
63
|
-
setAlertBox = (
|
|
62
|
+
sendNotification = (args) => { return args },
|
|
63
|
+
setAlertBox = (args) => { return args }
|
|
64
64
|
}) => {
|
|
65
65
|
const domain = getCurrentDomain()
|
|
66
66
|
const [loadingSale, setLoadingSale] = useState(false)
|
|
@@ -195,11 +195,11 @@ export const useSales = ({
|
|
|
195
195
|
// HANDLESS
|
|
196
196
|
// FILTER PRODUCT DATA_DB
|
|
197
197
|
// @ts-ignore
|
|
198
|
-
const handlePrint = (
|
|
198
|
+
const handlePrint = () => {
|
|
199
199
|
if (disabled) {
|
|
200
200
|
return sendNotification({
|
|
201
201
|
title: 'Error',
|
|
202
|
-
description: 'Esta es la
|
|
202
|
+
description: 'Esta es la descripción',
|
|
203
203
|
backgroundColor: 'error'
|
|
204
204
|
})
|
|
205
205
|
}
|
|
@@ -219,6 +219,25 @@ export const useSales = ({
|
|
|
219
219
|
const onChangeInput = (e) => {
|
|
220
220
|
return setValuesDates({ ...valuesDates, [e.target.name]: e.target.value })
|
|
221
221
|
}
|
|
222
|
+
const handleToggleEditingStatus = (state, action) => {
|
|
223
|
+
const { PRODUCT } = state ?? {
|
|
224
|
+
PRODUCT: []
|
|
225
|
+
}
|
|
226
|
+
return {
|
|
227
|
+
...state,
|
|
228
|
+
PRODUCT: PRODUCT.map((item) => {
|
|
229
|
+
if (item.pId === action.payload.pId) {
|
|
230
|
+
return {
|
|
231
|
+
...item,
|
|
232
|
+
editing: !item.editing,
|
|
233
|
+
oldQuantity: item.ProQuantity
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
return item
|
|
237
|
+
})
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
222
241
|
const handleChangeFilterProduct = (e) => {
|
|
223
242
|
const text = searchedInput(e.target.value)
|
|
224
243
|
if (text === undefined || text === '') {
|
|
@@ -232,11 +251,94 @@ export const useSales = ({
|
|
|
232
251
|
setOneProductToComment(product)
|
|
233
252
|
setValues({
|
|
234
253
|
...values,
|
|
235
|
-
comment: product?.comment
|
|
254
|
+
comment: product?.comment ?? ''
|
|
236
255
|
})
|
|
237
256
|
}
|
|
238
257
|
setOpenCommentModal(!openCommentModal)
|
|
239
258
|
}
|
|
259
|
+
const handleSuccessUpdateQuantity = (state, payload) => {
|
|
260
|
+
const { pId } = payload.payload || {
|
|
261
|
+
pId: null
|
|
262
|
+
}
|
|
263
|
+
return {
|
|
264
|
+
...state,
|
|
265
|
+
PRODUCT: state?.PRODUCT?.map((items) => {
|
|
266
|
+
return items.pId === pId
|
|
267
|
+
? {
|
|
268
|
+
...items,
|
|
269
|
+
editing: false,
|
|
270
|
+
oldQuantity: items.ProQuantity
|
|
271
|
+
}
|
|
272
|
+
: items
|
|
273
|
+
})
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Cancels the update of a product's quantity, resetting it to the previous value.
|
|
279
|
+
* @param {Object} state - The current state.
|
|
280
|
+
* @param {Object} payload - The payload containing the product ID.
|
|
281
|
+
* @returns {Object} - The new state with the updated product quantity and editing status.
|
|
282
|
+
*/
|
|
283
|
+
const handleCancelUpdateQuantity = (state, payload) => {
|
|
284
|
+
// Validación de `state`
|
|
285
|
+
if (!state || typeof state !== 'object') {
|
|
286
|
+
sendNotification({
|
|
287
|
+
title: 'Error',
|
|
288
|
+
backgroundColor: 'error',
|
|
289
|
+
description: 'Ha ocurrido un error al actualizar la cantidad del producto.'
|
|
290
|
+
})
|
|
291
|
+
return state // Retorna el estado sin cambios si es inválido.
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// Validación de `PRODUCT`
|
|
295
|
+
if (!Array.isArray(state.PRODUCT)) {
|
|
296
|
+
sendNotification({
|
|
297
|
+
title: 'Error',
|
|
298
|
+
backgroundColor: 'error',
|
|
299
|
+
description: 'Ha ocurrido un error al actualizar la cantidad del producto.'
|
|
300
|
+
})
|
|
301
|
+
return state // Retorna el estado sin cambios si `PRODUCT` no es un array.
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// Validación de `payload`
|
|
305
|
+
const { pId } = payload.payload || {}
|
|
306
|
+
if (!pId) {
|
|
307
|
+
sendNotification({
|
|
308
|
+
title: 'Error',
|
|
309
|
+
backgroundColor: 'error',
|
|
310
|
+
description: 'Ha ocurrido un error al actualizar la cantidad del producto.'
|
|
311
|
+
})
|
|
312
|
+
return state // Retorna el estado sin cambios si falta `pId`.
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
return {
|
|
316
|
+
...state,
|
|
317
|
+
PRODUCT: state.PRODUCT.map((item) => {
|
|
318
|
+
// Validación de propiedades en cada item
|
|
319
|
+
if (item.pId === pId) {
|
|
320
|
+
if (typeof item.oldQuantity !== 'number' || typeof item.unitPrice !== 'number') {
|
|
321
|
+
sendNotification({
|
|
322
|
+
title: 'Error',
|
|
323
|
+
backgroundColor: 'error',
|
|
324
|
+
description: 'Ha ocurrido un error al actualizar la cantidad del producto.'
|
|
325
|
+
})
|
|
326
|
+
return item // Retorna el item sin cambios si las propiedades son inválidas.
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
return {
|
|
330
|
+
...item,
|
|
331
|
+
editing: false,
|
|
332
|
+
ProQuantity: item.oldQuantity,
|
|
333
|
+
ProPrice: item.oldQuantity * item.unitPrice
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
return item
|
|
338
|
+
})
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
240
342
|
const handleChangeNumber = useCallback(
|
|
241
343
|
(state, action) => {
|
|
242
344
|
const event = action.payload
|
|
@@ -302,6 +404,12 @@ export const useSales = ({
|
|
|
302
404
|
case 'ON_CHANGE': {
|
|
303
405
|
return handleChangeNumber(state, action)
|
|
304
406
|
}
|
|
407
|
+
case 'UPDATE_SUCCESS_QUANTITY_EDITING_PRODUCT': {
|
|
408
|
+
return handleSuccessUpdateQuantity(state, action)
|
|
409
|
+
}
|
|
410
|
+
case 'CANCEL_UPDATE_QUANTITY_EDITING_PRODUCT': {
|
|
411
|
+
return handleCancelUpdateQuantity(state, action)
|
|
412
|
+
}
|
|
305
413
|
case 'REMOVE_ALL_PRODUCTS':
|
|
306
414
|
// @ts-ignore
|
|
307
415
|
setValues({
|
|
@@ -319,6 +427,9 @@ export const useSales = ({
|
|
|
319
427
|
|
|
320
428
|
case 'TOGGLE_FREE_PRODUCT':
|
|
321
429
|
return toggleFreeProducts(state, action)
|
|
430
|
+
case 'TOGGLE_EDITING_PRODUCT': {
|
|
431
|
+
return handleToggleEditingStatus(state, action)
|
|
432
|
+
}
|
|
322
433
|
case 'INCREMENT':
|
|
323
434
|
return {
|
|
324
435
|
...state,
|
|
@@ -365,6 +476,8 @@ export const useSales = ({
|
|
|
365
476
|
}
|
|
366
477
|
}
|
|
367
478
|
const [data, dispatch] = useReducer(PRODUCT, initialStateSales, initializer)
|
|
479
|
+
console.log({ data })
|
|
480
|
+
|
|
368
481
|
const handleRemoveValue = useCallback(({ name, value, pId }) => {
|
|
369
482
|
setValues({
|
|
370
483
|
...values,
|
|
@@ -611,6 +724,7 @@ export const useSales = ({
|
|
|
611
724
|
const updatedProduct = {
|
|
612
725
|
pId,
|
|
613
726
|
pName,
|
|
727
|
+
editing: false,
|
|
614
728
|
getOneTags,
|
|
615
729
|
unitPrice: OurProduct?.ProPrice,
|
|
616
730
|
ProDescription,
|
|
@@ -639,6 +753,8 @@ export const useSales = ({
|
|
|
639
753
|
...item,
|
|
640
754
|
getOneTags: OurProduct?.genderTags,
|
|
641
755
|
unitPrice: OurProduct?.ProPrice,
|
|
756
|
+
editing: false,
|
|
757
|
+
oldQuantity: productExist.ProQuantity + +1,
|
|
642
758
|
ProPrice: isFree ? 0 : (productExist.ProQuantity + 1) * OurProduct?.ProPrice,
|
|
643
759
|
ProQuantity: productExist.ProQuantity + +1,
|
|
644
760
|
free: !!isFree
|
|
@@ -741,41 +857,40 @@ export const useSales = ({
|
|
|
741
857
|
}
|
|
742
858
|
return ''
|
|
743
859
|
}
|
|
744
|
-
const arrayProduct =
|
|
745
|
-
data?.PRODUCT?.
|
|
746
|
-
|
|
747
|
-
const filteredDataExtra =
|
|
860
|
+
const arrayProduct = data?.PRODUCT?.length > 0
|
|
861
|
+
? data?.PRODUCT?.map((product) => {
|
|
862
|
+
const filteredDataExtra =
|
|
748
863
|
product?.dataExtra?.map(({ __typename, ...rest }) => rest) ?? []
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
}
|
|
757
|
-
)
|
|
758
|
-
return {
|
|
759
|
-
...rest,
|
|
760
|
-
ExtProductFoodsSubOptionalAll: adjustedSubOptionalAll
|
|
864
|
+
const dataOptional = product?.dataOptional?.map(
|
|
865
|
+
({ __typename, ...product }) => {
|
|
866
|
+
const { ExtProductFoodsSubOptionalAll, ...rest } = product
|
|
867
|
+
const adjustedSubOptionalAll = ExtProductFoodsSubOptionalAll?.map(
|
|
868
|
+
(subOption) => {
|
|
869
|
+
const { __typename, ...subOptionRest } = subOption
|
|
870
|
+
return subOptionRest
|
|
761
871
|
}
|
|
872
|
+
)
|
|
873
|
+
return {
|
|
874
|
+
...rest,
|
|
875
|
+
ExtProductFoodsSubOptionalAll: adjustedSubOptionalAll
|
|
762
876
|
}
|
|
763
|
-
)
|
|
764
|
-
const refCodePid = RandomCode(20)
|
|
765
|
-
return {
|
|
766
|
-
pId: product?.pId,
|
|
767
|
-
refCodePid,
|
|
768
|
-
id: values?.cliId,
|
|
769
|
-
cantProducts: parseInt(
|
|
770
|
-
product?.ProQuantity ? product?.ProQuantity : 0
|
|
771
|
-
),
|
|
772
|
-
comments: product?.comment ?? '',
|
|
773
|
-
dataOptional: dataOptional ?? [],
|
|
774
|
-
dataExtra: filteredDataExtra || [],
|
|
775
|
-
ProPrice: product.ProPrice
|
|
776
877
|
}
|
|
777
|
-
|
|
778
|
-
|
|
878
|
+
)
|
|
879
|
+
const refCodePid = RandomCode(20)
|
|
880
|
+
return {
|
|
881
|
+
pId: product?.pId,
|
|
882
|
+
refCodePid,
|
|
883
|
+
id: values?.cliId,
|
|
884
|
+
cantProducts: parseInt(
|
|
885
|
+
product?.ProQuantity ? product?.ProQuantity : 0
|
|
886
|
+
),
|
|
887
|
+
comments: product?.comment ?? '',
|
|
888
|
+
dataOptional: dataOptional ?? [],
|
|
889
|
+
dataExtra: filteredDataExtra || [],
|
|
890
|
+
ProPrice: product.ProPrice
|
|
891
|
+
}
|
|
892
|
+
})
|
|
893
|
+
: []
|
|
779
894
|
const finalArrayProduct = arrayProduct.map((item) => {
|
|
780
895
|
const totalExtra = item.dataExtra.reduce(
|
|
781
896
|
(accumulator, extra) => accumulator + extra.newExtraPrice,
|
|
@@ -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,6 +1,7 @@
|
|
|
1
1
|
import { useState } from 'react'
|
|
2
2
|
import * as XLSX from 'xlsx'
|
|
3
3
|
import { RandomCode } from '../../utils'
|
|
4
|
+
import { validateProductDataExcel } from './helpers/validateProductDataExcel'
|
|
4
5
|
|
|
5
6
|
const STEPS = {
|
|
6
7
|
UPLOAD_FILE: 0,
|
|
@@ -41,19 +42,37 @@ export const useUploadProducts = ({
|
|
|
41
42
|
const filePromises = Array.from(files).map(file => readExcelFile(file))
|
|
42
43
|
const newData = await Promise.all(filePromises)
|
|
43
44
|
|
|
44
|
-
const newProducts = newData.flat().map((product) => {
|
|
45
|
+
const newProducts = newData.flat().map((product, index) => {
|
|
45
46
|
const PRECIO_AL_PUBLICO = isNaN(product.PRECIO_AL_PUBLICO) ? 0.00 : product.PRECIO_AL_PUBLICO
|
|
46
47
|
const VALOR_DE_COMPRA = isNaN(product.VALOR_DE_COMPRA) ? 0.00 : product.VALOR_DE_COMPRA
|
|
48
|
+
const validationErrors = validateProductDataExcel(product, index)
|
|
49
|
+
|
|
47
50
|
const code = RandomCode(9)
|
|
48
51
|
return {
|
|
49
52
|
...product,
|
|
50
53
|
CANTIDAD: isNaN(product.CANTIDAD) ? 1 : product.CANTIDAD,
|
|
51
54
|
ORIGINAL_CANTIDAD: isNaN(product.CANTIDAD) ? 1 : product.CANTIDAD,
|
|
52
55
|
free: false,
|
|
56
|
+
product: product?.DESCRIPCION,
|
|
53
57
|
pCode: code,
|
|
54
58
|
editing: false,
|
|
55
59
|
PRECIO_AL_PUBLICO,
|
|
56
|
-
VALOR_DE_COMPRA
|
|
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
|
+
})
|
|
57
76
|
}
|
|
58
77
|
})
|
|
59
78
|
|
|
@@ -80,7 +99,7 @@ export const useUploadProducts = ({
|
|
|
80
99
|
})
|
|
81
100
|
} catch (error) {
|
|
82
101
|
sendNotification({
|
|
83
|
-
description: 'Un
|
|
102
|
+
description: 'Un error ha ocurrido mientras se cargaba el archivo de productos.',
|
|
84
103
|
title: 'Error',
|
|
85
104
|
backgroundColor: 'error'
|
|
86
105
|
})
|
|
@@ -188,27 +207,38 @@ export const useUploadProducts = ({
|
|
|
188
207
|
setData((prevData) => {
|
|
189
208
|
// Validar que el índice es un número válido
|
|
190
209
|
if (typeof productIndex !== 'number' || productIndex < 0 || productIndex >= prevData.length) {
|
|
191
|
-
|
|
210
|
+
sendNotification({
|
|
211
|
+
description: `Invalid product index: ${productIndex}`,
|
|
212
|
+
title: 'Error',
|
|
213
|
+
backgroundColor: 'error'
|
|
214
|
+
})
|
|
192
215
|
return prevData // Retorna el estado anterior si el índice es inválido
|
|
193
216
|
}
|
|
194
217
|
|
|
195
218
|
// Validar que el producto existe y tiene la propiedad 'editing'
|
|
196
219
|
const product = prevData[productIndex]
|
|
197
220
|
if (!product || typeof product.editing === 'undefined') {
|
|
198
|
-
|
|
221
|
+
sendNotification({
|
|
222
|
+
description: `Product or "editing" property not found for index: ${productIndex}`,
|
|
223
|
+
title: 'Error',
|
|
224
|
+
backgroundColor: 'error'
|
|
225
|
+
})
|
|
199
226
|
return prevData // Retorna el estado anterior si no se encuentra el producto
|
|
200
227
|
}
|
|
201
228
|
|
|
202
229
|
// Evitar cambios innecesarios si el estado de 'editing' no cambia
|
|
203
230
|
const updatedEditingStatus = !product.editing
|
|
204
231
|
if (product.editing === updatedEditingStatus) {
|
|
205
|
-
|
|
232
|
+
sendNotification({
|
|
233
|
+
description: `Product "editing" status is already: ${updatedEditingStatus}`,
|
|
234
|
+
title: 'Info',
|
|
235
|
+
backgroundColor: 'info'
|
|
236
|
+
})
|
|
206
237
|
return prevData // No actualiza si el estado es el mismo
|
|
207
238
|
}
|
|
208
239
|
|
|
209
240
|
// Crear una nueva copia de los datos actualizando solo el producto específico
|
|
210
241
|
return prevData.map((product, index) => {
|
|
211
|
-
console.log(index === productIndex)
|
|
212
242
|
return index === productIndex
|
|
213
243
|
? {
|
|
214
244
|
...product,
|
|
@@ -227,12 +257,13 @@ export const useUploadProducts = ({
|
|
|
227
257
|
* @param {number} productIndex - The index of the product to update.
|
|
228
258
|
*/
|
|
229
259
|
const handleSuccessUpdateQuantity = (productIndex) => {
|
|
260
|
+
const product = data[productIndex]
|
|
230
261
|
setData((prevData) => {
|
|
231
262
|
// Validar que `CANTIDAD` sea un número entero
|
|
232
263
|
const product = prevData[productIndex]
|
|
233
264
|
if (!Number.isInteger(product?.CANTIDAD)) {
|
|
234
265
|
sendNotification({
|
|
235
|
-
description: '
|
|
266
|
+
description: 'La cantidad debe ser un valor entero.',
|
|
236
267
|
title: 'Error',
|
|
237
268
|
backgroundColor: 'error'
|
|
238
269
|
})
|
|
@@ -256,12 +287,13 @@ export const useUploadProducts = ({
|
|
|
256
287
|
|
|
257
288
|
return filteredData
|
|
258
289
|
})
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
290
|
+
if (product.CANTIDAD !== data[productIndex].ORIGINAL_CANTIDAD) {
|
|
291
|
+
sendNotification({
|
|
292
|
+
description: `Cantidad actualizada con éxito para el producto ${product.NOMBRE} #${productIndex}.`,
|
|
293
|
+
title: 'Éxito',
|
|
294
|
+
backgroundColor: 'success'
|
|
295
|
+
})
|
|
296
|
+
}
|
|
265
297
|
}
|
|
266
298
|
|
|
267
299
|
const handleChangeQuantity = (event, productIndex) => {
|