vr-commons 1.0.96 → 1.0.98

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.
Files changed (28) hide show
  1. package/dist/utils/admin.device.utils.d.ts +59 -0
  2. package/dist/utils/admin.device.utils.js +231 -0
  3. package/dist/utils/admin.devicePayment.utils.d.ts +46 -0
  4. package/dist/utils/admin.devicePayment.utils.js +206 -0
  5. package/dist/utils/index.d.ts +3 -1
  6. package/dist/utils/index.js +5 -1
  7. package/dist/utils/types.d.ts +7 -0
  8. package/dist/validations/admin.devicePayment.validations.d.ts +270 -0
  9. package/dist/validations/admin.devicePayment.validations.js +98 -0
  10. package/dist/validations/admin.devices.validations.d.ts +297 -0
  11. package/dist/validations/admin.devices.validations.js +118 -0
  12. package/dist/validations/appSpecs.validations.d.ts +16 -16
  13. package/dist/validations/appeals.validations.d.ts +8 -8
  14. package/dist/validations/auth.validations.d.ts +2 -2
  15. package/dist/validations/bans.validations.d.ts +8 -8
  16. package/dist/validations/devicePaymentPlan.validations.d.ts +12 -12
  17. package/dist/validations/index.d.ts +2 -0
  18. package/dist/validations/index.js +22 -1
  19. package/dist/validations/moderation.validations.d.ts +105 -105
  20. package/dist/validations/payinstallment.validations.d.ts +5 -5
  21. package/dist/validations/pricing.validations.d.ts +313 -0
  22. package/dist/validations/pricing.validations.js +376 -0
  23. package/dist/validations/pricings.validations.d.ts +54 -54
  24. package/dist/validations/product.validations.d.ts +42 -42
  25. package/dist/validations/profiles.validations.d.ts +46 -46
  26. package/dist/validations/suspensions.validations.d.ts +8 -8
  27. package/dist/validations/users.admin.validations.d.ts +44 -44
  28. package/package.json +1 -1
@@ -0,0 +1,59 @@
1
+ import { UserRole } from "vr-models";
2
+ import { Transaction } from "sequelize";
3
+ import { StockChangeResult } from "./types";
4
+ export declare const stockUtil: {
5
+ /**
6
+ * Increment stock when devices are added/created
7
+ */
8
+ incrementStock(productId: string, quantity?: number, options?: {
9
+ transaction?: Transaction;
10
+ reason?: string;
11
+ actorId?: string;
12
+ actorType: UserRole;
13
+ }): Promise<StockChangeResult>;
14
+ /**
15
+ * Decrement stock when devices are removed/deleted/assigned
16
+ */
17
+ decrementStock(productId: string, quantity?: number, options?: {
18
+ transaction?: Transaction;
19
+ reason?: string;
20
+ actorId?: string;
21
+ allowNegative?: boolean;
22
+ actorType: UserRole;
23
+ }): Promise<StockChangeResult>;
24
+ /**
25
+ * Set stock to specific value
26
+ */
27
+ setStock(productId: string, newStock: number, options?: {
28
+ transaction?: Transaction;
29
+ reason?: string;
30
+ actorId?: string;
31
+ actorType: UserRole;
32
+ }): Promise<StockChangeResult>;
33
+ /**
34
+ * Validate if product has enough stock
35
+ */
36
+ hasEnoughStock(productId: string, quantity?: number, transaction?: Transaction): Promise<boolean>;
37
+ /**
38
+ * Get current stock level
39
+ */
40
+ getStockLevel(productId: string, transaction?: Transaction): Promise<number>;
41
+ /**
42
+ * Bulk update stock for multiple products
43
+ */
44
+ bulkUpdateStock(updates: Array<{
45
+ productId: string;
46
+ change: number;
47
+ reason?: string;
48
+ }>, actorType: UserRole, options?: {
49
+ transaction?: Transaction;
50
+ actorId?: string;
51
+ }): Promise<Record<string, StockChangeResult>>;
52
+ /**
53
+ * Sync stock based on actual device count
54
+ */
55
+ syncStockWithDeviceCount(productId: string, actorType: UserRole, options?: {
56
+ transaction?: Transaction;
57
+ actorId?: string;
58
+ }): Promise<StockChangeResult>;
59
+ };
@@ -0,0 +1,231 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.stockUtil = void 0;
4
+ // src/utils/stock.util.ts
5
+ const vr_models_1 = require("vr-models");
6
+ const eventLog_utils_1 = require("./eventLog.utils");
7
+ exports.stockUtil = {
8
+ /**
9
+ * Increment stock when devices are added/created
10
+ */
11
+ async incrementStock(productId, quantity = 1, options) {
12
+ const product = await vr_models_1.Product.findByPk(productId, {
13
+ transaction: options?.transaction,
14
+ });
15
+ if (!product) {
16
+ throw new Error(`Product with ID ${productId} not found`);
17
+ }
18
+ const previousStock = product.stock;
19
+ // Use the model's instance method if available, otherwise direct update
20
+ if (typeof product.incrementStock === "function") {
21
+ await product.incrementStock(quantity);
22
+ }
23
+ else {
24
+ product.stock += quantity;
25
+ await product.save({ transaction: options?.transaction });
26
+ }
27
+ // Log stock change
28
+ if (options?.actorId) {
29
+ await (0, eventLog_utils_1.logEvent)({
30
+ actorId: options.actorId,
31
+ actorType: options.actorType,
32
+ action: "PRODUCT_STOCK_INCREMENTED",
33
+ entity: "Product",
34
+ entityId: productId,
35
+ deviceSession: null,
36
+ metadata: {
37
+ quantity,
38
+ previousStock,
39
+ newStock: product.stock,
40
+ reason: options.reason || "Device added to inventory",
41
+ },
42
+ transaction: options?.transaction,
43
+ });
44
+ }
45
+ return {
46
+ success: true,
47
+ previousStock,
48
+ newStock: product.stock,
49
+ productId: product.id,
50
+ productName: product.name,
51
+ };
52
+ },
53
+ /**
54
+ * Decrement stock when devices are removed/deleted/assigned
55
+ */
56
+ async decrementStock(productId, quantity = 1, options) {
57
+ const product = await vr_models_1.Product.findByPk(productId, {
58
+ transaction: options?.transaction,
59
+ });
60
+ if (!product) {
61
+ throw new Error(`Product with ID ${productId} not found`);
62
+ }
63
+ // Check if enough stock (unless allowNegative is true)
64
+ if (!options?.allowNegative && product.stock < quantity) {
65
+ throw new Error(`Insufficient stock. Available: ${product.stock}, Requested: ${quantity}`);
66
+ }
67
+ const previousStock = product.stock;
68
+ // Use the model's instance method if available
69
+ if (typeof product.decrementStock === "function") {
70
+ await product.decrementStock(quantity);
71
+ }
72
+ else {
73
+ product.stock -= quantity;
74
+ await product.save({ transaction: options?.transaction });
75
+ }
76
+ // Log stock change
77
+ if (options?.actorId) {
78
+ await (0, eventLog_utils_1.logEvent)({
79
+ actorId: options.actorId,
80
+ actorType: options.actorType,
81
+ action: "PRODUCT_STOCK_DECREMENTED",
82
+ entity: "Product",
83
+ entityId: productId,
84
+ deviceSession: null,
85
+ metadata: {
86
+ quantity,
87
+ previousStock,
88
+ newStock: product.stock,
89
+ reason: options.reason || "Device removed from inventory",
90
+ },
91
+ transaction: options?.transaction,
92
+ });
93
+ }
94
+ return {
95
+ success: true,
96
+ previousStock,
97
+ newStock: product.stock,
98
+ productId: product.id,
99
+ productName: product.name,
100
+ };
101
+ },
102
+ /**
103
+ * Set stock to specific value
104
+ */
105
+ async setStock(productId, newStock, options) {
106
+ const product = await vr_models_1.Product.findByPk(productId, {
107
+ transaction: options?.transaction,
108
+ });
109
+ if (!product) {
110
+ throw new Error(`Product with ID ${productId} not found`);
111
+ }
112
+ if (newStock < 0) {
113
+ throw new Error("Stock cannot be negative");
114
+ }
115
+ const previousStock = product.stock;
116
+ product.stock = newStock;
117
+ await product.save({ transaction: options?.transaction });
118
+ // Log stock change
119
+ if (options?.actorId) {
120
+ await (0, eventLog_utils_1.logEvent)({
121
+ actorId: options.actorId,
122
+ actorType: options.actorType,
123
+ action: "PRODUCT_STOCK_SET_MANUALLY",
124
+ entity: "Product",
125
+ entityId: productId,
126
+ deviceSession: null,
127
+ metadata: {
128
+ previousStock,
129
+ newStock,
130
+ reason: options.reason || "Manual stock adjustment",
131
+ },
132
+ transaction: options?.transaction,
133
+ });
134
+ }
135
+ return {
136
+ success: true,
137
+ previousStock,
138
+ newStock: product.stock,
139
+ productId: product.id,
140
+ productName: product.name,
141
+ };
142
+ },
143
+ /**
144
+ * Validate if product has enough stock
145
+ */
146
+ async hasEnoughStock(productId, quantity = 1, transaction) {
147
+ const product = await vr_models_1.Product.findByPk(productId, { transaction });
148
+ if (!product)
149
+ return false;
150
+ return product.stock >= quantity;
151
+ },
152
+ /**
153
+ * Get current stock level
154
+ */
155
+ async getStockLevel(productId, transaction) {
156
+ const product = await vr_models_1.Product.findByPk(productId, {
157
+ transaction,
158
+ attributes: ["stock"],
159
+ });
160
+ return product?.stock || 0;
161
+ },
162
+ /**
163
+ * Bulk update stock for multiple products
164
+ */
165
+ async bulkUpdateStock(updates, actorType, options) {
166
+ const results = {};
167
+ for (const update of updates) {
168
+ try {
169
+ if (update.change > 0) {
170
+ results[update.productId] = await this.incrementStock(update.productId, update.change, {
171
+ transaction: options?.transaction,
172
+ reason: update.reason,
173
+ actorId: options?.actorId,
174
+ actorType: actorType,
175
+ });
176
+ }
177
+ else if (update.change < 0) {
178
+ results[update.productId] = await this.decrementStock(update.productId, Math.abs(update.change), {
179
+ transaction: options?.transaction,
180
+ reason: update.reason,
181
+ actorId: options?.actorId,
182
+ actorType: actorType,
183
+ });
184
+ }
185
+ }
186
+ catch (error) {
187
+ console.error(`Failed to update stock for product ${update.productId}:`, error);
188
+ results[update.productId] = {
189
+ success: false,
190
+ previousStock: 0,
191
+ newStock: 0,
192
+ productId: update.productId,
193
+ productName: "Unknown",
194
+ };
195
+ }
196
+ }
197
+ return results;
198
+ },
199
+ /**
200
+ * Sync stock based on actual device count
201
+ */
202
+ async syncStockWithDeviceCount(productId, actorType, options) {
203
+ // Count total devices for this product
204
+ const totalDevices = await vr_models_1.Device.count({
205
+ where: { productId },
206
+ transaction: options?.transaction,
207
+ });
208
+ // Count devices that are in use (have active payment plans)
209
+ const inUseDevices = await vr_models_1.Device.count({
210
+ where: { productId },
211
+ include: [
212
+ {
213
+ model: vr_models_1.DevicePaymentPlan,
214
+ as: "paymentPlans",
215
+ where: { status: "ACTIVE" },
216
+ required: true,
217
+ },
218
+ ],
219
+ transaction: options?.transaction,
220
+ });
221
+ // Available devices = total - inUse
222
+ const availableDevices = totalDevices - inUseDevices;
223
+ // Set stock to available devices
224
+ return await this.setStock(productId, availableDevices, {
225
+ transaction: options?.transaction,
226
+ reason: "Stock synced with actual device count",
227
+ actorId: options?.actorId,
228
+ actorType: actorType,
229
+ });
230
+ },
231
+ };
@@ -0,0 +1,46 @@
1
+ import { DevicePaymentPlan } from "vr-models";
2
+ import { Transaction } from "sequelize";
3
+ export interface DeleteCheckResult {
4
+ canDelete: boolean;
5
+ reason?: string;
6
+ }
7
+ export declare const DPP_OperationsUtil: {
8
+ /**
9
+ * Check if a payment plan can be deleted
10
+ * Rule: Can only delete if NO payments have been made
11
+ */
12
+ canDeletePlan(planId: string, transaction?: Transaction): Promise<DeleteCheckResult>;
13
+ /**
14
+ * Check if plan can be updated (before payments)
15
+ */
16
+ canUpdatePlan(plan: DevicePaymentPlan): {
17
+ canUpdate: boolean;
18
+ reason?: string;
19
+ };
20
+ /**
21
+ * Validate payment amount against next pending installment
22
+ */
23
+ validatePaymentAmount(plan: DevicePaymentPlan, amount: number, transaction?: Transaction): Promise<{
24
+ valid: boolean;
25
+ reason?: string;
26
+ nextInstallment?: any;
27
+ }>;
28
+ /**
29
+ * Calculate new values after payment
30
+ */
31
+ calculatePaymentEffects(plan: DevicePaymentPlan, amount: number): {
32
+ newPaidAmount: number;
33
+ newOutstandingAmount: number;
34
+ isNowCompleted: boolean;
35
+ progress: number;
36
+ statusChanged: boolean;
37
+ };
38
+ /**
39
+ * Generate installments for a hire purchase plan
40
+ */
41
+ generateInstallments(plan: DevicePaymentPlan, transaction?: Transaction): Promise<void>;
42
+ /**
43
+ * Format plan for operation response
44
+ */
45
+ formatPlanForOps(plan: DevicePaymentPlan | null): any;
46
+ };
@@ -0,0 +1,206 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DPP_OperationsUtil = void 0;
4
+ // src/utils/admin.devicePayment.utils.ts
5
+ const vr_models_1 = require("vr-models");
6
+ exports.DPP_OperationsUtil = {
7
+ /**
8
+ * Check if a payment plan can be deleted
9
+ * Rule: Can only delete if NO payments have been made
10
+ */
11
+ async canDeletePlan(planId, transaction) {
12
+ // Check if any payments exist for this plan
13
+ const paymentCount = await vr_models_1.Payment.count({
14
+ where: { devicePaymentPlanId: planId },
15
+ transaction,
16
+ });
17
+ if (paymentCount > 0) {
18
+ return {
19
+ canDelete: false,
20
+ reason: `Cannot delete plan with ${paymentCount} payment(s) already recorded`,
21
+ };
22
+ }
23
+ // Also check if any installments are paid
24
+ const paidInstallments = await vr_models_1.Installment.count({
25
+ where: {
26
+ devicePaymentPlanId: planId,
27
+ status: "PAID",
28
+ },
29
+ transaction,
30
+ });
31
+ if (paidInstallments > 0) {
32
+ return {
33
+ canDelete: false,
34
+ reason: "Cannot delete plan with paid installments",
35
+ };
36
+ }
37
+ return { canDelete: true };
38
+ },
39
+ /**
40
+ * Check if plan can be updated (before payments)
41
+ */
42
+ canUpdatePlan(plan) {
43
+ if (plan.paidAmount > 0) {
44
+ return {
45
+ canUpdate: false,
46
+ reason: "Cannot update plan after payments have been made",
47
+ };
48
+ }
49
+ if (plan.status !== "ACTIVE") {
50
+ return {
51
+ canUpdate: false,
52
+ reason: `Cannot update plan with status: ${plan.status}`,
53
+ };
54
+ }
55
+ return { canUpdate: true };
56
+ },
57
+ /**
58
+ * Validate payment amount against next pending installment
59
+ */
60
+ async validatePaymentAmount(plan, amount, transaction) {
61
+ const InstallmentModel = vr_models_1.Installment;
62
+ const nextInstallment = await InstallmentModel.findOne({
63
+ where: {
64
+ devicePaymentPlanId: plan.id,
65
+ status: "PENDING",
66
+ },
67
+ order: [["dueDate", "ASC"]],
68
+ transaction,
69
+ });
70
+ if (!nextInstallment) {
71
+ return {
72
+ valid: false,
73
+ reason: "No pending installments found",
74
+ };
75
+ }
76
+ // For now, require exact installment amount
77
+ // Could be modified to allow overpayment later
78
+ if (amount !== nextInstallment.amount) {
79
+ return {
80
+ valid: false,
81
+ reason: `Payment amount must equal the next installment amount of ${nextInstallment.amount}`,
82
+ nextInstallment,
83
+ };
84
+ }
85
+ return { valid: true, nextInstallment };
86
+ },
87
+ /**
88
+ * Calculate new values after payment
89
+ */
90
+ calculatePaymentEffects(plan, amount) {
91
+ const newPaidAmount = plan.paidAmount + amount;
92
+ const newOutstandingAmount = Math.max(0, plan.outstandingAmount - amount);
93
+ const wasCompleted = plan.status === "COMPLETED";
94
+ const isNowCompleted = newOutstandingAmount <= 0;
95
+ const totalAmount = plan.pricingSnapshot.totalAmount;
96
+ const progress = (newPaidAmount / totalAmount) * 100;
97
+ return {
98
+ newPaidAmount,
99
+ newOutstandingAmount,
100
+ isNowCompleted,
101
+ progress,
102
+ statusChanged: !wasCompleted && isNowCompleted,
103
+ };
104
+ },
105
+ /**
106
+ * Generate installments for a hire purchase plan
107
+ */
108
+ async generateInstallments(plan, transaction) {
109
+ const pricing = plan.pricingSnapshot;
110
+ if (pricing.type !== "HIRE_PURCHASE" || !pricing.installmentCount) {
111
+ return; // No installments for full payment plans
112
+ }
113
+ const InstallmentModel = vr_models_1.Installment;
114
+ const installments = [];
115
+ const dueDate = new Date(); // First installment due after creation
116
+ if (pricing.installmentFrequency === "DAILY") {
117
+ dueDate.setDate(dueDate.getDate() + 1);
118
+ }
119
+ else if (pricing.installmentFrequency === "WEEKLY") {
120
+ dueDate.setDate(dueDate.getDate() + 7);
121
+ }
122
+ else if (pricing.installmentFrequency === "MONTHLY") {
123
+ dueDate.setMonth(dueDate.getMonth() + 1);
124
+ }
125
+ for (let i = 1; i <= pricing.installmentCount; i++) {
126
+ installments.push({
127
+ devicePaymentPlanId: plan.id,
128
+ installmentNumber: i,
129
+ amount: Number(pricing.installmentAmount),
130
+ dueDate: new Date(dueDate),
131
+ status: "PENDING",
132
+ isAutoGenerated: true,
133
+ });
134
+ // Calculate next due date
135
+ if (pricing.installmentFrequency === "DAILY") {
136
+ dueDate.setDate(dueDate.getDate() + 1);
137
+ }
138
+ else if (pricing.installmentFrequency === "WEEKLY") {
139
+ dueDate.setDate(dueDate.getDate() + 7);
140
+ }
141
+ else if (pricing.installmentFrequency === "MONTHLY") {
142
+ dueDate.setMonth(dueDate.getMonth() + 1);
143
+ }
144
+ }
145
+ await InstallmentModel.bulkCreate(installments, { transaction });
146
+ // Set the first installment as next due
147
+ plan.nextInstallmentDueAt = installments[0]?.dueDate || null;
148
+ await plan.save({ transaction });
149
+ },
150
+ /**
151
+ * Format plan for operation response
152
+ */
153
+ formatPlanForOps(plan) {
154
+ if (!plan)
155
+ return null;
156
+ // Safely extract data without using toJSON() which exposes internal types
157
+ const planData = {
158
+ id: plan.id,
159
+ userId: plan.userId,
160
+ pricingSnapshot: plan.pricingSnapshot,
161
+ paidAmount: plan.paidAmount,
162
+ outstandingAmount: plan.outstandingAmount,
163
+ lastPaymentAt: plan.lastPaymentAt,
164
+ nextInstallmentDueAt: plan.nextInstallmentDueAt,
165
+ status: plan.status,
166
+ completedAt: plan.completedAt,
167
+ createdAt: plan.createdAt,
168
+ updatedAt: plan.updatedAt,
169
+ devices: plan.devices || [],
170
+ user: plan.user || null,
171
+ installments: plan.installments || [],
172
+ };
173
+ const totalAmount = planData.pricingSnapshot?.totalAmount || 0;
174
+ const hasInstallments = (planData.installments?.length ?? 0) > 0;
175
+ return {
176
+ id: planData.id,
177
+ userId: planData.userId,
178
+ pricingSnapshot: {
179
+ type: planData.pricingSnapshot?.type || null,
180
+ totalAmount: planData.pricingSnapshot?.totalAmount || 0,
181
+ downPayment: planData.pricingSnapshot?.downPayment || 0,
182
+ installmentAmount: planData.pricingSnapshot?.installmentAmount || null,
183
+ installmentFrequency: planData.pricingSnapshot?.installmentFrequency || null,
184
+ installmentCount: planData.pricingSnapshot?.installmentCount || null,
185
+ gracePeriodDays: planData.pricingSnapshot?.gracePeriodDays || 2,
186
+ autoLockOnMiss: planData.pricingSnapshot?.autoLockOnMiss ?? true,
187
+ },
188
+ paidAmount: planData.paidAmount || 0,
189
+ outstandingAmount: planData.outstandingAmount || 0,
190
+ lastPaymentAt: planData.lastPaymentAt,
191
+ nextInstallmentDueAt: planData.nextInstallmentDueAt,
192
+ status: planData.status || "ACTIVE",
193
+ completedAt: planData.completedAt,
194
+ createdAt: planData.createdAt,
195
+ updatedAt: planData.updatedAt,
196
+ devices: planData.devices || [],
197
+ user: planData.user || null,
198
+ installments: planData.installments || [],
199
+ progress: totalAmount > 0 ? (plan.paidAmount / totalAmount) * 100 : 0,
200
+ canEdit: plan.paidAmount === 0,
201
+ canDelete: plan.paidAmount === 0,
202
+ isOverdue: false,
203
+ hasInstallments,
204
+ };
205
+ },
206
+ };
@@ -9,5 +9,7 @@ export { suspensionUtil } from "./suspension.utils";
9
9
  export { createDeviceSession } from "./session.utils";
10
10
  export { generateOTP, getOTPExpiry, getVerificationMethod, sendEmail, sendSMS, sendVerificationCode, } from "./verification.utils";
11
11
  export { getUserLevel, isRankEqual, isSubordinate, isSubordinateOrEqual, isSuperior, isSuperiorOrEqual, validateHierarchy, } from "./hierarchy.utils";
12
+ export { stockUtil } from "./admin.device.utils";
12
13
  export { cloudinaryUtil } from "./product.utils";
13
- export { PendingRegistration, VerificationMethod, ConfirmResponse, UploadResult, } from "./types";
14
+ export { DPP_OperationsUtil } from "./admin.devicePayment.utils";
15
+ export { PendingRegistration, VerificationMethod, ConfirmResponse, UploadResult, StockChangeResult, } from "./types";
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.isRankEqual = exports.getUserLevel = exports.sendVerificationCode = exports.sendSMS = exports.sendEmail = exports.getVerificationMethod = exports.getOTPExpiry = exports.generateOTP = exports.createDeviceSession = exports.suspensionUtil = exports.banUtil = exports.hasHigherAuthority = exports.getModeratableRoles = exports.canModerateUser = exports.canModerate = exports.softDeleteUser = exports.hashPassword = exports.validatePassword = exports.validateUniqueFields = exports.generateJacketId = exports.getSortOrder = exports.generateEventSearchConditions = exports.generateUserSearchConditions = exports.findSecurityClearanceByRole = exports.getUsersByRole = exports.getUserById = exports.isAccountAccessible = exports.canModifyAccount = exports.hasAllPermissions = exports.hasAnyPermission = exports.hasPermission = exports.hasRole = exports.formatUserListResponse = exports.formatUserProfile = exports.sendErrorResponse = exports.sendSuccessResponse = exports.logEvent = exports.formatTimeRemaining = exports.getTokenTimeRemaining = exports.generateToken = exports.shouldRefreshToken = exports.verifyToken = exports.generateRiderToken = exports.generatePassengerToken = exports.generateAdminToken = exports.checkSuspensionStatus = exports.checkIsUserBannedOrSuspended = exports.checkBanStatus = exports.hasActiveDependencies = exports.checkAccountDependencies = void 0;
4
- exports.cloudinaryUtil = exports.validateHierarchy = exports.isSuperiorOrEqual = exports.isSuperior = exports.isSubordinateOrEqual = exports.isSubordinate = void 0;
4
+ exports.DPP_OperationsUtil = exports.cloudinaryUtil = exports.stockUtil = exports.validateHierarchy = exports.isSuperiorOrEqual = exports.isSuperior = exports.isSubordinateOrEqual = exports.isSubordinate = void 0;
5
5
  var account_utils_1 = require("./account.utils");
6
6
  Object.defineProperty(exports, "checkAccountDependencies", { enumerable: true, get: function () { return account_utils_1.checkAccountDependencies; } });
7
7
  Object.defineProperty(exports, "hasActiveDependencies", { enumerable: true, get: function () { return account_utils_1.hasActiveDependencies; } });
@@ -75,5 +75,9 @@ Object.defineProperty(exports, "isSubordinateOrEqual", { enumerable: true, get:
75
75
  Object.defineProperty(exports, "isSuperior", { enumerable: true, get: function () { return hierarchy_utils_1.isSuperior; } });
76
76
  Object.defineProperty(exports, "isSuperiorOrEqual", { enumerable: true, get: function () { return hierarchy_utils_1.isSuperiorOrEqual; } });
77
77
  Object.defineProperty(exports, "validateHierarchy", { enumerable: true, get: function () { return hierarchy_utils_1.validateHierarchy; } });
78
+ var admin_device_utils_1 = require("./admin.device.utils");
79
+ Object.defineProperty(exports, "stockUtil", { enumerable: true, get: function () { return admin_device_utils_1.stockUtil; } });
78
80
  var product_utils_1 = require("./product.utils");
79
81
  Object.defineProperty(exports, "cloudinaryUtil", { enumerable: true, get: function () { return product_utils_1.cloudinaryUtil; } });
82
+ var admin_devicePayment_utils_1 = require("./admin.devicePayment.utils");
83
+ Object.defineProperty(exports, "DPP_OperationsUtil", { enumerable: true, get: function () { return admin_devicePayment_utils_1.DPP_OperationsUtil; } });
@@ -27,3 +27,10 @@ export interface UploadResult {
27
27
  url: string;
28
28
  publicId: string;
29
29
  }
30
+ export interface StockChangeResult {
31
+ success: boolean;
32
+ previousStock: number;
33
+ newStock: number;
34
+ productId: string;
35
+ productName: string;
36
+ }