washday-sdk 0.0.165 → 0.0.167
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/dist/api/axiosInstance.js +2 -2
- package/dist/api/index.js +8 -0
- package/dist/api/order/get.js +4 -0
- package/dist/api/routes/delete.js +25 -0
- package/dist/api/routes/get.js +50 -0
- package/dist/api/routes/index.js +1 -0
- package/dist/api/routes/post.js +28 -0
- package/dist/api/routes/put.js +29 -0
- package/dist/utils/orders/calculateTotalTaxesIncluded.js +25 -23
- package/dist/utils/orders/calculateTotalTaxesOverPrice.js +18 -12
- package/package.json +1 -1
- package/src/api/axiosInstance.ts +2 -2
- package/src/api/index.ts +8 -0
- package/src/api/order/get.ts +10 -1
- package/src/api/routes/delete.ts +15 -0
- package/src/api/routes/get.ts +50 -1
- package/src/api/routes/index.ts +1 -0
- package/src/api/routes/post.ts +20 -0
- package/src/api/routes/put.ts +27 -0
- package/src/interfaces/Api.ts +8 -0
- package/src/utils/orders/calculateTotalTaxesIncluded.ts +27 -25
- package/src/utils/orders/calculateTotalTaxesOverPrice.ts +19 -12
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import axios from 'axios';
|
|
2
2
|
// Define the type for the Axios instance
|
|
3
3
|
let axiosInstance = null;
|
|
4
|
-
|
|
5
|
-
const BASE_URL = 'https://washday-backend.herokuapp.com/';
|
|
4
|
+
const BASE_URL = 'http://localhost:5555/';
|
|
5
|
+
//const BASE_URL: string = 'https://washday-backend.herokuapp.com/';
|
|
6
6
|
// Function to create or return the singleton instance
|
|
7
7
|
const getAxiosInstance = () => {
|
|
8
8
|
if (!axiosInstance) {
|
package/dist/api/index.js
CHANGED
|
@@ -73,6 +73,14 @@ const WashdayClient = function WashdayClient(apiToken) {
|
|
|
73
73
|
getStoreRoutesList: routesEndpoints.getModule.getStoreRoutesList,
|
|
74
74
|
createRoute: routesEndpoints.postModule.createRoute,
|
|
75
75
|
closeStoreRoutes: routesEndpoints.putModule.closeStoreRoutes,
|
|
76
|
+
//NEW V2 ENDPOINTS
|
|
77
|
+
getRoutesByStore: routesEndpoints.getModule.getRoutesByStore,
|
|
78
|
+
createRouteV2: routesEndpoints.postModule.createRouteV2,
|
|
79
|
+
getRouteByIdV2: routesEndpoints.getModule.getRouteByIdV2,
|
|
80
|
+
deleteRouteById: routesEndpoints.deleteModule.deleteRouteById,
|
|
81
|
+
closeRouteById: routesEndpoints.putModule.closeRouteById,
|
|
82
|
+
updateRouteById: routesEndpoints.putModule.updateRouteById,
|
|
83
|
+
getRoutesByDriver: routesEndpoints.getModule.getRoutesByDriver,
|
|
76
84
|
});
|
|
77
85
|
this.auth = bindMethods(this, {
|
|
78
86
|
customerLoginToken: authEndpoints.postModule.customerLoginToken,
|
package/dist/api/order/get.js
CHANGED
|
@@ -36,6 +36,10 @@ export const getList = function (params) {
|
|
|
36
36
|
'readyDateTime',
|
|
37
37
|
'collectedDateTime',
|
|
38
38
|
'q',
|
|
39
|
+
'pickupFromDate',
|
|
40
|
+
'pickupToDate',
|
|
41
|
+
'deliveryFromDate',
|
|
42
|
+
'deliveryToDate',
|
|
39
43
|
], params);
|
|
40
44
|
// ], { ...params, q: params.q ? encodeURIComponent(params.q) : undefined });
|
|
41
45
|
return yield axiosInstance.get(`${GET_SET_ORDER}?${queryParams}`, config);
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import axiosInstance from "../axiosInstance";
|
|
11
|
+
const GET_SET_ROUTES = 'api/routes';
|
|
12
|
+
export const deleteRouteById = function (id) {
|
|
13
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
14
|
+
try {
|
|
15
|
+
const config = {
|
|
16
|
+
headers: { Authorization: `Bearer ${this.apiToken}` }
|
|
17
|
+
};
|
|
18
|
+
return yield axiosInstance.delete(`${GET_SET_ROUTES}/${id}`, config);
|
|
19
|
+
}
|
|
20
|
+
catch (error) {
|
|
21
|
+
console.error('Error fetching deleteRouteById:', error);
|
|
22
|
+
throw error;
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
};
|
package/dist/api/routes/get.js
CHANGED
|
@@ -11,6 +11,9 @@ import { generateQueryParamsStr } from "../../utils/apiUtils";
|
|
|
11
11
|
import axiosInstance from "../axiosInstance";
|
|
12
12
|
const GET_SET_ROUTES_ORDERS = 'api/routes/orders';
|
|
13
13
|
const GET_STORE_ROUTES = 'api/storeRoutes';
|
|
14
|
+
const GET_STORE_ROUTES_BY_ID = 'api/stores/:id/routes';
|
|
15
|
+
const GET_ROUTE = 'api/routes';
|
|
16
|
+
//@deprecated
|
|
14
17
|
export const getOrdersForRoute = function (params) {
|
|
15
18
|
return __awaiter(this, void 0, void 0, function* () {
|
|
16
19
|
try {
|
|
@@ -29,6 +32,7 @@ export const getOrdersForRoute = function (params) {
|
|
|
29
32
|
}
|
|
30
33
|
});
|
|
31
34
|
};
|
|
35
|
+
//@deprecated
|
|
32
36
|
export const getStoreRoutesList = function (storeId) {
|
|
33
37
|
return __awaiter(this, void 0, void 0, function* () {
|
|
34
38
|
try {
|
|
@@ -43,3 +47,49 @@ export const getStoreRoutesList = function (storeId) {
|
|
|
43
47
|
}
|
|
44
48
|
});
|
|
45
49
|
};
|
|
50
|
+
//NEW V2 ENDPOINTS
|
|
51
|
+
export const getRoutesByStore = function (storeId) {
|
|
52
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
53
|
+
try {
|
|
54
|
+
const config = {
|
|
55
|
+
headers: { Authorization: `Bearer ${this.apiToken}` }
|
|
56
|
+
};
|
|
57
|
+
return yield axiosInstance.get(`${GET_STORE_ROUTES_BY_ID.replace(':id', storeId)}`, config);
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
console.error('Error fetching getRoutesByStore:', error);
|
|
61
|
+
throw error;
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
};
|
|
65
|
+
export const getRouteByIdV2 = function (routeId) {
|
|
66
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
67
|
+
try {
|
|
68
|
+
const config = {
|
|
69
|
+
headers: { Authorization: `Bearer ${this.apiToken}` }
|
|
70
|
+
};
|
|
71
|
+
return yield axiosInstance.get(`${GET_ROUTE}/${routeId}`, config);
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
console.error('Error fetching getRouteByIdV2:', error);
|
|
75
|
+
throw error;
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
};
|
|
79
|
+
export const getRoutesByDriver = function (query) {
|
|
80
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
81
|
+
try {
|
|
82
|
+
const config = {
|
|
83
|
+
headers: { Authorization: `Bearer ${this.apiToken}` }
|
|
84
|
+
};
|
|
85
|
+
const queryParams = generateQueryParamsStr([
|
|
86
|
+
'status',
|
|
87
|
+
], query);
|
|
88
|
+
return yield axiosInstance.get(`${GET_ROUTE}?${queryParams}`, config);
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
console.error('Error fetching getRoutesByDriver:', error);
|
|
92
|
+
throw error;
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
};
|
package/dist/api/routes/index.js
CHANGED
package/dist/api/routes/post.js
CHANGED
|
@@ -7,8 +7,21 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
11
|
+
var t = {};
|
|
12
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
13
|
+
t[p] = s[p];
|
|
14
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
15
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
16
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
17
|
+
t[p[i]] = s[p[i]];
|
|
18
|
+
}
|
|
19
|
+
return t;
|
|
20
|
+
};
|
|
10
21
|
import axiosInstance from "../axiosInstance";
|
|
11
22
|
const GET_SET_ROUTES = 'api/routes';
|
|
23
|
+
const GET_STORE_ROUTES_BY_ID = 'api/stores/:id/routes';
|
|
24
|
+
//@deprecated
|
|
12
25
|
export const createRoute = function (data) {
|
|
13
26
|
return __awaiter(this, void 0, void 0, function* () {
|
|
14
27
|
try {
|
|
@@ -23,3 +36,18 @@ export const createRoute = function (data) {
|
|
|
23
36
|
}
|
|
24
37
|
});
|
|
25
38
|
};
|
|
39
|
+
export const createRouteV2 = function (data) {
|
|
40
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
41
|
+
try {
|
|
42
|
+
const config = {
|
|
43
|
+
headers: { Authorization: `Bearer ${this.apiToken}` }
|
|
44
|
+
};
|
|
45
|
+
const { storeId } = data, rest = __rest(data, ["storeId"]);
|
|
46
|
+
return yield axiosInstance.post(GET_STORE_ROUTES_BY_ID.replace(':id', storeId), rest, config);
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
console.error('Error fetching createRouteV2:', error);
|
|
50
|
+
throw error;
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
};
|
package/dist/api/routes/put.js
CHANGED
|
@@ -9,6 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
};
|
|
10
10
|
import axiosInstance from "../axiosInstance";
|
|
11
11
|
const GET_STORE_ROUTES = 'api/storeRoutes';
|
|
12
|
+
const GET_ROUTE = 'api/routes';
|
|
12
13
|
export const closeStoreRoutes = function (storeId, data) {
|
|
13
14
|
return __awaiter(this, void 0, void 0, function* () {
|
|
14
15
|
try {
|
|
@@ -23,3 +24,31 @@ export const closeStoreRoutes = function (storeId, data) {
|
|
|
23
24
|
}
|
|
24
25
|
});
|
|
25
26
|
};
|
|
27
|
+
export const closeRouteById = function (routeId) {
|
|
28
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
29
|
+
try {
|
|
30
|
+
const config = {
|
|
31
|
+
headers: { Authorization: `Bearer ${this.apiToken}` }
|
|
32
|
+
};
|
|
33
|
+
return yield axiosInstance.put(`${GET_ROUTE}/${routeId}/close`, {}, config);
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
console.error('Error fetching closeRouteById:', error);
|
|
37
|
+
throw error;
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
export const updateRouteById = function (routeId, data) {
|
|
42
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
43
|
+
try {
|
|
44
|
+
const config = {
|
|
45
|
+
headers: { Authorization: `Bearer ${this.apiToken}` }
|
|
46
|
+
};
|
|
47
|
+
return yield axiosInstance.put(`${GET_ROUTE}/${routeId}`, data, config);
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
console.error('Error fetching updateRouteById:', error);
|
|
51
|
+
throw error;
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
};
|
|
@@ -5,14 +5,14 @@ export const calculateTotalTaxesIncluded = (order, selectedCustomer, storeSettin
|
|
|
5
5
|
const qty = current.qty || 0;
|
|
6
6
|
const taxPercentage = getProductTaxesPercentage(current, storeSettings);
|
|
7
7
|
const taxFactor = 1 + taxPercentage / 100;
|
|
8
|
-
//
|
|
8
|
+
// Convertir extraAmount de bruto a neto
|
|
9
9
|
const extraAmountGross = current.extraAmount || 0;
|
|
10
10
|
const extraAmountNet = extraAmountGross / taxFactor;
|
|
11
|
-
//
|
|
11
|
+
// Precio bruto del producto (sin extraAmount)
|
|
12
12
|
const productGrossPrice = order.express ? current.expressPrice : current.price;
|
|
13
|
-
//
|
|
13
|
+
// Convertir precio bruto a neto
|
|
14
14
|
const unitNetPrice = productGrossPrice / taxFactor;
|
|
15
|
-
//
|
|
15
|
+
// Determinar el porcentaje de descuento (si aplica)
|
|
16
16
|
let discPercentageInteger = 0;
|
|
17
17
|
let productPercentageDiscount = 0;
|
|
18
18
|
let customerDiscount = 0;
|
|
@@ -42,32 +42,34 @@ export const calculateTotalTaxesIncluded = (order, selectedCustomer, storeSettin
|
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
|
-
//
|
|
46
|
-
|
|
47
|
-
const
|
|
48
|
-
//
|
|
49
|
-
const
|
|
50
|
-
//
|
|
51
|
-
|
|
52
|
-
|
|
45
|
+
// === NUEVO: Aplicar descuento sobre el precio total ajustado (producto base + extra prorrateado) ===
|
|
46
|
+
// Si hay cantidad, repartir el extra neto entre cada unidad
|
|
47
|
+
const unitExtraNet = qty > 0 ? extraAmountNet / qty : 0;
|
|
48
|
+
// Precio neto ajustado: precio base + extra (por unidad)
|
|
49
|
+
const adjustedUnitNetPrice = unitNetPrice + unitExtraNet;
|
|
50
|
+
// Calcular el descuento sobre el precio ajustado
|
|
51
|
+
const discountAmountPerUnit = discPercentageInteger ? adjustedUnitNetPrice * discPercentageInteger : 0;
|
|
52
|
+
// Precio neto con descuento aplicado por unidad
|
|
53
|
+
const discountedUnitNetPrice = adjustedUnitNetPrice - discountAmountPerUnit;
|
|
54
|
+
// === Totales de la línea ===
|
|
55
|
+
// Total neto sin descuento: precio base total + extra (ya prorrateado en el total)
|
|
56
|
+
const productNetTotalWithoutDiscount = (unitNetPrice * qty) + extraAmountNet;
|
|
57
|
+
// Total neto con descuento: se aplica el descuento sobre el precio ajustado por unidad
|
|
53
58
|
const productNetTotalWithDiscount = discountedUnitNetPrice * qty;
|
|
54
|
-
//
|
|
55
|
-
const
|
|
56
|
-
const
|
|
57
|
-
//
|
|
58
|
-
const
|
|
59
|
-
const productLineTotalWithDiscount = +(totalNetWithDiscount * taxFactor).toFixed(2);
|
|
60
|
-
// Calculate the taxes as the difference between gross and net:
|
|
61
|
-
const totalTaxesApplied = +(productLineTotalWithDiscount - totalNetWithDiscount).toFixed(2);
|
|
59
|
+
// Reaplicar IVA a ambos totales
|
|
60
|
+
const productLineImportTotal = +(productNetTotalWithoutDiscount * taxFactor).toFixed(2);
|
|
61
|
+
const productLineTotalWithDiscount = +(productNetTotalWithDiscount * taxFactor).toFixed(2);
|
|
62
|
+
// Calcular el total de impuestos como la diferencia entre bruto y neto con descuento
|
|
63
|
+
const totalTaxesApplied = +(productLineTotalWithDiscount - productNetTotalWithDiscount).toFixed(2);
|
|
62
64
|
const lineDiscount = +(discountAmountPerUnit * qty).toFixed(2);
|
|
63
65
|
return {
|
|
64
66
|
product: current,
|
|
65
67
|
qty,
|
|
66
|
-
productLineImportTotal, //
|
|
67
|
-
productLineTotalWithDiscount, //
|
|
68
|
+
productLineImportTotal, // Total bruto sin descuento (incluye extra y IVA)
|
|
69
|
+
productLineTotalWithDiscount, // Total bruto con descuento aplicado sobre el precio ajustado
|
|
68
70
|
productLineTaxesTotal: totalTaxesApplied,
|
|
69
71
|
lineDiscountAmount: lineDiscount,
|
|
70
|
-
productLineSubtotal:
|
|
72
|
+
productLineSubtotal: productNetTotalWithoutDiscount // Subtotal neto (sin IVA)
|
|
71
73
|
};
|
|
72
74
|
});
|
|
73
75
|
return productTableImports;
|
|
@@ -6,10 +6,16 @@ export const calculateTotalTaxesOverPrice = (order, selectedCustomer, storeSetti
|
|
|
6
6
|
let discPercentageInteger = 0;
|
|
7
7
|
let productPercentageDiscount = 0;
|
|
8
8
|
let customerDiscount = 0;
|
|
9
|
-
const qty = current.qty; // cantidad
|
|
9
|
+
const qty = current.qty || current.quantity; // cantidad
|
|
10
10
|
// Precio base sin impuestos (en modo over_price el precio es neto)
|
|
11
11
|
const productBasePrice = order.express ? current.expressPrice : current.price;
|
|
12
|
-
//
|
|
12
|
+
// === NUEVO: Considerar extraAmount en el precio a descontar ===
|
|
13
|
+
// extraAmount es el ajuste total para la línea; se reparte por unidad
|
|
14
|
+
const extraAmount = current.extraAmount || 0;
|
|
15
|
+
const unitExtra = qty > 0 ? extraAmount / qty : 0;
|
|
16
|
+
// Precio ajustado: suma del precio base y el extra por unidad
|
|
17
|
+
const adjustedPrice = productBasePrice + unitExtra;
|
|
18
|
+
// Cálculo de descuento sobre el precio ajustado
|
|
13
19
|
if (!order.discountCode) {
|
|
14
20
|
const discountsToApply = storeDiscounts.filter((discount) => discount.products.includes(current._id) && discount.isActive);
|
|
15
21
|
customerDiscount = ((_a = selectedCustomer === null || selectedCustomer === void 0 ? void 0 : selectedCustomer.customer) === null || _a === void 0 ? void 0 : _a.discount) || 0;
|
|
@@ -35,29 +41,29 @@ export const calculateTotalTaxesOverPrice = (order, selectedCustomer, storeSetti
|
|
|
35
41
|
}
|
|
36
42
|
}
|
|
37
43
|
}
|
|
38
|
-
// Calcular descuento por unidad
|
|
39
|
-
const productDiscount =
|
|
40
|
-
const
|
|
41
|
-
// Subtotal para la línea (precio
|
|
42
|
-
const subtotal =
|
|
44
|
+
// Calcular el descuento por unidad sobre el precio ajustado
|
|
45
|
+
const productDiscount = adjustedPrice * discPercentageInteger;
|
|
46
|
+
const discountedAdjustedPrice = adjustedPrice - productDiscount;
|
|
47
|
+
// Subtotal para la línea (precio descontado por unidad * cantidad) SIN impuestos
|
|
48
|
+
const subtotal = discountedAdjustedPrice * qty;
|
|
43
49
|
// Calcular impuestos sobre el subtotal
|
|
44
50
|
const taxPercentage = getProductTaxesPercentage(current, storeSettings) / 100;
|
|
45
51
|
const taxes = subtotal * taxPercentage;
|
|
46
52
|
// Resultados finales:
|
|
47
53
|
const totalTaxesApplied = +taxes.toFixed(2);
|
|
48
54
|
const lineDiscount = +(productDiscount * qty).toFixed(2);
|
|
49
|
-
// Precio total con descuento, reaplicando
|
|
55
|
+
// Precio total con descuento, reaplicando impuestos
|
|
50
56
|
const prodLinePriceWithDiscount = +((subtotal * (1 + taxPercentage))).toFixed(2);
|
|
51
57
|
return {
|
|
52
58
|
product: current,
|
|
53
59
|
qty,
|
|
54
|
-
// Total bruto original sin descuento (precio base * cantidad + extraAmount
|
|
55
|
-
productLineImportTotal: (productBasePrice * qty) +
|
|
56
|
-
// Total final con descuento,
|
|
60
|
+
// Total bruto original sin descuento: (precio base * cantidad) + extraAmount
|
|
61
|
+
productLineImportTotal: (productBasePrice * qty) + extraAmount,
|
|
62
|
+
// Total final con descuento, con impuestos incluidos
|
|
57
63
|
productLineTotalWithDiscount: prodLinePriceWithDiscount,
|
|
58
64
|
productLineTaxesTotal: totalTaxesApplied,
|
|
59
65
|
lineDiscountAmount: lineDiscount,
|
|
60
|
-
// Subtotal
|
|
66
|
+
// Subtotal neto (sin impuestos) con descuento aplicado
|
|
61
67
|
productLineSubtotal: subtotal
|
|
62
68
|
};
|
|
63
69
|
});
|
package/package.json
CHANGED
package/src/api/axiosInstance.ts
CHANGED
|
@@ -3,8 +3,8 @@ import axios, { AxiosInstance, AxiosRequestConfig } from 'axios';
|
|
|
3
3
|
// Define the type for the Axios instance
|
|
4
4
|
let axiosInstance: AxiosInstance | null = null;
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
const BASE_URL: string = 'https://washday-backend.herokuapp.com/';
|
|
6
|
+
const BASE_URL: string = 'http://localhost:5555/';
|
|
7
|
+
//const BASE_URL: string = 'https://washday-backend.herokuapp.com/';
|
|
8
8
|
|
|
9
9
|
// Function to create or return the singleton instance
|
|
10
10
|
const getAxiosInstance = (): AxiosInstance => {
|
package/src/api/index.ts
CHANGED
|
@@ -80,6 +80,14 @@ const WashdayClient: WashdayClientConstructor = function WashdayClient(this: Was
|
|
|
80
80
|
getStoreRoutesList: routesEndpoints.getModule.getStoreRoutesList,
|
|
81
81
|
createRoute: routesEndpoints.postModule.createRoute,
|
|
82
82
|
closeStoreRoutes: routesEndpoints.putModule.closeStoreRoutes,
|
|
83
|
+
//NEW V2 ENDPOINTS
|
|
84
|
+
getRoutesByStore: routesEndpoints.getModule.getRoutesByStore,
|
|
85
|
+
createRouteV2: routesEndpoints.postModule.createRouteV2,
|
|
86
|
+
getRouteByIdV2: routesEndpoints.getModule.getRouteByIdV2,
|
|
87
|
+
deleteRouteById: routesEndpoints.deleteModule.deleteRouteById,
|
|
88
|
+
closeRouteById: routesEndpoints.putModule.closeRouteById,
|
|
89
|
+
updateRouteById: routesEndpoints.putModule.updateRouteById,
|
|
90
|
+
getRoutesByDriver: routesEndpoints.getModule.getRoutesByDriver,
|
|
83
91
|
});
|
|
84
92
|
this.auth = bindMethods(this, {
|
|
85
93
|
customerLoginToken: authEndpoints.postModule.customerLoginToken,
|
package/src/api/order/get.ts
CHANGED
|
@@ -23,7 +23,12 @@ export const getList = async function (this: WashdayClientInstance, params: {
|
|
|
23
23
|
cleanedDateTime: string | undefined,
|
|
24
24
|
readyDateTime: string | undefined,
|
|
25
25
|
collectedDateTime: string | undefined,
|
|
26
|
-
q: string | undefined
|
|
26
|
+
q: string | undefined,
|
|
27
|
+
pickupFromDate: string | undefined,
|
|
28
|
+
pickupToDate: string | undefined,
|
|
29
|
+
deliveryFromDate: string | undefined,
|
|
30
|
+
deliveryToDate: string | undefined,
|
|
31
|
+
|
|
27
32
|
}): Promise<any> {
|
|
28
33
|
try {
|
|
29
34
|
const config = {
|
|
@@ -46,6 +51,10 @@ export const getList = async function (this: WashdayClientInstance, params: {
|
|
|
46
51
|
'readyDateTime',
|
|
47
52
|
'collectedDateTime',
|
|
48
53
|
'q',
|
|
54
|
+
'pickupFromDate',
|
|
55
|
+
'pickupToDate',
|
|
56
|
+
'deliveryFromDate',
|
|
57
|
+
'deliveryToDate',
|
|
49
58
|
], params);
|
|
50
59
|
// ], { ...params, q: params.q ? encodeURIComponent(params.q) : undefined });
|
|
51
60
|
return await axiosInstance.get(`${GET_SET_ORDER}?${queryParams}`, config);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { WashdayClientInstance } from "../../interfaces/Api";
|
|
2
|
+
import axiosInstance from "../axiosInstance";
|
|
3
|
+
const GET_SET_ROUTES = 'api/routes';
|
|
4
|
+
|
|
5
|
+
export const deleteRouteById = async function (this: WashdayClientInstance, id: string): Promise<any> {
|
|
6
|
+
try {
|
|
7
|
+
const config = {
|
|
8
|
+
headers: { Authorization: `Bearer ${this.apiToken}` }
|
|
9
|
+
};
|
|
10
|
+
return await axiosInstance.delete(`${GET_SET_ROUTES}/${id}`, config);
|
|
11
|
+
} catch (error) {
|
|
12
|
+
console.error('Error fetching deleteRouteById:', error);
|
|
13
|
+
throw error;
|
|
14
|
+
}
|
|
15
|
+
};
|
package/src/api/routes/get.ts
CHANGED
|
@@ -4,7 +4,10 @@ import { generateQueryParamsStr } from "../../utils/apiUtils";
|
|
|
4
4
|
import axiosInstance from "../axiosInstance";
|
|
5
5
|
const GET_SET_ROUTES_ORDERS = 'api/routes/orders';
|
|
6
6
|
const GET_STORE_ROUTES = 'api/storeRoutes';
|
|
7
|
+
const GET_STORE_ROUTES_BY_ID = 'api/stores/:id/routes';
|
|
8
|
+
const GET_ROUTE = 'api/routes';
|
|
7
9
|
|
|
10
|
+
//@deprecated
|
|
8
11
|
export const getOrdersForRoute = async function (this: WashdayClientInstance, params: {
|
|
9
12
|
store: string | undefined,
|
|
10
13
|
routeDate: string | undefined,
|
|
@@ -24,6 +27,7 @@ export const getOrdersForRoute = async function (this: WashdayClientInstance, pa
|
|
|
24
27
|
}
|
|
25
28
|
};
|
|
26
29
|
|
|
30
|
+
//@deprecated
|
|
27
31
|
export const getStoreRoutesList = async function (this: WashdayClientInstance, storeId: string): Promise<any> {
|
|
28
32
|
try {
|
|
29
33
|
const config = {
|
|
@@ -34,4 +38,49 @@ export const getStoreRoutesList = async function (this: WashdayClientInstance, s
|
|
|
34
38
|
console.error('Error fetching getStoreRoutesList:', error);
|
|
35
39
|
throw error;
|
|
36
40
|
}
|
|
37
|
-
};
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
//NEW V2 ENDPOINTS
|
|
45
|
+
export const getRoutesByStore = async function (this: WashdayClientInstance, storeId: string): Promise<any> {
|
|
46
|
+
try {
|
|
47
|
+
const config = {
|
|
48
|
+
headers: { Authorization: `Bearer ${this.apiToken}` }
|
|
49
|
+
};
|
|
50
|
+
return await axiosInstance.get(`${GET_STORE_ROUTES_BY_ID.replace(':id', storeId)}`, config);
|
|
51
|
+
} catch (error) {
|
|
52
|
+
console.error('Error fetching getRoutesByStore:', error);
|
|
53
|
+
throw error;
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export const getRouteByIdV2 = async function (this: WashdayClientInstance, routeId: string): Promise<any> {
|
|
58
|
+
try {
|
|
59
|
+
const config = {
|
|
60
|
+
headers: { Authorization: `Bearer ${this.apiToken}` }
|
|
61
|
+
};
|
|
62
|
+
return await axiosInstance.get(`${GET_ROUTE}/${routeId}`, config);
|
|
63
|
+
} catch (error) {
|
|
64
|
+
console.error('Error fetching getRouteByIdV2:', error);
|
|
65
|
+
throw error;
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export const getRoutesByDriver = async function (this: WashdayClientInstance, query: {
|
|
70
|
+
status?: string,
|
|
71
|
+
}): Promise<any> {
|
|
72
|
+
try {
|
|
73
|
+
const config = {
|
|
74
|
+
headers: { Authorization: `Bearer ${this.apiToken}` }
|
|
75
|
+
};
|
|
76
|
+
const queryParams = generateQueryParamsStr([
|
|
77
|
+
'status',
|
|
78
|
+
], query);
|
|
79
|
+
return await axiosInstance.get(`${GET_ROUTE}?${queryParams}`, config);
|
|
80
|
+
} catch (error) {
|
|
81
|
+
console.error('Error fetching getRoutesByDriver:', error);
|
|
82
|
+
throw error;
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
|
package/src/api/routes/index.ts
CHANGED
package/src/api/routes/post.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { WashdayClientInstance } from "../../interfaces/Api";
|
|
2
2
|
import axiosInstance from "../axiosInstance";
|
|
3
3
|
const GET_SET_ROUTES = 'api/routes';
|
|
4
|
+
const GET_STORE_ROUTES_BY_ID = 'api/stores/:id/routes';
|
|
4
5
|
|
|
6
|
+
//@deprecated
|
|
5
7
|
export const createRoute = async function (this: WashdayClientInstance, data: {
|
|
6
8
|
driver: string;
|
|
7
9
|
store: string;
|
|
@@ -25,3 +27,21 @@ export const createRoute = async function (this: WashdayClientInstance, data: {
|
|
|
25
27
|
throw error;
|
|
26
28
|
}
|
|
27
29
|
};
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
export const createRouteV2 = async function (this: WashdayClientInstance, data: {
|
|
33
|
+
storeId: string,
|
|
34
|
+
driver: string,
|
|
35
|
+
orders: Array<string>,
|
|
36
|
+
}): Promise<any> {
|
|
37
|
+
try {
|
|
38
|
+
const config = {
|
|
39
|
+
headers: { Authorization: `Bearer ${this.apiToken}` }
|
|
40
|
+
};
|
|
41
|
+
const { storeId, ...rest } = data;
|
|
42
|
+
return await axiosInstance.post(GET_STORE_ROUTES_BY_ID.replace(':id', storeId), rest, config);
|
|
43
|
+
} catch (error) {
|
|
44
|
+
console.error('Error fetching createRouteV2:', error);
|
|
45
|
+
throw error;
|
|
46
|
+
}
|
|
47
|
+
};
|
package/src/api/routes/put.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { WashdayClientInstance } from "../../interfaces/Api";
|
|
2
2
|
import axiosInstance from "../axiosInstance";
|
|
3
3
|
const GET_STORE_ROUTES = 'api/storeRoutes';
|
|
4
|
+
const GET_ROUTE = 'api/routes';
|
|
4
5
|
|
|
5
6
|
export const closeStoreRoutes = async function (this: WashdayClientInstance, storeId: string, data: {
|
|
6
7
|
routes: string[],
|
|
@@ -15,3 +16,29 @@ export const closeStoreRoutes = async function (this: WashdayClientInstance, sto
|
|
|
15
16
|
throw error;
|
|
16
17
|
}
|
|
17
18
|
};
|
|
19
|
+
|
|
20
|
+
export const closeRouteById = async function (this: WashdayClientInstance, routeId: string): Promise<any> {
|
|
21
|
+
try {
|
|
22
|
+
const config = {
|
|
23
|
+
headers: { Authorization: `Bearer ${this.apiToken}` }
|
|
24
|
+
};
|
|
25
|
+
return await axiosInstance.put(`${GET_ROUTE}/${routeId}/close`, {}, config);
|
|
26
|
+
} catch (error) {
|
|
27
|
+
console.error('Error fetching closeRouteById:', error);
|
|
28
|
+
throw error;
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export const updateRouteById = async function (this: WashdayClientInstance, routeId: string, data: {
|
|
33
|
+
driver?: string,
|
|
34
|
+
}): Promise<any> {
|
|
35
|
+
try {
|
|
36
|
+
const config = {
|
|
37
|
+
headers: { Authorization: `Bearer ${this.apiToken}` }
|
|
38
|
+
};
|
|
39
|
+
return await axiosInstance.put(`${GET_ROUTE}/${routeId}`, data, config);
|
|
40
|
+
} catch (error) {
|
|
41
|
+
console.error('Error fetching updateRouteById:', error);
|
|
42
|
+
throw error;
|
|
43
|
+
}
|
|
44
|
+
};
|
package/src/interfaces/Api.ts
CHANGED
|
@@ -80,6 +80,14 @@ export interface WashdayClientInstance {
|
|
|
80
80
|
getStoreRoutesList: typeof routesEndpoints.getModule.getStoreRoutesList,
|
|
81
81
|
createRoute: typeof routesEndpoints.postModule.createRoute,
|
|
82
82
|
closeStoreRoutes: typeof routesEndpoints.putModule.closeStoreRoutes,
|
|
83
|
+
//NEW V2 ENDPOINTS
|
|
84
|
+
getRoutesByStore: typeof routesEndpoints.getModule.getRoutesByStore,
|
|
85
|
+
createRouteV2: typeof routesEndpoints.postModule.createRouteV2,
|
|
86
|
+
getRouteByIdV2: typeof routesEndpoints.getModule.getRouteByIdV2,
|
|
87
|
+
deleteRouteById: typeof routesEndpoints.deleteModule.deleteRouteById,
|
|
88
|
+
closeRouteById: typeof routesEndpoints.putModule.closeRouteById,
|
|
89
|
+
updateRouteById: typeof routesEndpoints.putModule.updateRouteById,
|
|
90
|
+
getRoutesByDriver: typeof routesEndpoints.getModule.getRoutesByDriver,
|
|
83
91
|
},
|
|
84
92
|
orders: {
|
|
85
93
|
getList: typeof ordersEndpoints.getModule.getList;
|
|
@@ -14,16 +14,16 @@ export const calculateTotalTaxesIncluded = (
|
|
|
14
14
|
const taxPercentage = getProductTaxesPercentage(current, storeSettings);
|
|
15
15
|
const taxFactor = 1 + taxPercentage / 100;
|
|
16
16
|
|
|
17
|
-
//
|
|
17
|
+
// Convertir extraAmount de bruto a neto
|
|
18
18
|
const extraAmountGross = current.extraAmount || 0;
|
|
19
19
|
const extraAmountNet = extraAmountGross / taxFactor;
|
|
20
20
|
|
|
21
|
-
//
|
|
21
|
+
// Precio bruto del producto (sin extraAmount)
|
|
22
22
|
const productGrossPrice = order.express ? current.expressPrice : current.price;
|
|
23
|
-
//
|
|
23
|
+
// Convertir precio bruto a neto
|
|
24
24
|
const unitNetPrice = productGrossPrice / taxFactor;
|
|
25
25
|
|
|
26
|
-
//
|
|
26
|
+
// Determinar el porcentaje de descuento (si aplica)
|
|
27
27
|
let discPercentageInteger = 0;
|
|
28
28
|
let productPercentageDiscount = 0;
|
|
29
29
|
let customerDiscount = 0;
|
|
@@ -32,7 +32,7 @@ export const calculateTotalTaxesIncluded = (
|
|
|
32
32
|
(discount) => discount.products.includes(current._id) && discount.isActive
|
|
33
33
|
);
|
|
34
34
|
customerDiscount = selectedCustomer?.customer?.discount || 0;
|
|
35
|
-
productPercentageDiscount = discountsToApply.reduce((prev
|
|
35
|
+
productPercentageDiscount = discountsToApply.reduce((prev, next) => {
|
|
36
36
|
return next.type === 'percentage' ? prev + next.value : prev;
|
|
37
37
|
}, 0);
|
|
38
38
|
discPercentageInteger = +((productPercentageDiscount + customerDiscount) / 100).toFixed(2);
|
|
@@ -55,37 +55,39 @@ export const calculateTotalTaxesIncluded = (
|
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
//
|
|
59
|
-
|
|
60
|
-
const
|
|
61
|
-
//
|
|
62
|
-
const
|
|
58
|
+
// === NUEVO: Aplicar descuento sobre el precio total ajustado (producto base + extra prorrateado) ===
|
|
59
|
+
// Si hay cantidad, repartir el extra neto entre cada unidad
|
|
60
|
+
const unitExtraNet = qty > 0 ? extraAmountNet / qty : 0;
|
|
61
|
+
// Precio neto ajustado: precio base + extra (por unidad)
|
|
62
|
+
const adjustedUnitNetPrice = unitNetPrice + unitExtraNet;
|
|
63
|
+
// Calcular el descuento sobre el precio ajustado
|
|
64
|
+
const discountAmountPerUnit = discPercentageInteger ? adjustedUnitNetPrice * discPercentageInteger : 0;
|
|
65
|
+
// Precio neto con descuento aplicado por unidad
|
|
66
|
+
const discountedUnitNetPrice = adjustedUnitNetPrice - discountAmountPerUnit;
|
|
63
67
|
|
|
64
|
-
//
|
|
65
|
-
//
|
|
66
|
-
const productNetTotalWithoutDiscount = unitNetPrice * qty;
|
|
68
|
+
// === Totales de la línea ===
|
|
69
|
+
// Total neto sin descuento: precio base total + extra (ya prorrateado en el total)
|
|
70
|
+
const productNetTotalWithoutDiscount = (unitNetPrice * qty) + extraAmountNet;
|
|
71
|
+
// Total neto con descuento: se aplica el descuento sobre el precio ajustado por unidad
|
|
67
72
|
const productNetTotalWithDiscount = discountedUnitNetPrice * qty;
|
|
68
|
-
// Add the extraAmount net (since it is not discounted):
|
|
69
|
-
const totalNetWithoutDiscount = productNetTotalWithoutDiscount + extraAmountNet;
|
|
70
|
-
const totalNetWithDiscount = productNetTotalWithDiscount + extraAmountNet;
|
|
71
73
|
|
|
72
|
-
//
|
|
73
|
-
const productLineImportTotal = +
|
|
74
|
-
const productLineTotalWithDiscount = +
|
|
74
|
+
// Reaplicar IVA a ambos totales
|
|
75
|
+
const productLineImportTotal = +(productNetTotalWithoutDiscount * taxFactor).toFixed(2);
|
|
76
|
+
const productLineTotalWithDiscount = +(productNetTotalWithDiscount * taxFactor).toFixed(2);
|
|
75
77
|
|
|
76
|
-
//
|
|
77
|
-
const totalTaxesApplied = +
|
|
78
|
+
// Calcular el total de impuestos como la diferencia entre bruto y neto con descuento
|
|
79
|
+
const totalTaxesApplied = +(productLineTotalWithDiscount - productNetTotalWithDiscount).toFixed(2);
|
|
78
80
|
|
|
79
|
-
const lineDiscount = +
|
|
81
|
+
const lineDiscount = +(discountAmountPerUnit * qty).toFixed(2);
|
|
80
82
|
|
|
81
83
|
return {
|
|
82
84
|
product: current,
|
|
83
85
|
qty,
|
|
84
|
-
productLineImportTotal,
|
|
85
|
-
productLineTotalWithDiscount,
|
|
86
|
+
productLineImportTotal, // Total bruto sin descuento (incluye extra y IVA)
|
|
87
|
+
productLineTotalWithDiscount, // Total bruto con descuento aplicado sobre el precio ajustado
|
|
86
88
|
productLineTaxesTotal: totalTaxesApplied,
|
|
87
89
|
lineDiscountAmount: lineDiscount,
|
|
88
|
-
productLineSubtotal:
|
|
90
|
+
productLineSubtotal: productNetTotalWithoutDiscount // Subtotal neto (sin IVA)
|
|
89
91
|
};
|
|
90
92
|
});
|
|
91
93
|
return productTableImports;
|
|
@@ -13,12 +13,19 @@ export const calculateTotalTaxesOverPrice = (
|
|
|
13
13
|
let discPercentageInteger = 0;
|
|
14
14
|
let productPercentageDiscount = 0;
|
|
15
15
|
let customerDiscount = 0;
|
|
16
|
-
const qty = current.qty; // cantidad
|
|
16
|
+
const qty = current.qty || current.quantity; // cantidad
|
|
17
17
|
|
|
18
18
|
// Precio base sin impuestos (en modo over_price el precio es neto)
|
|
19
19
|
const productBasePrice = order.express ? current.expressPrice : current.price;
|
|
20
20
|
|
|
21
|
-
//
|
|
21
|
+
// === NUEVO: Considerar extraAmount en el precio a descontar ===
|
|
22
|
+
// extraAmount es el ajuste total para la línea; se reparte por unidad
|
|
23
|
+
const extraAmount = current.extraAmount || 0;
|
|
24
|
+
const unitExtra = qty > 0 ? extraAmount / qty : 0;
|
|
25
|
+
// Precio ajustado: suma del precio base y el extra por unidad
|
|
26
|
+
const adjustedPrice = productBasePrice + unitExtra;
|
|
27
|
+
|
|
28
|
+
// Cálculo de descuento sobre el precio ajustado
|
|
22
29
|
if (!order.discountCode) {
|
|
23
30
|
const discountsToApply = storeDiscounts.filter(
|
|
24
31
|
(discount) => discount.products.includes(current._id) && discount.isActive
|
|
@@ -45,12 +52,12 @@ export const calculateTotalTaxesOverPrice = (
|
|
|
45
52
|
}
|
|
46
53
|
}
|
|
47
54
|
|
|
48
|
-
// Calcular descuento por unidad
|
|
49
|
-
const productDiscount =
|
|
50
|
-
const
|
|
55
|
+
// Calcular el descuento por unidad sobre el precio ajustado
|
|
56
|
+
const productDiscount = adjustedPrice * discPercentageInteger;
|
|
57
|
+
const discountedAdjustedPrice = adjustedPrice - productDiscount;
|
|
51
58
|
|
|
52
|
-
// Subtotal para la línea (precio
|
|
53
|
-
const subtotal =
|
|
59
|
+
// Subtotal para la línea (precio descontado por unidad * cantidad) SIN impuestos
|
|
60
|
+
const subtotal = discountedAdjustedPrice * qty;
|
|
54
61
|
|
|
55
62
|
// Calcular impuestos sobre el subtotal
|
|
56
63
|
const taxPercentage = getProductTaxesPercentage(current, storeSettings) / 100;
|
|
@@ -60,19 +67,19 @@ export const calculateTotalTaxesOverPrice = (
|
|
|
60
67
|
const totalTaxesApplied = +taxes.toFixed(2);
|
|
61
68
|
const lineDiscount = +(productDiscount * qty).toFixed(2);
|
|
62
69
|
|
|
63
|
-
// Precio total con descuento, reaplicando
|
|
70
|
+
// Precio total con descuento, reaplicando impuestos
|
|
64
71
|
const prodLinePriceWithDiscount = +((subtotal * (1 + taxPercentage))).toFixed(2);
|
|
65
72
|
|
|
66
73
|
return {
|
|
67
74
|
product: current,
|
|
68
75
|
qty,
|
|
69
|
-
// Total bruto original sin descuento (precio base * cantidad + extraAmount
|
|
70
|
-
productLineImportTotal: (productBasePrice * qty) +
|
|
71
|
-
// Total final con descuento,
|
|
76
|
+
// Total bruto original sin descuento: (precio base * cantidad) + extraAmount
|
|
77
|
+
productLineImportTotal: (productBasePrice * qty) + extraAmount,
|
|
78
|
+
// Total final con descuento, con impuestos incluidos
|
|
72
79
|
productLineTotalWithDiscount: prodLinePriceWithDiscount,
|
|
73
80
|
productLineTaxesTotal: totalTaxesApplied,
|
|
74
81
|
lineDiscountAmount: lineDiscount,
|
|
75
|
-
// Subtotal
|
|
82
|
+
// Subtotal neto (sin impuestos) con descuento aplicado
|
|
76
83
|
productLineSubtotal: subtotal
|
|
77
84
|
};
|
|
78
85
|
});
|