Выполните рефакторинг кода по модульной архитектуре для удобства чтения и поддержки.

Я не знаю, каким должен быть заголовок, но мне очень трудно рефакторинг кода.

Мне нужно понимание и помощь.

Вот бизнес-требования:

Заказ необходимо создать и обработать.

Заказ может иметь разные типы товаров, и их процесс будет отличаться.

По заказу будут выполняться некоторые базовые операции, такие как применение купона или применение монет.

Итак, я получу подробную информацию о заказе в API, например, код купона, следует ли использовать монеты, а также подробную информацию о заказываемых iStem, например, о комбинациях или услугах.

Для заказов типа комбо должна быть создана запись комбо-портфеля.

Для заказов типа услуги должно быть создано бронирование или запрос на услугу.

Итак, в OrderController ниже я сначала получаю все товары из корзины пользователя. Затем я применяю к ним купон после его проверки. OrderService.doApplyCoupon Является ли это.

OrderService.doApplyCoupon возвращается cartValue который имеет,

{
  subtotal,
  total,
  couponDiscount,
  discount, // base dicount on each item

}

Если купон не передан, я рассчитываю стоимость корзины calculateCartValue который возвращает тот же объект, что и выше.

После этого я применяю монеты, если пользователь не хотел их использовать, в противном случае.

Я храню как couponDiscount, так и usedCoins в примечаниях к заказу.

После этого создаю заказ OrderService.doCreateOrder.

doCreateOrder делает ниже вещей.

Он записывает детали в Order таблица, а также создает запись в таблице счетов со значениями,

{
  total,
  total_due, // total- (couponDiscount + coinsUsed)
  tax
}

В заказе или в счете может быть несколько позиций, поэтому,

Он создает запись в таблице сопоставления для orderItems и invoices который OrderItemInvoice.

Теперь также должны быть добавлены предметы OrderItem стол.

Наконец, я создаю транзакции для использованных купонов и монет.

Вот мой код, OrderController.js

const createOrder = async (req, res) => {
  const orderData = {
    combos: req.body.combos,
    zoneId: req.body.zone_id,
    services: req.body.services,
    couponCode: req.body.combos,
    isCoinsUsed: req.body.coins_used,
  };
  const notes = {};
  let cartValue = {};
  const userId = req.user.id;
  const userDevice = req.device.type;

  const cart = await CartService.doGetCartItemsByUserId(userId);
  if (orderData.couponCode) {
    const userCartValue = await OrderService.doApplyCoupon({
      userId,
      cartItems: cart.items,
      zoneId: orderData.zoneId,
      couponCode: orderData.couponCode,
      slotId: safelyGet(() => orderData.services[0].slot_id),
      bookingDate: safelyGet(() => orderData.services[0].bookingDate),
    });
    cartValue = userCartValue;
    notes.couponCode = orderData.couponCode;
    notes.couponDiscount = cartValue.coupon_discount;
  } else {
    cartValue = calculateCartValue(cart.items);
  }
  if (orderData.isCoinsUsed) {
    const coins = await WalletService.getWalletBalance({ userId });
    notes.coinsUsed = coins > cartValue.total ? cartValue.total : coins;
  }
  // create order and generate receipt
  const order = await OrderService.doCreateOrder({
    notes,
    userId,
    cartValue,
    userDevice,
    cartItems: cart.items,
  });
  if (orderData.services
    && orderData.services.length) {
    order.bookings = await RequestService.doCreateServiceRequest({
      userId,
      orderId: order.id,
      requestedServices: orderData.services,
    });
  }

  if (orderData.combos
    && orderData.combos.length) {
    order.combos = await ComboService.doCreateComboPurchase({
      userId,
      combos: orderData.combos,
      orderId: order.order_id,
      isActive: false,
    });
  }
  return res.status(200).send(order);
};

OrderServic.js

const doCreateOrder = async ({
  notes,
  userId,
  cartItems,
  userDevice,
  cartValue,
  createdBy = 'system',
  updatedBy = 'system',
}) => {
  const { couponDiscount, coinsUsed } = notes;
  let rzOrder = {};
  const result = await sequelize.transaction(async 
    const {
      tax,
      subtotal: totalAmount,
      total: totalDueAmount,
    } = cartValue;

    const netDueAmount = totalDueAmount - (coinsUsed || 0);

    if (netDueAmount > 0) {
      rzOrder = await RazorpayService.createRzOrder({
        notes,
        userId,
        amount: netDueAmount,
      });
    }
    const order = await Order.create(
      {
        user_id: userId,
        status: ORDER_CREATED,
        device_type: userDevice,
        coins_used: coinsUsed || 0,
        notes: JSON.stringify(notes),
        coupon_discount: couponDiscount || 0,
        order_number: `OD-${genRandomString(userId)}`,
        created_by: createdBy,
        updated_by: updatedBy,
        invoices: [{
          tax,
          total_amount: totalAmount,
          razorpay_order: rzOrder.id,
          total_due_amount: netDueAmount,
        }],
      },
      {
        include: {
          model: Invoice,
          as: 'invoices',
        },
        transaction: t,
      },
    );

    const orderData = order.toJSON();
    const invoiceId = orderData.invoices[0].id;
    cartItems.forEach((carItem) => {
      carItem.order_id = order.id;
    });
    const orderItems = await OrderItem.bulkCreate(cartItems, { transaction: t });
    const orderItemInvoices = JSON.parse(JSON.stringify(orderItems)).map(
      (orderItem) => ({
        customer_order_item_id: orderItem.id,
        invoice_id: invoiceId,
      }),
    );
    const invoiceItems = await OrderItemInvoice.bulkCreate(orderItemInvoices, { transaction: t });
    orderData.orderItems = orderItems;
    orderData.invoiceItems = invoiceItems;
    if (coinsUsed && coinsUsed > 0) {
      const walletDetail = await WalletService.deductFromWallet({
        userId,
        createdBy,
        updatedBy,
        transaction: t,
        orderId: order.id,
        amount: order.coins_used,
        transactionComment: `Debited against order ${order.order_number}`,
      });
      orderData.walletDetail = walletDetail;
    }
    if (couponDiscount && couponDiscount > 0) {
      await CouponService.doCreateCouponUse({
        userId,
        createdBy,
        updatedBy,
        transaction: t,
        orderId: order.id,
        couponCode: notes.couponCode,
        couponDiscount: notes.couponDiscount,
      });
    }
    return orderData;
  });
  return result;
};

Как видите, здесь много чего происходит, и я не могу найти простой способ его реорганизовать.

Я всегда сталкиваюсь с этой проблемой. Как сделать его лучше и читабельным? и разделить его на простые модули?

0

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *