Your IP : 216.73.216.43


Current Path : /home/deltalab/PMS/partner-manager-backend/rest/queries/
Upload File :
Current File : //home/deltalab/PMS/partner-manager-backend/rest/queries/order.js

const { orderModel } = require('../../models/mongoose/order');
const { productModel } = require('../../models/mongoose/product');

function getYearRange(year) {
  if (year) {
    const startDate = new Date(
      year,
      0,
      1,
    );
    const endDate = new Date(
      year,
      11,
      31,
    );
    return { $gte: startDate, $lte: endDate };
  }
  return undefined;
}

/**
 * Returns the earning of the year
 * @param {*} partnerId
 * @param {*} year
 * @returns earnings of the month
 */
async function readMany(partnerId, year) {
  const query = {};
  if (year) {
    query.createdAt = getYearRange(year);
  }

  const result = {};
  const orders = await orderModel.find(query);

  for (let i = 0; i < orders.length; i++) {
    for (let j = 0; j < orders[i].items.length; j++) {
      const product = await productModel.findOne({ sku: orders[i].items[j].sku });
      if (product && product.partnerId.equals(partnerId)) {
        const date = new Date(orders[i].createdAt);
        const month = date.getMonth();
        if (month in result) {
          result[month] = Math.round((result[month] + orders[i].items[j].totalPriceSet.amount) * 100) / 100;
        } else {
          result[month] = Math.round(orders[i].items[j].totalPriceSet.amount * 100) / 100;
        }
      }
    }
  }

  return result;
}

/**
 * Returns the number of products sold for each month during the year
 * @param {*} partnerId
 * @param {*} year
 * @returns number of products sold during the year
 */
async function nProductSold(partnerId, year) {
  const query = {};
  if (year) {
    query.createdAt = getYearRange(year);
  }

  const result = {};
  const orders = await orderModel.find(query);

  for (let i = 0; i < orders.length; i++) {
    for (let j = 0; j < orders[i].items.length; j++) {
      const product = await productModel.findOne({ sku: orders[i].items[j].sku });
      if (product && product.partnerId.equals(partnerId)) {
        const date = new Date(orders[i].createdAt);
        const month = date.getMonth();
        if (month in result) {
          result[month] += 1;
        } else {
          result[month] = 1;
        }
      }
    }
  }

  return result;
}

/**
 * Returns the list of best selling categories of the partner
 * @param {*} partnerId
 * @param {*} year
 * @param {*} firstN
 * @returns best-selling categories
 */
async function nCategoriesSold(partnerId, year, firstN = 5) {
  const query = {};
  if (year) {
    query.createdAt = getYearRange(year);
  }

  const result = {};
  const orders = await orderModel.find(query);

  for (let i = 0; i < orders.length; i++) {
    for (let j = 0; j < orders[i].items.length; j++) {
      const product = await productModel.findOne({ sku: orders[i].items[j].sku }).populate('categoryId');
      if (product && product.partnerId.equals(partnerId) && product.categoryId) {
        const type = product.categoryId.name[0].label;
        if (type in result) {
          result[type] += 1;
        } else {
          result[type] = 1;
        }
      }
    }
  }

  const resultSorted = Object.keys(result).sort((a, b) => result[b] - result[a])
    .reduce((r, k) => ({ ...r, [k]: result[k] }), {});
  const sliced = Object.fromEntries(Object.entries(resultSorted).slice(0, firstN));

  return sliced;
}

/**
 * For the channel manager, returns the best selling brands
 * @param {*} partnerId
 * @param {*} year
 * @param {*} firstN
 * @returns best selling brands
 */
async function nBrandsSold(partnerId, year, firstN = 5) {
  const query = {};
  if (year) {
    query.createdAt = getYearRange(year);
  }

  const result = {};
  const orders = await orderModel.find(query);

  for (let i = 0; i < orders.length; i++) {
    for (let j = 0; j < orders[i].items.length; j++) {
      const product = await productModel.findOne({ sku: orders[i].items[j].sku }).populate('categoryId');
      if (product && product.partnerId.equals(partnerId) && product.categoryId) {
        const { brand } = product;
        if (brand in result) {
          result[brand] += 1;
        } else {
          result[brand] = 1;
        }
      }
    }
  }

  const resultSorted = Object.keys(result).sort((a, b) => result[b] - result[a])
    .reduce((r, k) => ({ ...r, [k]: result[k] }), {});
  const sliced = Object.fromEntries(Object.entries(resultSorted).slice(0, firstN));

  return sliced;
}

/**
 * For the channel manager, returns the are from where the orders have been made
 * @param {*} partnerId
 * @param {*} year
 * @param {*} firstN
 * @returns customer area
 */
async function readCustomerByZone(partnerId, year, firstN = 5) {
  const query = {};
  if (year) {
    query.createdAt = getYearRange(year);
  }

  const result = {};
  const orders = await orderModel.find(query);

  for (let i = 0; i < orders.length; i++) {
    if (orders[i].partnerId.equals(partnerId)) {
      const { city } = orders[i].shippingAddress;
      if (city in result) {
        result[city] += 1;
      } else {
        result[city] = 1;
      }
    }
  }

  const resultSorted = Object.keys(result).sort((a, b) => result[b] - result[a])
    .reduce((r, k) => ({ ...r, [k]: result[k] }), {});
  const sliced = Object.fromEntries(Object.entries(resultSorted).slice(0, firstN));

  return sliced;
}

/**
 * Returns the list of best selling products of the partner
 * @param {*} partnerId
 * @param {*} year
 * @param {*} firstN
 * @returns best-selling products
 */
async function readBestSellers(partnerId, year, firstN = 5) {
  const query = {};
  if (year) {
    query.createdAt = getYearRange(year);
  }

  const result = {};
  const orders = await orderModel.find(query);

  for (let i = 0; i < orders.length; i++) {
    for (let j = 0; j < orders[i].items.length; j++) {
      const product = await productModel.findOne({ sku: orders[i].items[j].sku });
      if (product && product.partnerId.equals(partnerId)) {
        if (product.title in result) {
          result[product.title] += 1;
        } else {
          result[product.title] = 1;
        }
      }
    }
  }
  const resultSorted = Object.keys(result).sort((a, b) => result[b] - result[a])
    .reduce((r, k) => ({ ...r, [k]: result[k] }), {});
  const sliced = Object.fromEntries(Object.entries(resultSorted).slice(0, firstN));

  return sliced;
}

module.exports = {
  readMany,
  nProductSold,
  nCategoriesSold,
  nBrandsSold,
  readBestSellers,
  readCustomerByZone,
};