courseworx/backend/plugins/financial-plugin/models/Order.js
mmabdalla 5477297914 v2.0.2 - Complete Plugin Architecture System and Multi-Currency Implementation
Major Features Added:
- Complete Plugin Architecture System with financial plugin
- Multi-currency support with exchange rates
- Course type system (online, classroom, hybrid)
- Attendance tracking and QR code scanning
- Classroom sessions management
- Course sections and content management
- Professional video player with authentication
- Secure media serving system
- Shopping cart and checkout system
- Financial dashboard and earnings tracking
- Trainee progress tracking
- User notes and assignments system

Backend Infrastructure:
- Plugin loader and registry system
- Multi-currency database models
- Secure media middleware
- Course access middleware
- Financial plugin with payment processing
- Database migrations for new features
- API endpoints for all new functionality

Frontend Components:
- Course management interface
- Content creation and editing
- Section management with drag-and-drop
- Professional video player
- QR scanner for attendance
- Shopping cart and checkout flow
- Financial dashboard
- Plugin management interface
- Trainee details and progress views

This represents a major evolution of CourseWorx from a basic LMS to a comprehensive educational platform with plugin architecture.
2025-09-14 04:20:37 +03:00

187 lines
4.2 KiB
JavaScript

/**
* Order Model for Financial Plugin
*
* This model handles order management including order creation,
* status tracking, and order history.
*/
const { DataTypes } = require('sequelize');
module.exports = (sequelize) => {
const Order = sequelize.define('FinancialOrder', {
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
primaryKey: true
},
userId: {
type: DataTypes.UUID,
allowNull: false,
references: {
model: 'users',
key: 'id'
}
},
orderNumber: {
type: DataTypes.STRING(50),
allowNull: false,
unique: true
},
status: {
type: DataTypes.ENUM('pending', 'paid', 'failed', 'refunded', 'cancelled'),
allowNull: false,
defaultValue: 'pending'
},
totalAmount: {
type: DataTypes.DECIMAL(10, 2),
allowNull: false,
validate: {
min: 0
}
},
discountAmount: {
type: DataTypes.DECIMAL(10, 2),
allowNull: false,
defaultValue: 0.00,
validate: {
min: 0
}
},
taxAmount: {
type: DataTypes.DECIMAL(10, 2),
allowNull: false,
defaultValue: 0.00,
validate: {
min: 0
}
},
finalAmount: {
type: DataTypes.DECIMAL(10, 2),
allowNull: false,
validate: {
min: 0
}
},
paymentMethod: {
type: DataTypes.STRING(50),
allowNull: true
},
gatewayTransactionId: {
type: DataTypes.STRING(255),
allowNull: true
},
couponId: {
type: DataTypes.UUID,
allowNull: true,
references: {
model: 'financial_coupons',
key: 'id'
}
},
metadata: {
type: DataTypes.JSONB,
allowNull: true,
defaultValue: {}
},
paidAt: {
type: DataTypes.DATE,
allowNull: true
},
refundedAt: {
type: DataTypes.DATE,
allowNull: true
},
refundAmount: {
type: DataTypes.DECIMAL(10, 2),
allowNull: true,
defaultValue: 0.00
}
}, {
tableName: 'financial_orders',
timestamps: true,
indexes: [
{
fields: ['userId']
},
{
fields: ['orderNumber']
},
{
fields: ['status']
},
{
fields: ['gatewayTransactionId']
}
]
});
// Instance methods
Order.prototype.markAsPaid = function(transactionId, paymentMethod) {
this.status = 'paid';
this.gatewayTransactionId = transactionId;
this.paymentMethod = paymentMethod;
this.paidAt = new Date();
return this.save();
};
Order.prototype.markAsFailed = function() {
this.status = 'failed';
return this.save();
};
Order.prototype.markAsRefunded = function(refundAmount) {
this.status = 'refunded';
this.refundAmount = refundAmount;
this.refundedAt = new Date();
return this.save();
};
Order.prototype.markAsCancelled = function() {
this.status = 'cancelled';
return this.save();
};
Order.prototype.calculateTotals = function() {
// This will be calculated based on order items
// Implementation will be added when OrderItem model is created
return this;
};
// Static methods
Order.generateOrderNumber = function() {
const prefix = 'ORD-';
const timestamp = Date.now().toString(36);
const random = Math.random().toString(36).substr(2, 5);
return `${prefix}${timestamp}${random}`.toUpperCase();
};
Order.findByOrderNumber = function(orderNumber) {
return this.findOne({ where: { orderNumber } });
};
Order.findByUser = function(userId, options = {}) {
return this.findAll({
where: { userId },
order: [['createdAt', 'DESC']],
...options
});
};
Order.getRevenueStats = function(startDate, endDate) {
return this.findAll({
where: {
status: 'paid',
createdAt: {
[sequelize.Sequelize.Op.between]: [startDate, endDate]
}
},
attributes: [
[sequelize.fn('COUNT', sequelize.col('id')), 'totalOrders'],
[sequelize.fn('SUM', sequelize.col('finalAmount')), 'totalRevenue'],
[sequelize.fn('AVG', sequelize.col('finalAmount')), 'averageOrderValue']
]
});
};
return Order;
};