Untitled

 avatar
unknown
plain_text
14 days ago
6.4 kB
3
Indexable
const ACTIVE_STATUSES = [
  'Не согласован',
  'Согласован',
  'готов к отгрузке',
  'К обеспечению',
];

@Injectable()
export default class Orders {
  private context: BaseContextI;

  constructor(
    @Inject(ProductService) private readonly productService: ProductService,
    @InjectModel(CustomersOrders)
    private customerOrdersModel: typeof CustomersOrders,
    private readonly configService: ConfigService,
  ) {}

  public setContext(context: BaseContextI) {
    this.context = context;
  }

  public async getDatabaseOrderByID(order_id: number) {
    const order_db = await this.customerOrdersModel.findOne({
      where: { id: order_id },
    });

    return order_db.dataValues;
  }

  public async repeatOrder(params: RepeatOrderSharedDto) {
    this.setContext(params.context);
    const order_db = await this.getDatabaseOrderByID(params.order_id);
    const order = new OrderItem(
      order_db,
      this.configService,
      this.context,
      this.productService,
    );
    const response = await order.repeat();
    return response;
  }

  public async getOrder(params: getOrderSharedDto): Promise<OrderResponse> {
    this.setContext(params.context);
    const order_db = await this.getDatabaseOrderByID(params.order_id);
    const order = new OrderItem(
      order_db,
      this.configService,
      this.context,
      this.productService,
    );

    if (!(await order.isCustomerOrder(this.context.customer_id))) {
      throw new Error('Not this customers order');
    }

    const base_info = await order.getFormattedOrderBaseInfo();
    const formatted_order = await order.getFormattedOrderFullInfo(base_info);
    return { formatted_order: formatted_order };
  }

  public async getOrders(
    getOrders: GetOrdersSharedDto,
  ): Promise<OrdersResponse> {
    this.setContext(getOrders.context);
    const { customer_id } = this.context;
    const { active, filter_year, page, page_size } = getOrders;
    const offset = page * page_size;

    const whereClause: any = {};
    if (active) {
      whereClause.status = { [Op.in]: ACTIVE_STATUSES };
      whereClause.conducted = 'Y';
      whereClause.deleted = 'N';
    }

    const startDate = new Date(`${filter_year}-01-01`);
    const endDate = new Date(`${Number(filter_year) + 1}-01-01`);
    whereClause.add_date = {
      [Op.and]: [{ [Op.gte]: startDate }, { [Op.lt]: endDate }],
    };

    const contragents_ids = await Core.getCustomersContragentsIds(customer_id);
    whereClause.contragent_id1c = contragents_ids;

    const orders = await this.customerOrdersModel.findAll({
      where: whereClause,
      limit: Number(page_size),
      offset: offset,
      order: [['add_date', 'DESC']],
    });

    if (!orders.length) {
      return { formatted_orders: [] };
    }

    // Собираем все order_id
    const orderIds = orders.map((order) => order.id);
    // Загружаем товары для всех заказов разом
    const goodsMap = await OrderItem.loadGoodsForOrders(orderIds);

    const formattedOrders: FormattedOrderBase[] = await Promise.all(
      orders.map(async (orderRecord) => {
        const orderItem = new OrderItem(
          orderRecord,
          this.configService,
          this.context,
          this.productService,
        );
        // Передаём предзагруженные данные для текущего заказа
        const pre_loaded_goods_data = goodsMap.get(orderRecord.id);
        return await orderItem.getFormattedOrderBaseInfo(pre_loaded_goods_data);
      }),
    );

    return { formatted_orders: formattedOrders };
  }

  public async createOrder(params: CreateOrderSharedDto): Promise<string> {
    const { checkout_id, contragent_id, token, context } = params;

    const checkout_db = await this.getCheckoutRecord(checkout_id);
    const fillial_db = await this.getFillialRecord(context.city_id);

    const checkout_item = await this.prepareCheckoutItem(checkout_db, context);
    const contragent = this.getContragent(checkout_item, contragent_id);
    const total_sum = this.calculateTotal(checkout_item.products);
    const desired_shipment_date = this.getDesiredShipmentDate(
      checkout_item.products,
      checkout_db,
    );

    const order_body = await this.buildOrderBody({
      checkout_db,
      fillial_db,
      context,
      contragent,
      sum: total_sum,
      desired_shipment_date,
    });
    order_body.goods = this.mapGoods(checkout_item.products);

    console.log(order_body);

    const order_response = await this.sendOrderInfoToApi(order_body, token);
    if (!order_response || !order_response.order_id) {
      throw new Error('Order creation failed');
    }

    if (order_response.order_id) {
      await this.updateBasketRecords(
        checkout_item.products,
        context.customer_id,
      );
      await CheckoutDbModel.destroy({ where: { id: checkout_db.id } });
    }

    return order_response.order_id;
  }

  private async getCheckoutRecord(checkout_id: number): Promise<any> {
    const checkout_record = await CheckoutDbModel.findOne({
      where: { id: checkout_id },
    });
    if (!checkout_record) {
      throw new Error(`Checkout record not found for id ${checkout_id}`);
    }
    return checkout_record;
  }

  private async getFillialRecord(city_id: number): Promise<any> {
    const fillial_record = await FillialDBModel.findOne({
      where: { id: city_id },
    });
    if (!fillial_record) {
      throw new Error(`Fillial not found for city_id ${city_id}`);
    }
    return fillial_record;
  }

  private async prepareCheckoutItem(
    checkout_db: any,
    context: BaseContextI,
  ): Promise<CheckoutItem> {
    const checkout_item = new CheckoutItem(this.productService);
    await checkout_item.loadUserData(context.customer_id);
    await checkout_item.loadProducts(context);
    checkout_item.products = checkout_item.filterProducts(
      checkout_item.products,
      checkout_db.basket_type,
    );
    return checkout_item;
  }

  private getContragent(
    checkout_item: CheckoutItem,
    contragent_id: number,
  ): ContragentData {
    const contragent = checkout_item.user_data.contragents.find(
      (c) => c.id === contragent_id,
    );
    if (!contragent) {
      throw new Error(`Contragent with id ${contragent_id} not found`);
    }
    return contragent;
  }
Editor is loading...
Leave a Comment