Untitled

mail@pastecode.io avatar
unknown
plain_text
3 years ago
9.0 kB
2
Indexable
Never
var _ = require('lodash');
var HashDataHelper = require('../../../helpers/HashDataHelper');
var ReponseHelper = require('../../../helpers/ReponseHelper');

var PaymentHistoryModel = require('../../../models/paymentHistory.model');
var PaymentHistoryItemModel = require('../../../models/PaymentHistoryItem.model');
var Validator = require('./validators.js');
var PostModel = require('../../../models/post.model');
var OrderModel = require('../../../models/order.model');
var PaymentGatewayModel = require('../../../models/paymentGateway.model');
var SettingModel = require('../../../models/setting.model');
var crypto = require('crypto');
exports.order = async (req, res) => {
  Validator.validatePayment(req, async (err, data) => {
    if (err) {
      return ReponseHelper.response(res, 422, HashDataHelper.makeError({
        status: 422,
        error: err
      }));
    }
    let setting = await PaymentGatewayModel.findOne({
      slug: 'ccbill'
    });
    if (!setting) {
      return ReponseHelper.response(res, 404, HashDataHelper.makeError({
        status: 404,
        msg: "Please contact admin to setup payment getway"
      }));
    }
    try {
      let productIds = data.products.map((item) => {
        return item._id;
      })
      let items = await PostModel.find({
        _id: {
          "$in": productIds
        },
        isDeleted: false
      });
      if (items.length == 0) {
        return ReponseHelper.response(res, 422, HashDataHelper.makeError({
          status: 422,
          'msg': 'Can not found any product match in systeam'
        }));
      }
      let itemsAllowOrder = [];
      let itemsNotAllowOrder = [];
      let total = 0;
      let paymentDetail = [];
      let shops = {};
      let shopIds = [];
      let fee = 0.1;
      let orders = [];
      let orderDetails = [];
      let totalFee = 0;
      let feeData = await SettingModel.findOne({
        slug: 'fee'
      });
      if (feeData) {
        fee = feeData.value / 100;
      }

      let mappData = await mappingItem(req, productIds, items);

      shops = mappData.shops;
      total = mappData.total;
      shopIds = mappData.shopIds;
      itemsAllowOrder = mappData.itemsAllowOrder;
      paymentDetail = mappData.paymentDetail;
      let oriPrice = total;
      totalFee = total * fee;
      total = total + totalFee;
      var payment = new PaymentHistoryModel({
        userId: req.user._id,
        price: total,
        type: 'money',
        fee: totalFee,
        oriPrice: oriPrice,
        billingAddress: data.billingAddress,
        fromType: 'product'
      })
      let result = await payment.save();
      orders = await mappingOrderData(req, shops, shopIds, payment, fee);
      await asyncForEach(paymentDetail, async (item) => {
        item.paymentId = result._id;
      });

      let ccbillLink = generateCcbillLink(req.user._id, 'product', setting, result, total);
      await PaymentHistoryItemModel.create(paymentDetail);
      await OrderModel.create(orders);
      return ReponseHelper.response(res, 200, HashDataHelper.make({paymentLink: ccbillLink}));
    } catch (err) {

      return ReponseHelper.response(res, 422, HashDataHelper.makeError({
        status: 422,
        error: err.message
      }));
    }


  })
}

function generateCcbillLink(userId, type, setting, payment, price) {
  let paymentLink = setting.metaValue.paymentLink;
  let clientSubacc = setting.metaValue.clientSubacc;
  let currencyCode = setting.metaValue.currencyCode;
  let salt = setting.metaValue.salt;
  let initialPeriod = 1;
  let formDigest = crypto.createHash('md5').update(price.toFixed(2) + initialPeriod + currencyCode + salt).digest('hex');
  paymentLink = paymentLink + '?initialPrice=' + price.toFixed(2) + '&clientSubacc=' + clientSubacc + '&initialPeriod=' + initialPeriod + '&currencyCode=' + currencyCode + '&user=' + userId + '&bill-type=' + type + '&formDigest=' + formDigest + '&payment=' + payment._id;
  paymentLink = paymentLink + '&language=english';
  return paymentLink;
}
async function mappingOrderData(req, shops, shopIds, payment, fee) {
  let orders = [];
  await asyncForEach(shopIds, async (shopId) => {
    var totalFee = shops[shopId].total * fee;
    var totalAmount = totalFee + shops[shopId].total;
    orders.push({
      paymentId: payment._id,
      userId: req.user._id,
      shop: shopId,
      totalAmount: totalAmount,
      fee: totalFee,
      amount: shops[shopId].total,
      type: 'product',
      paymentSeq: payment.paymentSeq,
      items: shops[shopId].products,
      statusTransaction: 'pending'
    });
  });
  return orders;
}
async function mappingItem(req, productIds, items) {
  let data = req.body;
  let shops = {};
  let total = 0;
  let itemsNotAllowOrder = [];
  let itemsAllowOrder = [];
  let shopIds = [];
  let paymentDetail = [];
  await asyncForEach(items, async (item) => {
    let idex = productIds.indexOf(item._id.toString());
    if (typeof shops[item.userId] == 'undefined') {
      shops[item.userId] = {
        products: [],
        total: 0,
      };
    }
    let shopIndex = shopIds.indexOf(item.userId.toString());
    if (shopIndex == -1) {
      shopIds.push(item.userId);
    }
    if (idex == -1) {
      await itemsNotAllowOrder.push(item);
    } else {
      let qty = data.products[idex].qty;
      item.qty = qty;
      let price = item.price;
      console.log(price);
      itemsAllowOrder.push(item);
      total += qty * price;

      shops[item.userId].total = shops[item.userId].total + (qty * price);
      shops[item.userId].products.push({
        amount: qty * price,
        priceRegular: item.price,
        priceSale: item.price,
        name: item.title,
        product: item._id,
        type: 'product',
        qty: qty
      });
      await paymentDetail.push({
        userId: req.user._id,
        shop: item.userId,
        price: qty * price,
        priceRegular: price,
        priceSale: price,
        description: item.title,
        type: 'product',
        qty: qty
      })
    }
  });

  return {
    itemsNotAllowOrder: itemsNotAllowOrder,
    itemsAllowOrder: itemsAllowOrder,
    shops: shops,
    shopIds: shopIds,
    total: total,
    paymentDetail: paymentDetail

  }
}

exports.buyPost = async (req, res) => {
  Validator.validatePaymentPost(req, async (err, data) => {
    if (err) {
      return ReponseHelper.response(res, 422, HashDataHelper.makeError({
        status: 422,
        error: err
      }));
    }
    try {
      let setting = await PaymentGatewayModel.findOne({
        slug: 'ccbill'
      });
      if (!setting) {
        return ReponseHelper.response(res, 404, HashDataHelper.makeError({
          status: 404,
          msg: "Please contact admin to setup payment getway"
        }));
      }
      let item = await PostModel.findOne({
        _id: {
          "$in": req.params.id
        },
        isDeleted: false
      });
      if (!item) {
        return ReponseHelper.response(res, 422, HashDataHelper.makeError({
          status: 422,
          'msg': 'Can not found any product match in systeam'
        }));
      }
      let total = item.price;
      let fee = 0.1;
      let totalFee = 0;
      let feeData = await SettingModel.findOne({
        slug: 'fee'
      });
      if (feeData) {
        fee = feeData.value / 100;
      }
      let oriPrice = total;
      totalFee = total * fee;
      total = total + totalFee;
      var payment = new PaymentHistoryModel({
        userId: req.user._id,
        price: total,
        type: 'money',
        fromType: 'post',
        fee: totalFee,
        postId: item._id,
        description: "Buy post #" + item._id,
        oriPrice: oriPrice,
        payforUser: item.userId
      })
      var itemDetail = {
        price: item.price,
        priceRegular: item.price,
        priceSale: item.price,
        type: 'post',
        qty: 1,
        product: item._id
      }
      let paymentSaved = await payment.save();
      itemDetail.paymentId = paymentSaved._id;
      var paymentDetail = new PaymentHistoryItemModel(itemDetail)
      itemDetail._id = item._id;
      await PaymentHistoryItemModel.create(paymentDetail);

      let ccbillLink = generateCcbillLink(req.user._id, 'post', setting, paymentSaved, total);

      return ReponseHelper.response(res, 200, HashDataHelper.make({paymentLink: ccbillLink}));

    } catch (e) {
      console.log('err', e);
      return ReponseHelper.response(res, 422, HashDataHelper.makeError({
        status: 422,
        error: e.message
      }));
    }
  })
}




async function asyncForEach(array, callback) {

  for (let index = 0; index < array.length; index++) {

    await callback(array[index], index, array);
  }
}