courseworx/backend/plugins/financial-plugin/models/OrderItem.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

165 lines
3.7 KiB
JavaScript

/**
* Order Item Model for Financial Plugin
*
* This model handles individual items within an order,
* linking courses to orders with pricing and enrollment details.
*/
const { DataTypes } = require('sequelize');
module.exports = (sequelize) => {
const OrderItem = sequelize.define('FinancialOrderItem', {
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
primaryKey: true
},
orderId: {
type: DataTypes.UUID,
allowNull: false,
references: {
model: 'financial_orders',
key: 'id',
onDelete: 'CASCADE'
}
},
courseId: {
type: DataTypes.UUID,
allowNull: false,
references: {
model: 'courses',
key: 'id'
}
},
courseType: {
type: DataTypes.ENUM('online', 'classroom', 'hybrid'),
allowNull: false
},
enrollmentType: {
type: DataTypes.ENUM('one-time', 'subscription', 'installment'),
allowNull: false,
defaultValue: 'one-time'
},
originalPrice: {
type: DataTypes.DECIMAL(10, 2),
allowNull: false,
validate: {
min: 0
}
},
finalPrice: {
type: DataTypes.DECIMAL(10, 2),
allowNull: false,
validate: {
min: 0
}
},
quantity: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: 1,
validate: {
min: 1
}
},
discountAmount: {
type: DataTypes.DECIMAL(10, 2),
allowNull: false,
defaultValue: 0.00,
validate: {
min: 0
}
},
metadata: {
type: DataTypes.JSONB,
allowNull: true,
defaultValue: {}
},
enrolledAt: {
type: DataTypes.DATE,
allowNull: true
},
enrollmentStatus: {
type: DataTypes.ENUM('pending', 'enrolled', 'failed'),
allowNull: false,
defaultValue: 'pending'
}
}, {
tableName: 'financial_order_items',
timestamps: true,
indexes: [
{
fields: ['orderId']
},
{
fields: ['courseId']
},
{
fields: ['enrollmentStatus']
}
]
});
// Instance methods
OrderItem.prototype.markAsEnrolled = function() {
this.enrollmentStatus = 'enrolled';
this.enrolledAt = new Date();
return this.save();
};
OrderItem.prototype.markAsFailed = function() {
this.enrollmentStatus = 'failed';
return this.save();
};
OrderItem.prototype.calculateDiscount = function(coupon) {
if (!coupon) {
this.discountAmount = 0;
this.finalPrice = this.originalPrice;
return this;
}
if (coupon.type === 'percentage') {
this.discountAmount = (this.originalPrice * coupon.value) / 100;
} else if (coupon.type === 'fixed') {
this.discountAmount = Math.min(coupon.value, this.originalPrice);
}
this.finalPrice = Math.max(0, this.originalPrice - this.discountAmount);
return this;
};
// Static methods
OrderItem.findByOrder = function(orderId) {
return this.findAll({
where: { orderId },
order: [['createdAt', 'ASC']]
});
};
OrderItem.findByCourse = function(courseId) {
return this.findAll({
where: { courseId },
order: [['createdAt', 'DESC']]
});
};
OrderItem.getCourseStats = function(courseId, startDate, endDate) {
return this.findAll({
where: {
courseId,
enrollmentStatus: 'enrolled',
createdAt: {
[sequelize.Sequelize.Op.between]: [startDate, endDate]
}
},
attributes: [
[sequelize.fn('COUNT', sequelize.col('id')), 'totalEnrollments'],
[sequelize.fn('SUM', sequelize.col('finalPrice')), 'totalRevenue'],
[sequelize.fn('AVG', sequelize.col('finalPrice')), 'averagePrice']
]
});
};
return OrderItem;
};