Refactor invoice module to use userId and cartId

master
nicekid1 2 months ago
parent 7da8f22cb2
commit 98139f75bf
  1. 62
      migrations/20250105085732-create-invoice.js
  2. 2
      src/cart/cart.controller.ts
  3. 18
      src/cart/cart.service.ts
  4. 68
      src/invoice/entities/invoice.entity.ts
  5. 25
      src/invoice/invoice.service.ts

@ -1,10 +1,10 @@
"use strict"; 'use strict';
module.exports = { module.exports = {
up: async (queryInterface, Sequelize) => {
await queryInterface.dropTable("Invoices", { cascade: true });
await queryInterface.createTable("Invoices", { up: async (queryInterface, Sequelize) => {
await queryInterface.dropTable('Invoices', { cascade: true });
await queryInterface.createTable('Invoices', {
id: { id: {
type: Sequelize.INTEGER, type: Sequelize.INTEGER,
autoIncrement: true, autoIncrement: true,
@ -15,66 +15,38 @@ module.exports = {
type: Sequelize.INTEGER, type: Sequelize.INTEGER,
allowNull: false, allowNull: false,
references: { references: {
model: "Users", model: 'Users',
key: "id", key: 'id',
},
onDelete: "CASCADE",
},
firstName: {
type: Sequelize.STRING,
allowNull: false,
},
lastName: {
type: Sequelize.STRING,
allowNull: false,
},
phoneNumber: {
type: Sequelize.STRING,
allowNull: false,
},
email: {
type: Sequelize.STRING,
allowNull: false,
unique: false,
},
totalPaymentAmount: {
type: Sequelize.DECIMAL(10, 2),
allowNull: true,
}, },
productId: { onDelete: 'CASCADE',
type: Sequelize.INTEGER,
allowNull: false,
}, },
quantity: { cartId: {
type: Sequelize.INTEGER, type: Sequelize.INTEGER,
allowNull: false, allowNull: false,
references: {
model: 'Carts',
key: 'id',
}, },
price: { onDelete: 'CASCADE',
type: Sequelize.DECIMAL(10, 2),
allowNull: false,
}, },
totalPrice: { totalPaymentAmount: {
type: Sequelize.DECIMAL(10, 2), type: Sequelize.FLOAT,
allowNull: false,
},
productName: {
type: Sequelize.STRING,
allowNull: false, allowNull: false,
}, },
createdAt: { createdAt: {
type: Sequelize.DATE, type: Sequelize.DATE,
allowNull: false, allowNull: false,
defaultValue: Sequelize.fn("NOW"), defaultValue: Sequelize.fn('NOW'),
}, },
updatedAt: { updatedAt: {
type: Sequelize.DATE, type: Sequelize.DATE,
allowNull: false, allowNull: false,
defaultValue: Sequelize.fn("NOW"), defaultValue: Sequelize.fn('NOW'),
}, },
}); });
}, },
down: async (queryInterface, Sequelize) => { down: async (queryInterface, Sequelize) => {
await queryInterface.dropTable("Invoices"); await queryInterface.dropTable('Invoices');
}, },
}; };

@ -49,7 +49,7 @@ export class CartController {
async processOrder( async processOrder(
@Param('userId') userId: number, @Param('userId') userId: number,
@Body('totalAmount') totalAmount: number, @Body('totalAmount') totalAmount: number,
):Promise<{ message: string; invoices: Invoice[] }> { ):Promise<{ message: string; invoices: Invoice}> {
if (!totalAmount || totalAmount <= 0) { if (!totalAmount || totalAmount <= 0) {
throw new HttpException('Invalid total amount.', HttpStatus.BAD_REQUEST); throw new HttpException('Invalid total amount.', HttpStatus.BAD_REQUEST);
} }

@ -109,8 +109,15 @@ export class CartService {
} }
//order(clearCart disable) //order(clearCart disable)
async processOrder(userId: number, totalAmount: number): Promise<{ message: string; invoices: Invoice[] }> { async processOrder(userId: number, totalAmount: number): Promise<{ message: string; invoices: Invoice }> {
try { try {
const cart = await this.cartModel.findOne({ where: { userId } });
if (!cart) {
throw new HttpException("Cart not found for this user.", HttpStatus.NOT_FOUND);
}
const cartId = cart.id;
// Deducting credit from wallet // Deducting credit from wallet
await this.walletService.processPayment(userId, totalAmount); await this.walletService.processPayment(userId, totalAmount);
@ -138,10 +145,10 @@ export class CartService {
await product.save(); await product.save();
} }
// Create the invoices for all cart items // Create the invoices for all cart
const invoices = await this.invoiceService.createInvoiceFromCart(userId); const invoices = await this.invoiceService.createInvoiceFromCart(userId,cartId);
return { message: "Order processed successfully", invoices }; // Return invoices as an array return { message: "Order processed successfully", invoices };
} catch (error) { } catch (error) {
console.log(error); console.log(error);
if (error instanceof HttpException) { if (error instanceof HttpException) {
@ -151,7 +158,4 @@ export class CartService {
} }
} }
} }
} }

@ -1,71 +1,33 @@
import { Table, Column, ForeignKey, BelongsTo, DataType, Model } from "sequelize-typescript"; import {
Table,
Column,
ForeignKey,
BelongsTo,
DataType,
Model,
} from "sequelize-typescript";
import { User } from "../../users/entities/user.entity"; import { User } from "../../users/entities/user.entity";
import { Cart } from "src/cart/entities/cart.entity";
@Table @Table
export class Invoice extends Model<Invoice> { export class Invoice extends Model<Invoice> {
@ForeignKey(() => User) @ForeignKey(() => User)
@Column @Column
userId: number; userId: number;
@BelongsTo(() => User, { onDelete: "CASCADE" }) @BelongsTo(() => User, { onDelete: "CASCADE" })
user: User; user: User;
@Column({
type: DataType.STRING,
allowNull: false,
})
firstName: string;
@Column({
type: DataType.STRING,
allowNull: false,
})
lastName: string;
@Column({
type: DataType.STRING,
allowNull: false,
})
phoneNumber: string;
@Column({
type: DataType.STRING,
allowNull: false,
unique: false,
})
email: string;
@ForeignKey(() => Cart)
@Column @Column
totalPaymentAmount: number; cartId: number;
@Column({ @BelongsTo(() => Cart, { onDelete: "CASCADE" })
type: DataType.INTEGER, cart: Cart;
allowNull: false,
})
productId: number;
@Column({ @Column({
type: DataType.INTEGER, type: DataType.FLOAT,
allowNull: false, allowNull: false,
}) })
quantity: number; totalPaymentAmount: number;
@Column({
type: DataType.DECIMAL(10, 2),
allowNull: false,
})
price: number;
@Column({
type: DataType.DECIMAL(10, 2),
allowNull: false,
})
totalPrice: number;
@Column({
type: DataType.STRING,
allowNull: false,
})
productName: string;
} }

@ -12,7 +12,7 @@ export class InvoiceService {
private cartService: CartService, private cartService: CartService,
) {} ) {}
async createInvoiceFromCart(userId: number): Promise<Invoice[]> { async createInvoiceFromCart(userId: number,cartId:number): Promise<Invoice> {
const user = await User.findByPk(userId); const user = await User.findByPk(userId);
if (!user) { if (!user) {
throw new HttpException("User not found", HttpStatus.NOT_FOUND); throw new HttpException("User not found", HttpStatus.NOT_FOUND);
@ -23,27 +23,12 @@ export class InvoiceService {
throw new HttpException("Cart is empty", HttpStatus.BAD_REQUEST); throw new HttpException("Cart is empty", HttpStatus.BAD_REQUEST);
} }
const invoices: Invoice[] = [];
for (const cartItem of userCartItems.cartItems) {
const invoice = await this.invoiceModel.create({ const invoice = await this.invoiceModel.create({
userId, userId,
firstName: user.firstName, cartId,
lastName: user.lastName, totalPaymentAmount:userCartItems.totalPrice,
phoneNumber: user.phoneNumber, })
email: user.email, return invoice
totalPaymentAmount: userCartItems.totalPrice,
productId: cartItem.productId,
quantity: cartItem.quantity,
price: cartItem.productPrice,
totalPrice:(cartItem.quantity*cartItem.productPrice),
productName: cartItem.productName,
});
invoices.push(invoice);
}
return invoices; // بازگرداندن آرایهای از فاکتورها
} }

Loading…
Cancel
Save