39647-vm/backend/models/cartModel.js
2026-04-08 14:28:58 +04:00

184 lines
4.5 KiB
JavaScript

const fs = require('fs');
const path = require('path');
// Simple file-based storage for demo purposes
const CARTS_FILE = path.join(__dirname, '../data/carts.json');
// Ensure data directory exists
const dataDir = path.dirname(CARTS_FILE);
if (!fs.existsSync(dataDir)) {
fs.mkdirSync(dataDir, { recursive: true });
}
// Initialize carts file if it doesn't exist
if (!fs.existsSync(CARTS_FILE)) {
fs.writeFileSync(CARTS_FILE, JSON.stringify([], null, 2));
}
// Cart Schema (simplified for file storage)
class Cart {
constructor(data) {
this.user = data.user;
this.items = data.items || [];
this.subtotal = data.subtotal || 0;
this.tax = data.tax || 0;
this.taxRate = data.taxRate || 0.1; // 10% tax
this.shippingCost = data.shippingCost || 0;
this.discountCode = data.discountCode || null;
this.discountAmount = data.discountAmount || 0;
this.total = data.total || 0;
this.notes = data.notes || null;
this.createdAt = data.createdAt || new Date();
this.updatedAt = data.updatedAt || new Date();
}
// Method to calculate totals
calculateTotals() {
// Calculate subtotal
this.subtotal = this.items.reduce((sum, item) => {
return sum + item.price * item.quantity;
}, 0);
// Calculate tax
this.tax = Number((this.subtotal * this.taxRate).toFixed(2));
// Calculate total
this.total = this.subtotal + this.tax + this.shippingCost - this.discountAmount;
this.total = Number(this.total.toFixed(2));
return this;
}
// Method to add item to cart
addItem(productId, quantity, price) {
const existingItem = this.items.find(item => item.product.toString() === productId);
if (existingItem) {
existingItem.quantity += quantity;
} else {
this.items.push({
product: productId,
quantity,
price,
addedAt: new Date(),
});
}
this.calculateTotals();
return this;
}
// Method to remove item from cart
removeItem(productId) {
this.items = this.items.filter(item => item.product.toString() !== productId);
this.calculateTotals();
return this;
}
// Method to update item quantity
updateItemQuantity(productId, quantity) {
const item = this.items.find(item => item.product.toString() === productId);
if (item) {
if (quantity <= 0) {
this.removeItem(productId);
} else {
item.quantity = quantity;
}
}
this.calculateTotals();
return this;
}
// Method to clear cart
clearCart() {
this.items = [];
this.calculateTotals();
return this;
}
// Method to get item count
getItemCount() {
return this.items.reduce((count, item) => count + item.quantity, 0);
}
}
// Static methods for file operations
Cart.findOne = async (query) => {
try {
const data = fs.readFileSync(CARTS_FILE, 'utf8');
const carts = JSON.parse(data);
if (query.user) {
const cart = carts.find(c => c.user === query.user);
return cart ? new Cart(cart) : null;
}
return null;
} catch (error) {
console.error('Error reading carts:', error);
return null;
}
};
Cart.findOneAndUpdate = async (query, updateData, options = {}) => {
try {
const data = fs.readFileSync(CARTS_FILE, 'utf8');
let carts = JSON.parse(data);
if (query.user) {
const index = carts.findIndex(c => c.user === query.user);
if (index === -1) {
// Create new cart if upsert is true
if (options.upsert) {
const newCart = new Cart({ user: query.user, ...updateData });
carts.push(newCart);
fs.writeFileSync(CARTS_FILE, JSON.stringify(carts, null, 2));
return newCart;
}
return null;
}
// Update existing cart
Object.assign(carts[index], updateData, { updatedAt: new Date() });
fs.writeFileSync(CARTS_FILE, JSON.stringify(carts, null, 2));
return new Cart(carts[index]);
}
return null;
} catch (error) {
console.error('Error updating cart:', error);
throw error;
}
};
Cart.findOneAndDelete = async (query) => {
try {
const data = fs.readFileSync(CARTS_FILE, 'utf8');
let carts = JSON.parse(data);
if (query.user) {
const index = carts.findIndex(c => c.user === query.user);
if (index === -1) {
return null;
}
const deletedCart = carts.splice(index, 1)[0];
fs.writeFileSync(CARTS_FILE, JSON.stringify(carts, null, 2));
return new Cart(deletedCart);
}
return null;
} catch (error) {
console.error('Error deleting cart:', error);
throw error;
}
};
module.exports = Cart;