npm-pkg-hook 1.12.7 → 1.12.9
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/.babelrc +0 -0
- package/.env +5 -0
- package/.github/pull_request_template.md +18 -0
- package/.github/workflows/pepeline.yaml +30 -0
- package/dist/index.js +47752 -10080
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +47068 -9612
- package/dist/index.mjs.map +1 -0
- package/eslint.config.mts +153 -0
- package/expire.json +1 -0
- package/jsconfig.json +28 -0
- package/package.json +24 -61
- package/script.txt +7 -0
- package/src/config/client/errors.ts +39 -0
- package/src/config/client/index.ts +1 -0
- package/src/config/content/en.json +5 -0
- package/src/config/content/es.json +5 -0
- package/src/config/content/index.ts +16 -0
- package/src/cookies/index.ts +3 -0
- package/src/hooks/addTenMinutes/index.ts +14 -0
- package/src/hooks/calculateLogLatHaversine/index.ts +41 -0
- package/src/hooks/completeSchedules/index.ts +22 -0
- package/src/hooks/convertToMilitaryTime/index.ts +18 -0
- package/src/hooks/generateStoreURL/index.ts +41 -0
- package/src/hooks/generateTemplate/index.ts +66 -0
- package/src/hooks/getCardType/index.ts +24 -0
- package/src/hooks/getCategoriesWithProduct/helpers/index.ts +7 -0
- package/src/hooks/getCategoriesWithProduct/index.ts +62 -0
- package/src/hooks/getGlobalSession/index.ts +69 -0
- package/src/hooks/getSession/index.ts +72 -0
- package/src/hooks/getTodayTimestamps/index.ts +70 -0
- package/src/hooks/getTotalHours/index.ts +76 -0
- package/src/hooks/handleLogin/index.ts +14 -0
- package/src/hooks/index.ts +153 -0
- package/src/hooks/isTokenExpired/index.ts +17 -0
- package/src/hooks/newMessageSubscription/index.ts +28 -0
- package/src/hooks/newStoreOrderSubscription/index.ts +26 -0
- package/src/hooks/statusOpenStores/helpers/index.ts +124 -0
- package/src/hooks/statusOpenStores/index.ts +221 -0
- package/src/hooks/updateExtProductFoodsOptional/index.ts +49 -0
- package/src/hooks/useAcumulateDate/index.ts +18 -0
- package/src/hooks/useAllStoresPendingToRegister/index.ts +37 -0
- package/src/hooks/useAmountInput/index.ts +127 -0
- package/src/hooks/useAnimationFrame/index.ts +45 -0
- package/src/hooks/useAnimationText/index.ts +31 -0
- package/src/hooks/useAsideCart/helpers/index.ts +22 -0
- package/src/hooks/useAsideCart/index.ts +217 -0
- package/src/hooks/useAsideCart/queries.ts +10 -0
- package/src/hooks/useBanner/index.ts +20 -0
- package/src/hooks/useCart/index.ts +2 -0
- package/src/hooks/useCart/queries.ts +174 -0
- package/src/hooks/useCart/useCart/helpers/index.ts +79 -0
- package/src/hooks/useCart/useCart/index.ts +424 -0
- package/src/hooks/useCart/useGetCart/index.ts +34 -0
- package/src/hooks/useCatWithProduct/index.ts +54 -0
- package/src/hooks/useCatWithProduct/queries.ts +200 -0
- package/src/hooks/useCatWithProduct/types/index.ts +104 -0
- package/src/hooks/useCatWithProductClient/index.ts +57 -0
- package/src/hooks/useCatWithProductClient/queries.ts +56 -0
- package/src/hooks/useCategoriesProduct/index.ts +14 -0
- package/src/hooks/useCategoriesProduct/queries.ts +16 -0
- package/src/hooks/useCategoryInStore/index.ts +167 -0
- package/src/hooks/useCategoryInStore/queries.ts +78 -0
- package/src/hooks/useCategoryStore/index.ts +8 -0
- package/src/hooks/useCategoryStore/queries.ts +16 -0
- package/src/hooks/useChartData/index.ts +171 -0
- package/src/hooks/useChartData/useChartData/index.ts +200 -0
- package/src/hooks/useChartData/useChartDataAllOrders/index.ts +94 -0
- package/src/hooks/useChatRoomSubscription/index.ts +28 -0
- package/src/hooks/useCheckbox/index.ts +115 -0
- package/src/hooks/useCities/index.ts +14 -0
- package/src/hooks/useCities/queries.ts +12 -0
- package/src/hooks/useClients/index.ts +97 -0
- package/src/hooks/useClients/queries.ts +215 -0
- package/src/hooks/useColorByLetters/helpers/alea.ts +73 -0
- package/src/hooks/useColorByLetters/helpers/colors.ts +45 -0
- package/src/hooks/useColorByLetters/helpers/index.ts +22 -0
- package/src/hooks/useColorByLetters/helpers/mersenne_twister.ts +118 -0
- package/src/hooks/useColorByLetters/index.ts +24 -0
- package/src/hooks/useConnection/index.ts +24 -0
- package/src/hooks/useCountries/index.ts +20 -0
- package/src/hooks/useCountries/queries.ts +12 -0
- package/src/hooks/useCreateDeliveryTime/index.ts +51 -0
- package/src/hooks/useCreateOrderStatusType/index.ts +134 -0
- package/src/hooks/useCreateProduct/helpers/index.ts +23 -0
- package/src/hooks/useCreateProduct/helpers/manageCacheDataCatProduct/index.ts +52 -0
- package/src/hooks/useCreateProduct/helpers/useEditImageProduct/index.ts +182 -0
- package/src/hooks/useCreateProduct/index.ts +337 -0
- package/src/hooks/useCreateStorePendingToRegister/index.ts +17 -0
- package/src/hooks/useCreateStorePendingToRegister/queries.ts +10 -0
- package/src/hooks/useDashboardComponents/index.ts +50 -0
- package/src/hooks/useDeleteExtraProductFoods/index.ts +13 -0
- package/src/hooks/useDeleteSubProductOptional/index.ts +32 -0
- package/src/hooks/useDeleteSubProductOptional/queries.ts +10 -0
- package/src/hooks/useDeliveryTime/index.ts +29 -0
- package/src/hooks/useDepartments/index.ts +14 -0
- package/src/hooks/useDepartments/queries.ts +13 -0
- package/src/hooks/useDessert/helpers/index.ts +51 -0
- package/src/hooks/useDessert/index.ts +529 -0
- package/src/hooks/useDessertWithPrice/helpers/index.ts +76 -0
- package/src/hooks/useDessertWithPrice/index.ts +381 -0
- package/src/hooks/useDessertWithPrice/queries.ts +18 -0
- package/src/hooks/useDevWS/index.ts +53 -0
- package/src/hooks/useDevices/index.ts +2 -0
- package/src/hooks/useDevices/queries.ts +28 -0
- package/src/hooks/useDevices/useGetDevices.ts +28 -0
- package/src/hooks/useDevices/useRegisterDevices.ts +75 -0
- package/src/hooks/useDownloadReports/helpers/downloadFileFromResponse.ts +21 -0
- package/src/hooks/useDownloadReports/index.ts +2 -0
- package/src/hooks/useDownloadReports/useDownloadReportByDay/index.ts +105 -0
- package/src/hooks/useDownloadReports/useGetReportByDateRange/index.ts +116 -0
- package/src/hooks/useDrag/index.ts +79 -0
- package/src/hooks/useDropzone/index.ts +94 -0
- package/src/hooks/useDynamicAuth/index.ts +14 -0
- package/src/hooks/useDynamicAuth/queries.ts +24 -0
- package/src/hooks/useEditCategory/index.ts +41 -0
- package/src/hooks/useEditOneExtProductFoodOptional/index.ts +28 -0
- package/src/hooks/useEditOneExtProductFoodOptional/queries.ts +16 -0
- package/src/hooks/useEditSubProductOptional/index.ts +12 -0
- package/src/hooks/useEditSubProductOptional/queries.ts +10 -0
- package/src/hooks/useEmployee/index.ts +18 -0
- package/src/hooks/useEmployee/queries.ts +85 -0
- package/src/hooks/useEmployee/useCreateEmployee.ts +90 -0
- package/src/hooks/useEvent/index.ts +34 -0
- package/src/hooks/useFavoriteStores/index.ts +31 -0
- package/src/hooks/useFavoriteStores/queries.ts +54 -0
- package/src/hooks/useFetchJson/index.ts +25 -0
- package/src/hooks/useFetchMoreInteractions/index.jsx +39 -0
- package/src/hooks/useFilterConfigs/index.ts +173 -0
- package/src/hooks/useFingerprintjs/index.ts +197 -0
- package/src/hooks/useFormTools/index.ts +143 -0
- package/src/hooks/useFormatDate/index.ts +91 -0
- package/src/hooks/useFormatNumberPhone/index.ts +23 -0
- package/src/hooks/useFullScreenMode/index.ts +61 -0
- package/src/hooks/useGenerateNumberArray/index.ts +17 -0
- package/src/hooks/useGetAllLocationUser/index.ts +13 -0
- package/src/hooks/useGetAllLocationUser/queries.ts +44 -0
- package/src/hooks/useGetAllSales/index.ts +26 -0
- package/src/hooks/useGetCookies/index.ts +43 -0
- package/src/hooks/useGetExtProductFoodsSubOptionalAll/index.ts +15 -0
- package/src/hooks/useGetFoodRecomended/index.ts +33 -0
- package/src/hooks/useGetFoodRecomended/queries.ts +47 -0
- package/src/hooks/useGetMessagesToRoom/index.ts +23 -0
- package/src/hooks/useGetMinPrice/index.ts +13 -0
- package/src/hooks/useGetMinPrice/queries.ts +7 -0
- package/src/hooks/useGetOneStoreRating/index.ts +41 -0
- package/src/hooks/useGetOneStoreRating/queries.ts +18 -0
- package/src/hooks/useGetSalesAmountToday/index.ts +31 -0
- package/src/hooks/useGetStoreCookie/index.ts +21 -0
- package/src/hooks/useGoogleLogin/index.ts +169 -0
- package/src/hooks/useGoogleLogin/loadScript.ts +15 -0
- package/src/hooks/useGoogleLogin/removeScript.ts +7 -0
- package/src/hooks/useHover/index.ts +32 -0
- package/src/hooks/useImageOptimization/index.ts +32 -0
- package/src/hooks/useImageUploaderProduct/helper/canvasUtils.ts +146 -0
- package/src/hooks/useImageUploaderProduct/helper/getOrientation.ts +54 -0
- package/src/hooks/useImageUploaderProduct/helper/index.ts +5 -0
- package/src/hooks/useImageUploaderProduct/index.ts +295 -0
- package/src/hooks/useImageWeight/index.ts +55 -0
- package/src/hooks/useImagesStore/index.ts +227 -0
- package/src/hooks/useImagesStore/queries.ts +193 -0
- package/src/hooks/useImagesStore/utils/index.ts +4 -0
- package/src/hooks/useIncomingOrders/index.ts +11 -0
- package/src/hooks/useIncomingOrders/queries.ts +87 -0
- package/src/hooks/useInnerHtml/index.ts +39 -0
- package/src/hooks/useIntersection/index.ts +84 -0
- package/src/hooks/useInventory/index.ts +2 -0
- package/src/hooks/useInventory/queries.ts +58 -0
- package/src/hooks/useInventory/useGetProductsInStock.ts +16 -0
- package/src/hooks/useInventory/useUpdateManageStock.ts +41 -0
- package/src/hooks/useKeypress/index.ts +28 -0
- package/src/hooks/useLazyScript/index.ts +74 -0
- package/src/hooks/useLocalBackendIp/index.ts +34 -0
- package/src/hooks/useLocalSorage/index.ts +36 -0
- package/src/hooks/useLocationManager/index.ts +63 -0
- package/src/hooks/useLocationNavigate/index.ts +54 -0
- package/src/hooks/useLoginEmployeeInStore/index.ts +38 -0
- package/src/hooks/useLogout/helpers/BroadcastChannel.ts +74 -0
- package/src/hooks/useLogout/helpers/apiBaseUrl.ts +12 -0
- package/src/hooks/useLogout/helpers/fetchData.ts +37 -0
- package/src/hooks/useLogout/helpers/getCsrfToken.ts +37 -0
- package/src/hooks/useLogout/helpers/index.ts +65 -0
- package/src/hooks/useLogout/helpers/logger.ts +88 -0
- package/src/hooks/useLogout/helpers/parseUrl.ts +39 -0
- package/src/hooks/useLogout/index.ts +105 -0
- package/src/hooks/useManageNewOrder/helpers/index.ts +45 -0
- package/src/hooks/useManageNewOrder/helpers/mock.ts +0 -0
- package/src/hooks/useManageNewOrder/index.ts +104 -0
- package/src/hooks/useManageQueryParams/index.ts +120 -0
- package/src/hooks/useMobile/index.ts +65 -0
- package/src/hooks/useModules/helpers/index.ts +1 -0
- package/src/hooks/useModules/helpers/validateModules.ts +29 -0
- package/src/hooks/useModules/index.ts +124 -0
- package/src/hooks/useMouse/index.ts +55 -0
- package/src/hooks/useMutateHeight/index.ts +36 -0
- package/src/hooks/useOrderClient/index.ts +5 -0
- package/src/hooks/useOrderStatusTypes/index.ts +2 -0
- package/src/hooks/useOrderStatusTypes/useOrderStatusTypes/index.ts +133 -0
- package/src/hooks/useOrderStatusTypes/useUpdateOrderStatusPriorities/index.ts +99 -0
- package/src/hooks/useOrders/index.ts +3 -0
- package/src/hooks/useOrders/queries.ts +99 -0
- package/src/hooks/useOrders/useChangeOrderState/index.ts +128 -0
- package/src/hooks/useOrders/useOrdersFromStore/index.ts +78 -0
- package/src/hooks/usePWAInstall/index.ts +38 -0
- package/src/hooks/usePaymentMethod/index.ts +3 -0
- package/src/hooks/usePaymentMethod/paymentMethod.gql.ts +62 -0
- package/src/hooks/usePaymentMethod/paymentMethod.types.ts +28 -0
- package/src/hooks/usePaymentMethod/useCreatePaymentMethod/index.ts +25 -0
- package/src/hooks/usePaymentMethod/useGetAllPaymentMethods/index.ts +19 -0
- package/src/hooks/usePaymentMethod/useGetPaymentMethod/index.ts +26 -0
- package/src/hooks/usePortFetcher/index.ts +33 -0
- package/src/hooks/usePrintSaleTicket/index.ts +68 -0
- package/src/hooks/useProductsFood/index.ts +341 -0
- package/src/hooks/useProductsFood/queriesStore.ts +964 -0
- package/src/hooks/useProductsFood/types/index.ts +0 -0
- package/src/hooks/useProductsFood/useEditProduct.ts +49 -0
- package/src/hooks/useProductsFood/usetagsProducts.ts +101 -0
- package/src/hooks/useProviders/index.ts +3 -0
- package/src/hooks/useProviders/queries.ts +31 -0
- package/src/hooks/useProviders/useProvidersCreateStore/index.ts +13 -0
- package/src/hooks/useProviders/useProvidersDataStore/index.ts +25 -0
- package/src/hooks/useProvidersStore/index.ts +25 -0
- package/src/hooks/useProvidersStore/queries.ts +31 -0
- package/src/hooks/usePushNotificationOrder/index.ts +52 -0
- package/src/hooks/usePushNotifications/helpers/index.ts +123 -0
- package/src/hooks/usePushNotifications/index.ts +150 -0
- package/src/hooks/useQueryLocationsMap/index.ts +20 -0
- package/src/hooks/useQueryLocationsMap/queries.ts +40 -0
- package/src/hooks/useRatingArrayData/index.ts +54 -0
- package/src/hooks/useRatingArrayData/queries.ts +19 -0
- package/src/hooks/useReactToPrint/index.txt +1223 -0
- package/src/hooks/useRemoveExtraProductFoodsOptional/index.ts +24 -0
- package/src/hooks/useRemoveExtraProductFoodsOptional/queries.ts +48 -0
- package/src/hooks/useReport/index.ts +48 -0
- package/src/hooks/useReport/queries.ts +72 -0
- package/src/hooks/useRestaurant/helpers/index.ts +28 -0
- package/src/hooks/useRestaurant/helpers/manageStatusOpen.ts +26 -0
- package/src/hooks/useRestaurant/index.ts +71 -0
- package/src/hooks/useRestaurant/queries.ts +81 -0
- package/src/hooks/useRoads/index.ts +20 -0
- package/src/hooks/useRoads/queries.ts +13 -0
- package/src/hooks/useRoles/index.ts +4 -0
- package/src/hooks/useRoles/queries.ts +70 -0
- package/src/hooks/useRoles/useCreateRole.ts +40 -0
- package/src/hooks/useRoles/useGetRoles.ts +37 -0
- package/src/hooks/useRoles/useRemoveRoles.ts +40 -0
- package/src/hooks/useRoles/useUpdateRolesPriority.ts +44 -0
- package/src/hooks/useSales/helpers/add-product.utils.ts +120 -0
- package/src/hooks/useSales/helpers/apply-discount-to-cart.utils.ts +292 -0
- package/src/hooks/useSales/helpers/comment-product.utils.ts +41 -0
- package/src/hooks/useSales/helpers/constants/index.ts +38 -0
- package/src/hooks/useSales/helpers/extras.utils.ts +42 -0
- package/src/hooks/useSales/helpers/filterProductsByCarProId.utils.ts +17 -0
- package/src/hooks/useSales/helpers/increment-product-quantity.utils.ts +76 -0
- package/src/hooks/useSales/helpers/index.ts +3 -0
- package/src/hooks/useSales/helpers/initializer.utils.ts +22 -0
- package/src/hooks/useSales/helpers/isStockInsufficient.ts +3 -0
- package/src/hooks/useSales/helpers/remove-product.utils.test.ts +49 -0
- package/src/hooks/useSales/helpers/remove-product.utils.ts +34 -0
- package/src/hooks/useSales/helpers/resolveProduct.ts +29 -0
- package/src/hooks/useSales/helpers/useAddToCart.ts +64 -0
- package/src/hooks/useSales/index.ts +1418 -0
- package/src/hooks/useSales/queries.ts +532 -0
- package/src/hooks/useSales/types/index.ts +206 -0
- package/src/hooks/useSales/types/use-sales.types.ts +8 -0
- package/src/hooks/useSales/useGetSale.ts +21 -0
- package/src/hooks/useSales/useTotalSales.ts +24 -0
- package/src/hooks/useSaveAvailableProduct/helpers/index.ts +38 -0
- package/src/hooks/useSaveAvailableProduct/index.ts +32 -0
- package/src/hooks/useSaveAvailableProduct/queries.ts +10 -0
- package/src/hooks/useSaveLocation/index.ts +17 -0
- package/src/hooks/useSaveLocation/queries.ts +19 -0
- package/src/hooks/useSchedule/index.ts +35 -0
- package/src/hooks/useSchedule/queries.ts +43 -0
- package/src/hooks/useSchedule/schedule.ts +79 -0
- package/src/hooks/useScheduleData/index.ts +135 -0
- package/src/hooks/useScroll/index.ts +56 -0
- package/src/hooks/useScrollRotate/index.ts +16 -0
- package/src/hooks/useSetImageProducts/index.ts +59 -0
- package/src/hooks/useSetImageProducts/queries.ts +18 -0
- package/src/hooks/useSetSession/index.ts +44 -0
- package/src/hooks/useSetState/index.ts +24 -0
- package/src/hooks/useSetupSchedule/helpers/index.ts +85 -0
- package/src/hooks/useSetupSchedule/index.ts +284 -0
- package/src/hooks/useStatusOpenStore/helpers/index.ts +124 -0
- package/src/hooks/useStatusOpenStore/index.ts +195 -0
- package/src/hooks/useStatusOrdersClient/helpers/index.ts +14 -0
- package/src/hooks/useStatusOrdersClient/index.ts +18 -0
- package/src/hooks/useStatusOrdersClient/queries.ts +80 -0
- package/src/hooks/useStock/index.ts +1 -0
- package/src/hooks/useStock/useStockUpdatedAllSubscription.ts +40 -0
- package/src/hooks/useStockMovements/helpers/index.ts +16 -0
- package/src/hooks/useStockMovements/index.ts +39 -0
- package/src/hooks/useStore/index.ts +83 -0
- package/src/hooks/useStore/queries.ts +163 -0
- package/src/hooks/useStoreCalendar/index.ts +5 -0
- package/src/hooks/useStoreContacts/index.ts +53 -0
- package/src/hooks/useStoreContacts/queries.ts +48 -0
- package/src/hooks/useStoreTable/index.ts +2 -0
- package/src/hooks/useStoreTable/queries.ts +47 -0
- package/src/hooks/useStoreTable/useStoreTableCreate.ts +77 -0
- package/src/hooks/useStoreTable/useStoreTables.ts +15 -0
- package/src/hooks/useSubscriptionValidation/index.ts +112 -0
- package/src/hooks/useTagProducts/index.ts +3 -0
- package/src/hooks/useTagProducts/useDeleteOneTag.ts +106 -0
- package/src/hooks/useTagProducts/useGetAllTags.ts +68 -0
- package/src/hooks/useTagProducts/useRegisterMultipleTags.ts +157 -0
- package/src/hooks/useTheme/index.ts +65 -0
- package/src/hooks/useTimeAgo/useTimeAgo.ts +39 -0
- package/src/hooks/useTokenCards/index.ts +45 -0
- package/src/hooks/useTopProductsMovements/index.ts +27 -0
- package/src/hooks/useTotalAllSales/index.ts +25 -0
- package/src/hooks/useTotalProductsInStock/index.ts +23 -0
- package/src/hooks/useTotalProductsSold/index.ts +23 -0
- package/src/hooks/useTotalProductsSolded/index.ts +20 -0
- package/src/hooks/useUpdateCart/index.ts +131 -0
- package/src/hooks/useUpdateCartCookie/index.ts +60 -0
- package/src/hooks/useUpdateDashboardComponent/index.ts +91 -0
- package/src/hooks/useUpdateExistingOrders/index.ts +85 -0
- package/src/hooks/useUpdateExtProductFoodsSubOptional/index.ts +61 -0
- package/src/hooks/useUpdateModuleOrder/index.ts +37 -0
- package/src/hooks/useUpdateMultipleExtProduct/index.ts +34 -0
- package/src/hooks/useUpdateMultipleExtProduct/queries.ts +33 -0
- package/src/hooks/useUpdateMultipleProducts/index.ts +117 -0
- package/src/hooks/useUpdateMultipleProducts/queries.ts +51 -0
- package/src/hooks/useUploadProducts/helpers/index.ts +1 -0
- package/src/hooks/useUploadProducts/helpers/parseNumber.ts +37 -0
- package/src/hooks/useUploadProducts/helpers/validateProductDataExcel.ts +73 -0
- package/src/hooks/useUploadProducts/index.ts +442 -0
- package/src/hooks/useUpsertGoal/index.ts +68 -0
- package/src/hooks/useUser/index.ts +24 -0
- package/src/hooks/useUser/queries.ts +131 -0
- package/src/hooks/useWeeklyStockMovement/helpers/index.ts +32 -0
- package/src/hooks/useWeeklyStockMovement/index.ts +52 -0
- package/src/hooks/useWindowSize/index.ts +45 -0
- package/src/index.ts +8 -0
- package/src/mock/dessert/index.ts +16 -0
- package/src/mock/index.ts +1 -0
- package/src/security/index.ts +1 -0
- package/src/services/index.ts +1 -0
- package/src/utils/UtilDateRange.ts +56 -0
- package/src/utils/generateCode.ts +222 -0
- package/src/utils/index.ts +2 -0
- package/src/utils/utils.ts +344 -0
- package/tsconfig.eslint.json +16 -0
- package/tsconfig.json +21 -0
- package/tsup.config.ts +24 -0
- package/dist/index.cjs +0 -20089
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { NotificationPayload } from '../types'
|
|
2
|
+
|
|
3
|
+
import { isStockInsufficient } from './isStockInsufficient'
|
|
4
|
+
|
|
5
|
+
interface AddToCartProps {
|
|
6
|
+
state: any
|
|
7
|
+
action: any
|
|
8
|
+
product: any
|
|
9
|
+
sendNotification?: (args: NotificationPayload) => any
|
|
10
|
+
sendAlertStock: (stock: number) => void
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Adds a product to the cart with maximum performance.
|
|
15
|
+
* Avoids full array scans and minimizes object cloning.
|
|
16
|
+
* @param {any} state - Current reducer state.
|
|
17
|
+
* @param {any} action - Action containing product data.
|
|
18
|
+
* @returns {any} Updated state.
|
|
19
|
+
*/
|
|
20
|
+
export const addToCartFunc = ({
|
|
21
|
+
state = {},
|
|
22
|
+
action = {},
|
|
23
|
+
product,
|
|
24
|
+
sendNotification = () => { },
|
|
25
|
+
sendAlertStock = () => { }
|
|
26
|
+
}: AddToCartProps) => {
|
|
27
|
+
const payload = action?.payload ?? {}
|
|
28
|
+
const {
|
|
29
|
+
pId,
|
|
30
|
+
pName,
|
|
31
|
+
getOneTags,
|
|
32
|
+
stock,
|
|
33
|
+
ProDescription,
|
|
34
|
+
ProImage,
|
|
35
|
+
ProPrice,
|
|
36
|
+
ProDescuento
|
|
37
|
+
} = payload
|
|
38
|
+
|
|
39
|
+
// Validate basic stock
|
|
40
|
+
if (stock === 0) {
|
|
41
|
+
sendNotification({
|
|
42
|
+
title: 'Sin stock',
|
|
43
|
+
backgroundColor: 'warning',
|
|
44
|
+
description: 'Producto sin stock disponible en tu inventario'
|
|
45
|
+
})
|
|
46
|
+
return state
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// PRE-FETCH product references (only ONCE)
|
|
50
|
+
const productExistIndex = state.PRODUCT.findIndex((item: any) => {return item.pId === pId})
|
|
51
|
+
const productExist = productExistIndex !== -1 ? state.PRODUCT[productExistIndex] : null
|
|
52
|
+
if (!product) return state
|
|
53
|
+
|
|
54
|
+
// Check stock handling rules
|
|
55
|
+
const currentQty = productExist?.ProQuantity ?? 0
|
|
56
|
+
if (product.manageStock && isStockInsufficient(currentQty, product.stock)) {
|
|
57
|
+
sendAlertStock(stock)
|
|
58
|
+
return state
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const isFree = productExist?.free ?? false
|
|
62
|
+
const newQuantity = productExist ? currentQty + 1 : 1
|
|
63
|
+
|
|
64
|
+
// Calculate new unit price only once
|
|
65
|
+
const unitPrice = product.ProPrice ?? 0
|
|
66
|
+
|
|
67
|
+
// Calculate final price respecting 'free' mode
|
|
68
|
+
const newPrice = isFree ? 0 : newQuantity * unitPrice
|
|
69
|
+
|
|
70
|
+
// COMMON STATE UPDATES
|
|
71
|
+
const baseState = {
|
|
72
|
+
...state,
|
|
73
|
+
counter: state.counter + 1,
|
|
74
|
+
totalAmount: state.totalAmount + ProPrice,
|
|
75
|
+
startAnimateUp: 'start-animate-up'
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// CASE 1: Product does NOT exist → add it
|
|
79
|
+
if (!productExist) {
|
|
80
|
+
const newProduct = {
|
|
81
|
+
pId,
|
|
82
|
+
pName,
|
|
83
|
+
editing: false,
|
|
84
|
+
getOneTags,
|
|
85
|
+
unitPrice,
|
|
86
|
+
manageStock: product.manageStock ?? false,
|
|
87
|
+
ProDescription,
|
|
88
|
+
ProImage,
|
|
89
|
+
ProPrice,
|
|
90
|
+
stock,
|
|
91
|
+
ProDescuento,
|
|
92
|
+
ProQuantity: 1,
|
|
93
|
+
free: false
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return {
|
|
97
|
+
...baseState,
|
|
98
|
+
PRODUCT: [...state.PRODUCT, newProduct]
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// CASE 2: Product already exists → update only ONE item
|
|
103
|
+
const newList = [...state.PRODUCT]
|
|
104
|
+
|
|
105
|
+
newList[productExistIndex] = {
|
|
106
|
+
...productExist,
|
|
107
|
+
getOneTags: product.genderTags,
|
|
108
|
+
unitPrice,
|
|
109
|
+
editing: false,
|
|
110
|
+
oldQuantity: newQuantity,
|
|
111
|
+
ProPrice: newPrice,
|
|
112
|
+
ProQuantity: newQuantity,
|
|
113
|
+
free: isFree
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return {
|
|
117
|
+
...baseState,
|
|
118
|
+
PRODUCT: newList
|
|
119
|
+
}
|
|
120
|
+
}
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
export enum TypeDiscount {
|
|
2
|
+
PERCENT = 'PERCENT',
|
|
3
|
+
AMOUNT = 'AMOUNT'
|
|
4
|
+
}
|
|
5
|
+
interface DiscountPayload {
|
|
6
|
+
type: TypeDiscount
|
|
7
|
+
value: number
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Apply a discount to the reducer state in a mathematically-exact way.
|
|
12
|
+
*
|
|
13
|
+
* - Supports two discount types: "PERCENT" (0-100) and "AMOUNT" (fixed currency amount).
|
|
14
|
+
* - Works in integer cents to avoid floating point errors, distributes rounding
|
|
15
|
+
* remainders using the Largest Remainder Method so allocations sum exactly.
|
|
16
|
+
* - BEFORE applying a new discount, restores original prices if they were previously saved
|
|
17
|
+
* (originalProPrice and originalNewExtraPrice). This prevents stacking discounts.
|
|
18
|
+
* - Applies discount first to `ProPrice` (base) and, if needed, to `dataExtra[].newExtraPrice`
|
|
19
|
+
* proportionally, never producing negative prices.
|
|
20
|
+
* - Returns a new state (immutable) and sets metadata: discountType, discountPercent,
|
|
21
|
+
* discountAmount, discountBreakdown and preserves original prices in `originalProPrice`
|
|
22
|
+
* and `dataExtra[].originalNewExtraPrice`.
|
|
23
|
+
*
|
|
24
|
+
* NOTE: Uses optional `sendNotification` to report errors/success.
|
|
25
|
+
*
|
|
26
|
+
* @param {any} state - current reducer state
|
|
27
|
+
* @param {{ type: string, value: number }} payload - { type: 'PERCENT'|'AMOUNT', value: number }
|
|
28
|
+
* @param {(notification: {title:string,backgroundColor:'success'|'error'|'warning'|'info',description:string}) => void} sendNotification
|
|
29
|
+
* @returns {any} new state with discounts applied (idempotent w.r.t repeated calls)
|
|
30
|
+
*/
|
|
31
|
+
export const applyDiscountToCart = (
|
|
32
|
+
state: any,
|
|
33
|
+
payload: DiscountPayload,
|
|
34
|
+
sendNotification?: (notification: {
|
|
35
|
+
title: string
|
|
36
|
+
backgroundColor: 'success' | 'error' | 'warning' | 'info'
|
|
37
|
+
description: string
|
|
38
|
+
}) => void
|
|
39
|
+
) => {
|
|
40
|
+
const discountType = (payload?.type ?? TypeDiscount.PERCENT).toString().toUpperCase()
|
|
41
|
+
const rawValue = Number(payload?.value)
|
|
42
|
+
|
|
43
|
+
// Basic validations
|
|
44
|
+
if (!Array.isArray(state?.PRODUCT) || state.PRODUCT.length === 0) {
|
|
45
|
+
sendNotification?.({
|
|
46
|
+
title: 'Warning',
|
|
47
|
+
backgroundColor: 'warning',
|
|
48
|
+
description: 'No items in cart to apply discount.'
|
|
49
|
+
})
|
|
50
|
+
return {
|
|
51
|
+
...state,
|
|
52
|
+
discountType,
|
|
53
|
+
discountPercent: 0,
|
|
54
|
+
discountAmount: 0,
|
|
55
|
+
discountBreakdown: []
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (Number.isNaN(rawValue) || rawValue < 0) {
|
|
60
|
+
sendNotification?.({
|
|
61
|
+
title: 'Error',
|
|
62
|
+
backgroundColor: 'error',
|
|
63
|
+
description: 'Invalid discount value.'
|
|
64
|
+
})
|
|
65
|
+
return state
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (discountType !== TypeDiscount.PERCENT && discountType !== TypeDiscount.AMOUNT) {
|
|
69
|
+
sendNotification?.({
|
|
70
|
+
title: 'Error',
|
|
71
|
+
backgroundColor: 'error',
|
|
72
|
+
description: 'Invalid discount type.'
|
|
73
|
+
})
|
|
74
|
+
return state
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (discountType === TypeDiscount.PERCENT && (rawValue < 0 || rawValue > 100)) {
|
|
78
|
+
sendNotification?.({
|
|
79
|
+
title: 'Error',
|
|
80
|
+
backgroundColor: 'warning',
|
|
81
|
+
description: 'Percentage must be between 0 and 100.'
|
|
82
|
+
})
|
|
83
|
+
return state
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Helpers - work in cents to preserve exactness
|
|
87
|
+
const toCents = (n: number) => {return Math.round((Number(n) || 0) * 100)}
|
|
88
|
+
const fromCents = (c: number) => {return c / 100}
|
|
89
|
+
|
|
90
|
+
// --- Normalize / Restore originals to avoid stacking discounts ---
|
|
91
|
+
// For each product, use saved original prices if present; otherwise use current as "original"
|
|
92
|
+
const normalizedItems = state.PRODUCT.map((item: any) => {
|
|
93
|
+
// Determine original base price (prefer originalProPrice if present)
|
|
94
|
+
const origBaseRaw =
|
|
95
|
+
item.originalProPrice !== undefined && item.originalProPrice !== null
|
|
96
|
+
? Number(item.originalProPrice)
|
|
97
|
+
: Number(item.ProPrice || 0)
|
|
98
|
+
|
|
99
|
+
const baseCents = toCents(origBaseRaw)
|
|
100
|
+
|
|
101
|
+
// Normalize extras: preserve originalNewExtraPrice if exists, else take current newExtraPrice
|
|
102
|
+
const extrasRaw = Array.isArray(item.dataExtra) ? item.dataExtra : []
|
|
103
|
+
const extrasNormalized = extrasRaw.map((ex: any) => {
|
|
104
|
+
const origExRaw =
|
|
105
|
+
ex.originalNewExtraPrice !== undefined && ex.originalNewExtraPrice !== null
|
|
106
|
+
? Number(ex.originalNewExtraPrice)
|
|
107
|
+
: Number(ex.newExtraPrice || 0)
|
|
108
|
+
return {
|
|
109
|
+
originalExtraObject: ex,
|
|
110
|
+
originalNewExtraPriceRaw: origExRaw,
|
|
111
|
+
originalNewExtraPriceCents: toCents(origExRaw)
|
|
112
|
+
}
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
const extrasCentsList = extrasNormalized.map((e: any) => {return e.originalNewExtraPriceCents})
|
|
116
|
+
const extrasTotalCents = extrasCentsList.reduce((s: number, v: number) => {return s + v}, 0)
|
|
117
|
+
const itemTotalCents = baseCents + extrasTotalCents
|
|
118
|
+
|
|
119
|
+
return {
|
|
120
|
+
originalItem: item,
|
|
121
|
+
baseCents,
|
|
122
|
+
extrasNormalized,
|
|
123
|
+
extrasCentsList,
|
|
124
|
+
extrasTotalCents,
|
|
125
|
+
itemTotalCents
|
|
126
|
+
}
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
const cartTotalCents = normalizedItems.reduce((s: number, it: any) => {return s + it.itemTotalCents}, 0)
|
|
130
|
+
|
|
131
|
+
if (cartTotalCents === 0) {
|
|
132
|
+
sendNotification?.({
|
|
133
|
+
title: 'Warning',
|
|
134
|
+
backgroundColor: 'warning',
|
|
135
|
+
description: 'Cart total is zero; nothing to discount.'
|
|
136
|
+
})
|
|
137
|
+
return {
|
|
138
|
+
...state,
|
|
139
|
+
discountType,
|
|
140
|
+
discountPercent: 0,
|
|
141
|
+
discountAmount: 0,
|
|
142
|
+
discountBreakdown: []
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Determine requested total discount in cents
|
|
147
|
+
let totalDiscountCents = 0
|
|
148
|
+
if (discountType === TypeDiscount.PERCENT) {
|
|
149
|
+
totalDiscountCents = Math.round((cartTotalCents * rawValue) / 100)
|
|
150
|
+
} else {
|
|
151
|
+
totalDiscountCents = toCents(rawValue)
|
|
152
|
+
// Cap to cart total
|
|
153
|
+
if (totalDiscountCents > cartTotalCents) {
|
|
154
|
+
totalDiscountCents = cartTotalCents
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// If no discount to apply
|
|
159
|
+
if (totalDiscountCents <= 0) {
|
|
160
|
+
sendNotification?.({
|
|
161
|
+
title: 'Notice',
|
|
162
|
+
backgroundColor: 'info',
|
|
163
|
+
description: 'No discount applied.'
|
|
164
|
+
})
|
|
165
|
+
return {
|
|
166
|
+
...state,
|
|
167
|
+
discountType,
|
|
168
|
+
discountPercent: discountType === TypeDiscount.PERCENT ? rawValue : +((totalDiscountCents / cartTotalCents) * 100).toFixed(2),
|
|
169
|
+
discountAmount: fromCents(totalDiscountCents),
|
|
170
|
+
discountBreakdown: []
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// ---- Allocation using Largest Remainder Method (exact cents) ----
|
|
175
|
+
const rawAllocs = normalizedItems.map((it: any) => {return (it.itemTotalCents * totalDiscountCents) / cartTotalCents})
|
|
176
|
+
const floorAllocs = rawAllocs.map((v: any) => {return Math.floor(v)})
|
|
177
|
+
const remainders = rawAllocs.map((v: any, i: number) => {return { idx: i, rem: v - floorAllocs[i] }})
|
|
178
|
+
const sumFloor = floorAllocs.reduce((s: number, v: number) => {return s + v}, 0)
|
|
179
|
+
let remainingCents = totalDiscountCents - sumFloor
|
|
180
|
+
|
|
181
|
+
remainders.sort((a: any, b: any) => {return b.rem - a.rem})
|
|
182
|
+
const finalAllocs = [...floorAllocs]
|
|
183
|
+
for (let i = 0; i < remainders.length && remainingCents > 0; i++) {
|
|
184
|
+
finalAllocs[remainders[i].idx] += 1
|
|
185
|
+
remainingCents -= 1
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// ---- Apply allocations to restored originals (base first, then extras) ----
|
|
189
|
+
const breakdown: { pId: string | number; discountAmount: number }[] = []
|
|
190
|
+
const newProducts = normalizedItems.map((it: any, idx: number) => {
|
|
191
|
+
const allocated = finalAllocs[idx] // cents
|
|
192
|
+
let remainingToTake = allocated
|
|
193
|
+
|
|
194
|
+
// Apply on base
|
|
195
|
+
const origBaseCents = it.baseCents
|
|
196
|
+
const usedOnBase = Math.min(origBaseCents, remainingToTake)
|
|
197
|
+
const baseAfter = origBaseCents - usedOnBase
|
|
198
|
+
remainingToTake -= usedOnBase
|
|
199
|
+
|
|
200
|
+
// Apply on extras proportionally if needed
|
|
201
|
+
let newExtrasCentsList = it.extrasCentsList.slice() // copy
|
|
202
|
+
if (remainingToTake > 0 && it.extrasTotalCents > 0) {
|
|
203
|
+
const extrasTotal = it.extrasTotalCents
|
|
204
|
+
// raw per-extra allocation
|
|
205
|
+
const rawExtraAllocs = newExtrasCentsList.map((exCents: number) => {return (exCents / extrasTotal) * remainingToTake})
|
|
206
|
+
const floorExtraAllocs = rawExtraAllocs.map((v: number) => {return Math.floor(v)})
|
|
207
|
+
const usedExtraFloor = floorExtraAllocs.reduce((s: number, v: number) => {return s + v}, 0)
|
|
208
|
+
let rest = remainingToTake - usedExtraFloor
|
|
209
|
+
|
|
210
|
+
const extraRemainders = rawExtraAllocs.map((v: number, i: number) => {return { idx: i, rem: v - floorExtraAllocs[i] }})
|
|
211
|
+
extraRemainders.sort((a: any, b: any) => {return b.rem - a.rem})
|
|
212
|
+
const finalExtraAllocs = [...floorExtraAllocs]
|
|
213
|
+
for (let k = 0; k < extraRemainders.length && rest > 0; k++) {
|
|
214
|
+
finalExtraAllocs[extraRemainders[k].idx] += 1
|
|
215
|
+
rest -= 1
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// apply finalExtraAllocs with cap
|
|
219
|
+
newExtrasCentsList = newExtrasCentsList.map((exCents: number, i: number) => {
|
|
220
|
+
const reduceBy = Math.min(exCents, finalExtraAllocs[i])
|
|
221
|
+
return exCents - reduceBy
|
|
222
|
+
})
|
|
223
|
+
|
|
224
|
+
remainingToTake = 0
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// Build updated product object:
|
|
228
|
+
const newBaseCents = baseAfter
|
|
229
|
+
const newProPrice = fromCents(newBaseCents)
|
|
230
|
+
|
|
231
|
+
const originalExtrasObjects = it.extrasNormalized.map((e: any) => {return e.originalExtraObject || {}})
|
|
232
|
+
const newDataExtra = originalExtrasObjects.map((exObj: any, i: number) => {
|
|
233
|
+
const newExtraPrice = fromCents(newExtrasCentsList[i] || 0)
|
|
234
|
+
// preserve originalNewExtraPrice on each extra (if not already)
|
|
235
|
+
return {
|
|
236
|
+
...exObj,
|
|
237
|
+
originalNewExtraPrice: exObj.originalNewExtraPrice !== undefined ? exObj.originalNewExtraPrice : exObj.newExtraPrice,
|
|
238
|
+
newExtraPrice
|
|
239
|
+
}
|
|
240
|
+
})
|
|
241
|
+
|
|
242
|
+
const appliedDiscountCents = allocated - remainingToTake
|
|
243
|
+
breakdown.push({ pId: it.originalItem.pId, discountAmount: fromCents(appliedDiscountCents) })
|
|
244
|
+
|
|
245
|
+
const itemTotalCentsBefore = it.itemTotalCents || 0
|
|
246
|
+
const itemDiscountPercent = itemTotalCentsBefore > 0 ? +((appliedDiscountCents / itemTotalCentsBefore) * 100).toFixed(4) : 0
|
|
247
|
+
|
|
248
|
+
return {
|
|
249
|
+
...it.originalItem,
|
|
250
|
+
// save originalProPrice if not present (so future calls can restore)
|
|
251
|
+
originalProPrice:
|
|
252
|
+
it.originalItem.originalProPrice !== undefined && it.originalItem.originalProPrice !== null
|
|
253
|
+
? it.originalItem.originalProPrice
|
|
254
|
+
: fromCents(it.baseCents),
|
|
255
|
+
ProPrice: newProPrice,
|
|
256
|
+
dataExtra: newDataExtra,
|
|
257
|
+
// per-item metadata
|
|
258
|
+
discountAmount: fromCents(appliedDiscountCents),
|
|
259
|
+
discountPercent: itemDiscountPercent
|
|
260
|
+
}
|
|
261
|
+
})
|
|
262
|
+
|
|
263
|
+
// Final safety check & tiny correction if needed
|
|
264
|
+
const allocatedSumCents = breakdown.reduce((s, b) => {return s + toCents(Number(b.discountAmount) || 0)}, 0)
|
|
265
|
+
if (allocatedSumCents !== totalDiscountCents) {
|
|
266
|
+
const diff = totalDiscountCents - allocatedSumCents
|
|
267
|
+
if (newProducts.length > 0 && diff !== 0) {
|
|
268
|
+
const first = newProducts[0]
|
|
269
|
+
first.discountAmount = Number(first.discountAmount || 0) + fromCents(diff)
|
|
270
|
+
const adjustOnBase = Math.min(toCents(first.ProPrice), diff)
|
|
271
|
+
first.ProPrice = fromCents(Math.max(0, toCents(first.ProPrice) - adjustOnBase))
|
|
272
|
+
breakdown[0].discountAmount = Number(breakdown[0].discountAmount || 0) + fromCents(diff)
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
const overallPercent = +((totalDiscountCents / cartTotalCents) * 100).toFixed(4)
|
|
277
|
+
|
|
278
|
+
sendNotification?.({
|
|
279
|
+
title: 'Discount applied',
|
|
280
|
+
backgroundColor: 'success',
|
|
281
|
+
description: `${discountType === TypeDiscount.PERCENT ? rawValue + '%' : fromCents(totalDiscountCents)} discount applied successfully.`
|
|
282
|
+
})
|
|
283
|
+
|
|
284
|
+
return {
|
|
285
|
+
...state,
|
|
286
|
+
PRODUCT: newProducts,
|
|
287
|
+
discountType,
|
|
288
|
+
discountPercent: discountType === TypeDiscount.PERCENT ? rawValue : overallPercent,
|
|
289
|
+
discountAmount: fromCents(totalDiscountCents),
|
|
290
|
+
discountBreakdown: breakdown
|
|
291
|
+
}
|
|
292
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Adds or removes a comment from a product in cart.
|
|
3
|
+
* - Pure function (reducer-safe)
|
|
4
|
+
* - Supports delete mode
|
|
5
|
+
* - Avoids unnecessary re-renders
|
|
6
|
+
*
|
|
7
|
+
* @param {Object} params
|
|
8
|
+
* @param {Object} params.state - Current reducer state
|
|
9
|
+
* @param {string | number} params.productId - Product identifier
|
|
10
|
+
* @param {string} params.comment - Comment text
|
|
11
|
+
* @param {boolean} params.deleteValue - If true, removes the comment
|
|
12
|
+
*
|
|
13
|
+
* @returns {Object} Updated state
|
|
14
|
+
*/
|
|
15
|
+
export const commentProduct = ({
|
|
16
|
+
state,
|
|
17
|
+
productId,
|
|
18
|
+
comment = '',
|
|
19
|
+
deleteValue = false
|
|
20
|
+
}: {
|
|
21
|
+
state: any;
|
|
22
|
+
productId: string | number;
|
|
23
|
+
comment?: string;
|
|
24
|
+
deleteValue?: boolean;
|
|
25
|
+
}) => {
|
|
26
|
+
if (!productId) return state
|
|
27
|
+
|
|
28
|
+
const PRODUCT = state.PRODUCT.map((item: any) =>
|
|
29
|
+
{return item.pId === productId
|
|
30
|
+
? {
|
|
31
|
+
...item,
|
|
32
|
+
comment: deleteValue ? '' : comment
|
|
33
|
+
}
|
|
34
|
+
: item}
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
return {
|
|
38
|
+
...state,
|
|
39
|
+
PRODUCT
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { SalesState } from '../../types'
|
|
2
|
+
import { TypeDiscount } from '../apply-discount-to-cart.utils'
|
|
3
|
+
|
|
4
|
+
export enum SalesActionTypes {
|
|
5
|
+
ADD_TO_CART = 'ADD_TO_CART',
|
|
6
|
+
ADD_PRODUCT = 'ADD_PRODUCT',
|
|
7
|
+
REMOVE_PRODUCT = 'REMOVE_PRODUCT',
|
|
8
|
+
REMOVE_PRODUCT_TO_CART = 'REMOVE_PRODUCT_TO_CART',
|
|
9
|
+
ON_CHANGE = 'ON_CHANGE',
|
|
10
|
+
UPDATE_SUCCESS_QUANTITY_EDITING_PRODUCT = 'UPDATE_SUCCESS_QUANTITY_EDITING_PRODUCT',
|
|
11
|
+
CANCEL_UPDATE_QUANTITY_EDITING_PRODUCT = 'CANCEL_UPDATE_QUANTITY_EDITING_PRODUCT',
|
|
12
|
+
REMOVE_ALL_PRODUCTS = 'REMOVE_ALL_PRODUCTS',
|
|
13
|
+
TOGGLE_FREE_PRODUCT = 'TOGGLE_FREE_PRODUCT',
|
|
14
|
+
TOGGLE_EDITING_PRODUCT = 'TOGGLE_EDITING_PRODUCT',
|
|
15
|
+
INCREMENT = 'INCREMENT',
|
|
16
|
+
DECREMENT = 'DECREMENT',
|
|
17
|
+
PUT_COMMENT = 'PUT_COMMENT',
|
|
18
|
+
PUT_EXTRA_PRODUCTS_AND_OPTIONAL_PRODUCT = 'PUT_EXTRA_PRODUCTS_AND_OPTIONAL_PRODUCT',
|
|
19
|
+
PRICE_RANGE = 'PRICE_RANGE',
|
|
20
|
+
SORT = 'SORT',
|
|
21
|
+
PAYMENT_METHOD = 'PAYMENT_METHOD',
|
|
22
|
+
APPLY_DISCOUNT = 'APPLY_DISCOUNT'
|
|
23
|
+
}
|
|
24
|
+
export const initialStateSales: SalesState = {
|
|
25
|
+
animateType: '',
|
|
26
|
+
counter: 0,
|
|
27
|
+
discountAmount: 0,
|
|
28
|
+
discountPercent: 0,
|
|
29
|
+
discountType: TypeDiscount.PERCENT,
|
|
30
|
+
itemsInCart: 0,
|
|
31
|
+
payId: '',
|
|
32
|
+
priceRange: 0,
|
|
33
|
+
PRODUCT: [],
|
|
34
|
+
sortBy: null,
|
|
35
|
+
startAnimateUp: '',
|
|
36
|
+
totalAmount: 0,
|
|
37
|
+
totalPrice: 0
|
|
38
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* extrasUtils.ts
|
|
3
|
+
* Increment/decrement extras handling as pure functions returning new arrays.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Increment extra entry
|
|
8
|
+
* @param {Array} dataExtra
|
|
9
|
+
* @param {string|number} exPid
|
|
10
|
+
* @returns {Array}
|
|
11
|
+
*/
|
|
12
|
+
export const incrementExtra = (dataExtra = [], exPid: string | number) => {
|
|
13
|
+
if (!Array.isArray(dataExtra)) return []
|
|
14
|
+
return dataExtra.map((producto: any) => {
|
|
15
|
+
if (producto.exPid === exPid) {
|
|
16
|
+
const initialQuantity = producto.quantity ? producto.quantity : 0
|
|
17
|
+
const newQuantity = initialQuantity + 1
|
|
18
|
+
const newExtraPrice = (producto.extraPrice || 0) * newQuantity
|
|
19
|
+
return { ...producto, quantity: newQuantity, newExtraPrice }
|
|
20
|
+
}
|
|
21
|
+
return producto
|
|
22
|
+
})
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Decrement extra entry
|
|
27
|
+
* @param {Array} dataExtra
|
|
28
|
+
* @param {string|number} exPid
|
|
29
|
+
* @returns {Array}
|
|
30
|
+
*/
|
|
31
|
+
export const decrementExtra = (dataExtra = [], exPid: string | number) => {
|
|
32
|
+
if (!Array.isArray(dataExtra)) return []
|
|
33
|
+
return dataExtra.map((producto: any) => {
|
|
34
|
+
if (producto.exPid === exPid) {
|
|
35
|
+
const { quantity = 0, extraPrice = 0 } = producto
|
|
36
|
+
const newQuantity = Math.max(quantity - 1, 0)
|
|
37
|
+
const newExtraPrice = newQuantity === 0 ? extraPrice : extraPrice * newQuantity
|
|
38
|
+
return { ...producto, quantity: newQuantity, newExtraPrice }
|
|
39
|
+
}
|
|
40
|
+
return producto
|
|
41
|
+
})
|
|
42
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Filter products by carProId.
|
|
3
|
+
* @param {Array} products - Array of products to filter.
|
|
4
|
+
* @param {Array} carProIds - Array of carProId to filter by.
|
|
5
|
+
* @returns {Array} - Filtered array of products or all products if no matches found.
|
|
6
|
+
*/
|
|
7
|
+
export function filterProductsByCarProId(products: any[], carProIds: (string | number)[]) {
|
|
8
|
+
if (!Array.isArray(products)) {
|
|
9
|
+
return []
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
if (!Array.isArray(carProIds) || carProIds.length === 0) {
|
|
13
|
+
return products
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return products.filter(product => {return carProIds.includes(product.carProId)})
|
|
17
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Increments product quantity in cart safely.
|
|
3
|
+
* - Validates stock
|
|
4
|
+
* - Respects free mode
|
|
5
|
+
* - Avoids unnecessary mutations
|
|
6
|
+
*
|
|
7
|
+
* @param {Object} params
|
|
8
|
+
* @param {Object} params.state - Current reducer state
|
|
9
|
+
* @param {string | number} params.productId - Product identifier
|
|
10
|
+
* @param {Object[]} params.productsFood - Source products list
|
|
11
|
+
* @param {Function} params.sendNotification - Notification handler
|
|
12
|
+
*
|
|
13
|
+
* @returns {Object} Updated state
|
|
14
|
+
*/
|
|
15
|
+
export const incrementProductQuantity = ({
|
|
16
|
+
state,
|
|
17
|
+
productId,
|
|
18
|
+
productsFood = [],
|
|
19
|
+
sendNotification = () => {}
|
|
20
|
+
}: {
|
|
21
|
+
state: any;
|
|
22
|
+
productId: string | number;
|
|
23
|
+
productsFood: any[];
|
|
24
|
+
sendNotification?: Function;
|
|
25
|
+
}) => {
|
|
26
|
+
const sourceProduct = productsFood.find(
|
|
27
|
+
(product) => {return product.pId === productId}
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
if (!sourceProduct) return state
|
|
31
|
+
|
|
32
|
+
const PRODUCT = state.PRODUCT.map((item: any) => {
|
|
33
|
+
if (item.pId !== productId) return item
|
|
34
|
+
|
|
35
|
+
const {
|
|
36
|
+
stock = 0,
|
|
37
|
+
manageStock,
|
|
38
|
+
ProPrice: unitPrice = 0
|
|
39
|
+
} = sourceProduct
|
|
40
|
+
|
|
41
|
+
const isFree = Boolean(item.free)
|
|
42
|
+
const newQuantity = item.ProQuantity + 1
|
|
43
|
+
|
|
44
|
+
// Stock = 0
|
|
45
|
+
if (stock === 0) {
|
|
46
|
+
sendNotification({
|
|
47
|
+
title: 'Sin stock',
|
|
48
|
+
backgroundColor: 'warning',
|
|
49
|
+
description: `El producto ${item.pName} está agotado y no puede ser añadido al carrito.`
|
|
50
|
+
})
|
|
51
|
+
return item
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Stock exceeded
|
|
55
|
+
if (manageStock && newQuantity > stock) {
|
|
56
|
+
sendNotification({
|
|
57
|
+
title: 'Stock insuficiente',
|
|
58
|
+
backgroundColor: 'warning',
|
|
59
|
+
description: `No puedes agregar más unidades de ${item.pName}, stock disponible: ${stock}`
|
|
60
|
+
})
|
|
61
|
+
return item
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return {
|
|
65
|
+
...item,
|
|
66
|
+
ProQuantity: newQuantity,
|
|
67
|
+
ProPrice: isFree ? 0 : newQuantity * unitPrice
|
|
68
|
+
}
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
return {
|
|
72
|
+
...state,
|
|
73
|
+
counter: state.counter + 1,
|
|
74
|
+
PRODUCT
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Cookies } from '../../../cookies'
|
|
2
|
+
import { SalesState } from '../types'
|
|
3
|
+
|
|
4
|
+
import { initialStateSales } from './constants'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Initializes sales state from cookies or fallback state
|
|
8
|
+
* @param initialValue
|
|
9
|
+
*/
|
|
10
|
+
export const initializer = (
|
|
11
|
+
initialValue: SalesState = initialStateSales
|
|
12
|
+
): SalesState => {
|
|
13
|
+
try {
|
|
14
|
+
const raw = Cookies.get(process.env.NEXT_LOCAL_SALES_STORE)
|
|
15
|
+
|
|
16
|
+
if (!raw) return initialValue
|
|
17
|
+
|
|
18
|
+
return JSON.parse(raw) as SalesState
|
|
19
|
+
} catch {
|
|
20
|
+
return initialValue
|
|
21
|
+
}
|
|
22
|
+
}
|