flykup_model_production 1.0.14 → 1.0.16
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/models/notification.model.js +16 -8
- package/models/order.modal.js +5 -1
- package/models/orderPayment.model.js +119 -5
- package/models/productListing.model.js +85 -105
- package/models/seller_settlements_2025-11-18 (1).csv +4 -0
- package/models/seller_settlements_2025-11-18.csv +4 -0
- package/models/shows.model.js +455 -27
- package/models/stock.model.js +78 -58
- package/models/user.model.js +35 -16
- package/package.json +1 -1
|
@@ -21,7 +21,11 @@ const notificationSchema = new mongoose.Schema(
|
|
|
21
21
|
'seller_broadcast',
|
|
22
22
|
'live_stream_start',
|
|
23
23
|
'seller_order_update',
|
|
24
|
-
'new_show_scheduled'
|
|
24
|
+
'new_show_scheduled',
|
|
25
|
+
'cohost_invite',
|
|
26
|
+
'cohost_accepted',
|
|
27
|
+
'cohost_rejected',
|
|
28
|
+
'cohost_join_live'
|
|
25
29
|
],
|
|
26
30
|
required: true,
|
|
27
31
|
},
|
|
@@ -101,14 +105,18 @@ const notificationSchema = new mongoose.Schema(
|
|
|
101
105
|
type: String,
|
|
102
106
|
},
|
|
103
107
|
},
|
|
108
|
+
// metadata: {
|
|
109
|
+
// status: String,
|
|
110
|
+
// reason: String,
|
|
111
|
+
// orderId: mongoose.Schema.Types.ObjectId,
|
|
112
|
+
// requestId: mongoose.Schema.Types.ObjectId,
|
|
113
|
+
// customerName: String,
|
|
114
|
+
// sellerName: String,
|
|
115
|
+
// customerProfileURL: String,
|
|
116
|
+
// },
|
|
104
117
|
metadata: {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
orderId: mongoose.Schema.Types.ObjectId,
|
|
108
|
-
requestId: mongoose.Schema.Types.ObjectId,
|
|
109
|
-
customerName: String,
|
|
110
|
-
sellerName: String,
|
|
111
|
-
customerProfileURL: String,
|
|
118
|
+
type: mongoose.Schema.Types.Mixed, // This allows any JSON object
|
|
119
|
+
default: {} // Default to empty object
|
|
112
120
|
},
|
|
113
121
|
},
|
|
114
122
|
{
|
package/models/order.modal.js
CHANGED
|
@@ -252,7 +252,7 @@ const orderSchema = new mongoose.Schema(
|
|
|
252
252
|
},
|
|
253
253
|
sourceType: {
|
|
254
254
|
type: String,
|
|
255
|
-
enum: ['static', 'shoppable_video', 'livestream', 'auction', 'flash_sale', 'giveaway'],
|
|
255
|
+
enum: ['static', 'shoppable_video', 'livestream', 'auction', 'flash_sale', 'giveaway','bundle_sale','bundle_flash_sale'],
|
|
256
256
|
required: true
|
|
257
257
|
},
|
|
258
258
|
sourceRefId: String,
|
|
@@ -351,6 +351,10 @@ cancelSource: {
|
|
|
351
351
|
flashPrice: Number,
|
|
352
352
|
originalPrice: Number
|
|
353
353
|
}],
|
|
354
|
+
labelPrinted: {
|
|
355
|
+
type: Boolean,
|
|
356
|
+
default: false
|
|
357
|
+
},
|
|
354
358
|
payment: {
|
|
355
359
|
type: mongoose.Schema.Types.ObjectId,
|
|
356
360
|
ref: 'orderPayment'
|
|
@@ -61,7 +61,9 @@ const paymentSchema = new mongoose.Schema({
|
|
|
61
61
|
},
|
|
62
62
|
paymentMethod: String,
|
|
63
63
|
transactionTime: Date,
|
|
64
|
-
|
|
64
|
+
|
|
65
|
+
// ✅ SELLER PAYMENTS FIELD - Now matching package model
|
|
66
|
+
sellerPayments: [{
|
|
65
67
|
sellerId: {
|
|
66
68
|
type: mongoose.Schema.Types.ObjectId,
|
|
67
69
|
ref: 'users',
|
|
@@ -94,12 +96,124 @@ const paymentSchema = new mongoose.Schema({
|
|
|
94
96
|
|
|
95
97
|
// Create indexes for better performance
|
|
96
98
|
paymentSchema.index({ razorpayOrderId: 1 });
|
|
97
|
-
// paymentSchema.index({ cfOrderId: 1 });
|
|
98
99
|
paymentSchema.index({ orderId: 1 });
|
|
99
100
|
|
|
100
|
-
// ❌ The pre-save middleware is no longer needed and should be removed.
|
|
101
|
-
|
|
102
101
|
const OrderPayment =
|
|
103
102
|
mongoose.models.OrderPayment || mongoose.model('orderPayment', paymentSchema);
|
|
104
103
|
|
|
105
|
-
export default OrderPayment;
|
|
104
|
+
export default OrderPayment;
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
// import mongoose from 'mongoose';
|
|
116
|
+
|
|
117
|
+
// const paymentSchema = new mongoose.Schema({
|
|
118
|
+
// orderId: {
|
|
119
|
+
// type: mongoose.Schema.Types.ObjectId,
|
|
120
|
+
// ref: 'Order',
|
|
121
|
+
// required: true
|
|
122
|
+
// },
|
|
123
|
+
// userId: {
|
|
124
|
+
// type: mongoose.Schema.Types.ObjectId,
|
|
125
|
+
// ref: 'users',
|
|
126
|
+
// required: true
|
|
127
|
+
// },
|
|
128
|
+
// paymentGateway: {
|
|
129
|
+
// type: String,
|
|
130
|
+
// enum: ['RAZORPAY', 'CASHFREE'],
|
|
131
|
+
// required: true
|
|
132
|
+
// },
|
|
133
|
+
|
|
134
|
+
// // Razorpay-specific fields
|
|
135
|
+
// razorpayOrderId: {
|
|
136
|
+
// type: String,
|
|
137
|
+
// // ✅ This field is now required only if the gateway is RAZORPAY
|
|
138
|
+
// required: function() {
|
|
139
|
+
// return this.paymentGateway === 'RAZORPAY';
|
|
140
|
+
// }
|
|
141
|
+
// },
|
|
142
|
+
// razorpayPaymentId: {
|
|
143
|
+
// type: String,
|
|
144
|
+
// default: null
|
|
145
|
+
// },
|
|
146
|
+
|
|
147
|
+
// // Cashfree-specific fields
|
|
148
|
+
// cfPaymentSessionId: {
|
|
149
|
+
// type: String,
|
|
150
|
+
// // ✅ This field is now required only if the gateway is CASHFREE
|
|
151
|
+
// required: function() {
|
|
152
|
+
// return this.paymentGateway === 'CASHFREE';
|
|
153
|
+
// }
|
|
154
|
+
// },
|
|
155
|
+
// cfOrderId: {
|
|
156
|
+
// type: String,
|
|
157
|
+
// // ✅ This field is now required only if the gateway is CASHFREE
|
|
158
|
+
// required: function() {
|
|
159
|
+
// return this.paymentGateway === 'CASHFREE';
|
|
160
|
+
// }
|
|
161
|
+
// },
|
|
162
|
+
|
|
163
|
+
// amount: {
|
|
164
|
+
// type: Number,
|
|
165
|
+
// required: true
|
|
166
|
+
// },
|
|
167
|
+
// currency: {
|
|
168
|
+
// type: String,
|
|
169
|
+
// default: 'INR'
|
|
170
|
+
// },
|
|
171
|
+
// status: {
|
|
172
|
+
// type: String,
|
|
173
|
+
// enum: ['PENDING', 'SUCCESS', 'FAILED', 'REFUNDED'],
|
|
174
|
+
// default: 'PENDING'
|
|
175
|
+
// },
|
|
176
|
+
// paymentMethod: String,
|
|
177
|
+
// transactionTime: Date,
|
|
178
|
+
// sellerPayments: [{
|
|
179
|
+
// sellerId: {
|
|
180
|
+
// type: mongoose.Schema.Types.ObjectId,
|
|
181
|
+
// ref: 'users',
|
|
182
|
+
// required: true
|
|
183
|
+
// },
|
|
184
|
+
// payableAmount: { // Amount for products only
|
|
185
|
+
// type: Number,
|
|
186
|
+
// required: true,
|
|
187
|
+
// default: 0
|
|
188
|
+
// },
|
|
189
|
+
// deliveryCharge: { // Delivery fee for this seller's shipment
|
|
190
|
+
// type: Number,
|
|
191
|
+
// required: true,
|
|
192
|
+
// default: 0
|
|
193
|
+
// },
|
|
194
|
+
// totalAmount: { // The sum of payableAmount + deliveryCharge
|
|
195
|
+
// type: Number,
|
|
196
|
+
// required: true,
|
|
197
|
+
// default: 0
|
|
198
|
+
// },
|
|
199
|
+
// settlementStatus: {
|
|
200
|
+
// type: String,
|
|
201
|
+
// enum: ['PENDING', 'SETTLED', 'FAILED'],
|
|
202
|
+
// default: 'PENDING'
|
|
203
|
+
// }
|
|
204
|
+
// }]
|
|
205
|
+
// }, {
|
|
206
|
+
// timestamps: true
|
|
207
|
+
// });
|
|
208
|
+
|
|
209
|
+
// // Create indexes for better performance
|
|
210
|
+
// paymentSchema.index({ razorpayOrderId: 1 });
|
|
211
|
+
// // paymentSchema.index({ cfOrderId: 1 });
|
|
212
|
+
// paymentSchema.index({ orderId: 1 });
|
|
213
|
+
|
|
214
|
+
// // ❌ The pre-save middleware is no longer needed and should be removed.
|
|
215
|
+
|
|
216
|
+
// const OrderPayment =
|
|
217
|
+
// mongoose.models.OrderPayment || mongoose.model('orderPayment', paymentSchema);
|
|
218
|
+
|
|
219
|
+
// export default OrderPayment;
|
|
@@ -1,26 +1,25 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
// backend/models/ProductListing.js (or similar path)
|
|
6
1
|
import mongoose from "mongoose";
|
|
7
2
|
const { Schema } = mongoose;
|
|
8
3
|
|
|
9
4
|
const ProductListingSchema = new Schema(
|
|
10
5
|
{
|
|
11
6
|
sellerId: { type: Schema.Types.ObjectId, ref: "sellers" },
|
|
12
|
-
stockId: { type: Schema.Types.ObjectId, ref: "stocks" },
|
|
7
|
+
stockId: { type: Schema.Types.ObjectId, ref: "stocks" }, // ✅ KEEP THIS - for main inventory management
|
|
13
8
|
title: String,
|
|
14
9
|
description: String,
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
10
|
+
flashSale: {
|
|
11
|
+
isActive: { type: Boolean, default: false },
|
|
12
|
+
flashSaleId: { type: mongoose.Schema.Types.ObjectId, ref: 'FlashSale' },
|
|
13
|
+
flashPrice: { type: Number, default: 0 },
|
|
14
|
+
// ❌ REMOVED: flashStock field - now using main quantity
|
|
15
|
+
originalPrice: { type: Number, default: 0 },
|
|
16
|
+
endsAt: { type: Date, default: null },
|
|
17
|
+
startsAt: { type: Date, default: null }
|
|
18
|
+
},
|
|
19
|
+
reserveForLive: {
|
|
20
|
+
type: Boolean,
|
|
21
|
+
default: false
|
|
22
|
+
},
|
|
24
23
|
sku: {
|
|
25
24
|
type: String,
|
|
26
25
|
required: true,
|
|
@@ -54,7 +53,7 @@ const ProductListingSchema = new Schema(
|
|
|
54
53
|
min: 0,
|
|
55
54
|
default: null,
|
|
56
55
|
},
|
|
57
|
-
|
|
56
|
+
logisticsType: {
|
|
58
57
|
type: String,
|
|
59
58
|
enum: ["flykupLogistics", "selfShipment"],
|
|
60
59
|
default: null,
|
|
@@ -65,47 +64,45 @@ const ProductListingSchema = new Schema(
|
|
|
65
64
|
default: null,
|
|
66
65
|
},
|
|
67
66
|
estimatedDeliveryDate: {
|
|
68
|
-
type: Number,
|
|
67
|
+
type: Number,
|
|
69
68
|
min: 0,
|
|
70
69
|
default: null,
|
|
71
70
|
},
|
|
72
|
-
|
|
73
|
-
// --- ADDED/UPDATED FIELDS FROM FRONTEND ---
|
|
74
|
-
brand: { type: String, default: null }, // ADDED
|
|
71
|
+
brand: { type: String, default: null },
|
|
75
72
|
manufacturer: String,
|
|
76
|
-
manufacturerAddress: String,
|
|
73
|
+
manufacturerAddress: String,
|
|
77
74
|
countryOfOrigin: String,
|
|
78
|
-
netQuantity: { type: String, default: null },
|
|
79
|
-
packagingType: { type: String, default: null },
|
|
80
|
-
weight: {
|
|
75
|
+
netQuantity: { type: String, default: null },
|
|
76
|
+
packagingType: { type: String, default: null },
|
|
77
|
+
weight: {
|
|
81
78
|
value: { type: Number, default: null },
|
|
82
79
|
unit: { type: String, default: null },
|
|
83
80
|
},
|
|
84
|
-
dimensions: {
|
|
81
|
+
dimensions: {
|
|
85
82
|
length: { type: Number, default: null },
|
|
86
83
|
width: { type: Number, default: null },
|
|
87
84
|
height: { type: Number, default: null },
|
|
88
85
|
},
|
|
89
|
-
expiryDate: { type: Date, default: null },
|
|
90
|
-
shelfLife: { type: String, default: null },
|
|
91
|
-
batchNumber: { type: String, default: null },
|
|
92
|
-
gstRate: { type: Number, default: null },
|
|
86
|
+
expiryDate: { type: Date, default: null },
|
|
87
|
+
shelfLife: { type: String, default: null },
|
|
88
|
+
batchNumber: { type: String, default: null },
|
|
89
|
+
gstRate: { type: Number, default: null },
|
|
93
90
|
sellerName: String,
|
|
94
|
-
sellerContact: { type: String, default: null },
|
|
95
|
-
sellerGSTIN: { type: String, default: null },
|
|
91
|
+
sellerContact: { type: String, default: null },
|
|
92
|
+
sellerGSTIN: { type: String, default: null },
|
|
96
93
|
returnPolicy: [String],
|
|
97
94
|
warranty: {
|
|
98
|
-
hasWarranty: { type: Boolean, default: false },
|
|
99
|
-
duration: { type: String, default: null },
|
|
95
|
+
hasWarranty: { type: Boolean, default: false },
|
|
96
|
+
duration: { type: String, default: null },
|
|
100
97
|
},
|
|
101
|
-
fssaiLicenseNo: { type: String, default: null },
|
|
102
|
-
bisCertification: { type: String, default: null },
|
|
103
|
-
importerName: { type: String, default: null },
|
|
104
|
-
importerAddress: { type: String, default: null },
|
|
105
|
-
importerGSTIN: { type: String, default: null },
|
|
106
|
-
eWasteCompliance: { type: Boolean, default: false },
|
|
107
|
-
recyclablePackaging: { type: Boolean, default: false },
|
|
108
|
-
hazardousMaterials: { type: String, default: null },
|
|
98
|
+
fssaiLicenseNo: { type: String, default: null },
|
|
99
|
+
bisCertification: { type: String, default: null },
|
|
100
|
+
importerName: { type: String, default: null },
|
|
101
|
+
importerAddress: { type: String, default: null },
|
|
102
|
+
importerGSTIN: { type: String, default: null },
|
|
103
|
+
eWasteCompliance: { type: Boolean, default: false },
|
|
104
|
+
recyclablePackaging: { type: Boolean, default: false },
|
|
105
|
+
hazardousMaterials: { type: String, default: null },
|
|
109
106
|
allowDropshipping: {
|
|
110
107
|
type: Boolean,
|
|
111
108
|
default: false,
|
|
@@ -114,65 +111,51 @@ const ProductListingSchema = new Schema(
|
|
|
114
111
|
commissionRate: {
|
|
115
112
|
type: Number,
|
|
116
113
|
min: [0, 'Commission rate cannot be negative.'],
|
|
117
|
-
// max: [100, 'Commission rate cannot exceed 100%.'], // Max was 25, changed to 100 based on frontend
|
|
118
114
|
max: [100, 'Commission rate cannot exceed 100%.'],
|
|
119
115
|
default: null,
|
|
120
|
-
// Removed Mongoose-level required validation dependent on allowDropshipping
|
|
121
|
-
// Let application logic handle this if needed, or adjust validator
|
|
122
|
-
// required: [
|
|
123
|
-
// function () { return this.allowDropshipping === true; },
|
|
124
|
-
// 'Commission rate is required when allowing dropshipping.'
|
|
125
|
-
// ],
|
|
126
|
-
// validate: { ... } // Keep or remove validation as needed
|
|
127
116
|
},
|
|
128
117
|
hasReturn: {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
},
|
|
132
|
-
returnDays: {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
},
|
|
137
|
-
size: {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
},
|
|
118
|
+
type: Boolean,
|
|
119
|
+
default: false
|
|
120
|
+
},
|
|
121
|
+
returnDays: {
|
|
122
|
+
type: Number,
|
|
123
|
+
min: 0,
|
|
124
|
+
default: null
|
|
125
|
+
},
|
|
126
|
+
size: {
|
|
127
|
+
type: String,
|
|
128
|
+
default: null
|
|
129
|
+
},
|
|
141
130
|
isActive: {
|
|
142
131
|
type: Boolean,
|
|
143
132
|
default: true,
|
|
144
|
-
},
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
1: { type: Number, default: 0 },
|
|
149
|
-
2: { type: Number, default: 0 },
|
|
150
|
-
3: { type: Number, default: 0 },
|
|
151
|
-
4: { type: Number, default: 0 },
|
|
152
|
-
5: { type: Number, default: 0 }
|
|
153
|
-
}
|
|
133
|
+
},
|
|
134
|
+
shopifySynced: {
|
|
135
|
+
type: Boolean,
|
|
136
|
+
default: false,
|
|
154
137
|
},
|
|
155
|
-
|
|
138
|
+
ratingSummary: {
|
|
139
|
+
averageRating: { type: Number, default: 0 },
|
|
140
|
+
totalRatings: { type: Number, default: 0 },
|
|
141
|
+
ratingDistribution: {
|
|
142
|
+
1: { type: Number, default: 0 },
|
|
143
|
+
2: { type: Number, default: 0 },
|
|
144
|
+
3: { type: Number, default: 0 },
|
|
145
|
+
4: { type: Number, default: 0 },
|
|
146
|
+
5: { type: Number, default: 0 }
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
totalReviews: { type: Number, default: 0 }
|
|
156
150
|
},
|
|
157
151
|
{ timestamps: true }
|
|
158
152
|
);
|
|
159
|
-
ProductListingSchema.index({ title: 'text', description: 'text', category: 'text' });
|
|
160
153
|
|
|
154
|
+
ProductListingSchema.index({ title: 'text', description: 'text', category: 'text' });
|
|
161
155
|
|
|
162
|
-
// Safe export to prevent OverwriteModelError
|
|
163
156
|
const ProductListing = mongoose.models.productlistings || mongoose.model("productlistings", ProductListingSchema);
|
|
164
157
|
export default ProductListing;
|
|
165
158
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
159
|
// // backend/models/ProductListing.js (or similar path)
|
|
177
160
|
// import mongoose from "mongoose";
|
|
178
161
|
// const { Schema } = mongoose;
|
|
@@ -192,25 +175,11 @@ export default ProductListing;
|
|
|
192
175
|
// endsAt: { type: Date, default: null },
|
|
193
176
|
// startsAt: { type: Date, default: null }
|
|
194
177
|
// },
|
|
195
|
-
|
|
196
|
-
// //new fields added
|
|
197
|
-
|
|
198
|
-
// returnPolicy: {
|
|
199
|
-
// hasReturn: { type: Boolean, default: false },
|
|
200
|
-
// returnType: {
|
|
201
|
-
// type: [String],
|
|
202
|
-
// enum: ['refund', 'replacement'],
|
|
203
|
-
// default: []
|
|
204
|
-
// },
|
|
205
|
-
// returnDays: { type: Number, min: 0, default: null },
|
|
206
|
-
// terms: [String] // Keep existing terms for backward compatibility
|
|
207
|
-
// },
|
|
208
178
|
// sku: {
|
|
209
179
|
// type: String,
|
|
210
180
|
// required: true,
|
|
211
|
-
//
|
|
181
|
+
// index: true
|
|
212
182
|
// },
|
|
213
|
-
// // ----------end of new fields added
|
|
214
183
|
// images: [
|
|
215
184
|
// {
|
|
216
185
|
// key: { type: String, maxLength: 255, default: null },
|
|
@@ -239,7 +208,22 @@ export default ProductListing;
|
|
|
239
208
|
// min: 0,
|
|
240
209
|
// default: null,
|
|
241
210
|
// },
|
|
242
|
-
|
|
211
|
+
// logisticsType: {
|
|
212
|
+
// type: String,
|
|
213
|
+
// enum: ["flykupLogistics", "selfShipment"],
|
|
214
|
+
// default: null,
|
|
215
|
+
// },
|
|
216
|
+
// deliveryCharge: {
|
|
217
|
+
// type: Number,
|
|
218
|
+
// min: 0,
|
|
219
|
+
// default: null,
|
|
220
|
+
// },
|
|
221
|
+
// estimatedDeliveryDate: {
|
|
222
|
+
// type: Number, // Change from Date to Number
|
|
223
|
+
// min: 0,
|
|
224
|
+
// default: null,
|
|
225
|
+
// },
|
|
226
|
+
|
|
243
227
|
// // --- ADDED/UPDATED FIELDS FROM FRONTEND ---
|
|
244
228
|
// brand: { type: String, default: null }, // ADDED
|
|
245
229
|
// manufacturer: String,
|
|
@@ -324,13 +308,10 @@ export default ProductListing;
|
|
|
324
308
|
// },
|
|
325
309
|
// totalReviews: { type: Number, default: 0 }
|
|
326
310
|
// },
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
311
|
// { timestamps: true }
|
|
331
312
|
// );
|
|
332
313
|
// ProductListingSchema.index({ title: 'text', description: 'text', category: 'text' });
|
|
333
|
-
|
|
314
|
+
|
|
334
315
|
|
|
335
316
|
// // Safe export to prevent OverwriteModelError
|
|
336
317
|
// const ProductListing = mongoose.models.productlistings || mongoose.model("productlistings", ProductListingSchema);
|
|
@@ -339,4 +320,3 @@ export default ProductListing;
|
|
|
339
320
|
|
|
340
321
|
|
|
341
322
|
|
|
342
|
-
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
Seller Name,Owner Name,Email,Mobile,Total Amount,Total Orders,Total Products,Account Number,IFSC Code,Bank Name
|
|
2
|
+
"HARISH A","HARISH A","thebrandspot@gmail.com","THEBRANDSPOT","1270","38","38","","",""
|
|
3
|
+
"Shanthi","Shanthi","shanthiaravindan81@gmail.com","+919500060775","450","1","1","","",""
|
|
4
|
+
"Gokul Krishnan","Gokul Krishnan","gkgokul1817@gmail.com","gokul_krishnan","55","1","1","","",""
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
Seller Name,Owner Name,Email,Mobile,Total Amount,Total Orders,Total Products,Account Number,IFSC Code,Bank Name
|
|
2
|
+
"HARISH A","HARISH A","thebrandspot@gmail.com","THEBRANDSPOT","1270","38","38","","",""
|
|
3
|
+
"Shanthi","Shanthi","shanthiaravindan81@gmail.com","+919500060775","450","1","1","","",""
|
|
4
|
+
"Gokul Krishnan","Gokul Krishnan","gkgokul1817@gmail.com","gokul_krishnan","55","1","1","","",""
|
package/models/shows.model.js
CHANGED
|
@@ -6,43 +6,113 @@ const giveawayProductSchema = new Schema({
|
|
|
6
6
|
productId: { type: Schema.Types.ObjectId, ref: "productlistings", required: true },
|
|
7
7
|
productOwnerSellerId: { type: Schema.Types.ObjectId, ref: 'sellers', required: true },
|
|
8
8
|
productTitle: { type: String },
|
|
9
|
-
|
|
10
|
-
// BGA Integration Fields
|
|
11
9
|
giveawayObjectId: { type: Schema.Types.ObjectId, required: true, index: true },
|
|
12
10
|
giveawayStatus: {
|
|
13
11
|
type: String,
|
|
14
12
|
enum: ['preparing', 'ready', 'active', 'ended', 'failed'],
|
|
15
13
|
default: 'preparing'
|
|
16
14
|
},
|
|
17
|
-
|
|
15
|
+
requireAutoFollow: {
|
|
18
16
|
type: Boolean,
|
|
19
17
|
default: false
|
|
20
18
|
},
|
|
21
|
-
|
|
22
19
|
activatedAt: { type: Date, default: null },
|
|
23
20
|
createdAt: { type: Date, default: Date.now }
|
|
24
21
|
});
|
|
25
22
|
|
|
26
|
-
|
|
23
|
+
const liveFlashSaleSchema = new Schema({
|
|
24
|
+
_id: false,
|
|
25
|
+
productId: {
|
|
26
|
+
type: Schema.Types.ObjectId,
|
|
27
|
+
ref: "productlistings",
|
|
28
|
+
required: true
|
|
29
|
+
},
|
|
30
|
+
stockId: {
|
|
31
|
+
type: Schema.Types.ObjectId,
|
|
32
|
+
ref: "stocks",
|
|
33
|
+
required: true
|
|
34
|
+
},
|
|
35
|
+
flashPrice: {
|
|
36
|
+
type: Number,
|
|
37
|
+
required: true,
|
|
38
|
+
min: 1
|
|
39
|
+
},
|
|
40
|
+
duration: {
|
|
41
|
+
type: Number,
|
|
42
|
+
required: true,
|
|
43
|
+
enum: [10, 20, 30, 40, 50, 60, 240]
|
|
44
|
+
},
|
|
45
|
+
initialStock: {
|
|
46
|
+
type: Number,
|
|
47
|
+
required: true,
|
|
48
|
+
min: 1
|
|
49
|
+
},
|
|
50
|
+
currentStock: {
|
|
51
|
+
type: Number,
|
|
52
|
+
required: true,
|
|
53
|
+
min: 0
|
|
54
|
+
},
|
|
55
|
+
sold: {
|
|
56
|
+
type: Number,
|
|
57
|
+
default: 0
|
|
58
|
+
},
|
|
59
|
+
status: {
|
|
60
|
+
type: String,
|
|
61
|
+
enum: ['scheduled', 'active', 'ended', 'cancelled'],
|
|
62
|
+
default: 'scheduled'
|
|
63
|
+
},
|
|
64
|
+
startTime: Date,
|
|
65
|
+
endTime: Date,
|
|
66
|
+
flashSaleId: {
|
|
67
|
+
type: Schema.Types.ObjectId,
|
|
68
|
+
ref: 'FlashSale'
|
|
69
|
+
},
|
|
70
|
+
createdAt: {
|
|
71
|
+
type: Date,
|
|
72
|
+
default: Date.now
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
const bundleSaleSchema = new Schema({
|
|
76
|
+
_id: false,
|
|
77
|
+
bundleSaleId: {
|
|
78
|
+
type: Schema.Types.ObjectId,
|
|
79
|
+
ref: "bundlesales",
|
|
80
|
+
required: true
|
|
81
|
+
},
|
|
82
|
+
bundleOwnerSellerId: {
|
|
83
|
+
type: Schema.Types.ObjectId,
|
|
84
|
+
ref: 'sellers',
|
|
85
|
+
required: function() {
|
|
86
|
+
return this.bundleSaleId != null;
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
bundleTitle: { type: String }, // Quick reference title
|
|
90
|
+
bundleMRP: { type: Number, min: 0, default: null }, // Original MRP
|
|
91
|
+
sellingPrice: { type: Number, min: 0, default: null }, // Actual selling price
|
|
92
|
+
bundleImage: { // Bundle thumbnail image
|
|
93
|
+
key: { type: String, default: null },
|
|
94
|
+
url: { type: String, default: null }
|
|
95
|
+
},
|
|
96
|
+
createdAt: { type: Date, default: Date.now }
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
// Show Schema with FIXED validation
|
|
27
100
|
const showSchema = new Schema(
|
|
28
101
|
{
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
// === Host Information ===
|
|
35
|
-
host: { // Host (Seller or Dropshipper)
|
|
102
|
+
sellerId: {
|
|
103
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
104
|
+
ref: "sellers",
|
|
105
|
+
},
|
|
106
|
+
host: {
|
|
36
107
|
type: mongoose.Schema.Types.ObjectId,
|
|
37
108
|
required: true,
|
|
38
|
-
refPath: 'hostModel'
|
|
109
|
+
refPath: 'hostModel'
|
|
39
110
|
},
|
|
40
|
-
hostModel: {
|
|
111
|
+
hostModel: {
|
|
41
112
|
type: String,
|
|
42
113
|
required: true,
|
|
43
|
-
enum: ['sellers', 'dropshippers']
|
|
114
|
+
enum: ['sellers', 'dropshippers']
|
|
44
115
|
},
|
|
45
|
-
|
|
46
116
|
title: {
|
|
47
117
|
type: String,
|
|
48
118
|
required: true,
|
|
@@ -55,7 +125,7 @@ const showSchema = new Schema(
|
|
|
55
125
|
},
|
|
56
126
|
scheduledAt: {
|
|
57
127
|
type: Date,
|
|
58
|
-
index: true
|
|
128
|
+
index: true
|
|
59
129
|
},
|
|
60
130
|
category: {
|
|
61
131
|
type: String,
|
|
@@ -73,13 +143,12 @@ const showSchema = new Schema(
|
|
|
73
143
|
type: [String],
|
|
74
144
|
default: [],
|
|
75
145
|
},
|
|
76
|
-
|
|
77
146
|
thumbnailImage: {
|
|
78
|
-
type: String,
|
|
147
|
+
type: String,
|
|
79
148
|
default: null,
|
|
80
149
|
},
|
|
81
150
|
previewVideo: {
|
|
82
|
-
type: String,
|
|
151
|
+
type: String,
|
|
83
152
|
default: null,
|
|
84
153
|
},
|
|
85
154
|
language: {
|
|
@@ -90,14 +159,30 @@ const showSchema = new Schema(
|
|
|
90
159
|
default: false,
|
|
91
160
|
},
|
|
92
161
|
streamUrl: {
|
|
93
|
-
type: String,
|
|
162
|
+
type: String,
|
|
94
163
|
default: null,
|
|
95
164
|
},
|
|
165
|
+
orientation: {
|
|
166
|
+
type: String,
|
|
167
|
+
enum: ['horizontal', 'vertical'],
|
|
168
|
+
default: 'horizontal'
|
|
169
|
+
},
|
|
170
|
+
layout: {
|
|
171
|
+
type: String,
|
|
172
|
+
enum: ['side-by-side', 'top-bottom'],
|
|
173
|
+
default: 'side-by-side'
|
|
174
|
+
},
|
|
96
175
|
showStatus: {
|
|
97
176
|
type: String,
|
|
98
177
|
enum: ['created', 'live', 'cancelled', 'ended'],
|
|
99
178
|
default: 'created'
|
|
100
179
|
},
|
|
180
|
+
viewerCount: {
|
|
181
|
+
type: Number,
|
|
182
|
+
default: 0,
|
|
183
|
+
min: 0
|
|
184
|
+
},
|
|
185
|
+
|
|
101
186
|
likes: {
|
|
102
187
|
type: Number,
|
|
103
188
|
default: 0,
|
|
@@ -108,27 +193,60 @@ const showSchema = new Schema(
|
|
|
108
193
|
default: [],
|
|
109
194
|
},
|
|
110
195
|
|
|
196
|
+
// ✅ FIXED: Better validation for buyNowProducts
|
|
111
197
|
buyNowProducts: {
|
|
112
198
|
type: [
|
|
113
199
|
{
|
|
114
200
|
_id: false,
|
|
115
201
|
productId: { type: Schema.Types.ObjectId, ref: "productlistings" },
|
|
116
|
-
productOwnerSellerId: {
|
|
117
|
-
|
|
202
|
+
productOwnerSellerId: {
|
|
203
|
+
type: Schema.Types.ObjectId,
|
|
204
|
+
ref: 'sellers',
|
|
205
|
+
required: function() {
|
|
206
|
+
// Only require if productId exists
|
|
207
|
+
return this.productId != null;
|
|
208
|
+
}
|
|
209
|
+
},
|
|
210
|
+
productPrice: { type: Number, min: 0, default: null },
|
|
118
211
|
},
|
|
119
212
|
],
|
|
120
213
|
default: [],
|
|
214
|
+
validate: {
|
|
215
|
+
validator: function(products) {
|
|
216
|
+
// Custom validation to ensure productOwnerSellerId exists when productId exists
|
|
217
|
+
return products.every(product =>
|
|
218
|
+
!product.productId || (product.productId && product.productOwnerSellerId)
|
|
219
|
+
);
|
|
220
|
+
},
|
|
221
|
+
message: 'productOwnerSellerId is required when productId is provided'
|
|
222
|
+
}
|
|
121
223
|
},
|
|
224
|
+
bundleSales: {
|
|
225
|
+
type: [bundleSaleSchema],
|
|
226
|
+
default: []
|
|
227
|
+
},
|
|
228
|
+
|
|
122
229
|
auctionProducts: {
|
|
123
230
|
type: [
|
|
124
231
|
{
|
|
125
232
|
_id: false,
|
|
126
233
|
productId: { type: Schema.Types.ObjectId, ref: "productlistings" },
|
|
127
|
-
productOwnerSellerId: {
|
|
234
|
+
productOwnerSellerId: {
|
|
235
|
+
type: Schema.Types.ObjectId,
|
|
236
|
+
ref: 'sellers',
|
|
237
|
+
required: function() {
|
|
238
|
+
return this.productId != null;
|
|
239
|
+
}
|
|
240
|
+
},
|
|
128
241
|
startingPrice: { type: Number, min: 0, default: null },
|
|
129
242
|
reservedPrice: { type: Number, min: 0, default: null },
|
|
130
243
|
auctionNumber: {
|
|
131
244
|
type: Number,
|
|
245
|
+
},
|
|
246
|
+
auctionObjectId: {
|
|
247
|
+
type: Schema.Types.ObjectId,
|
|
248
|
+
required: true,
|
|
249
|
+
index: true
|
|
132
250
|
}
|
|
133
251
|
},
|
|
134
252
|
],
|
|
@@ -140,6 +258,16 @@ const showSchema = new Schema(
|
|
|
140
258
|
default: []
|
|
141
259
|
},
|
|
142
260
|
|
|
261
|
+
liveFlashSales: {
|
|
262
|
+
type: [liveFlashSaleSchema],
|
|
263
|
+
default: []
|
|
264
|
+
},
|
|
265
|
+
currentFlashSale: {
|
|
266
|
+
type: Schema.Types.ObjectId,
|
|
267
|
+
ref: 'FlashSale',
|
|
268
|
+
default: null
|
|
269
|
+
},
|
|
270
|
+
|
|
143
271
|
enabledProductTypes: {
|
|
144
272
|
buyNow: { type: Boolean, default: false },
|
|
145
273
|
auction: { type: Boolean, default: false },
|
|
@@ -153,9 +281,39 @@ const showSchema = new Schema(
|
|
|
153
281
|
{ timestamps: true }
|
|
154
282
|
);
|
|
155
283
|
|
|
156
|
-
|
|
284
|
+
// ✅ ADD THIS PRE-SAVE MIDDLEWARE TO CLEAN INVALID DATA
|
|
285
|
+
showSchema.pre('save', function(next) {
|
|
157
286
|
const doc = this;
|
|
158
287
|
|
|
288
|
+
// Clean up buyNowProducts - remove items without required fields
|
|
289
|
+
if (doc.buyNowProducts && Array.isArray(doc.buyNowProducts)) {
|
|
290
|
+
doc.buyNowProducts = doc.buyNowProducts.filter(product =>
|
|
291
|
+
product &&
|
|
292
|
+
product.productId &&
|
|
293
|
+
product.productOwnerSellerId
|
|
294
|
+
);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// Clean up auctionProducts
|
|
298
|
+
if (doc.auctionProducts && Array.isArray(doc.auctionProducts)) {
|
|
299
|
+
doc.auctionProducts = doc.auctionProducts.filter(product =>
|
|
300
|
+
product &&
|
|
301
|
+
product.productId &&
|
|
302
|
+
product.productOwnerSellerId &&
|
|
303
|
+
product.auctionObjectId
|
|
304
|
+
);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// Clean up giveawayProducts
|
|
308
|
+
if (doc.giveawayProducts && Array.isArray(doc.giveawayProducts)) {
|
|
309
|
+
doc.giveawayProducts = doc.giveawayProducts.filter(product =>
|
|
310
|
+
product &&
|
|
311
|
+
product.productId &&
|
|
312
|
+
product.productOwnerSellerId &&
|
|
313
|
+
product.giveawayObjectId
|
|
314
|
+
);
|
|
315
|
+
}
|
|
316
|
+
|
|
159
317
|
// Set liveDrop based on product types
|
|
160
318
|
const hasBuyNow = doc.buyNowProducts && doc.buyNowProducts.length > 0;
|
|
161
319
|
const hasAuction = doc.auctionProducts && doc.auctionProducts.length > 0;
|
|
@@ -170,6 +328,276 @@ showSchema.pre('save', function (next) {
|
|
|
170
328
|
next();
|
|
171
329
|
});
|
|
172
330
|
|
|
173
|
-
|
|
331
|
+
// ✅ ADD THIS PRE-VALIDATION MIDDLEWARE FOR EXTRA SAFETY
|
|
332
|
+
showSchema.pre('validate', function(next) {
|
|
333
|
+
// Ensure all arrays exist (prevent undefined errors)
|
|
334
|
+
if (!this.buyNowProducts) this.buyNowProducts = [];
|
|
335
|
+
if (!this.auctionProducts) this.auctionProducts = [];
|
|
336
|
+
if (!this.giveawayProducts) this.giveawayProducts = [];
|
|
337
|
+
if (!this.liveFlashSales) this.liveFlashSales = [];
|
|
338
|
+
|
|
339
|
+
next();
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
const Show = mongoose.models.shows || mongoose.model("shows", showSchema);
|
|
343
|
+
export default Show;
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
// import mongoose from "mongoose";
|
|
348
|
+
// const { Schema } = mongoose;
|
|
349
|
+
|
|
350
|
+
// const giveawayProductSchema = new Schema({
|
|
351
|
+
// _id: false,
|
|
352
|
+
// productId: { type: Schema.Types.ObjectId, ref: "productlistings", required: true },
|
|
353
|
+
// productOwnerSellerId: { type: Schema.Types.ObjectId, ref: 'sellers', required: true },
|
|
354
|
+
// productTitle: { type: String },
|
|
355
|
+
// giveawayObjectId: { type: Schema.Types.ObjectId, required: true, index: true },
|
|
356
|
+
// giveawayStatus: {
|
|
357
|
+
// type: String,
|
|
358
|
+
// enum: ['preparing', 'ready', 'active', 'ended', 'failed'],
|
|
359
|
+
// default: 'preparing'
|
|
360
|
+
// },
|
|
361
|
+
// requireAutoFollow: {
|
|
362
|
+
// type: Boolean,
|
|
363
|
+
// default: false
|
|
364
|
+
// },
|
|
365
|
+
// activatedAt: { type: Date, default: null },
|
|
366
|
+
// createdAt: { type: Date, default: Date.now }
|
|
367
|
+
// });
|
|
368
|
+
|
|
369
|
+
// // Live Flash Sale Schema
|
|
370
|
+
// const liveFlashSaleSchema = new Schema({
|
|
371
|
+
// _id: false,
|
|
372
|
+
// productId: {
|
|
373
|
+
// type: Schema.Types.ObjectId,
|
|
374
|
+
// ref: "productlistings",
|
|
375
|
+
// required: true
|
|
376
|
+
// },
|
|
377
|
+
// stockId: {
|
|
378
|
+
// type: Schema.Types.ObjectId,
|
|
379
|
+
// ref: "stocks",
|
|
380
|
+
// required: true
|
|
381
|
+
// },
|
|
382
|
+
// flashPrice: {
|
|
383
|
+
// type: Number,
|
|
384
|
+
// required: true,
|
|
385
|
+
// min: 1
|
|
386
|
+
// },
|
|
387
|
+
// duration: {
|
|
388
|
+
// type: Number,
|
|
389
|
+
// required: true,
|
|
390
|
+
// enum: [10, 20, 30, 40, 50, 60,240]
|
|
391
|
+
// },
|
|
392
|
+
// initialStock: {
|
|
393
|
+
// type: Number,
|
|
394
|
+
// required: true,
|
|
395
|
+
// min: 1
|
|
396
|
+
// },
|
|
397
|
+
// currentStock: {
|
|
398
|
+
// type: Number,
|
|
399
|
+
// required: true,
|
|
400
|
+
// min: 0
|
|
401
|
+
// },
|
|
402
|
+
// sold: {
|
|
403
|
+
// type: Number,
|
|
404
|
+
// default: 0
|
|
405
|
+
// },
|
|
406
|
+
// status: {
|
|
407
|
+
// type: String,
|
|
408
|
+
// enum: ['scheduled', 'active', 'ended', 'cancelled'],
|
|
409
|
+
// default: 'scheduled'
|
|
410
|
+
// },
|
|
411
|
+
// startTime: Date,
|
|
412
|
+
// endTime: Date,
|
|
413
|
+
// flashSaleId: {
|
|
414
|
+
// type: Schema.Types.ObjectId,
|
|
415
|
+
// ref: 'FlashSale'
|
|
416
|
+
// },
|
|
417
|
+
// createdAt: {
|
|
418
|
+
// type: Date,
|
|
419
|
+
// default: Date.now
|
|
420
|
+
// }
|
|
421
|
+
// });
|
|
422
|
+
// // Show Schema
|
|
423
|
+
// const showSchema = new Schema(
|
|
424
|
+
// {
|
|
425
|
+
// sellerId: {
|
|
426
|
+
// type: mongoose.Schema.Types.ObjectId,
|
|
427
|
+
// ref: "sellers",
|
|
428
|
+
// },
|
|
429
|
+
// // === Host Information ===
|
|
430
|
+
// host: {
|
|
431
|
+
// type: mongoose.Schema.Types.ObjectId,
|
|
432
|
+
// required: true,
|
|
433
|
+
// refPath: 'hostModel'
|
|
434
|
+
// },
|
|
435
|
+
// hostModel: {
|
|
436
|
+
// type: String,
|
|
437
|
+
// required: true,
|
|
438
|
+
// enum: ['sellers', 'dropshippers']
|
|
439
|
+
// },
|
|
440
|
+
|
|
441
|
+
// title: {
|
|
442
|
+
// type: String,
|
|
443
|
+
// required: true,
|
|
444
|
+
// },
|
|
445
|
+
// date: {
|
|
446
|
+
// type: Date,
|
|
447
|
+
// },
|
|
448
|
+
// time: {
|
|
449
|
+
// type: String,
|
|
450
|
+
// },
|
|
451
|
+
// scheduledAt: {
|
|
452
|
+
// type: Date,
|
|
453
|
+
// index: true
|
|
454
|
+
// },
|
|
455
|
+
// category: {
|
|
456
|
+
// type: String,
|
|
457
|
+
// },
|
|
458
|
+
// subCategory: {
|
|
459
|
+
// type: String,
|
|
460
|
+
// default: '',
|
|
461
|
+
// },
|
|
462
|
+
// liveStreamId: { type: String, default: null },
|
|
463
|
+
// streamName: {
|
|
464
|
+
// type: String,
|
|
465
|
+
// default: ''
|
|
466
|
+
// },
|
|
467
|
+
// tags: {
|
|
468
|
+
// type: [String],
|
|
469
|
+
// default: [],
|
|
470
|
+
// },
|
|
471
|
+
|
|
472
|
+
// thumbnailImage: {
|
|
473
|
+
// type: String,
|
|
474
|
+
// default: null,
|
|
475
|
+
// },
|
|
476
|
+
// previewVideo: {
|
|
477
|
+
// type: String,
|
|
478
|
+
// default: null,
|
|
479
|
+
// },
|
|
480
|
+
// language: {
|
|
481
|
+
// type: String,
|
|
482
|
+
// },
|
|
483
|
+
// isLive: {
|
|
484
|
+
// type: Boolean,
|
|
485
|
+
// default: false,
|
|
486
|
+
// },
|
|
487
|
+
// streamUrl: {
|
|
488
|
+
// type: String,
|
|
489
|
+
// default: null,
|
|
490
|
+
// },
|
|
491
|
+
|
|
492
|
+
// // === Stream Layout Configuration ===
|
|
493
|
+
// orientation: {
|
|
494
|
+
// type: String,
|
|
495
|
+
// enum: ['horizontal', 'vertical'],
|
|
496
|
+
// default: 'horizontal'
|
|
497
|
+
// },
|
|
498
|
+
// layout: {
|
|
499
|
+
// type: String,
|
|
500
|
+
// enum: ['side-by-side', 'top-bottom'],
|
|
501
|
+
// default: 'side-by-side'
|
|
502
|
+
// },
|
|
503
|
+
|
|
504
|
+
// showStatus: {
|
|
505
|
+
// type: String,
|
|
506
|
+
// enum: ['created', 'live', 'cancelled', 'ended'],
|
|
507
|
+
// default: 'created'
|
|
508
|
+
// },
|
|
509
|
+
// likes: {
|
|
510
|
+
// type: Number,
|
|
511
|
+
// default: 0,
|
|
512
|
+
// },
|
|
513
|
+
// likedBy: {
|
|
514
|
+
// type: [mongoose.Schema.Types.ObjectId],
|
|
515
|
+
// ref: 'users',
|
|
516
|
+
// default: [],
|
|
517
|
+
// },
|
|
518
|
+
|
|
519
|
+
// buyNowProducts: {
|
|
520
|
+
// type: [
|
|
521
|
+
// {
|
|
522
|
+
// _id: false,
|
|
523
|
+
// productId: { type: Schema.Types.ObjectId, ref: "productlistings" },
|
|
524
|
+
// productOwnerSellerId: { type: Schema.Types.ObjectId, ref: 'sellers', required: true },
|
|
525
|
+
// productPrice: { type: Number, min: 0, default: null },
|
|
526
|
+
// },
|
|
527
|
+
// ],
|
|
528
|
+
// default: [],
|
|
529
|
+
// },
|
|
530
|
+
// auctionProducts: {
|
|
531
|
+
// type: [
|
|
532
|
+
// {
|
|
533
|
+
// _id: false,
|
|
534
|
+
// productId: { type: Schema.Types.ObjectId, ref: "productlistings" },
|
|
535
|
+
// productOwnerSellerId: { type: Schema.Types.ObjectId, ref: 'sellers', required: true },
|
|
536
|
+
// startingPrice: { type: Number, min: 0, default: null },
|
|
537
|
+
// reservedPrice: { type: Number, min: 0, default: null },
|
|
538
|
+
// auctionNumber: {
|
|
539
|
+
// type: Number,
|
|
540
|
+
// },
|
|
541
|
+
// // BGA Integration - Reference to BGA auction document
|
|
542
|
+
// auctionObjectId: {
|
|
543
|
+
// type: Schema.Types.ObjectId,
|
|
544
|
+
// required: true,
|
|
545
|
+
// index: true
|
|
546
|
+
// }
|
|
547
|
+
// },
|
|
548
|
+
// ],
|
|
549
|
+
// default: [],
|
|
550
|
+
// },
|
|
551
|
+
|
|
552
|
+
// giveawayProducts: {
|
|
553
|
+
// type: [giveawayProductSchema],
|
|
554
|
+
// default: []
|
|
555
|
+
// },
|
|
556
|
+
|
|
557
|
+
// // === LIVE FLASH SALE FIELDS (ADD THESE) ===
|
|
558
|
+
// liveFlashSales: {
|
|
559
|
+
// type: [liveFlashSaleSchema],
|
|
560
|
+
// default: [] // This ensures it's always an array
|
|
561
|
+
// },
|
|
562
|
+
// currentFlashSale: {
|
|
563
|
+
// type: Schema.Types.ObjectId,
|
|
564
|
+
// ref: 'FlashSale',
|
|
565
|
+
// default: null
|
|
566
|
+
// },
|
|
567
|
+
|
|
568
|
+
// enabledProductTypes: {
|
|
569
|
+
// buyNow: { type: Boolean, default: false },
|
|
570
|
+
// auction: { type: Boolean, default: false },
|
|
571
|
+
// giveaway: { type: Boolean, default: false }
|
|
572
|
+
// },
|
|
573
|
+
// notes: {
|
|
574
|
+
// type: String,
|
|
575
|
+
// default: ''
|
|
576
|
+
// },
|
|
577
|
+
// },
|
|
578
|
+
// { timestamps: true }
|
|
579
|
+
// );
|
|
580
|
+
|
|
581
|
+
// showSchema.pre('save', function (next) {
|
|
582
|
+
// const doc = this;
|
|
583
|
+
|
|
584
|
+
// // Set liveDrop based on product types
|
|
585
|
+
// const hasBuyNow = doc.buyNowProducts && doc.buyNowProducts.length > 0;
|
|
586
|
+
// const hasAuction = doc.auctionProducts && doc.auctionProducts.length > 0;
|
|
587
|
+
// const hasGiveaway = doc.giveawayProducts && doc.giveawayProducts.length > 0;
|
|
588
|
+
// doc.liveDrop = hasBuyNow && hasAuction && hasGiveaway;
|
|
589
|
+
|
|
590
|
+
// // Ensure coHost is null if hasCoHost is false
|
|
591
|
+
// if (!doc.hasCoHost) {
|
|
592
|
+
// doc.coHost = null;
|
|
593
|
+
// }
|
|
594
|
+
|
|
595
|
+
// next();
|
|
596
|
+
// });
|
|
597
|
+
|
|
598
|
+
// const Show = mongoose.model("shows", showSchema);
|
|
599
|
+
|
|
600
|
+
// export default Show;
|
|
601
|
+
|
|
602
|
+
|
|
174
603
|
|
|
175
|
-
export default Show;
|
package/models/stock.model.js
CHANGED
|
@@ -1,19 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
// models/Stock.js
|
|
1
|
+
// models/Stock.js - Simplified
|
|
3
2
|
import mongoose from "mongoose";
|
|
4
3
|
const { Schema } = mongoose;
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
const StockUpdateHistorySchema = new Schema({
|
|
8
|
-
change: { type: Number, required: true }, // e.g., +50 or -10
|
|
9
|
-
previousQuantity: { type: Number, required: true },
|
|
10
|
-
newQuantity: { type: Number, required: true },
|
|
11
|
-
reason: { type: String, default: "Manual update by seller" },
|
|
12
|
-
updatedAt: { type: Date, default: Date.now }
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const StockSchema = new Schema(
|
|
5
|
+
const stockSchema = new mongoose.Schema(
|
|
17
6
|
{
|
|
18
7
|
sellerId: {
|
|
19
8
|
type: Schema.Types.ObjectId,
|
|
@@ -22,64 +11,95 @@ const StockSchema = new Schema(
|
|
|
22
11
|
productListingId: {
|
|
23
12
|
type: Schema.Types.ObjectId,
|
|
24
13
|
ref: "productlistings",
|
|
14
|
+
required: true,
|
|
15
|
+
unique: true
|
|
16
|
+
},
|
|
17
|
+
quantity: {
|
|
18
|
+
type: Number,
|
|
19
|
+
default: 0,
|
|
20
|
+
min: 0
|
|
25
21
|
},
|
|
26
22
|
title: String,
|
|
27
23
|
images: [{
|
|
28
24
|
key: String,
|
|
29
25
|
url: String
|
|
30
26
|
}],
|
|
31
|
-
|
|
27
|
+
// ❌ REMOVED: totalReserved, flashSaleReservations
|
|
28
|
+
lowStockThreshold: {
|
|
32
29
|
type: Number,
|
|
33
|
-
|
|
34
|
-
default: 0,
|
|
30
|
+
default: 10
|
|
35
31
|
},
|
|
36
|
-
|
|
37
|
-
stockUpdateHistory: [StockUpdateHistorySchema],
|
|
38
|
-
|
|
39
|
-
// Track reservations for flash sales
|
|
40
|
-
flashSaleReservations: [{
|
|
41
|
-
flashSaleId: {
|
|
42
|
-
type: Schema.Types.ObjectId,
|
|
43
|
-
ref: "FlashSale",
|
|
44
|
-
required: true
|
|
45
|
-
},
|
|
46
|
-
quantity: { type: Number, min: 0, default: 0 },
|
|
47
|
-
status: {
|
|
48
|
-
type: String,
|
|
49
|
-
enum: ['reserved', 'active', 'released', 'sold', 'partially_sold'],
|
|
50
|
-
default: 'reserved'
|
|
51
|
-
},
|
|
52
|
-
reservedAt: { type: Date, default: Date.now },
|
|
53
|
-
releasedAt: Date,
|
|
54
|
-
soldQuantity: { type: Number, default: 0 }
|
|
55
|
-
}],
|
|
56
|
-
totalReserved: {
|
|
32
|
+
reorderQuantity: {
|
|
57
33
|
type: Number,
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
34
|
+
default: 50
|
|
35
|
+
},
|
|
36
|
+
isInStock: {
|
|
37
|
+
type: Boolean,
|
|
38
|
+
default: true
|
|
39
|
+
},
|
|
40
|
+
lastRestocked: {
|
|
41
|
+
type: Date,
|
|
42
|
+
default: null
|
|
43
|
+
},
|
|
44
|
+
stockUpdateHistory: [{
|
|
45
|
+
change: Number,
|
|
46
|
+
previousQuantity: Number,
|
|
47
|
+
newQuantity: Number,
|
|
48
|
+
reason: String,
|
|
49
|
+
updatedAt: { type: Date, default: Date.now }
|
|
50
|
+
}]
|
|
61
51
|
},
|
|
62
52
|
{ timestamps: true }
|
|
63
53
|
);
|
|
64
54
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
55
|
+
const Stock = mongoose.models.stocks || mongoose.model("stocks", stockSchema);
|
|
56
|
+
export default Stock;
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
// // models/Stock.js - Simplified version without flash sale reservations
|
|
60
|
+
// import mongoose from "mongoose";
|
|
61
|
+
// const { Schema } = mongoose;
|
|
62
|
+
|
|
63
|
+
// const stockSchema = new mongoose.Schema(
|
|
64
|
+
// {
|
|
65
|
+
// productListingId: {
|
|
66
|
+
// type: Schema.Types.ObjectId,
|
|
67
|
+
// ref: "productlistings",
|
|
68
|
+
// required: true,
|
|
69
|
+
// unique: true
|
|
70
|
+
// },
|
|
71
|
+
// quantity: {
|
|
72
|
+
// type: Number,
|
|
73
|
+
// default: 0,
|
|
74
|
+
// min: 0
|
|
75
|
+
// },
|
|
76
|
+
// // REMOVED: totalReserved field since we don't need reservations
|
|
77
|
+
// // REMOVED: flashSaleReservations array completely
|
|
78
|
+
// lowStockThreshold: {
|
|
79
|
+
// type: Number,
|
|
80
|
+
// default: 10
|
|
81
|
+
// },
|
|
82
|
+
// reorderQuantity: {
|
|
83
|
+
// type: Number,
|
|
84
|
+
// default: 50
|
|
85
|
+
// },
|
|
86
|
+
// isInStock: {
|
|
87
|
+
// type: Boolean,
|
|
88
|
+
// default: true
|
|
89
|
+
// },
|
|
90
|
+
// lastRestocked: {
|
|
91
|
+
// type: Date,
|
|
92
|
+
// default: null
|
|
93
|
+
// }
|
|
94
|
+
// },
|
|
95
|
+
// { timestamps: true }
|
|
96
|
+
// );
|
|
74
97
|
|
|
75
|
-
//
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
});
|
|
98
|
+
// // Indexes
|
|
99
|
+
// stockSchema.index({ productListingId: 1 });
|
|
100
|
+
// stockSchema.index({ isInStock: 1 });
|
|
101
|
+
// stockSchema.index({ quantity: 1 });
|
|
79
102
|
|
|
80
|
-
//
|
|
81
|
-
|
|
82
|
-
StockSchema.set('toObject', { virtuals: true });
|
|
103
|
+
// const Stock = mongoose.models.stocks || mongoose.model("stocks", stockSchema);
|
|
104
|
+
// export default Stock;
|
|
83
105
|
|
|
84
|
-
const Stock = mongoose.models.stocks || mongoose.model("stocks", StockSchema);
|
|
85
|
-
export default Stock;
|
package/models/user.model.js
CHANGED
|
@@ -7,20 +7,22 @@ import Seller from "./seller.model.js";
|
|
|
7
7
|
const UserSchema = new mongoose.Schema(
|
|
8
8
|
{
|
|
9
9
|
devices: [
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
10
|
+
{
|
|
11
|
+
deviceId: { type: String, required: true },
|
|
12
|
+
fcmToken: { type: String, required: true },
|
|
13
|
+
snsEndpointArn: { type: String, default: null }, // New field for SNS
|
|
14
|
+
platform: {
|
|
15
|
+
type: String,
|
|
16
|
+
enum: ["web", "android", "ios", "mobile-web"],
|
|
17
|
+
required: true,
|
|
18
|
+
},
|
|
19
|
+
lastLogin: { type: Date, default: Date.now },
|
|
20
|
+
lastLogout: { type: Date },
|
|
21
|
+
isActive: { type: Boolean, default: true },
|
|
22
|
+
_id: false,
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
|
|
24
26
|
sellerInfo: { type: mongoose.Schema.Types.ObjectId, ref: "sellers" },
|
|
25
27
|
dropshipperInfo: { type: mongoose.Schema.Types.ObjectId, ref: "dropshippers" },
|
|
26
28
|
categories: { type: [String], default: [], maxLength: 100 },
|
|
@@ -42,6 +44,7 @@ const UserSchema = new mongoose.Schema(
|
|
|
42
44
|
maxLength: 60,
|
|
43
45
|
index: true,
|
|
44
46
|
},
|
|
47
|
+
isMandate: { type: Boolean, default: false },
|
|
45
48
|
password: {
|
|
46
49
|
type: String,
|
|
47
50
|
required: function () {
|
|
@@ -49,7 +52,6 @@ const UserSchema = new mongoose.Schema(
|
|
|
49
52
|
},
|
|
50
53
|
maxLength: 120,
|
|
51
54
|
},
|
|
52
|
-
mobile: { type: String, trim: true, maxLength: 15 },
|
|
53
55
|
isEmailVerified: { type: Boolean, default: false },
|
|
54
56
|
role: {
|
|
55
57
|
type: String,
|
|
@@ -59,6 +61,12 @@ const UserSchema = new mongoose.Schema(
|
|
|
59
61
|
},
|
|
60
62
|
default: null,
|
|
61
63
|
},
|
|
64
|
+
gender: {
|
|
65
|
+
type: String,
|
|
66
|
+
enum: ["male", "female", "other", "prefer-not-to-say"],
|
|
67
|
+
lowercase: true,
|
|
68
|
+
default: null
|
|
69
|
+
},
|
|
62
70
|
accessAllowed: { type: Boolean, default: true },
|
|
63
71
|
oAuth: {
|
|
64
72
|
type: String,
|
|
@@ -120,6 +128,13 @@ const UserSchema = new mongoose.Schema(
|
|
|
120
128
|
isAddressSelected: { type: Boolean, default: false },
|
|
121
129
|
addressSelectedDate: { type: Date },
|
|
122
130
|
|
|
131
|
+
//Mobile Verification
|
|
132
|
+
mobile: { type: String, trim: true, maxLength: 15, unique: true, sparse: true }, // Make it unique but allow nulls
|
|
133
|
+
isMobileVerified: { type: Boolean, default: false },
|
|
134
|
+
mobileVerificationOTP: { type: String, select: false }, // 'select: false' hides it from default queries
|
|
135
|
+
mobileVerificationOTPExpiry: { type: Date, select: false },
|
|
136
|
+
|
|
137
|
+
|
|
123
138
|
// Payment Mandate Setup (Auto-Payment)
|
|
124
139
|
payuMandate: {
|
|
125
140
|
mandateToken: { type: String, default: null },
|
|
@@ -144,7 +159,11 @@ const UserSchema = new mongoose.Schema(
|
|
|
144
159
|
},
|
|
145
160
|
isAutoPaymentEnabled: { type: Boolean, default: false },
|
|
146
161
|
autoPaymentSetupDate: { type: Date },
|
|
147
|
-
|
|
162
|
+
onboardingStatus: {
|
|
163
|
+
type: String,
|
|
164
|
+
enum: ["pending","profile_setup", "completed"],
|
|
165
|
+
default: "completed" // Default to completed for existing users
|
|
166
|
+
},
|
|
148
167
|
deviceInfo: {
|
|
149
168
|
deviceId: { type: String, default: null },
|
|
150
169
|
appPlatform: { type: String, enum: ["android", "ios", "web"], default: "web" },
|