cart.js 13 KB
'use strict';

const _ = require('lodash');
const helpers = global.yoho.helpers;
const paymentProcess = require(global.utils + '/payment-process');
const shoppingModel = require('./shopping');
const logger = global.yoho.logger;
const payModel = require('../models/pay');

class cartModel extends global.yoho.BaseModel {
    constructor(ctx) {
        super(ctx);
    }

    /**
     * 调用购物车结算接口返回的数据处理
     */
    cartPay(params) {
        let result = {};
        let skuList = [];
        let isLimitGoods = params.skn && params.sku && params.buyNumber; // 存在sku, skn 和buyNumber时为限购商品
        let orderComputeAPI = null;

        if (isLimitGoods) {
            skuList.push({
                type: 'limitcode',
                limitproductcode: params.limitProductCode,
                buy_number: params.buyNumber,
                skn: params.skn,
                sku: params.sku
            });

            result.isLimit = true;
        }

        let orderInfoCookie = _.get(params, 'orderInfo', null);

        // 是否需要重新计算
        let needReComputer = orderInfoCookie && !_.isEmpty(orderInfoCookie) &&
            (orderInfoCookie.yohoCoin || orderInfoCookie.user_check_coupon === 'Y');

        if (needReComputer) {
            orderInfoCookie.paymentType = orderInfoCookie.paymentType ? orderInfoCookie.paymentType : '';
            orderComputeAPI = this.ctx.req.ctx(shoppingModel).orderComputeAPI({
                uid: params.uid,
                cart_type: params.cartType,
                delivery_way: orderInfoCookie.deliveryId,
                payment_type: orderInfoCookie.paymentType,
                coupon_code: orderInfoCookie.coupon_code,
                gift_card_code: orderInfoCookie.gift_card_code,
                use_yoho_coin: orderInfoCookie.yohoCoin,
                product_sku_list: skuList,
                activityInfo: params.activityInfo
            });
        }

        // 区分套餐量贩和普通商品
        let cartPayAPI;
        let cartPayAPIParams = {
            uid: params.uid,
            cart_type: params.cartType,
            delivery_way: orderInfoCookie.deliveryId,
            payment_type: orderInfoCookie.paymentType,
            coupon_code: orderInfoCookie.couponCode,
            gift_card_code: orderInfoCookie.gift_card_code,
            use_yoho_coin: orderInfoCookie.yohoCoin,
            product_sku_list: skuList,
            activityInfo: params.activityInfo
        };

        if (params.activityInfo) {
            cartPayAPI = this.ctx.req.ctx(shoppingModel).cartPayAPI(_.assign(cartPayAPIParams, {
                activityInfo: params.activityInfo
            }));
        } else {
            cartPayAPI = this.ctx.req.ctx(shoppingModel).cartPayAPI(cartPayAPIParams);
        }

        return Promise.all([
            cartPayAPI, // 0. 订单数据
            orderComputeAPI,
            this.ctx.req.ctx(shoppingModel).getValidCouponCount({
                uid: params.uid,
                delivery_way: orderInfoCookie.deliveryId
            }), // 2. 有效优惠券
            this.ctx.req.ctx(shoppingModel).countUsableGiftCard(params.uid) // 3 可用礼品卡数量
        ]).then(res => {
            let pay = res[0];
            let orderCompute = _.get(res[1], 'data', {});
            let validCouponCount = _.get(res[2], 'data.count', 0);
            let validGiftCardCount = _.get(res[3], 'data.count', 0);
            let goodsList = _.get(pay, 'data.goods_list', []);
            let paymentApiCouponData = _.get(pay, 'data.coupon_pay', {});

            if (_.isEmpty(goodsList)) {
                logger.info(`orderEnsure: goodsList is empty, isLimitGoods: ${isLimitGoods}`);
                if (isLimitGoods) {
                    result.error = true;
                    result.message = pay.message;
                } else {
                    // 错误消息要 暴露出去
                    result.error = true;
                    result.message = pay.message;
                    result.cartUrl = helpers.urlFormat('/cart/index/index');
                }

                return result;
            }

            _.assign(
                result,
                paymentProcess.tranformPayment(pay.data, orderInfoCookie, params.cartType, skuList, orderCompute),
                {
                    coupon: paymentProcess.handleCoupons({
                        paymentApiCouponData,
                        validCouponCount: validCouponCount,
                        orderComputeCouponPay: orderCompute.coupon_pay,
                        userCheckCoupon: orderInfoCookie.user_check_coupon
                    }),
                    giftCards: paymentProcess.handleGiftCards({
                        validGiftCardCount: validGiftCardCount,
                        orderCompute: orderCompute
                    })
                });

            return result;
        });
    }

    /**
     * 购物车结算--支付方式和配送方式选择以及是否使用有货币接口返回的数据处理
     */
    orderCompute(params) {
        return Promise.all([
            this.ctx.req.ctx(shoppingModel).orderComputeAPI(params),
            this.ctx.req.ctx(shoppingModel).getValidCouponCount({
                uid: params.uid,
                delivery_way: params.delivery_way
            })
        ]).then(result => {
            let computerResult = result[0];
            let validCouponCount = _.get(result[1], 'data.count', 0);

            if (computerResult && computerResult.data) {
                computerResult.data.use_yoho_coin = paymentProcess.transPrice(computerResult.data.use_yoho_coin);
                computerResult.data.yohoCoinCompute = paymentProcess.yohoCoinCompute(computerResult.data);
                computerResult.data.coupon = paymentProcess.handleCoupons({
                    paymentApiCouponData: {},
                    validCouponCount: validCouponCount,
                    orderComputeCouponPay: _.get(computerResult, 'data.coupon_pay'),
                    userCheckCoupon: params.user_check_coupon
                });
                return computerResult.data;
            } else {
                return {};
            }
        });
    }

    ticketsOrderCompute(uid, productSku, buyNumber, yohoCoin, gift_card_code) {
        return this.ctx.req.ctx(shoppingModel).checkTickets(uid, productSku, buyNumber,
            yohoCoin, null, gift_card_code).then(result => {
            if (result && result.data) {
                let resu = {};

                result.data.shopping_cart_data.use_yoho_coin =
                    paymentProcess.transPrice(result.data.shopping_cart_data.use_yoho_coin);
                resu = result.data.shopping_cart_data;
                resu.yohoCoinCompute = paymentProcess.yohoCoinCompute(result.data.shopping_cart_data);

                let gift_card = _.get(result, 'data.gift_card', false);

                if (gift_card) {
                    _.set(resu, 'gift_card', gift_card);
                }

                return resu;
            } else {
                return {};
            }
        });
    }

    /**
     * 购物车结算--提交结算信息
     */
    orderSub(params) {
        if (!params.qhy_union) {
            params.qhy_union = '';
        }

        if (!params.userAgent) {
            params.userAgent = null;
        }

        if (!params.times) {
            params.times = 1;
        }

        if (!params.activityInfo) {
            params.activityInfo = null;
        }

        if (!params.address_id) {
            return Promise.resolve({code: 401, message: '配送地址不能为空'});
        }

        if (!params.delivery_time) {
            return Promise.resolve({code: 402, message: '请选择配送时间'});
        }

        if (!params.delivery_way) {
            return Promise.resolve({code: 403, message: '请选择配送方式'});
        }

        return this.ctx.req.ctx(shoppingModel).orderSub(params).then(orderSubRes => {
            let finalResult = {};

            if (orderSubRes && orderSubRes.data && orderSubRes.data.is_hint === 'Y') {
                finalResult.code = 409;

                if (orderSubRes.data.hintInfo) {
                    let productName = _.get('orderSubRes', 'data.hintInfo.productName', '');

                    if (productName.length > 50) { // TODO 需要检查长度是否正确
                        orderSubRes.data.hintInfo.productName =
                            productName.substring(0, 47) + '...';
                    }

                    finalResult.message = [
                        encodeURI(productName + _.get(orderSubRes, 'data.hintInfo.suffix', '')),
                        encodeURI(_.get(orderSubRes, 'data.hintInfo.lastLine', ''))
                    ];
                }

                finalResult.buttons = [
                    {
                        href: helpers.urlFormat('/cart/index/index'),
                        text: '重新选择商品',
                        class: ''
                    },
                    {
                        href: '',
                        text: '继续结算',
                        class: 'order-tip-btnred'
                    }
                ];
            } else if (orderSubRes && orderSubRes.code) {
                finalResult = orderSubRes;
            } else {
                finalResult = {
                    code: 400,
                    message: '出错啦'
                };
            }

            return finalResult;
        });

    }

    /**
     * 处理优惠券列表数据
     *
     * @param int $uid 用户ID
     * @return array|mixed 处理之后的优惠券数据
     */
    getCouponList(params) {
        let result = {
            availableCoupons: [],
            usableFreesCoupons: [],
            notAvailableCoupons: [],
        };

        return this.ctx.req.ctx(shoppingModel).listCoupon({
            uid: params.uid,
            delivery_way: params.delivery_way,
            is_group_frees: params.is_group_frees
        }).then(coupons => {
            let usableCoupons = _.get(coupons, 'data.usable_coupons', []);
            let freesCoupons = _.get(coupons, 'data.usable_frees_coupons', []);
            let unusableCoupons = _.get(coupons, 'data.unusable_coupons', []);

            let orderInfoUsableUsualCode = _.get(params, 'orderInfo.usable_usual_code', '');
            let orderInfoUsableFreeCode = _.get(params, 'orderInfo.usable_free_code', '');

            let procCouponsData = coupon => {
                return {
                    couponCode: coupon.coupon_code,
                    couponDetailInfomation: coupon.coupon_name,
                    couponValue: coupon.coupon_value,
                    couponValidity: coupon.coupon_validity,
                    checked: coupon.coupon_code === orderInfoUsableUsualCode ||
                        coupon.coupon_code === orderInfoUsableFreeCode
                };
            };

            result.availableCoupons = usableCoupons.map(procCouponsData); // 可用优惠券
            result.usableFreesCoupons = freesCoupons.map(procCouponsData); // 运费券
            result.notAvailableCoupons = unusableCoupons.map(procCouponsData); // 不可用优惠券

            return result;
        });
    }

    useCouponCode(uid, couponCode) {
        let result = {code: 400, message: '出错啦~'};

        if (!couponCode) {
            return Promise.resolve({
                code: 401,
                message: '优惠券代码为空'
            });
        }

        return this.ctx.req.ctx(shoppingModel).useCoupon(uid, couponCode)
            .catch(() => result);
    }

    /**
     * jit拆单数据(结算页和订单详情页)
     */
    jitDetailData(uid, cartType, skuList, orderCode, sessionKey,
        deliveryId, paymentType, couponCode, yohoCoin) {

        // 订单详情页拆单
        if (orderCode) {
            return this.ctx.req.ctx(payModel).getOtherDetail({
                uid: uid,
                orderCode: orderCode,
                sessionKey: sessionKey
            }).then(result => {
                return paymentProcess.transformJit(_.get(result, 'data.package_info.package_list', []));
            });
        }

        // 购物车拆单
        if (deliveryId) {

            // 购物车选择改变字段,重新运算订单数据
            return this.ctx.req.ctx(shoppingModel).orderComputeAPI({
                uid: uid,
                cart_type: cartType,
                delivery_way: deliveryId,
                payment_type: paymentType,
                coupon_code: couponCode,
                use_yoho_coin: yohoCoin,
                product_sku_list: skuList
            }).then(result => {
                return paymentProcess.transformJit(_.get(result, 'data.package_list', []));
            });
        } else {
            return this.ctx.req.ctx(shoppingModel).cartPayAPI({
                uid: uid,
                cart_type: cartType,
                product_sku_list: skuList
            }).then(result => {
                return paymentProcess.transformJit(_.get(result, 'data.shopping_cart_data.package_list', []));
            });
        }
    }
}

module.exports = cartModel;