#include "JsonModule.h"
#include "../utility/utility.h"
#include "../3rdParty/rapidjson/rapidjson.h"
#include "../3rdParty/rapidjson/document.h"
#include "../3rdParty/rapidjson/reader.h"
#include "../3rdParty/rapidjson/writer.h"
#include "../3rdParty/rapidjson/stringbuffer.h"
#include "../3rdParty/easylogging/easylogging++.h"

#include <iostream>

using namespace rapidjson;

// std::string GetTestJson(const int statuscode,const char* msg,const char* orderid)
// {
//     rapidjson::StringBuffer buffer;
//     rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
//     writer.StartObject();

//     writer.Key("statusCode");
//     writer.Int(statuscode);

//     writer.Key("msg");
//     writer.String(msg);

//     writer.Key("orderid");
//     writer.String(orderid);   

//     writer.EndObject();

//     return buffer.GetString();
// }

// void parseJson(const char* json)
// {
//     rapidjson::Document document; // 定义一个Document对象
//     document.Parse(json); // 解析，Parse()无返回值，也不会抛异常
//     if (document.HasParseError()) // 通过HasParseError()来判断解析是否成功
//     {
//         // 可通过GetParseError()取得出错代码，
//         // 注意GetParseError()返回的是一个rapidjson::ParseErrorCode类型的枚举值
//         // 使用函数rapidjson::GetParseError_En()得到错误码的字符串说明，这里的En为English简写
//         // 函数GetErrorOffset()返回出错发生的位置
//         LOG(ERROR)<<"JSON parse error:"<<document.GetParseError()<<":"<<document.GetErrorOffset();
//     }
//     else
//     {
//         rapidjson::Value& vStatusCode = document["statusCode"];
//         rapidjson::Value& vMsg = document["msg"];
//         rapidjson::Value& vOrderid = document["orderid"];

//         int iStatusCode = vStatusCode.GetInt();
//         std::string strMsg = vMsg.GetString();
//         std::string strOrderid = vOrderid.GetString();
    
//         LOG(INFO)<<"statusCode:"<<iStatusCode;
//         LOG(INFO)<<"msg:"<<strMsg;
//         LOG(INFO)<<"orderId:"<<strOrderid;
//     }
// }

JsonModule::JsonModule()
{

}

JsonModule::~JsonModule()
{

}

const char* GetJsonStringSafe(rapidjson::Value& obj,const char* key)
{
    if(obj.HasMember(key)){
        rapidjson::Value& vObj = obj[key];
        if(vObj.IsString()){
            return vObj.GetString();  
        }
    }
    return "";
}

int GetJsonIntSafe(rapidjson::Value& obj,const char* key)
{
    if(obj.HasMember(key)){
        rapidjson::Value& vObj = obj[key];
        if(vObj.IsInt()){
            return vObj.GetInt();  
        }
    }
    return 0;
}

void JsonModule::jsonTest()
{
    std::string json="{\"title\":\"PLAYER INFO\",\"num\":null,\"players\":[{ \"id\":123,\"name\":\"test\"}]}";
    rapidjson::Document document; // 定义一个Document对象
    document.Parse(json.data()); // 解析，Parse()无返回值，也不会抛异常
    if (document.HasParseError()) // 通过HasParseError()来判断解析是否成功
    {
        // 可通过GetParseError()取得出错代码，
        // 注意GetParseError()返回的是一个rapidjson::ParseErrorCode类型的枚举值
        // 使用函数rapidjson::GetParseError_En()得到错误码的字符串说明，这里的En为English简写
        // 函数GetErrorOffset()返回出错发生的位置
        LOG(ERROR)<<"JSON parse error:"<<document.GetParseError()<<":"<<document.GetErrorOffset();
    }
    else
    {
        rapidjson::Value& vTitle = document["title"];
        rapidjson::Value& vNum = document["num"];
        LOG(INFO)<<"title:"<<GetJsonStringSafe(document,"title");
        LOG(INFO)<<"num:"<<GetJsonStringSafe(document,"num");
        rapidjson::Value& vPlayers = document["players"];
        if(vPlayers.IsArray())
        {
            for(unsigned int i=0;i<vPlayers.Size();i++){
                rapidjson::Value& players_obj = vPlayers[i];

                LOG(INFO)<<"id:"<<GetJsonStringSafe(players_obj,"id");
                LOG(INFO)<<"name:"<<GetJsonStringSafe(players_obj,"name");
            }
        }
    }    
}

bool JsonModule::getPushOrders(IN const char* json,OUT orderObj &order)
{ 
    rapidjson::Document document; // 定义一个Document对象
    document.Parse(json); // 解析，Parse()无返回值，也不会抛异常
    if (document.HasParseError()) // 通过HasParseError()来判断解析是否成功
    {
        // 可通过GetParseError()取得出错代码，
        // 注意GetParseError()返回的是一个rapidjson::ParseErrorCode类型的枚举值
        // 使用函数rapidjson::GetParseError_En()得到错误码的字符串说明，这里的En为English简写
        // 函数GetErrorOffset()返回出错发生的位置
        LOG(ERROR)<<"getPushOrders JSON parse error:"<<document.GetParseError()<<":"<<document.GetErrorOffset();
        return false;
    }
    else
    {
        rapidjson::Value& channel = document["channel"];
        order.channel=channel.GetString();

        if(document.HasMember("offlinePoints")){
            rapidjson::Value& offlinePoints = document["offlinePoints"];
            order.offline_bonus=offlinePoints.GetBool(); 
        }

        GetJsonStringSafe(document,"token");
        GetJsonStringSafe(document,"ver");

        //配送信息
        std::string delivery_type;
        if(document.HasMember("delivery"))
        {
            rapidjson::Value& delivery_obj = document["delivery"];
            if(delivery_obj.IsObject())
            {
                order.customerInfo.address=GetJsonStringSafe(delivery_obj,"customerAddress");
                order.customerInfo.name=GetJsonStringSafe(delivery_obj,"customerName");
                order.customerInfo.phone=GetJsonStringSafe(delivery_obj,"customerPhone");
                order.delivery_time=GetJsonStringSafe(delivery_obj,"deliveryTime");
                order.deliveryInfo.driver_name=GetJsonStringSafe(delivery_obj,"name");
                order.deliveryInfo.driver_phone=GetJsonStringSafe(delivery_obj,"phone");
                order.deliveryInfo.type=GetJsonStringSafe(delivery_obj,"type");
                delivery_type=GetJsonStringSafe(delivery_obj,"type");
            }
        }
            
        //发票信息
        if(document.HasMember("invoice"))
        {
            rapidjson::Value& invoice_obj = document["invoice"];
            if(invoice_obj.IsObject())
            {
                GetJsonStringSafe(invoice_obj,"companyName");
                GetJsonStringSafe(invoice_obj,"taxNum");
                GetJsonStringSafe(invoice_obj,"title");
                order.invoice_pickup_code = GetJsonStringSafe(invoice_obj,"transNum");

                GetJsonIntSafe(invoice_obj,"invoiceType");
            }   
        }
        //订单内容
        {
            rapidjson::Value& orderContent_obj = document["orderContent"];
        
            order.create_time = GetJsonStringSafe(orderContent_obj,"createTime");

            //用户信息
            //TODO 顾客信息为数组 因接口改版目前只有一个顾客信息
            if(orderContent_obj.HasMember("customer"))
            {
                rapidjson::Value& customer_array = orderContent_obj["customer"];
                if(customer_array.IsArray())
                {
                    for(unsigned int i=0;i<customer_array.Size();i++){
                        rapidjson::Value& customer_obj = customer_array[i];

                        order.customerInfo.account = GetJsonStringSafe(customer_obj,"accountId");
                        order.customerInfo.account_type = atoi(GetJsonStringSafe(customer_obj,"accountType"));
                        order.customerInfo.account_level = GetJsonStringSafe(customer_obj,"level");
                    }
                }
            }

            //自配送
            if("2"==delivery_type){
                order.delivery_price = GetJsonIntSafe(orderContent_obj,"deliveryFee"); 
                order.total_price = GetJsonIntSafe(orderContent_obj,"totalAmount");   
            }
            else{
                order.delivery_price=0;
                order.total_price = GetJsonIntSafe(orderContent_obj,"totalAmount")-GetJsonIntSafe(orderContent_obj,"deliveryFee"); 
            }

            order.wmDiscount=GetJsonIntSafe(orderContent_obj,"wmDiscount");
            order.wmPtSharedDiscount=GetJsonIntSafe(orderContent_obj,"wmPtSharedDiscount");
            order.wmSjSharedDiscount=GetJsonIntSafe(orderContent_obj,"wmSjSharedDiscount");
              

            //订单信息
            if(orderContent_obj.HasMember("orders"))
            {
                rapidjson::Value& orders_obj = orderContent_obj["orders"];

                order.deliveryInfo.status = atoi(GetJsonStringSafe(orders_obj,"deliveryStatus"));
                order.deliveryInfo.status_desc = GetJsonStringSafe(orders_obj,"deliveryStatusDesc");     
                
                order.order_id = GetJsonStringSafe(orders_obj,"orderId");  
                std::string pickupcode= GetJsonStringSafe(orders_obj,"pickupCode");  
                order.pickup_code= _getPickupCodeString(order.channel,pickupcode);
                order.pickup_point = GetJsonStringSafe(orders_obj,"pickupPoint");  

                order.remark = GetJsonStringSafe(orders_obj,"remark");

                order.status = atoi(GetJsonStringSafe(orders_obj,"status"));  
                order.ods_status=order.status;

                // int iCancelStatus = atoi(GetJsonStringSafe(orders_obj,"cancelStatus"));
                // if(ODS_ORDERSTATUS_REFUND_FULL==iCancelStatus||ODS_ORDERSTATUS_REFUND_AGREE==iCancelStatus||ODS_ORDERSTATUS_REFUND_DISAGREE==iCancelStatus){
                //     order.status=iCancelStatus;
                //     order.ods_status=order.status;
                // }

                order.status_desc = GetJsonStringSafe(orders_obj,"statusDesc");  

                //订单商品 
                if(orders_obj.HasMember("products"))
                {
                    rapidjson::Value& products_array = orders_obj["products"];
                    if(products_array.IsArray())
                    {
                        for(unsigned int i=0;i<products_array.Size();i++){
                            rapidjson::Value& product_obj = products_array[i];

                            productAttr structProduct;

                            structProduct.pro.attributes = GetJsonStringSafe(product_obj,"attributes");
                            structProduct.pro.combo_id = GetJsonStringSafe(product_obj,"catgId");
                            structProduct.pro.bom_id = GetJsonStringSafe(product_obj,"groupIndex");
                            structProduct.pro.name = GetJsonStringSafe(product_obj,"name");
                            structProduct.pro.price = GetJsonIntSafe(product_obj,"price");
                            GetJsonStringSafe(product_obj,"productType");
                            structProduct.pro.qty = GetJsonIntSafe(product_obj,"qty");
                            structProduct.pro.sku = GetJsonStringSafe(product_obj,"sku");
                            structProduct.pro.source = GetJsonStringSafe(product_obj,"source");

                            //子商品信息
                            if(product_obj.HasMember("specs"))
                            {
                                rapidjson::Value& specs_array = product_obj["specs"];
                                if(specs_array.IsArray())
                                {
                                    for(unsigned int i=0;i<specs_array.Size();i++){
                                        rapidjson::Value& specs_obj = specs_array[i];

                                        productSpec structProductSpec;
                                        structProductSpec.name = GetJsonStringSafe(specs_obj,"name");                                        
                                        structProductSpec.price = GetJsonIntSafe(specs_obj,"price");                                        
                                        structProductSpec.qty = GetJsonIntSafe(specs_obj,"qty");
                                        structProductSpec.sku = GetJsonStringSafe(specs_obj,"sku");

                                        structProduct.vecSpec.push_back(structProductSpec);
                                    }
                                }
                            }
                            order.vecProducts.push_back(structProduct);
                        }
                    }
                }
            }
            //支付信息
            if(orderContent_obj.HasMember("payInfos"))
            {
                //sumary未映射字段值
                rapidjson::Value& payInfos_array = orderContent_obj["payInfos"];
                if(payInfos_array.IsArray())
                {
                    for(unsigned int i=0;i<payInfos_array.Size();i++){
                        rapidjson::Value& payInfos_obj = payInfos_array[i];
                        paymentDetail detail;

                        detail.amount = GetJsonIntSafe(payInfos_obj,"amount");
                        //非自配送，第一种支付方式减去配送费
                        if("2"!=delivery_type&&0==i){
                            detail.amount = GetJsonIntSafe(payInfos_obj,"amount")-GetJsonIntSafe(orderContent_obj,"deliveryFee");
                        }

                        //支付类型需要拼接 channel+payType
                        std::string _strType=order.channel+GetJsonStringSafe(payInfos_obj,"payType");
                        detail.type = atoi(_strType.data());
                        detail.trans_id = GetJsonStringSafe(payInfos_obj,"transNum");
                        detail.account_id=GetJsonStringSafe(payInfos_obj,"accountId");

                        order.payInfo.vecDetail.push_back(detail);
                    }
                }
            }

            GetJsonStringSafe(orderContent_obj,"payType");

            //优惠信息
            if(orderContent_obj.HasMember("promotions"))
            {
                rapidjson::Value& promotions_obj = orderContent_obj["promotions"];
                if(promotions_obj.IsObject())
                {
                    GetJsonIntSafe(promotions_obj,"totalDiscount");
                    GetJsonIntSafe(promotions_obj,"totalOriginalPrice");
                    GetJsonIntSafe(promotions_obj,"totalPromotionPrice");

                    //优惠信息详情
                    if(promotions_obj.HasMember("promtionDetails"))
                    {
                        rapidjson::Value& promtionDetails_array = promotions_obj["promtionDetails"];
                        if(promtionDetails_array.IsArray())
                        {
                            for(unsigned int i=0;i<promtionDetails_array.Size();i++){
                                rapidjson::Value& promtionDetails_obj = promtionDetails_array[i];

                                promotions detail;
                                detail.pcode = GetJsonStringSafe(promtionDetails_obj,"pcode");
                                detail.proType = GetJsonStringSafe(promtionDetails_obj,"type");
                                detail.desc = GetJsonStringSafe(promtionDetails_obj,"desc");                                
                                detail.sku = GetJsonStringSafe(promtionDetails_obj,"sku");
                                detail.originalPrice = GetJsonIntSafe(promtionDetails_obj,"originalPrice");
                                detail.promotionPrice = GetJsonIntSafe(promtionDetails_obj,"promotionPrice");
                                detail.discount = GetJsonIntSafe(promtionDetails_obj,"discount");
                                if(promtionDetails_obj.HasMember("gifts")){
                                    rapidjson::Value& gifts_obj = orderContent_obj["gifts"];
                                    if(gifts_obj.IsObject()){
                                        detail.giftSku = GetJsonStringSafe(gifts_obj,"sku");
                                        detail.giftQty = GetJsonIntSafe(gifts_obj,"qty");
                                    }
                                }
                                order.vecPromotions.push_back(detail);
                            } 
                        }
                    }
                }
            }

            //积分信息
            if(orderContent_obj.HasMember("points"))
            {
                rapidjson::Value& points_obj = orderContent_obj["points"];
                if(points_obj.IsObject())
                {
                    std::to_string(GetJsonIntSafe(points_obj,"totalPoint"));
                    //积分信息详情
                    if(points_obj.HasMember("pointDetails"))
                    {
                        rapidjson::Value& pointDetails_array = points_obj["pointDetails"];
                        if(pointDetails_array.IsArray())
                        {
                            for(unsigned int i=0;i<pointDetails_array.Size();i++){
                                rapidjson::Value& pointDetails_obj = pointDetails_array[i];

                                bonus detail;
                                detail.pcode = GetJsonStringSafe(pointDetails_obj,"pcode");
                                detail.desc = GetJsonStringSafe(pointDetails_obj,"desc");
                                detail.bonus = GetJsonIntSafe(pointDetails_obj,"point");
                                detail.name = GetJsonStringSafe(pointDetails_obj, "name");
                                detail.sku = GetJsonStringSafe(pointDetails_obj,"sku");
                                detail.proType = GetJsonStringSafe(pointDetails_obj,"type");
                                if("00"==detail.proType){
                                    detail.proType="CP";
                                }

                                order.vecBonus.push_back(detail);
                            }
                        }
                    }
                }
            }


            //电子点标
            if(orderContent_obj.HasMember("ecouponVos"))
            {
                rapidjson::Value& ecouponVos_array = orderContent_obj["ecouponVos"];
                if(ecouponVos_array.IsArray())
                {
                    for(unsigned int i=0;i<ecouponVos_array.Size();i++){
                        rapidjson::Value& ecouponVos_obj = ecouponVos_array[i];
                        ecoupon detail;
                        detail.ecouponNumber = GetJsonStringSafe(ecouponVos_obj,"couponNumber");
                        detail.name = GetJsonStringSafe(ecouponVos_obj,"name");
                        detail.pcode = GetJsonStringSafe(ecouponVos_obj,"pcode");
                        detail.proType = GetJsonStringSafe(ecouponVos_obj,"type");
                        detail.ecouponQty = GetJsonIntSafe(ecouponVos_obj,"qty");

                        order.vecEcoupon.push_back(detail);
                    }
                }
            }

            GetJsonStringSafe(orderContent_obj,"sessionId");
            order.reduced_price = GetJsonIntSafe(orderContent_obj,"totalDiscount");

        }
        //第三方商户信息
        if(document.HasMember("sellerInfo"))
        {
            rapidjson::Value& sellerInfo_obj = document["sellerInfo"];
            if(sellerInfo_obj.IsObject())
            {
                GetJsonStringSafe(sellerInfo_obj,"sellerId");
                GetJsonStringSafe(sellerInfo_obj,"sellerName");
            }
            
        }
        //门店信息
        if(document.HasMember("shopInfo"))
        {
            rapidjson::Value& shopInfo_obj = document["shopInfo"];
            if(shopInfo_obj.IsObject()){
                GetJsonStringSafe(shopInfo_obj,"barCounter");
                GetJsonStringSafe(shopInfo_obj,"operator");
                order.storeInfo.pos_id = GetJsonStringSafe(shopInfo_obj,"posId");
                order.storeInfo.store_id = GetJsonStringSafe(shopInfo_obj,"storeId");

                //自助机信息
                rapidjson::Value& selfHelpMac_obj = shopInfo_obj["selfHelpMac"];
                if(selfHelpMac_obj.IsObject()){
                    order.storeInfo.vem_id = GetJsonStringSafe(selfHelpMac_obj,"id");
                    order.storeInfo.vem_shelf = GetJsonStringSafe(selfHelpMac_obj,"shelf");
                }
            }
        }

    }
    return true;
}

bool JsonModule::isInitData(const std::string &data)
{
    rapidjson::Document document; // 定义一个Document对象
    document.Parse(data.c_str()); // 解析，Parse()无返回值，也不会抛异常
    if (document.HasParseError()) // 通过HasParseError()来判断解析是否成功
    {
        LOG(ERROR) << "isInitData JSON parse error:" << document.GetParseError() << ":" << document.GetErrorOffset();
        return false;
    }
    return document["fm_cmd"].GetInt() == 1000;
}

bool JsonModule::isHeartbeatData(IN const char* data)
{
    rapidjson::Document document; // 定义一个Document对象
    document.Parse(data); // 解析，Parse()无返回值，也不会抛异常
    if (document.HasParseError()) // 通过HasParseError()来判断解析是否成功
    {
        LOG(ERROR) << "isHeartbeatData JSON parse error:" << document.GetParseError() << ":" << document.GetErrorOffset();
        return false;
    }
    if(document.HasMember("fm_cmd")){
        if(document["fm_cmd"].GetInt() == 3)
            return true;
    }
    return false;
}

bool JsonModule::checkInitData(const std::string &data, int &posListenPort)
{
    rapidjson::Document document; // 定义一个Document对象
    document.Parse(data.c_str()); // 解析，Parse()无返回值，也不会抛异常
    if (document.HasParseError()) // 通过HasParseError()来判断解析是否成功
    {
        LOG(ERROR) << "checkInitData JSON parse error:" << document.GetParseError() << ":" << document.GetErrorOffset();
        return false;
    }

    if( !document.HasMember("store_id")
            || !document.HasMember("pos_id")
            || !document.HasMember("operator_id")
            || !document.HasMember("is_master")
            || document["listen_port"].GetInt()< 0 )
    {
        return false;
    }

    posListenPort = document["listen_port"].GetInt();
    return true;
}

bool JsonModule::convertInitDataPos2Ods(IN const std::string& data, OUT std::string& result)
{  
    rapidjson::Document document; // 定义一个Document对象
    document.Parse(data.c_str()); // 解析，Parse()无返回值，也不会抛异常
    if (document.HasParseError()) // 通过HasParseError()来判断解析是否成功
    {
        LOG(ERROR) << "convertInitDataPos2Ods JSON parse error:" << document.GetParseError() << ":" << document.GetErrorOffset();
        return false;
    }

    int fm_cmd = document["fm_cmd"].GetInt();
    int listen_port = document["listen_port"].GetInt();
    std::string store_id = document["store_id"].GetString();
    std::string pos_id = document["pos_id"].GetString();
    std::string operator_id = document["operator_id"].GetString();
    bool is_master = document["is_master"].GetBool();

    rapidjson::StringBuffer buffer;
    rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
    writer.StartObject();

    writer.Key("fm_cmd");
    writer.Int(fm_cmd);

    writer.Key("listen_port");
    writer.Int(listen_port);

    writer.Key("storeId");    //中台命名
    writer.String(store_id.data());

    writer.Key("pos_id");
    writer.String(pos_id.data());   

    writer.Key("operator_id");
    writer.String(operator_id.data());   

    writer.Key("is_master");
    writer.Bool(is_master);   

    writer.Key("ver");
    writer.Int(1);   

    writer.EndObject();

    result = buffer.GetString();


    return true;
}

bool JsonModule::getInitBackData(IN const char* inJson,OUT std::string& outJson)
{
    rapidjson::Document document; // 定义一个Document对象
    document.Parse(inJson); // 解析，Parse()无返回值，也不会抛异常
    if (document.HasParseError()) // 通过HasParseError()来判断解析是否成功
    {
        LOG(ERROR) << "getInitBackData JSON parse error:" << document.GetParseError() << ":" << document.GetErrorOffset();
        return false;
    }

    if(document.HasMember("code"))
    {
        int status_code=0,autoconfirm=0;
        std::string default_pos,msg;

        rapidjson::Value& code = document["code"];
        status_code = atoi(code.GetString());

        autoconfirm = GetJsonIntSafe(document,"orderConfirmType");
        default_pos = GetJsonStringSafe(document,"orderPushPosIndex");

        // if(document.HasMember("message")){
        //     msg = document["message"].GetString();
        // }
        if(status_code==100){
            msg="success";
        }
        else{
            msg="failed";
        }

        rapidjson::StringBuffer buffer;
        rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
        writer.StartObject();

        writer.Key("status_code");
        writer.Int(status_code);

        writer.Key("autoconfirm");
        writer.Int(autoconfirm);

        writer.Key("default_pos");
        writer.String(default_pos.c_str());

        writer.Key("msg");
        writer.String(msg.c_str());

        writer.EndObject();

        outJson = buffer.GetString();
        
        return true;
    }
    return false;
}

bool JsonModule::getPosResponseData(int status, const std::string &msg, std::string &result)
{
    rapidjson::StringBuffer buffer;
    rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
    writer.StartObject();

    writer.Key("status_code");
    writer.Int(status);

    writer.Key("msg");
    writer.String(msg.c_str());

    writer.EndObject();

    result = buffer.GetString();
    return true;
}

bool JsonModule::getPosResponseData(const std::string &odsResponse,IN const std::string& posReq, std::string &result)
{
    bool rlt=false;
    rapidjson::Document document; // 定义一个Document对象
    document.Parse(posReq.c_str()); // 解析，Parse()无返回值，也不会抛异常
    if (document.HasParseError()) // 通过HasParseError()来判断解析是否成功
    {
        LOG(ERROR) << "getPosResponseData JSON parse error:" << document.GetParseError() << ":" << document.GetErrorOffset();
        return false;
    }

    if( !document.HasMember("fm_cmd"))
    {
        LOG(INFO)<<"Don't have fm_cmd";
        return false;
    }
    int fm_cmd = document["fm_cmd"].GetInt();
    
    if(fm_cmd==OPERATION_POS_CONFIRM
        ||fm_cmd==OPERATION_POS_CANCEL
        ||fm_cmd==OPERATION_POS_REFUND_AGREE
        ||fm_cmd==OPERATION_POS_REFUND_DISAGREE)
    {
       result = _convertToOrderOperationReponseJson(odsResponse.data());
       rlt=true;
    }

    // serverResponseOperationObj obj;
    // if(_getServerResponseData(odsResponse.data(),obj)){
    //     result=_convertServerResponseToJson(obj);
    //     return true;
    // }
    return rlt;
    //result = "{\"status_code\":100, \"msg\":\"\"}";
}

std::string JsonModule::_convertToOrderOperationReponseJson(IN const char* json)
{
    int status_code=0,status=0;
    std::string msg,status_desc;
    rapidjson::Document document; // 定义一个Document对象
    document.Parse(json); // 解析，Parse()无返回值，也不会抛异常
    if (document.HasParseError()) // 通过HasParseError()来判断解析是否成功
    {
        LOG(ERROR)<<"_convertToOrderOperationReponseJson JSON parse error:"<<document.GetParseError()<<":"<<document.GetErrorOffset();
    }
    else
    {
        std::string code = document["code"].GetString();
        status_code=atoi(code.c_str());

        msg = GetJsonStringSafe(document,"message");

        if(document.HasMember("result"))
        {
            rapidjson::Value& result_obj = document["result"];
            if(result_obj.IsObject())
            {
                int iStatus=atoi(GetJsonStringSafe(result_obj,"status"));
                status = _getPOSOrderStatus(iStatus);
                status_desc = GetJsonStringSafe(result_obj,"status_desc");
            }
        }

    }
    rapidjson::StringBuffer buffer;
    rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
    writer.StartObject();

    writer.Key("status_code");
    writer.Int(status_code);

    writer.Key("msg");
    writer.String(msg.c_str());

    writer.Key("status");
    writer.Int(status);

    writer.Key("status_desc");
    writer.String(status_desc.data());

    writer.EndObject();

    return buffer.GetString();
}

bool JsonModule::getOdsResponseData(int status_code, const std::string &msg, std::string &result)
{
    /*
    {
        "fm_cmd" : 2,
        "order_id" : "xxxxx",
        "status" : 1,
        "status_code" : 100,
        "msg" : "接收订单成功"
    }
    */
    rapidjson::StringBuffer buffer;
    rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
    writer.StartObject();

    writer.Key("fm_cmd");
    writer.Int(2);

    writer.Key("order_id");
    writer.String("");

    writer.Key("status");
    writer.Int(0);

    writer.Key("status_code");
    writer.Int(status_code);

    writer.Key("msg");
    writer.String(msg.c_str());

    writer.EndObject();

    result = buffer.GetString();
    return true;
}

 bool JsonModule::getOdsResponseData(IN const std::string& posResponse, IN const std::string& orderData,IN const std::string& odsData, OUT std::string& result)
 {
    if( posResponse.empty() || orderData.empty() || odsData.empty()){
        LOG(INFO)<<"getOdsResponseData empty input";
        return false;
    }

    rapidjson::Document document, document1,document2;
    document.Parse(posResponse.c_str());
    document1.Parse(orderData.c_str());
    document2.Parse(odsData.c_str());
    if (document.HasParseError() || document1.HasParseError() || document2.HasParseError())
    {
        LOG(INFO)<<"getOdsResponseData posResponse JSON parse error:"<<document.GetParseError()<<":"<<document.GetErrorOffset();
        return false;
    }

    if( !document1.HasMember("fm_cmd") )
    {
        LOG(INFO)<<"Don't have needed parames.";
        return false;
    }

    int fm_cmd = document1["fm_cmd"].GetInt();
    LOG(INFO)<<"fm_cmd:"<<fm_cmd;
    bool rlt=false;
    if(fm_cmd==REQUEST_TYPE_NEWORDER_PUSH){
        rlt=_getOrderResponseJson(posResponse,orderData,odsData,result);
    }
    else if(fm_cmd==REQUEST_TYPE_STOCK_WARN){
        rlt=_getStockWarnResponseJson(posResponse,orderData,odsData,result);
    }
    else if(fm_cmd==REQUEST_TYPE_COMMON_WARN){
        rlt=_getCommonWarnResponseJson(posResponse,orderData,odsData,result);
    }
 
    return rlt;
 }

bool JsonModule::convertDataPos2Ods(const std::string &data, std::string &result)
{
    if( data.empty()){
        LOG(INFO)<<"convertDataPos2Ods empty input";
        return false;
    }

    rapidjson::Document document;
    document.Parse(data.c_str());
    if (document.HasParseError())
    {
        LOG(INFO)<<"convertDataPos2Ods posResponse JSON parse error:"<<document.GetParseError()<<":"<<document.GetErrorOffset();
        return false;
    }

    if( !document.HasMember("fm_cmd") )
    {
        LOG(INFO)<<"Don't have needed parames.";
        return false;
    }

    int fm_cmd = document["fm_cmd"].GetInt();
    LOG(INFO)<<"fm_cmd:"<<fm_cmd;
    bool rlt=false;

    if(fm_cmd==OPERATION_POS_CONFIRM
        ||fm_cmd==OPERATION_POS_CANCEL
        ||fm_cmd==OPERATION_POS_REFUND_AGREE
        ||fm_cmd==OPERATION_POS_REFUND_DISAGREE)
    {
        orderOperationObj obj;
        if(_getPOSOperationObj(data.data(),obj)){
            result=_convertPosOperationToOdsJson(obj);
            rlt = true;
        }
    }
    else if(fm_cmd==REQUEST_TYPE_GOODS_CHANGE){

    }


    return rlt;
}

bool JsonModule::convertDataOds2Pos(const std::string &data, std::string &result)
{
    bool rlt=true;
    int pushType=getPushType(data.c_str());

    if(pushType==ODS_PUSH_TYPE_STOCKWARN){  //库存预警
        stockWarnObj warn_obj;
        _getStockWarnObj(data.c_str(),warn_obj);

        result = _convertToStockWarnJson(warn_obj);
    }
    else if(pushType==ODS_PUSH_TYPE_COMMON){
        result = _convertToCommonWarnJson(data.c_str());
    }
    else if(pushType==ODS_PUSH_TYPE_ORDER){
        orderObj order;
        rlt = getPushOrders(data.c_str(),order);
        
        if(rlt)
        {
            result = _convertToNewOrderJson(order);
        }
    }

    
    return rlt;
}

std::string JsonModule::_convertToNewOrderJson(orderObj &obj)
{
    rapidjson::StringBuffer buffer;
    rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
    writer.StartObject();

    writer.Key("fm_cmd");
    writer.Int(REQUEST_TYPE_NEWORDER_PUSH);

    writer.Key("channel");
    writer.String(obj.channel.c_str());

    writer.Key("offline_bonus");
    writer.Bool(obj.offline_bonus);

    writer.Key("order_no");
    writer.Int(obj.order_no);   

    writer.Key("order_id");
    writer.String(obj.order_id.c_str());

    writer.Key("create_time");
    writer.String(obj.create_time.c_str());

    writer.Key("delivery_time");
    writer.String(obj.delivery_time.c_str());

    writer.Key("status");
    writer.Int(_getPOSOrderStatus(obj.status)); 

    writer.Key("ods_status");
    writer.Int(obj.ods_status);

    writer.Key("status_desc");
    writer.String(obj.status_desc.c_str());

    writer.Key("remark");
    writer.String(obj.remark.c_str());

    writer.Key("total_price");
    writer.Int(obj.total_price);  

    writer.Key("delivery_price");
    writer.Int(obj.delivery_price);  

    writer.Key("reduced_price");
    writer.Int(obj.reduced_price);  

    writer.Key("wmDiscount");
    writer.Int(obj.wmDiscount);  

    writer.Key("wmPtSharedDiscount");
    writer.Int(obj.wmPtSharedDiscount);  

    writer.Key("wmSjSharedDiscount");
    writer.Int(obj.wmSjSharedDiscount);  

    writer.Key("pickup_code");
    writer.String(obj.pickup_code.c_str());

    writer.Key("pickup_point");
    writer.String(obj.pickup_point.c_str());

    writer.Key("invoice_pickup_code");
    writer.String(obj.invoice_pickup_code.c_str());

    //----------------门店信息----------------
    writer.Key("store");
    writer.StartObject();

    writer.Key("store_id");
    writer.String(obj.storeInfo.store_id.c_str());

    writer.Key("pos_id");
    writer.String(obj.storeInfo.pos_id.c_str());

    writer.Key("vem_id");
    writer.String(obj.storeInfo.vem_id.c_str());

    writer.Key("vem_shelf");
    writer.String(obj.storeInfo.vem_shelf.c_str());

    writer.EndObject();
    //----------------门店信息 结束-----------
    
    //----------------配送信息----------------
    writer.Key("delivery");
    writer.StartObject();

    writer.Key("type");
    writer.String(obj.deliveryInfo.type.c_str());

    writer.Key("status");
    writer.Int(obj.deliveryInfo.status);

    writer.Key("status_desc");
    writer.String(obj.deliveryInfo.status_desc.c_str());

    writer.Key("driver_name");
    writer.String(obj.deliveryInfo.driver_name.c_str());

    writer.Key("driver_phone");
    writer.String(obj.deliveryInfo.driver_phone.c_str());

    writer.EndObject();
    //----------------配送信息 结束-----------

    //----------------顾客信息----------------
    writer.Key("customer");
    writer.StartObject();

    writer.Key("name");
    writer.String(obj.customerInfo.name.c_str());

    writer.Key("phone");
    writer.String(obj.customerInfo.phone.c_str());

    writer.Key("address");
    writer.String(obj.customerInfo.address.c_str());

    writer.Key("account");
    writer.String(obj.customerInfo.account.c_str());

    writer.Key("account_type");
    writer.Int(obj.customerInfo.account_type);

    writer.Key("account_level");
    writer.String(obj.customerInfo.account_level.c_str());

    writer.EndObject();
    //----------------顾客信息 结束-----------
    
    //----------------商品信息----------------
    writer.Key("products");
    writer.StartArray();

    for(unsigned int i=0;i<obj.vecProducts.size();i++) 
    {
        //-----------------start 单个商品------------------
        writer.StartObject();

        writer.Key("source");
        writer.String(obj.vecProducts[i].pro.source.c_str());

        writer.Key("attributes");
        writer.String(obj.vecProducts[i].pro.attributes.c_str());

        writer.Key("combo_id");
        writer.String(obj.vecProducts[i].pro.combo_id.c_str());

        writer.Key("bom_id");
        writer.String(obj.vecProducts[i].pro.bom_id.c_str());

        writer.Key("bag_id");
        writer.String(obj.vecProducts[i].pro.bag_id.c_str());

        writer.Key("name");
        writer.String(obj.vecProducts[i].pro.name.c_str());

        writer.Key("price");
        writer.Int(obj.vecProducts[i].pro.price);

        writer.Key("qty");
        writer.Int(obj.vecProducts[i].pro.qty);

        writer.Key("sku");
        writer.String(obj.vecProducts[i].pro.sku.c_str());

        //-----------------start 商品规格------------------
        writer.Key("specs");
        writer.StartArray();
        for(unsigned int j=0;j<obj.vecProducts[i].vecSpec.size();j++) 
        {
            writer.StartObject();

            writer.Key("name");
            writer.String(obj.vecProducts[i].vecSpec[j].name.c_str());

            writer.Key("price");
            writer.Int(obj.vecProducts[i].vecSpec[j].price);

            writer.Key("qty");
            writer.Int(obj.vecProducts[i].vecSpec[j].qty);

            writer.Key("sku");
            writer.String(obj.vecProducts[i].vecSpec[j].sku.c_str());

            writer.EndObject();
        }
        writer.EndArray();
        //-----------------end 商品规格--------------------

        writer.EndObject();
        //-----------------end 单个商品------------------
    }
    
    writer.EndArray();
    //----------------商品信息 结束-----------
    
    //----------------付款明细----------------
    writer.Key("payment");
    writer.StartObject();

    writer.Key("summary");
    writer.String(obj.payInfo.summary.c_str());

    //-----------------start 付款详情------------------
    writer.Key("details");
    writer.StartArray();
    for(unsigned int i=0;i<obj.payInfo.vecDetail.size();i++) 
    {
        writer.StartObject();

        writer.Key("amount");
        writer.Int(obj.payInfo.vecDetail[i].amount);

        writer.Key("type");
        writer.Int(obj.payInfo.vecDetail[i].type);

        writer.Key("trans_id");
        writer.String(obj.payInfo.vecDetail[i].trans_id.c_str());
        
        writer.Key("account_id");
        writer.String(obj.payInfo.vecDetail[i].account_id.c_str());

        writer.EndObject();
    }
    writer.EndArray();
    //-----------------end 付款详情--------------------    

    writer.EndObject();
    //----------------付款明细 结束-----------

    //----------------消费积分----------------
    writer.Key("bonus");
    writer.StartArray();
    for(unsigned int i=0;i<obj.vecBonus.size();i++) 
    {
        writer.StartObject();
        
        writer.Key("pcode");
        writer.String(obj.vecBonus[i].pcode.c_str());

        writer.Key("proType");
        writer.String(obj.vecBonus[i].proType.c_str());

        writer.Key("type");
        writer.String(obj.vecBonus[i].type.c_str());

        writer.Key("desc");
        writer.String(obj.vecBonus[i].desc.c_str());

        writer.Key("name");
        writer.String(obj.vecBonus[i].name.c_str());

        writer.Key("sku");
        writer.String(obj.vecBonus[i].sku.c_str());

        writer.Key("bonus");
        writer.Int(obj.vecBonus[i].bonus);

        writer.EndObject();
    }
    writer.EndArray();
    //----------------消费积分 结束-----------

    //----------------促销----------------
    writer.Key("promotions");
    writer.StartArray();
    for(unsigned int i=0;i<obj.vecPromotions.size();i++) 
    {
        writer.StartObject();
        
        writer.Key("pcode");
        writer.String(obj.vecPromotions[i].pcode.c_str());

        writer.Key("proType");
        writer.String(obj.vecPromotions[i].proType.c_str());

        writer.Key("type");
        writer.String(obj.vecPromotions[i].type.c_str());

        writer.Key("desc");
        writer.String(obj.vecPromotions[i].desc.c_str());

        writer.Key("name");
        writer.String(obj.vecPromotions[i].name.c_str());

        writer.Key("sku");
        writer.String(obj.vecPromotions[i].sku.c_str());

        writer.Key("originalPrice");
        writer.Int(obj.vecPromotions[i].originalPrice);

        writer.Key("discount");
        writer.Int(obj.vecPromotions[i].discount);

        writer.Key("promotionPrice");
        writer.Int(obj.vecPromotions[i].promotionPrice);

        writer.Key("giftSku");
        writer.String(obj.vecPromotions[i].giftSku.c_str());

        writer.Key("giftQty");
        writer.Int(obj.vecPromotions[i].giftQty);

        writer.EndObject();
    }
    writer.EndArray();
    //----------------促销 结束-----------

    //----------------电子点标----------------
    writer.Key("ecoupon");
    writer.StartArray();
    for(unsigned int i=0;i<obj.vecEcoupon.size();i++) 
    {
        writer.StartObject();
        
        writer.Key("pcode");
        writer.String(obj.vecEcoupon[i].pcode.c_str());

        writer.Key("proType");
        writer.String(obj.vecEcoupon[i].proType.c_str());

        writer.Key("type");
        writer.String(obj.vecEcoupon[i].type.c_str());

        writer.Key("desc");
        writer.String(obj.vecEcoupon[i].desc.c_str());

        writer.Key("name");
        writer.String(obj.vecEcoupon[i].name.c_str());

        writer.Key("sku");
        writer.String(obj.vecEcoupon[i].sku.c_str());

        writer.Key("ecouponNumber");
        writer.String(obj.vecEcoupon[i].ecouponNumber.c_str());

        writer.Key("ecouponQty");
        writer.Int(obj.vecEcoupon[i].ecouponQty);

        writer.EndObject();
    }
    writer.EndArray();
    //----------------电子点标 结束-----------

    writer.EndObject();

    return buffer.GetString();
}

std::string JsonModule::_convertToOrderStatusJson(orderStatusObj &obj)
{
    rapidjson::StringBuffer buffer;
    rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
    writer.StartObject();

    writer.Key("fm_cmd");
    writer.Int(REQUEST_TYPE_STATUS_CHANGE);

    writer.Key("order_id");
    writer.String(obj.order_id.c_str());

    writer.Key("order_status");
    writer.Int(_getPOSOrderStatus(obj.order_status));

    writer.Key("delivery_status");
    writer.Int(obj.delivery_status);

    writer.EndObject();

    return buffer.GetString();
}

std::string JsonModule::_convertToRefundJson(refundObj &obj)
{
    rapidjson::StringBuffer buffer;
    rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
    writer.StartObject();

    writer.Key("fm_cmd");
    writer.Int(REQUEST_TYPE_REFUND);

    writer.Key("channel");
    writer.String(obj.channel.c_str());

    writer.Key("order_id");
    writer.String(obj.order_id.c_str());

    writer.Key("refund_amount");
    writer.Int(obj.refund_amount);

    //----------------商品信息----------------
    writer.Key("products");
    writer.StartArray();

    for(unsigned int i=0;i<obj.vecProducts.size();i++) 
    {
        //-----------------start 单个商品------------------
        writer.StartObject();

        writer.Key("source");
        writer.String(obj.vecProducts[i].pro.source.c_str());

        writer.Key("attributes");
        writer.String(obj.vecProducts[i].pro.attributes.c_str());

        writer.Key("combo_id");
        writer.String(obj.vecProducts[i].pro.combo_id.c_str());

        writer.Key("bom_id");
        writer.String(obj.vecProducts[i].pro.bom_id.c_str());

        writer.Key("bag_id");
        writer.String(obj.vecProducts[i].pro.bag_id.c_str());

        writer.Key("name");
        writer.String(obj.vecProducts[i].pro.name.c_str());

        writer.Key("price");
        writer.Int(obj.vecProducts[i].pro.price);

        writer.Key("qty");
        writer.Int(obj.vecProducts[i].pro.qty);

        writer.Key("sku");
        writer.String(obj.vecProducts[i].pro.sku.c_str());

        //-----------------start 商品规格------------------
        writer.Key("specs");
        writer.StartArray();
        for(unsigned int j=0;j<obj.vecProducts[i].vecSpec.size();j++) 
        {
            writer.StartObject();

            writer.Key("name");
            writer.String(obj.vecProducts[i].vecSpec[j].name.c_str());

            writer.Key("price");
            writer.Int(obj.vecProducts[i].vecSpec[j].price);

            writer.Key("qty");
            writer.Int(obj.vecProducts[i].vecSpec[j].qty);

            writer.Key("sku");
            writer.String(obj.vecProducts[i].vecSpec[j].sku.c_str());

            writer.EndObject();
        }
        writer.EndArray();
        //-----------------end 商品规格--------------------

        writer.EndObject();
        //-----------------end 单个商品------------------
    }
    
    writer.EndArray();
    //----------------商品信息 结束-----------

    writer.EndObject();

    return buffer.GetString();
}

std::string JsonModule::_convertToStockWarnJson(stockWarnObj &obj)
{
    rapidjson::StringBuffer buffer;
    rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
    writer.StartObject();

    writer.Key("fm_cmd");
    writer.Int(REQUEST_TYPE_STOCK_WARN);

    //----------------商品信息----------------
    writer.Key("products");
    writer.StartArray();

    for(unsigned int i=0;i<obj.vecProducts.size();i++) 
    {
        //-----------------start 单个商品------------------
        writer.StartObject();

        writer.Key("source");
        writer.String(obj.vecProducts[i].source.c_str());

        writer.Key("attributes");
        writer.String(obj.vecProducts[i].attributes.c_str());

        writer.Key("combo_id");
        writer.String(obj.vecProducts[i].combo_id.c_str());

        writer.Key("bom_id");
        writer.String(obj.vecProducts[i].bom_id.c_str());

        writer.Key("bag_id");
        writer.String(obj.vecProducts[i].bag_id.c_str());

        writer.Key("name");
        writer.String(obj.vecProducts[i].name.c_str());

        writer.Key("price");
        writer.Int(obj.vecProducts[i].price);

        writer.Key("stock");
        writer.Int(obj.vecProducts[i].stock);

        writer.Key("sku");
        writer.String(obj.vecProducts[i].sku.c_str());

        writer.Key("safeQty");
        writer.Int(obj.vecProducts[i].safeQty);

        writer.Key("alertTime");
        writer.String(obj.vecProducts[i].alertTime.c_str());        

        writer.EndObject();
        //-----------------end 单个商品------------------
    }
    
    writer.EndArray();
    //----------------商品信息 结束-----------

    writer.EndObject();

    return buffer.GetString();
}

std::string JsonModule::_getDeliveryTypeString(int type)
{
    std::string rlt;
    switch(type)
    {
        case ODS_DELIVERY_TYPE_SELF:
            rlt=DELIVERY_TYPE_SELF;
            break;
        case ODS_DELIVERY_TYPE_PLATFORM:
            rlt=DELIVERY_TYPE_PLATFORM;
            break;
        default:
            break;
    }
    return rlt;
}

int JsonModule::_getPOSOrderStatus(int status)
{
    int rltStatus=0;
    switch(status)
    {
        case ODS_ORDERSTATUS_NEW:
            rltStatus=ORDERSTATUS_NEW;
            break;
        case ODS_ORDERSTATUS_CONFIRMED:
            rltStatus=ORDERSTATUS_CONFIRMED;
            break;    
        case ODS_ORDERSTATUS_CANCELED:
            rltStatus=ORDERSTATUS_CANCELED;
            break; 
        case ODS_ORDERSTATUS_SHIPPING:
            rltStatus=ORDERSTATUS_SHIPPING;
            break; 
        case ODS_ORDERSTATUS_WAIT_SHIPPING:
            rltStatus=ORDERSTATUS_CONFIRMED;
            break; 
        case ODS_ORDERSTATUS_COMPLETE:
            rltStatus=ORDERSTATUS_COMPLETE;
            break; 
        case ODS_ORDERSTATUS_DONE:
            rltStatus=ORDERSTATUS_COMPLETE;
            break; 
        case ODS_ORDERSTATUS_REFUND_FULL:
            rltStatus=ORDERSTATUS_REFUND_FULL;
            break; 
        case ODS_ORDERSTATUS_REFUND_PART:
            rltStatus=ORDERSTATUS_REFUND_PART;
            break; 
        case ODS_ORDERSTATUS_REFUND_COMPLETE:
            rltStatus=ORDERSTATUS_REFUND_COMPLETE;
            break;    
        case ODS_ORDERSTATUS_LOCK:
            rltStatus=ORDERSTATUS_REFUND_FULL;
            break;     
        case ODS_ORDERSTATUS_CANCELED_TIMEOUT:
            rltStatus=ORDERSTATUS_CANCELED;
            break;  
        case ODS_ORDERSTATUS_CANCELED_USER:
            rltStatus=ORDERSTATUS_CANCELED;
            break;  
        case ODS_ORDERSTATUS_CANCELED_KEFU:
            rltStatus=ORDERSTATUS_CANCELED;
            break;  
        case ODS_ORDERSTATUS_CANCELED_SYS:
            rltStatus=ORDERSTATUS_CANCELED;
            break;          
        case ODS_ORDERSTATUS_CANCELED_OTHER:
            rltStatus=ORDERSTATUS_CANCELED;
            break;                                                                                                        
        default:
            break;
    }
    return rltStatus;
}

void JsonModule::_getStatusObj(IN orderObj &order_obj,OUT orderStatusObj &status_obj)
{
    status_obj.order_id=order_obj.order_id;
    status_obj.order_status=order_obj.status;
    status_obj.delivery_status=order_obj.deliveryInfo.status;
}

void JsonModule::_getRefundObj(IN orderObj &order_obj,OUT refundObj &refund_obj)
{
    refund_obj.order_id=order_obj.order_id;
    refund_obj.channel=order_obj.channel;
    refund_obj.refund_amount=order_obj.total_price;
}

bool JsonModule::_getPOSOperationObj(IN const char* data,OUT orderOperationObj &operation_obj)
{
    rapidjson::Document document; // 定义一个Document对象
    document.Parse(data); // 解析，Parse()无返回值，也不会抛异常
    if (document.HasParseError()) // 通过HasParseError()来判断解析是否成功
    {
        // 可通过GetParseError()取得出错代码，
        // 注意GetParseError()返回的是一个rapidjson::ParseErrorCode类型的枚举值
        // 使用函数rapidjson::GetParseError_En()得到错误码的字符串说明，这里的En为English简写
        // 函数GetErrorOffset()返回出错发生的位置
        LOG(ERROR)<<"_getPOSOperationObj JSON parse error:"<<document.GetParseError()<<":"<<document.GetErrorOffset();
    }
    else
    {
        rapidjson::Value& fm_cmd = document["fm_cmd"];
        operation_obj.fm_cmd=fm_cmd.GetInt();
        rapidjson::Value& order_id = document["order_id"];
        operation_obj.order_id=order_id.GetString();
        operation_obj.store_id=_store_id;

        if(document.HasMember("channel")){
            rapidjson::Value& channel = document["channel"];
            operation_obj.channel=channel.GetString();
        }

        if(document.HasMember("comment")){
            rapidjson::Value& comment = document["comment"];
            operation_obj.comment=comment.GetString();
        }
        
        return true;
    }
    return false;
}

std::string JsonModule::_convertPosOperationToOdsJson(orderOperationObj &operation_obj)
{
    rapidjson::StringBuffer buffer;
    rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
    writer.StartObject();

    writer.Key("fm_cmd");
    writer.Int(operation_obj.fm_cmd);

    writer.Key("channel");
    writer.String(operation_obj.channel.c_str());

    writer.Key("shopCode");
    writer.String(operation_obj.store_id.c_str());   

    writer.Key("orderId");
    writer.String(operation_obj.order_id.c_str()); 

    writer.Key("orderDealCode");
    int reqType=_getODSStatusByPOSReq(operation_obj.fm_cmd);
    writer.Int(reqType);

    writer.Key("reason");
    writer.String(operation_obj.comment.c_str());

    writer.EndObject();

    return buffer.GetString();
}

// bool JsonModule::_getServerResponseData(IN const char* json,OUT serverResponseOperationObj &obj)
// {
//     rapidjson::Document document; // 定义一个Document对象
//     document.Parse(json); // 解析，Parse()无返回值，也不会抛异常
//     if (document.HasParseError()) // 通过HasParseError()来判断解析是否成功
//     {
//         // 可通过GetParseError()取得出错代码，
//         // 注意GetParseError()返回的是一个rapidjson::ParseErrorCode类型的枚举值
//         // 使用函数rapidjson::GetParseError_En()得到错误码的字符串说明，这里的En为English简写
//         // 函数GetErrorOffset()返回出错发生的位置
//         LOG(ERROR)<<"_getServerResponseData JSON parse error:"<<document.GetParseError()<<":"<<document.GetErrorOffset();
//     }
//     else
//     {
//         rapidjson::Value& code = document["code"];
//         obj.code=code.GetString();
//         rapidjson::Value& message = document["message"];
//         obj.message=message.GetString();
//         rapidjson::Value& ver = document["ver"];
//         obj.ver=ver.GetString();      
//         return true; 
//     }
//     return false;
// }

// std::string JsonModule::_convertServerResponseToJson(serverResponseOperationObj &response_obj)
// {
//     rapidjson::StringBuffer buffer;
//     rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
//     writer.StartObject();

//     writer.Key("status_code");
//     writer.Int(atoi(response_obj.code.data()));

//     writer.Key("msg");
//     writer.String("");   

//     writer.Key("status");
//     writer.Int(0); 

//     writer.Key("status_desc");
//     writer.String("");   

//     writer.EndObject();

//     return buffer.GetString();
// }

void JsonModule::_getStockWarnObj(IN const char* json,OUT stockWarnObj &warn_obj)
{
    rapidjson::Document document; // 定义一个Document对象
    document.Parse(json); // 解析，Parse()无返回值，也不会抛异常
    if (document.HasParseError()) // 通过HasParseError()来判断解析是否成功
    {
        LOG(ERROR)<<"_getStockWarnObj JSON parse error:"<<document.GetParseError()<<":"<<document.GetErrorOffset();
    }
    else
    {
        productWarn detail;

        rapidjson::Value& qty = document["qty"];
        detail.stock = qty.GetInt();

        rapidjson::Value& sku = document["sku"];
        detail.sku = sku.GetString();

        if(document.HasMember("saftQty")){
            rapidjson::Value& safeQty = document["saftQty"];
            detail.safeQty = safeQty.GetInt();
        }

        rapidjson::Value& alertTime = document["alertTime"];
        int64_t iDatetime = alertTime.GetInt64();
        detail.alertTime = getdatetime(iDatetime);

        warn_obj.vecProducts.push_back(detail);
    }
}

int JsonModule::getPushType(IN const char* data)
{
    rapidjson::Document document; // 定义一个Document对象
    document.Parse(data); // 解析，Parse()无返回值，也不会抛异常
    if (document.HasParseError()) // 通过HasParseError()来判断解析是否成功
    {
        LOG(ERROR) << "getPushType JSON parse error:" << document.GetParseError() << ":" << document.GetErrorOffset();
        return 0;
    }
    if(document.HasMember("fm_cmd")){
        return document["fm_cmd"].GetInt();
    }
    return 0;
}

bool JsonModule::_getOrderResponseJson(IN const std::string& posResponse, IN const std::string& orderData, IN const std::string& odsData, OUT std::string& result)
{
    rapidjson::Document document, document1,document2;
    document.Parse(posResponse.c_str());
    document1.Parse(orderData.c_str());
    document2.Parse(odsData.c_str());

    if( !document.HasMember("status_code")
            || !document1.HasMember("order_id")
            || !document1.HasMember("ods_status")
            || !document1.HasMember("channel") )
    {
        LOG(INFO)<<"Don't have needed parames";
        return false;
    }

    int status_code = document["status_code"].GetInt();
    std::string msg = document["msg"].GetString();

    std::string order_id = document1["order_id"].GetString();
    int status = document1["ods_status"].GetInt();
    std::string channel = document1["channel"].GetString();

    int pk_id = GetJsonIntSafe(document2,"pk_id");

    rapidjson::StringBuffer buffer;
    rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
    writer.StartObject();

    writer.Key("fm_cmd");
    writer.Int(2);

    writer.Key("order_id");
    writer.String(order_id.c_str());

    writer.Key("channel");
    writer.String(channel.c_str());

    writer.Key("status");
    writer.Int(status);

    writer.Key("status_code");
    writer.Int(status_code);

    writer.Key("msg");
    writer.String(msg.c_str());

    writer.Key("pk_id");
    writer.Int(pk_id);

    writer.EndObject();

    result = buffer.GetString();
    return true;
}

bool JsonModule::_getStockWarnResponseJson(IN const std::string& posResponse, IN const std::string& orderData,IN const std::string& odsData, OUT std::string& result)
{
    //待接口确定
    rapidjson::Document document, document1,document2;
    document.Parse(posResponse.c_str());
    document1.Parse(orderData.c_str());
    document2.Parse(odsData.c_str());

    if( !document.HasMember("status_code") 
        || !document2.HasMember("channel") 
        || !document2.HasMember("alertTime")
        || !document2.HasMember("storeId"))
    {
        LOG(INFO)<<"Don't have needed parames";
        return false;
    }

    int status_code = document["status_code"].GetInt();
    std::string msg = document["msg"].GetString();


    std::string channel = document2["channel"].GetString();
    int64_t alertTime = document2["alertTime"].GetInt64();
    std::string storeId = document2["storeId"].GetString();
    int pk_id = GetJsonIntSafe(document2,"pk_id");

    rapidjson::StringBuffer buffer;
    rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
    writer.StartObject();

    writer.Key("fm_cmd");
    writer.Int(1016);

    writer.Key("channel");
    writer.String(channel.c_str());

    writer.Key("store_id");
    writer.String(storeId.c_str());

    writer.Key("alert_time");
    writer.Int64(alertTime);

    writer.Key("status_code");
    writer.Int(status_code);

    writer.Key("pk_id");
    writer.Int(pk_id);

    writer.EndObject();

    result = buffer.GetString();
    return true;
}

std::string JsonModule::_convertToCommonWarnJson(IN const char* json)
{
    std::string notifyDate,notifyDesc,rackNo,storeId,terminalNo;
    int notifyType=0;
    rapidjson::Document document; // 定义一个Document对象
    document.Parse(json); // 解析，Parse()无返回值，也不会抛异常
    if (document.HasParseError()) // 通过HasParseError()来判断解析是否成功
    {
        LOG(ERROR)<<"JSON parse error:"<<document.GetParseError()<<":"<<document.GetErrorOffset();
        return "";
    }
    else
    {
        rapidjson::Value& vNotifyDate = document["notifyDate"];
        rapidjson::Value& vNotifyDesc = document["notifyDesc"];
        rapidjson::Value& vNotifyType = document["notifyType"];
        rapidjson::Value& vRackNo = document["rackNo"];
        rapidjson::Value& vStoreId = document["storeId"];
        rapidjson::Value& vTerminalNo = document["terminalNo"];

        int64_t iDate = vNotifyDate.GetInt64();
        notifyDate=getdatetime(iDate);

        if(!vNotifyDesc.IsNull()){
            notifyDesc=vNotifyDesc.GetString();
        }

        notifyType = vNotifyType.GetInt();
        rackNo = vRackNo.GetString();
        storeId = vStoreId.GetString();
        terminalNo = vTerminalNo.GetString();
    }


    rapidjson::StringBuffer buffer;
    rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
    writer.StartObject();

    writer.Key("fm_cmd");
    writer.Int(REQUEST_TYPE_COMMON_WARN);

    writer.Key("notifyDate");
    writer.String(notifyDate.c_str());   

    writer.Key("notifyDesc");
    writer.String(notifyDesc.c_str()); 

    writer.Key("notifyType");
    writer.Int(notifyType);   

    writer.Key("rackNo");
    writer.String(rackNo.c_str()); 

    writer.Key("storeId");
    writer.String(storeId.c_str()); 

    writer.Key("terminalNo");
    writer.String(terminalNo.c_str()); 
            
    writer.EndObject();

    return buffer.GetString();
}

bool JsonModule::_getCommonWarnResponseJson(IN const std::string& posResponse, IN const std::string& orderData, IN const std::string& odsData,OUT std::string& result)
{
    std::string notifyDate,rackNo,storeId,terminalNo;
    int64_t iDatetime=0,pk_id;
    rapidjson::Document document,document1; // 定义一个Document对象
    document1.Parse(odsData.data()); // 解析，Parse()无返回值，也不会抛异常
    if (document1.HasParseError()) // 通过HasParseError()来判断解析是否成功
    {
        LOG(ERROR)<<"JSON odsData _getCommonWarnResponseJson parse error:"<<document1.GetParseError()<<":"<<document1.GetErrorOffset();
        return false;
    }
    else
    {
        rapidjson::Value& vNotifyDate = document1["notifyDate"];
        rapidjson::Value& vRackNo = document1["rackNo"];
        rapidjson::Value& vStoreId = document1["storeId"];
        rapidjson::Value& vTerminalNo = document1["terminalNo"];

        iDatetime = vNotifyDate.GetInt64();
        rackNo = vRackNo.GetString();
        storeId = vStoreId.GetString();
        terminalNo = vTerminalNo.GetString();
        pk_id = GetJsonIntSafe(document1,"pk_id");
    }
    document.Parse(posResponse.c_str());
    if (document.HasParseError()) // 通过HasParseError()来判断解析是否成功
    {
        LOG(ERROR)<<"JSON posResponse _getCommonWarnResponseJson parse error:"<<document1.GetParseError()<<":"<<document1.GetErrorOffset();
        return false;
    }
    int status_code = document["status_code"].GetInt();


    rapidjson::StringBuffer buffer;
    rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
    writer.StartObject();

    writer.Key("fm_cmd");
    writer.Int(ODS_PUSH_TYPE_COMMON_BACK);

    writer.Key("store_id");
    writer.String(storeId.c_str());   

    writer.Key("rack_no");
    writer.String(rackNo.c_str()); 

    writer.Key("terminal_no");
    writer.String(terminalNo.c_str());   

    writer.Key("alert_time");
    writer.Int64(iDatetime); 

    writer.Key("status_code");
    writer.Int(status_code);

    writer.Key("pk_id");
    writer.Int(pk_id); 
            
    writer.EndObject();    
    result = buffer.GetString();

    return true;
}

void JsonModule::setInitData(IN const char* data)
{
    rapidjson::Document document; // 定义一个Document对象
    document.Parse(data); // 解析，Parse()无返回值，也不会抛异常
    if (document.HasParseError()) // 通过HasParseError()来判断解析是否成功
    {
        LOG(ERROR) << "setInitData JSON parse error:" << document.GetParseError() << ":" << document.GetErrorOffset();
        return;
    }

    _store_id = document["store_id"].GetString();
}

int JsonModule::_getODSStatusByPOSReq(int fm_cmd)
{
    int rlt=0;
    switch(fm_cmd)
    {
        case OPERATION_POS_CONFIRM:
            rlt=ODS_POSPUSH_CONFIRM;
            break;
        case OPERATION_POS_CANCEL:
            rlt=ODS_POSPUSH_CANCEL;
            break;
        case OPERATION_POS_REFUND_AGREE:
            rlt=ODS_POSPUSH_REFUND_AGREE;
            break;
        case OPERATION_POS_REFUND_DISAGREE:
            rlt=ODS_POSPUSH_REFUND_DISAGREE;
            break;
        default:
            break;
    }
    return rlt;   
}

bool JsonModule::_convertPOSReqPriorityJson(IN const std::string& posReq,OUT const std::string& odsJson)
{
    std::string pos_id;
    rapidjson::Document document; // 定义一个Document对象
    document.Parse(posReq.data()); // 解析，Parse()无返回值，也不会抛异常
    if (document.HasParseError()) // 通过HasParseError()来判断解析是否成功
    {
        LOG(ERROR)<<"JSON _convertPOSReqPriorityJson parse error:"<<document.GetParseError()<<":"<<document.GetErrorOffset();
        return false;
    }
    else
    {
        rapidjson::Value& vPosId = document["pos_id"];
        pos_id = vPosId.GetString();
    }


    // rapidjson::StringBuffer buffer;
    // rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
    // writer.StartObject();

    // writer.Key("fm_cmd");
    // writer.Int(REQUEST_TYPE_COMMON_WARN);

    // writer.Key("notifyDate");
    // writer.String(notifyDate.c_str());   

    // writer.Key("notifyDesc");
    // writer.String(notifyDesc.c_str()); 
            
    // writer.EndObject();

    //odsJson = buffer.GetString();
    return true;

}

bool JsonModule::convertSetPosPriorityDataPos2Ods(IN const std::string& data, OUT std::string& result)
{
    return _convertPOSReqPriorityJson(data,result);
}

bool JsonModule::getSetPosPriorityBackData(IN const char* inJson,OUT std::string& outJson)
{
    //缺接口
    return true;
}

std::string JsonModule::_getPickupCodeString(std::string &channel,std::string &pickup_code)
{
    std::string rlt;
    if("101"==channel){
        rlt="普通单"+pickup_code+"号";
    }
    else if("102"==channel){
        rlt="易果分销"+pickup_code+"号";
    }
    else if("201"==channel){
        rlt="贩卖机"+pickup_code+"号";
    }
    else if("202"==channel){
        rlt="洗衣机"+pickup_code+"号";
    }
    else if("203"==channel){
        rlt="扫码购"+pickup_code+"号";
    }
    else if("204"==channel){
        rlt="线上易果分销"+pickup_code+"号";
    }
    else if("205"==channel){
        rlt="美团外卖"+pickup_code+"号";
    }
    else if("206"==channel){
        rlt="百度外卖"+pickup_code+"号";
    }  
    else if("207"==channel){
        rlt="饿了么"+pickup_code+"号";
    }
    else if("208"==channel){
        rlt="京东到家"+pickup_code+"号";
    }
    return rlt;
}