npm-pkg-hook 1.10.6 → 1.10.8

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.6"
50
+ "version": "1.10.8"
51
51
  }
@@ -14,6 +14,7 @@ export * from './useStoreTable/index'
14
14
  export * from './useSubscriptionValidation'
15
15
  export * from './convertToMilitaryTime'
16
16
  export * from './useRoles'
17
+ export * from './useLocalBackendIp'
17
18
  export * from './statusOpenStores'
18
19
  export * from './completeSchedules'
19
20
  export * from './useLogout/helpers/BroadcastChannel'
@@ -129,3 +130,4 @@ export * from './useTotalProductsSold'
129
130
  export * from './useTotalProductsInStock/index'
130
131
  export * from './useTotalAllSales/index'
131
132
  export * from './useTotalProductsSolded'
133
+ export * from './useWeeklyStockMovement'
@@ -10,13 +10,15 @@ export const useConnection = ({ setConnectionStatus }) => {
10
10
  // Attaching event handler for the load event
11
11
  // window.addEventListener('load', updateConnectionStatus);
12
12
 
13
- // Attaching event handler for the online event
14
- window.addEventListener('online', function (e) {
15
- updateConnectionStatus()
16
- })
13
+ if (typeof window !== 'undefined') {
14
+ // Attaching event handler for the online event
15
+ window.addEventListener('online', function () {
16
+ updateConnectionStatus()
17
+ })
17
18
 
18
- // Attaching event handler for the offline event
19
- window.addEventListener('offline', function (e) {
20
- updateConnectionStatus()
21
- })
19
+ // Attaching event handler for the offline event
20
+ window.addEventListener('offline', function () {
21
+ updateConnectionStatus()
22
+ })
23
+ }
22
24
  }
@@ -0,0 +1,25 @@
1
+ import { useQuery, gql } from '@apollo/client'
2
+
3
+ /**
4
+ * GraphQL query to get the local IP of the backend server.
5
+ */
6
+ const GET_LOCAL_BACKEND_IP = gql`
7
+ query GetLocalBackendIp {
8
+ getLocalBackendIp
9
+ }
10
+ `
11
+
12
+ /**
13
+ * Custom hook to fetch the local IP address of the backend server.
14
+ *
15
+ * @returns {Object} - Contains the IP string, loading state, and error.
16
+ */
17
+ export const useLocalBackendIp = () => {
18
+ const { data, loading, error } = useQuery(GET_LOCAL_BACKEND_IP)
19
+
20
+ return {
21
+ ip: data?.getLocalBackendIp || null,
22
+ loading,
23
+ error
24
+ }
25
+ }
@@ -1,14 +1,13 @@
1
1
  import { useEffect, useRef, useState } from "react";
2
- import type { MouseEvent } from "react";
3
2
 
4
- export function useMouse<T extends HTMLElement = any>(
5
- options: { resetOnExit?: boolean } = { resetOnExit: false }
3
+ export function useMouse(
4
+ options: { resetOnExit } = { resetOnExit: false }
6
5
  ) {
7
6
  const [position, setPosition] = useState({ x: 0, y: 0 });
8
7
 
9
- const ref = useRef<T>();
8
+ const ref = useRef();
10
9
 
11
- const setMousePosition = (event: MouseEvent<HTMLElement>) => {
10
+ const setMousePosition = (event) => {
12
11
  if (ref.current) {
13
12
  const rect = event.currentTarget.getBoundingClientRect();
14
13
 
@@ -36,14 +35,14 @@ export function useMouse<T extends HTMLElement = any>(
36
35
 
37
36
  useEffect(() => {
38
37
  const element = ref?.current ? ref.current : document;
39
- element.addEventListener("mousemove", setMousePosition as any);
38
+ element.addEventListener("mousemove", setMousePosition);
40
39
  if (options.resetOnExit)
41
- element.addEventListener("mouseleave", resetMousePosition as any);
40
+ element.addEventListener("mouseleave", resetMousePosition);
42
41
 
43
42
  return () => {
44
- element.removeEventListener("mousemove", setMousePosition as any);
43
+ element.removeEventListener("mousemove", setMousePosition);
45
44
  if (options.resetOnExit)
46
- element.removeEventListener("mouseleave", resetMousePosition as any);
45
+ element.removeEventListener("mouseleave", resetMousePosition);
47
46
  };
48
47
  }, [ref.current]);
49
48
 
@@ -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,47 +14,63 @@ 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
30
  const [showMore, setShowMore] = useState(500)
29
- const {
30
- data,
31
- loading,
32
- fetchMore,
33
- refetch,
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
- const productsFood = data?.productFoodsAll.data ?? []
49
+
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
+
55
71
  return [
56
- productsFood, {
57
- pagination: data?.productFoodsAll.pagination || {},
72
+ updatedProductsFood, {
73
+ pagination: data?.productFoodsAll?.pagination || {},
58
74
  loading: called ? false : loading,
59
75
  error,
60
76
  showMore,
@@ -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
  {
@@ -168,9 +169,11 @@ export const useSales = ({
168
169
  toDate: valuesDates?.toDate,
169
170
  fromDate: valuesDates?.fromDate,
170
171
  max: showMore,
171
- min: 0
172
+ min: 0,
173
+ isShopppingCard: true,
174
+ dataSale: (Array.isArray(saveDataState?.PRODUCT) && saveDataState?.PRODUCT) ?? [],
175
+ callback: () => { return null }
172
176
  })
173
- const [currentPage, setCurrentPage] = useState(1)
174
177
 
175
178
  const handlePageChange = (pageNumber) => {
176
179
  setCurrentPage(pageNumber)
@@ -379,7 +382,7 @@ export const useSales = ({
379
382
 
380
383
  // Validar si se intenta superar el stock disponible
381
384
  const finalQuantity = Math.min(value, productExist.stock)
382
- if (value > productExist.stock) {
385
+ if ((value > productExist.stock) && productExist.manageStock) {
383
386
  sendNotification({
384
387
  title: 'Stock insuficiente',
385
388
  backgroundColor: 'warning',
@@ -481,7 +484,8 @@ export const useSales = ({
481
484
  }
482
485
 
483
486
  // Validar si se supera el stock
484
- if (newQuantity > OurProduct?.stock) {
487
+ console.log(OurProduct)
488
+ if (newQuantity >= OurProduct?.stock && OurProduct?.manageStock) {
485
489
  sendNotification({
486
490
  title: 'Stock insuficiente',
487
491
  backgroundColor: 'warning',
@@ -489,7 +493,6 @@ export const useSales = ({
489
493
  })
490
494
  return items // Retornar el producto sin modificar
491
495
  }
492
-
493
496
  return {
494
497
  ...items,
495
498
  ProQuantity: newQuantity,
@@ -788,7 +791,8 @@ export const useSales = ({
788
791
  const OurProduct = productsFood?.find((item) => item.pId === pId)
789
792
  const isFree = productExist?.free
790
793
  const currentQuantity = productExist?.ProQuantity || 0
791
- if (productExist?.manageStock && isStockInsufficient(currentQuantity, stock)) {
794
+
795
+ if (OurProduct?.manageStock && isStockInsufficient(currentQuantity, OurProduct?.stock)) {
792
796
  sendAlertStock(stock)
793
797
  return state
794
798
  }
@@ -1286,6 +1290,16 @@ export const useSales = ({
1286
1290
  // Filtrar los productos de productsFood por los carProIds obtenidos
1287
1291
  const filteredProducts = filterProductsByCarProId(productsFood, carProIds)
1288
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
+
1289
1303
  return {
1290
1304
  loading: loading || loadingSale,
1291
1305
  loadingExtraProduct,
@@ -1310,7 +1324,7 @@ export const useSales = ({
1310
1324
  search,
1311
1325
  values,
1312
1326
  initialStateSales,
1313
- productsFood: filteredProducts,
1327
+ productsFood: allProducts,
1314
1328
  modalItem,
1315
1329
  sumExtraProducts,
1316
1330
  oneProductToComment: oneProductToComment ?? null,
@@ -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
  }
@@ -6,10 +6,10 @@ export const fillMissingDates = (data, days = 7) => {
6
6
  const date = new Date()
7
7
  date.setDate(today.getDate() - i)
8
8
 
9
- const formattedDate = date.toLocaleDateString('es-ES') // "dd/mm/yyyy"
9
+ const formattedDate = date.toISOString().split('T')[0] // "YYYY-MM-DD"
10
10
  const existingData = data.find(item => item.date === formattedDate)
11
11
 
12
- filledData.push(existingData || { date: formattedDate, TotalIn: 0, TotalOut: 0 })
12
+ filledData.push(existingData || { date: formattedDate, TotalIn: 0, TotalOut: 0, TotalAdjustment: 0 })
13
13
  }
14
14
 
15
15
  return filledData
@@ -6,7 +6,8 @@ const GET_STOCK_MOVEMENTS = gql`
6
6
  query {
7
7
  getStockMovementsByDay {
8
8
  date
9
- total_in
9
+ total_in,
10
+ total_adjustment
10
11
  total_out
11
12
  }
12
13
  }
@@ -24,9 +25,10 @@ export const useStockMovements = () => {
24
25
  if (data && data.getStockMovementsByDay) {
25
26
  // Transform data to be compatible with Recharts
26
27
  const formattedData = data.getStockMovementsByDay.map(entry => ({
27
- date: new Date(entry.date).toLocaleDateString(),
28
- TotalIn: entry.total_in,
29
- TotalOut: entry.total_out
28
+ date: entry.date,
29
+ TotalIn: entry.total_in ?? 0,
30
+ TotalOut: entry.total_out ?? 0,
31
+ TotalAdjustment: entry.total_adjustment ?? 0
30
32
  }))
31
33
  setChartData(formattedData)
32
34
  }
@@ -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'