npm-pkg-hook 1.10.4 → 1.10.7

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.10.4"
50
+ "version": "1.10.7"
51
51
  }
@@ -123,3 +123,10 @@ export * from './useGetStoreCookie'
123
123
  export * from './getGlobalSession'
124
124
  export * from './handleLogin'
125
125
  export * from './useInventory'
126
+ export * from './useStockMovements'
127
+ export * from './useTopProductsMovements'
128
+ export * from './useTotalProductsSold'
129
+ export * from './useTotalProductsInStock/index'
130
+ export * from './useTotalAllSales/index'
131
+ export * from './useTotalProductsSolded'
132
+ export * from './useWeeklyStockMovement'
@@ -74,73 +74,7 @@ export const GET_ALL_EMPLOYEE_STORE = gql`
74
74
  }
75
75
  }
76
76
  `
77
- export const GET_ALL_PRODUCT_STORE = gql`
78
- query productFoodsAll(
79
- $search: String
80
- $min: Int
81
- $max: Int
82
- $gender: [String]
83
- $pState: Int
84
- $desc: [String]
85
- $categories: [ID]
86
- $fromDate: DateTime
87
- $toDate: DateTime
88
- ) {
89
- productFoodsAll(
90
- search: $search
91
- min: $min
92
- max: $max
93
- gender: $gender
94
- desc: $desc
95
- pState: $pState
96
- categories: $categories
97
- toDate: $toDate
98
- fromDate: $fromDate
99
- ) {
100
- pId
101
- sizeId #Talla
102
- colorId #Color
103
- cId #Country
104
- dId #Department
105
- ctId #Cuidad
106
- fId #Características
107
- pName
108
- ProPrice
109
- ProDescuento
110
- free
111
- manageStock
112
- ProUniDisponibles
113
- ProDescription
114
- ProProtegido
115
- ProAssurance
116
- ValueDelivery
117
- ProStar
118
- sTateLogistic
119
- ProImage
120
- ProWidth
121
- ProHeight
122
- ProLength
123
- ProWeight
124
- ProQuantity
125
- ProOutstanding
126
- pDatCre
127
- pDatMod
128
- ProDelivery
129
- ProVoltaje
130
- stock
131
- pState
132
- feat {
133
- fId
134
- thpId
135
- hpqrQuestion
136
- }
137
- area {
138
- aId
139
- aName
140
- }
141
- }
142
- }
143
- `
77
+
144
78
  export const GET_ALL_RATING_START_STORE = gql`
145
79
  query getAllRatingStar($idStore: ID) {
146
80
  getAllRatingStar(idStore: $idStore) {
@@ -1,38 +1,38 @@
1
- import { useState, useEffect } from 'react';
1
+ import { useState, useEffect } from 'react'
2
2
 
3
3
  export const usePWAInstall = () => {
4
- const [deferredPrompt, setDeferredPrompt] = useState(null);
5
- const [isInstallable, setIsInstallable] = useState(false);
4
+ const [deferredPrompt, setDeferredPrompt] = useState(null)
5
+ const [isInstallable, setIsInstallable] = useState(false)
6
6
 
7
7
  useEffect(() => {
8
8
  const handleBeforeInstallPrompt = (e) => {
9
- e.preventDefault(); // Evita que el navegador muestre el diálogo automáticamente
10
- setDeferredPrompt(e); // Almacena el evento para que puedas llamarlo más tarde
11
- setIsInstallable(true); // Marca que la PWA es instalable
12
- };
9
+ e.preventDefault() // Evita que el navegador muestre el diálogo automáticamente
10
+ setDeferredPrompt(e) // Almacena el evento para que puedas llamarlo más tarde
11
+ setIsInstallable(true) // Marca que la PWA es instalable
12
+ }
13
13
 
14
- window.addEventListener('beforeinstallprompt', handleBeforeInstallPrompt);
14
+ window.addEventListener('beforeinstallprompt', handleBeforeInstallPrompt)
15
15
 
16
16
  return () => {
17
- window.removeEventListener('beforeinstallprompt', handleBeforeInstallPrompt);
18
- };
19
- }, []);
17
+ window.removeEventListener('beforeinstallprompt', handleBeforeInstallPrompt)
18
+ }
19
+ }, [])
20
20
 
21
21
  const installPWA = () => {
22
22
  if (deferredPrompt) {
23
- deferredPrompt.prompt();
23
+ deferredPrompt.prompt()
24
24
 
25
25
  deferredPrompt.userChoice.then((choiceResult) => {
26
26
  if (choiceResult.outcome === 'accepted') {
27
- console.log('User accepted the install prompt');
27
+ console.log('User accepted the install prompt')
28
28
  } else {
29
- console.log('User dismissed the install prompt');
29
+ console.log('User dismissed the install prompt')
30
30
  }
31
- setDeferredPrompt(null); // Limpia el evento después de usarlo
32
- setIsInstallable(false); // Oculta el botón de instalación
33
- });
31
+ setDeferredPrompt(null) // Limpia el evento después de usarlo
32
+ setIsInstallable(false) // Oculta el botón de instalación
33
+ })
34
34
  }
35
- };
35
+ }
36
36
 
37
- return { isInstallable, installPWA };
38
- };
37
+ return { isInstallable, installPWA }
38
+ }
@@ -14,51 +14,68 @@ import {
14
14
  export * from './useEditProduct'
15
15
 
16
16
  export const useProductsFood = ({
17
- categories,
18
- desc,
17
+ categories = [],
18
+ desc = [],
19
19
  fetchPolicy = 'cache-and-network',
20
- fromDate,
21
- gender,
20
+ fromDate = null,
21
+ gender = [],
22
22
  max = 100,
23
- min,
23
+ min = null,
24
24
  pState,
25
25
  search = null,
26
- toDate
26
+ toDate = null,
27
+ dataSale = [],
28
+ isShopppingCard = false
27
29
  }) => {
28
- // const [productsFood, setProductsFood] = useState([])
29
30
  const [showMore, setShowMore] = useState(500)
30
- const {
31
- data,
32
- loading,
33
- fetchMore,
34
- error,
35
- called
36
- } = useQuery(GET_ALL_PRODUCT_STORE, {
31
+
32
+ const { data, loading, fetchMore, refetch, error, called } = useQuery(GET_ALL_PRODUCT_STORE, {
37
33
  fetchPolicy,
38
34
  notifyOnNetworkStatusChange: true,
39
35
  nextFetchPolicy: 'cache-first',
40
36
  refetchWritePolicy: 'merge',
41
- variables:
42
- {
43
- categories: categories || [],
44
- desc: desc || [],
45
- fromDate: fromDate || null,
46
- gender: gender || [],
47
- max: max || null,
48
- min: min || null,
37
+ variables: {
38
+ categories,
39
+ desc,
40
+ fromDate,
41
+ gender,
42
+ max,
43
+ min,
49
44
  pState,
50
- search: search ?? search,
51
- toDate: toDate || null
45
+ search,
46
+ toDate
52
47
  }
53
48
  })
54
49
 
55
- const productsFood = data?.productFoodsAll
50
+ const productsFood = data?.productFoodsAll?.data ?? []
51
+
52
+ if (!isShopppingCard) {
53
+ return [
54
+ productsFood, {
55
+ pagination: data?.productFoodsAll?.pagination || {},
56
+ loading: called ? false : loading,
57
+ error,
58
+ showMore,
59
+ fetchMore,
60
+ refetch,
61
+ setShowMore
62
+ }
63
+ ]
64
+ }
65
+
66
+ const updatedProductsFood = productsFood.map(product => ({
67
+ ...product,
68
+ existsInSale: dataSale.some(item => item.pId === product.pId)
69
+ }));
70
+
56
71
  return [
57
- productsFood, {
58
- error,
72
+ updatedProductsFood, {
73
+ pagination: data?.productFoodsAll?.pagination || {},
59
74
  loading: called ? false : loading,
75
+ error,
60
76
  showMore,
61
77
  fetchMore,
78
+ refetch,
62
79
  setShowMore
63
80
  }
64
81
  ]
@@ -76,7 +76,7 @@ export const GET_ALL_EMPLOYEE_STORE = gql`
76
76
  `
77
77
 
78
78
  export const GET_ALL_PRODUCT_STORE = gql`
79
- query productFoodsAll(
79
+ query productFoodsAll(
80
80
  $search: String
81
81
  $min: Int
82
82
  $max: Int
@@ -86,6 +86,7 @@ export const GET_ALL_PRODUCT_STORE = gql`
86
86
  $categories: [ID]
87
87
  $fromDate: DateTime
88
88
  $toDate: DateTime
89
+ $page: Int
89
90
  ) {
90
91
  productFoodsAll(
91
92
  search: $search
@@ -97,7 +98,17 @@ export const GET_ALL_PRODUCT_STORE = gql`
97
98
  categories: $categories
98
99
  toDate: $toDate
99
100
  fromDate: $fromDate
101
+ page: $page
100
102
  ) {
103
+ success
104
+ message
105
+ pagination {
106
+ totalRecords
107
+ totalPages
108
+ currentPage
109
+ __typename
110
+ }
111
+ data {
101
112
  pId
102
113
  sizeId #Talla
103
114
  colorId #Color
@@ -149,6 +160,7 @@ export const GET_ALL_PRODUCT_STORE = gql`
149
160
  aName
150
161
  }
151
162
  }
163
+ }
152
164
  }
153
165
  `
154
166
  export const GET_ALL_RATING_START_STORE = gql`
@@ -34,7 +34,7 @@ export const useReport = ({
34
34
  })
35
35
 
36
36
  const totalSales = totalSalesData?.getAllSalesStoreTotal ?? {}
37
-
37
+ console.log(totalSales)
38
38
  return {
39
39
  getAllSalesStore: lazyQuery ? getAllSalesStore : () => { }, // Return function only if in lazy mode
40
40
  data: lazyQuery ? lazyDataSales : data, // Use data from lazy query if available
@@ -75,6 +75,7 @@ export const useSales = ({
75
75
  const [search, setSearch] = useState('')
76
76
  const [datCat] = useCatWithProduct({})
77
77
  const [categories, setCategories] = useState([])
78
+ const [currentPage, setCurrentPage] = useState(1)
78
79
  useEffect(() => {
79
80
  setCategories(datCat)
80
81
  }, [datCat])
@@ -102,6 +103,9 @@ export const useSales = ({
102
103
  const [valuesDates, setValuesDates] = useState(() => {
103
104
  return { fromDate: yearMonthDay, toDate: '' }
104
105
  })
106
+ const [product, setProduct] = useState({
107
+ PRODUCT: {}
108
+ })
105
109
  const [loadingExtraProduct, setLoadingExtraProduct] = useState(false)
106
110
  const [dataOptional, setDataOptional] = useState([])
107
111
  const [dataExtra, setDataExtra] = useState([])
@@ -134,12 +138,9 @@ export const useSales = ({
134
138
  }
135
139
  }
136
140
  )
137
- const [product, setProduct] = useState({
138
- PRODUCT: {}
139
- })
140
- const [productFoodsOne, { data: dataProduct }] = useLazyQuery(
141
- GET_ONE_PRODUCTS_FOOD
142
- )
141
+
142
+ const [productFoodsOne, { data: dataProduct }] = useLazyQuery(GET_ONE_PRODUCTS_FOOD)
143
+
143
144
  const [ExtProductFoodsSubOptionalAll, { loading: loadingExtProductFoodsSubOptionalAll }] = useLazyQuery(
144
145
  GET_EXTRAS_PRODUCT_FOOD_OPTIONAL,
145
146
  {
@@ -153,7 +154,13 @@ export const useSales = ({
153
154
  setDataExtra([])
154
155
  }
155
156
  })
156
- const [productsFood, { loading, fetchMore }] = useProductsFood({
157
+
158
+ const [productsFood, {
159
+ loading,
160
+ fetchMore,
161
+ pagination,
162
+ refetch
163
+ }] = useProductsFood({
157
164
  // @ts-ignore
158
165
  search: search?.length >= 4 ? search : '',
159
166
  gender: [],
@@ -162,8 +169,17 @@ export const useSales = ({
162
169
  toDate: valuesDates?.toDate,
163
170
  fromDate: valuesDates?.fromDate,
164
171
  max: showMore,
165
- min: 0
172
+ min: 0,
173
+ isShopppingCard: true,
174
+ dataSale: (Array.isArray(saveDataState?.PRODUCT) && saveDataState?.PRODUCT) ?? [],
175
+ callback: () => { return null }
166
176
  })
177
+
178
+ const handlePageChange = (pageNumber) => {
179
+ setCurrentPage(pageNumber)
180
+ refetch({ page: pageNumber })
181
+ }
182
+
167
183
  const handleChangeCheck = (caId) => {
168
184
  // @ts-ignore
169
185
  setCategories((prev) => {
@@ -176,7 +192,6 @@ export const useSales = ({
176
192
  })
177
193
  })
178
194
  }
179
-
180
195
  const max = productsFood?.reduce(function (a, b) {
181
196
  return Math.max(a, b?.ProPrice || 0)
182
197
  }, 0)
@@ -367,7 +382,7 @@ export const useSales = ({
367
382
 
368
383
  // Validar si se intenta superar el stock disponible
369
384
  const finalQuantity = Math.min(value, productExist.stock)
370
- if (value > productExist.stock) {
385
+ if ((value > productExist.stock) && productExist.manageStock) {
371
386
  sendNotification({
372
387
  title: 'Stock insuficiente',
373
388
  backgroundColor: 'warning',
@@ -469,7 +484,8 @@ export const useSales = ({
469
484
  }
470
485
 
471
486
  // Validar si se supera el stock
472
- if (newQuantity > OurProduct?.stock) {
487
+ console.log(OurProduct)
488
+ if (newQuantity >= OurProduct?.stock && OurProduct?.manageStock) {
473
489
  sendNotification({
474
490
  title: 'Stock insuficiente',
475
491
  backgroundColor: 'warning',
@@ -477,7 +493,6 @@ export const useSales = ({
477
493
  })
478
494
  return items // Retornar el producto sin modificar
479
495
  }
480
-
481
496
  return {
482
497
  ...items,
483
498
  ProQuantity: newQuantity,
@@ -776,8 +791,8 @@ export const useSales = ({
776
791
  const OurProduct = productsFood?.find((item) => item.pId === pId)
777
792
  const isFree = productExist?.free
778
793
  const currentQuantity = productExist?.ProQuantity || 0
779
- console.log('currentQuantity', productExist)
780
- if (productExist?.manageStock && isStockInsufficient(currentQuantity, stock)) {
794
+
795
+ if (OurProduct?.manageStock && isStockInsufficient(currentQuantity, OurProduct?.stock)) {
781
796
  sendAlertStock(stock)
782
797
  return state
783
798
  }
@@ -1062,7 +1077,6 @@ export const useSales = ({
1062
1077
  cache.modify({
1063
1078
  fields: {
1064
1079
  productFoodsAll (existingProductFoodsAll = []) {
1065
- console.log('existingProductFoodsAll', existingProductFoodsAll)
1066
1080
  return existingProductFoodsAll
1067
1081
  }
1068
1082
  }
@@ -1276,6 +1290,16 @@ export const useSales = ({
1276
1290
  // Filtrar los productos de productsFood por los carProIds obtenidos
1277
1291
  const filteredProducts = filterProductsByCarProId(productsFood, carProIds)
1278
1292
 
1293
+ const allProducts = useMemo(() => {
1294
+ const productMap = new Map(data.PRODUCT.map(item => [String(item.pId), item.ProQuantity || 0]))
1295
+
1296
+ return filteredProducts.map(product => ({
1297
+ ...product,
1298
+ existsInSale: productMap.has(String(product.pId)),
1299
+ ProQuantity: productMap.get(String(product.pId)) || 0
1300
+ }))
1301
+ }, [data.PRODUCT, filteredProducts])
1302
+
1279
1303
  return {
1280
1304
  loading: loading || loadingSale,
1281
1305
  loadingExtraProduct,
@@ -1300,7 +1324,7 @@ export const useSales = ({
1300
1324
  search,
1301
1325
  values,
1302
1326
  initialStateSales,
1303
- productsFood: filteredProducts,
1327
+ productsFood: allProducts,
1304
1328
  modalItem,
1305
1329
  sumExtraProducts,
1306
1330
  oneProductToComment: oneProductToComment ?? null,
@@ -1308,13 +1332,16 @@ export const useSales = ({
1308
1332
  dataOptional: dataOptional || [],
1309
1333
  dataExtra: dataExtra || [],
1310
1334
  fetchMore,
1335
+ pagination,
1311
1336
  discount,
1312
1337
  datCat: categories,
1338
+ currentPage,
1313
1339
  loadingProduct: loading,
1314
1340
  handleChangeCheck,
1315
1341
  errors,
1316
1342
  handleUpdateAllExtra,
1317
1343
  dispatch,
1344
+ handlePageChange,
1318
1345
  handleComment,
1319
1346
  setModalItem,
1320
1347
  handleChangeFilter,
@@ -1,24 +1,23 @@
1
1
  import { useApolloClient, useQuery } from '@apollo/client'
2
- import { useState } from 'react'
3
2
  import { GET_ALL_COUNT_SALES } from './queries'
4
3
 
5
4
  export const useTotalSales = () => {
6
- const [count, setCount] = useState(0)
7
5
  const client = useApolloClient()
8
6
 
9
- const { loading, error } = useQuery(GET_ALL_COUNT_SALES, {
10
- onCompleted: (data) => {
11
- if (data) {
12
- client.writeQuery({ query: GET_ALL_COUNT_SALES, data }) // Almacena la respuesta en la cache
13
- }
14
- if (data?.getTodaySales) {
15
- setCount(data?.getTodaySales || 0)
16
- }
17
- },
7
+ const { data, loading, error } = useQuery(GET_ALL_COUNT_SALES, {
18
8
  fetchPolicy: 'cache-and-network',
19
9
  notifyOnNetworkStatusChange: true,
20
10
  nextFetchPolicy: 'cache-first',
21
11
  refetchWritePolicy: 'merge'
22
12
  })
23
- return [count, { loading, error }]
13
+
14
+ // Guarda la respuesta en la caché manualmente (opcional)
15
+ if (data) {
16
+ client.writeQuery({ query: GET_ALL_COUNT_SALES, data })
17
+ }
18
+
19
+ return [data?.getTodaySales || 0, {
20
+ loading,
21
+ error
22
+ }]
24
23
  }
@@ -0,0 +1,16 @@
1
+ export const fillMissingDates = (data, days = 7) => {
2
+ const today = new Date()
3
+ const filledData = []
4
+
5
+ for (let i = days - 1; i >= 0; i--) {
6
+ const date = new Date()
7
+ date.setDate(today.getDate() - i)
8
+
9
+ const formattedDate = date.toISOString().split('T')[0] // "YYYY-MM-DD"
10
+ const existingData = data.find(item => item.date === formattedDate)
11
+
12
+ filledData.push(existingData || { date: formattedDate, TotalIn: 0, TotalOut: 0, TotalAdjustment: 0 })
13
+ }
14
+
15
+ return filledData
16
+ }
@@ -0,0 +1,38 @@
1
+ import { useState, useEffect } from 'react'
2
+ import { useQuery, gql } from '@apollo/client'
3
+ import { fillMissingDates } from './helpers'
4
+
5
+ const GET_STOCK_MOVEMENTS = gql`
6
+ query {
7
+ getStockMovementsByDay {
8
+ date
9
+ total_in,
10
+ total_adjustment
11
+ total_out
12
+ }
13
+ }
14
+ `
15
+
16
+ /**
17
+ * Custom hook to fetch stock movements data for visualization.
18
+ * @returns {Object} { data, loading, error }
19
+ */
20
+ export const useStockMovements = () => {
21
+ const { data, loading, error } = useQuery(GET_STOCK_MOVEMENTS)
22
+ const [chartData, setChartData] = useState([])
23
+
24
+ useEffect(() => {
25
+ if (data && data.getStockMovementsByDay) {
26
+ // Transform data to be compatible with Recharts
27
+ const formattedData = data.getStockMovementsByDay.map(entry => ({
28
+ date: entry.date,
29
+ TotalIn: entry.total_in ?? 0,
30
+ TotalOut: entry.total_out ?? 0,
31
+ TotalAdjustment: entry.total_adjustment ?? 0
32
+ }))
33
+ setChartData(formattedData)
34
+ }
35
+ }, [data])
36
+
37
+ return [fillMissingDates(chartData), { loading, error }]
38
+ }
@@ -0,0 +1,27 @@
1
+ import { useQuery, gql } from '@apollo/client'
2
+
3
+ /**
4
+ * GraphQL query to fetch top-selling products movements
5
+ */
6
+ const GET_TOP_PRODUCTS_MOVEMENTS = gql`
7
+ query {
8
+ getTopProductsMovements {
9
+ productName
10
+ idProduct
11
+ totalMovements
12
+ }
13
+ }
14
+ `
15
+
16
+ /**
17
+ * Custom hook to fetch and return the top-selling products movements
18
+ * @returns {Object} - { data, loading, error }
19
+ */
20
+ export const useTopProductsMovements = () => {
21
+ const { data, loading, error } = useQuery(GET_TOP_PRODUCTS_MOVEMENTS)
22
+
23
+ return [data?.getTopProductsMovements, {
24
+ loading,
25
+ error
26
+ }]
27
+ }
@@ -0,0 +1,25 @@
1
+ import { useQuery, gql } from '@apollo/client'
2
+
3
+ const GET_TOTAL_SALES = gql`
4
+ query totalSales {
5
+ totalSales {
6
+ success
7
+ message
8
+ totalSales
9
+ }
10
+ }
11
+ `
12
+
13
+ /**
14
+ * Custom hook to fetch total sales from GraphQL API.
15
+ * @returns {Object} An object containing total sales, loading state, error, and refetch function.
16
+ */
17
+ export const useTotalAllSales = () => {
18
+ const { data, loading, error, refetch } = useQuery(GET_TOTAL_SALES)
19
+
20
+ return [data?.totalSales?.totalSales, {
21
+ loading,
22
+ error,
23
+ refetch
24
+ }]
25
+ }
@@ -0,0 +1,23 @@
1
+ import { useQuery, gql } from '@apollo/client'
2
+
3
+ /**
4
+ * GraphQL query to fetch total products in stock.
5
+ */
6
+ const GET_TOTAL_PRODUCTS_IN_STOCK = gql`
7
+ query getTotalProductsInStock {
8
+ getTotalProductsInStock
9
+ }
10
+ `
11
+
12
+ /**
13
+ * Custom hook to fetch total products in stock.
14
+ * @returns {Object} - { totalProductsInStock, loading, error }
15
+ */
16
+ export const useTotalProductsInStock = () => {
17
+ const { data, loading, error } = useQuery(GET_TOTAL_PRODUCTS_IN_STOCK)
18
+
19
+ return [data?.getTotalProductsInStock ?? 0, {
20
+ loading,
21
+ error
22
+ }]
23
+ }
@@ -0,0 +1,23 @@
1
+ import { useQuery, gql } from '@apollo/client'
2
+
3
+ /**
4
+ * GraphQL query to fetch total products sold.
5
+ */
6
+ const GET_TOTAL_PRODUCTS_SOLD = gql`
7
+ query getTotalSalesSold {
8
+ getTotalSalesSold
9
+ }
10
+ `
11
+
12
+ /**
13
+ * Custom hook to fetch total products sold.
14
+ * @returns {Object} - { totalProductsSold, loading, error }
15
+ */
16
+ export const useTotalProductsSold = () => {
17
+ const { data, loading, error } = useQuery(GET_TOTAL_PRODUCTS_SOLD)
18
+
19
+ return [data?.getTotalSalesSold || 0, {
20
+ loading,
21
+ error
22
+ }]
23
+ }
@@ -0,0 +1,20 @@
1
+ import { useQuery, gql } from '@apollo/client'
2
+
3
+ const GET_TOTAL_PRODUCTS_SOLD = gql`
4
+ query {
5
+ getTotalProductsSold
6
+ }
7
+ `
8
+
9
+ /**
10
+ * Custom hook to fetch the total number of products sold.
11
+ * @returns {{ totalSold: number, loading: boolean, error: any }}
12
+ */
13
+ export const useTotalProductsSolded = () => {
14
+ const { data, loading, error } = useQuery(GET_TOTAL_PRODUCTS_SOLD)
15
+
16
+ return [data?.getTotalProductsSold, {
17
+ loading,
18
+ error
19
+ }]
20
+ }
@@ -38,7 +38,7 @@ export const useUpdateMultipleProducts = ({
38
38
  sTateLogistic: 1,
39
39
  ProStar: 0,
40
40
  stock,
41
- ProImage: null,
41
+ ProImage: '/images/placeholder-image.webp',
42
42
  vat,
43
43
  ProBarCode: String(ProBarCode) || '',
44
44
  ProHeight: null,
@@ -59,7 +59,9 @@ export const useUploadProducts = ({
59
59
  pCode: code,
60
60
  editing: false,
61
61
  PRECIO_AL_PUBLICO,
62
+ ProImage: '/images/placeholder-image.webp',
62
63
  VALOR_DE_COMPRA,
64
+ manageStock: true,
63
65
  errors: validationErrors.length > 0 ? validationErrors : null
64
66
  }
65
67
  })
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Fills missing weeks for the last 7 weeks, ensuring continuous data.
3
+ * If a week is missing, it fills it with totalOut: 0 and percentageChange: "N/A".
4
+ *
5
+ * @param {Array} data - Array of weekly stock movement objects.
6
+ * @returns {Array} - Filled data ensuring the last 7 weeks are covered.
7
+ */
8
+ export const fillLast7Weeks = (data) => {
9
+ const today = new Date()
10
+ const last7Weeks = []
11
+
12
+ // Generar las últimas 7 semanas (cada lunes)
13
+ for (let i = 6; i >= 0; i--) {
14
+ const weekDate = new Date(today)
15
+ weekDate.setDate(today.getDate() - today.getDay() - (i * 7) + 1) // Ajustar para que sea lunes
16
+ const weekStart = weekDate.toISOString().split('T')[0] // Formato YYYY-MM-DD
17
+ last7Weeks.push(weekStart)
18
+ }
19
+
20
+ // Mapear los datos existentes para acceso rápido
21
+ const dataMap = new Map(data.map(item => [item.weekStart, item]))
22
+
23
+ // Construir la nueva lista asegurando que todas las semanas estén presentes
24
+ return last7Weeks.map(weekStart => (
25
+ dataMap.get(weekStart) || {
26
+ weekStart,
27
+ totalOut: 0,
28
+ prevTotalOut: null,
29
+ percentageChange: 'N/A'
30
+ }
31
+ ))
32
+ }
@@ -0,0 +1,51 @@
1
+ import { gql, useQuery } from '@apollo/client'
2
+ import { fillLast7Weeks } from './helpers' // Asegúrate de importar el helper
3
+
4
+ const GET_WEEKLY_STOCK_MOVEMENT = gql`
5
+ query GetStockMovementPercentageChange {
6
+ getStockMovementWeeklyComparison {
7
+ weekStart
8
+ totalOut
9
+ prevTotalOut
10
+ percentageChange
11
+ }
12
+ }
13
+ `
14
+
15
+ /**
16
+ * Custom hook to fetch and format weekly stock movement data.
17
+ * @returns {Object} - { data, loading, error, formattedData }
18
+ */
19
+ export const useWeeklyStockMovement = () => {
20
+ const { data, loading, error } = useQuery(GET_WEEKLY_STOCK_MOVEMENT)
21
+
22
+ // Transform data and fill missing weeks
23
+ const rawData = data?.getStockMovementWeeklyComparison || []
24
+ const formattedData = fillLast7Weeks(
25
+ rawData.map(item => ({
26
+ ...item,
27
+ percentageChange: formatPercentageChange(item.percentageChange)
28
+ }))
29
+ )
30
+
31
+ return [formattedData, { loading, error }]
32
+ }
33
+
34
+ /**
35
+ * Ensures percentageChange is a valid string percentage, clamping between -100% and 100%.
36
+ *
37
+ * @param {string | null} percentageChange - Raw percentage change value.
38
+ * @returns {string} - Formatted and clamped percentage change.
39
+ */
40
+ const formatPercentageChange = (percentageChange) => {
41
+ if (percentageChange === null) return 'N/A'
42
+
43
+ // Convertir a número
44
+ let parsedValue = parseFloat(percentageChange)
45
+
46
+ // Clampear entre -100% y 100%
47
+ if (isNaN(parsedValue)) return 'N/A'
48
+ parsedValue = Math.max(-100, Math.min(100, parsedValue))
49
+
50
+ return `${parsedValue.toFixed(1)}`
51
+ }
@@ -0,0 +1,31 @@
1
+ export class UtilDateRange {
2
+ constructor (date = new Date()) {
3
+ this.date = new Date(date) // Asegura que sea un objeto Date
4
+ }
5
+
6
+ toLocalTime (date) {
7
+ const offset = -5 // UTC-5 (ajustar si es necesario)
8
+ const localDate = new Date(date)
9
+ localDate.setHours(localDate.getHours() + offset)
10
+ return localDate
11
+ }
12
+
13
+ getStartOfDay () {
14
+ const localDate = this.toLocalTime(this.date)
15
+ localDate.setHours(0, 0, 0, 0)
16
+ return localDate
17
+ }
18
+
19
+ getEndOfDay () {
20
+ const localDate = this.toLocalTime(this.date)
21
+ localDate.setHours(23, 59, 59, 999)
22
+ return localDate
23
+ }
24
+
25
+ getRange () {
26
+ return {
27
+ start: this.getStartOfDay(),
28
+ end: this.getEndOfDay()
29
+ }
30
+ }
31
+ }
@@ -210,3 +210,5 @@ export const paymentMethodCards = [
210
210
  ]
211
211
 
212
212
  export const CATEGORY_EMPTY = 'NINGUNO'
213
+
214
+ export * from './UtilDateRange'