Files
modstagram-back/models/OrderModel.js
2026-09-24 21:00:07 +03:30

159 lines
3.5 KiB
JavaScript

const mongoose = require('mongoose')
const mongoosePaginate = require('mongoose-paginate-v2')
const timestamp = require('mongoose-timestamp')
const variantSnapshotSchema = new mongoose.Schema({
color: { type: String, default: null },
size: { type: String, default: null },
weight: { type: String, default: null },
price: { type: Number, required: true }
}, { _id: false })
const buyerAddressSnapshotSchema = new mongoose.Schema({
first_name: { type: String, default: null },
last_name: { type: String, default: null },
mobile: { type: String, default: null },
address: { type: String, default: null },
province: { type: Object, default: null },
city: { type: Object, default: null },
lat: { type: String, default: null },
lng: { type: String, default: null }
}, { _id: false })
const orderSchema = new mongoose.Schema({
buyer: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
required: true,
index: true
},
shop: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Shop',
required: true,
index: true
},
listing: {
type: mongoose.Schema.Types.ObjectId,
ref: 'ShopProductListing',
required: true
},
variantId: {
type: mongoose.Schema.Types.ObjectId,
required: true
},
variantSnapshot: {
type: variantSnapshotSchema,
required: true
},
quantity: {
type: Number,
required: true,
min: 1
},
/** Short, human-searchable reference code shown on invoices (derived from _id, generated post-create). */
orderNumber: {
type: String,
index: true,
default: null
},
unit_price: {
type: Number,
required: true
},
shipping_method: {
type: String,
enum: ['post', 'tipax', 'chapar', 'intercity_freight', 'courier', 'own_vehicle', null],
default: null
},
shipping_cost: {
type: Number,
default: 0
},
commission_amount: {
type: Number,
required: true
},
seller_net_amount: {
type: Number,
required: true
},
total_amount: {
type: Number,
required: true
},
status: {
type: String,
enum: [
'pending_payment',
'on_hold',
'failed',
'processing',
'shipped',
'ready_for_pickup',
'completed',
'cancelled',
'refunded'
],
default: 'pending_payment',
index: true
},
tracking_code: {
type: String,
trim: true,
default: null
},
paymentAuthority: {
type: String,
default: null
},
// مبلغی که کاربر با تیکِ «استفاده از کیف پول» قرار بود از سبدِ charged کسر بشه —
// فقط در لحظه‌ی موفقیتِ قطعیِ پرداخت واقعاً کسر می‌شه (نگاه کن به utils/walletSplit.js)
walletAmountUsed: {
type: Number,
default: 0
},
buyerAddressSnapshot: {
type: buyerAddressSnapshotSchema,
default: null
},
fulfilledAt: {
type: Date,
default: null
},
completedAt: {
type: Date,
default: null
},
buyerConfirmedReceiptAt: {
type: Date,
default: null
},
receiptDeadlineAt: {
type: Date,
default: null
},
returnWindowExpiresAt: {
type: Date,
default: null
},
walletReleased: {
type: Boolean,
default: false
},
cancelReason: {
type: String,
default: null
},
refundReason: {
type: String,
default: null
}
})
orderSchema.plugin(timestamp)
orderSchema.plugin(mongoosePaginate)
const OrderModel = mongoose.model('Order', orderSchema)
module.exports = OrderModel