#include "printCupStickPosDB.h"
#include "QsLog.h"
#include "alertForm.h"
#include <QDateTime>
#include "Control/flowControl.h"
#include "DTools/configManger.h"
#include "checkPoskeyExistPosDB.h"
#include <Model/dishesObject.h>
#include <Model/couponsObject.h>

PrintCupStickPosDB::PrintCupStickPosDB()
{
    QLOG_INFO()<<"[<<<<---PrintCupStickPosDB:: Structure POS Print Cup Stick  INFO DataBase--->>>>]";

    // 为了发出告警消息;  注册信号槽参数
    qRegisterMetaType<AlertForm::Type>("AlertForm::Type");
}

bool PrintCupStickPosDB::initPrintCupStickPosDB(){
    bool bRetCheckColumn = false;
    bool bRet = false;
    m_sqlDb = QSqlDatabase::addDatabase("QODBC","PrintCupStickPosDB");   //数据库驱动类型为SQL Server
    if ( m_sqlDb.isValid() ) {
        QLOG_INFO()<<"[<<<<---SqlServer ODBC driver is valid--->>>>]";
        QString dsn="DRIVER={SQL SERVER};SERVER=127.0.0.1\\sqlexpress;DATABASE=MMXBenefits";
        m_sqlDb.setDatabaseName(dsn);                            //设置数据源名称
        m_sqlDb.setUserName("sa");                               //登录用户
        m_sqlDb.setPassword("SIM29@123");
        if(!m_sqlDb.open()) {                                      //打开数据库
            QLOG_ERROR()<<"[<<<<---SqlServer Open Database error:--->>>>]"<<m_sqlDb.lastError().text();
        } else {
            QLOG_INFO()<<"[<<<<---PrintCupStickPosDB::SqlServer Test Open database success!:--->>>>]";
            QSqlQuery query(m_sqlDb);
            QString selectsql ="select * from sys.tables where name='tb_main_prod_refinfo'" ;
            if(!query.exec(selectsql)) {
                QLOG_ERROR()<<"[<<<<---PrintCupStickPosDB::SqlServer Database  check tb_main_prod_refinfo failed--->>>>]"<<query.lastError().text();
            }
            if(query.next()) {
                QLOG_INFO() << "[<<<<---PrintCupStickPosDB::Table tb_main_prod_refinfo Has Exist--->>>>]";
                bRet = true;
            } else {
                QLOG_INFO() << "[<<<<---PrintCupStickPosDB::Table tb_main_prod_refinfo Does Not Exist--->>>>]";

                query.prepare( QString("CREATE TABLE [dbo].[tb_main_prod_refinfo] ("
                                    " [id] [int] IDENTITY(1,1) NOT NULL, [chk_num] [int] NOT NULL,[order_id] [varchar](50) NOT NULL,  [order_status] [int] NULL,"
                                    " [create_datetime] [datetime] NULL,"

                                    " [prod_seq] [int] NULL, [prod_code] [varchar](20) NULL, [prod_name] [varchar](60) NULL, [prod_qty] [int] NULL,"
                                    " [prod_price] [int] NULL,[prod_optionsCode] [varchar](20) NULL, [prod_optionsName] [varchar](40) NULL, [prod_discount] [int] NULL, [prod_discountName] [varchar](50) NULL,"
                                    " [prod_starDiscount] [int] NULL, [prod_starDiscountName] [varchar](50) NULL, [prod_owner] [varchar](50) NULL,"
                                    " [prod_resv0] [int] NULL, [prod_resv1] [int] NULL, [prod_resv2] [int] NULL, [prod_resv3] [varchar](50) NULL, [prod_resv4] [varchar](50) NULL,"
                                    " [prod_resv5] [varchar](80) NULL, [prod_resv6] [varchar](80) NULL, [prod_resv7] [varchar](100) NULL, [prod_resv8] [varchar](100) NULL,"
                                    " [parent_id] [int] NULL,"

                                    " [coupon_seq] [int] NULL, [coupon_code] [varchar](50) NULL, [coupon_name] [varchar](80) NULL, [coupon_qty] [int] NULL, [coupon_factPrice] [int] NULL,"
                                    " [coupon_discountPrice] [int] NULL, [coupon_discountCode] [varchar](20) NULL, [coupon_discountName] [varchar](40) NULL, [coupon_storeChannel] [int] NULL,"
                                    " [coupon_isCoupon] [int] NULL, [coupon_payMethodId] [varchar](20) NULL, [coupon_payMethodName] [varchar](50) NULL, [coupon_showGiver] [int] NULL,"
                                    " [coupon_giver] [varchar](50) NULL, [coupon_wishes] [varchar](80) NULL,"
                                    " [coupon_resv0] [int] NULL, [coupon_resv1] [int] NULL, [coupon_resv2] [int] NULL, [coupon_resv3] [varchar](50) NULL, [coupon_resv4] [varchar](50) NULL,"
                                    " [coupon_resv5] [varchar](80) NULL, [coupon_resv6] [varchar](80) NULL, [coupon_resv7] [varchar](100) NULL, [coupon_resv8] [varchar](100) NULL,"

                                    " [resv0] [int] NULL, [resv1] [int] NULL,[resv2] [int] NULL,[resv3] [int] NULL, [resv4] [int] NULL,[resv5] [int] NULL,[resv6] [varchar](60) NULL,"
                                    " [resv7] [varchar](60) NULL, [resv8] [varchar](60) NULL, [resv9] [varchar](80) NULL, [resv10] [varchar](80) NULL,[resv11] [varchar](80) NULL,"
                                    " [resv12] [varchar](100) NULL,[resv13] [varchar](100) NULL,[resv14] [varchar](100) NULL"
                                    " PRIMARY KEY CLUSTERED ( [id] ASC"
                                    ")WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = "
                                    " OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY]") );

                if(!query.exec()){
                    QLOG_ERROR()<< "[<<<<---Create Table tb_main_prod_refinfo Faild--->>>>]" <<query.lastError().text()<<QString::number(query.lastError().type());
                }else {
                    bRet = true;
                }
            }
            m_sqlDb.close();
        }
    } else {
        QLOG_ERROR()<<"[<<<<---SqlServer ODBC driver no valid--->>>>]";
    }

    QLOG_INFO()<<QString::fromLocal8Bit("[<<<<---FM TakeOut Plugin Version:2.2020.5.12 Begin check table tb_main_prod_refinfo Column--->>>>]");
    bRetCheckColumn = alterTablePrintCupStickAndCheck();

    return (bRet && bRetCheckColumn );
}


bool PrintCupStickPosDB::alterTablePrintCupStickAndCheck() {

    return true;
    /*
    QMutexLocker mutex(&m_mutex);
    int checkSuccessNum = 0;
    QSqlQuery query(m_sqlDb);
    QString selectsql;
    if(!m_sqlDb.open()) {
        QLOG_ERROR()<<"[<<<<---alterTablePrintCupStickAndCheck::SqlServer Database:Open Failed--->>>>]"<<m_sqlDb.lastError().text();
        return false;
    }
    // Alter Table accept_name;
    selectsql = "select * from syscolumns where id=object_id('tb_main_prod_refinfo') and name='accept_name'";
    query.exec(selectsql);
    if(!query.next()){
        selectsql = "alter table tb_main_prod_refinfo add accept_name varchar(400) null";
        if(!query.exec(selectsql)){
            QLOG_ERROR()<< "[<<<<---alter table tb_main_prod_refinfo accept_name Faild--->>>>]" <<query.lastError().text()<<QString::number(query.lastError().type());
        } else { checkSuccessNum++; }
    } else { checkSuccessNum++;}

    m_sqlDb.close();
    if (9 == checkSuccessNum) {
        QLOG_INFO()<<"[<<<<---alterTablePrintCupStickAndCheck::checkSuccessNum = 9 --->>>>]";
        return true;
    } else {
        QLOG_ERROR()<<"[<<<<---alterTablePrintCupStickAndCheck::checkSuccessNum < 9 = --->>>>]"<<checkSuccessNum;
        return false;
    }
    */
}


PrintCupStickPosDB &PrintCupStickPosDB::getInstance()
{
    static PrintCupStickPosDB printCupStickPosDB;
    return printCupStickPosDB;
}

bool PrintCupStickPosDB::insertOrderProduct(OrderObject* orderObj,const QString& posCheckNo, bool &checkProductValidRet) {
    // WSG-杯贴祝福-商品券号关联数据;
    if ( ( "WSG-MOD" == orderObj->channel || "WSG-MOP" == orderObj->channel ) && "4" == orderObj->platformSource   ) {
         checkProductValidRet = checkCouponProdAllVaild(orderObj);
    } else {  // All Channel 商品关联数据;
        checkProductValidRet = checkNormalProdAllVaild(orderObj);
    }

    if ( !checkProductValidRet ) {
        QLOG_ERROR()<<"insertOrderProduct:: Before Insert Normal Product Or Coupon Product Db, Check PosKey Is Invalid  Or Qty Is 0  Or  Main Product Not Exist ";
        return false;
    }

    QMutexLocker mutex(&m_mutex);
    if(!m_sqlDb.open()) {
        QLOG_ERROR()<<"[<<<<---SqlServer Database:Open Failed--->>>>]"<<m_sqlDb.lastError().text();
        return false;
    }

    // 开启数据库事务实现原子操作: 保证  tb_main_prod_refinfo:父商品与子商品   同时插入成功;
    // m_sqlDb.transaction(); 驱动不支持;
    QSqlQuery query(m_sqlDb);
    if ( !query.exec("begin tran") ) {
       QLOG_ERROR()<<"[<<<<---PrintCupStickPosDB::insertOrderProduct: Begin transaction Failed--->>>>]"<<m_sqlDb.lastError().text();
    }

    //刷新 存储订单 销售退货状态的内存标识;
    orderObj->orderSaleRefundStatus = orderObj->orderStatus == 6 ? 6 : 3 ;

    bool retInsCoupProd = false;
    bool retInsNorProd = false;
    // WSG-杯贴祝福-商品券号关联数据;
    if ( ( "WSG-MOD" == orderObj->channel || "WSG-MOP" == orderObj->channel ) && "4" == orderObj->platformSource   ) {
        retInsCoupProd = insertCouponProd(orderObj, posCheckNo);
    } else {  // All Channel 商品关联数据;
        retInsNorProd = insertNormalProd(orderObj, posCheckNo);
    }

    // 结束数据库事务操作 保证  tb_main_prod_refinfo:父商品与子商品  同时插入成功;
    // Sleep(10*1000);   // test  sqldb transaction
    // m_sqlDb.commit()  and m_sqlDb.rollback() 都是不支持的;
    if ( retInsCoupProd || retInsNorProd ) {
        if ( !query.exec( "commit" ) ) {
            QLOG_ERROR()<<"[<<<<---insertOrderProduct::insertOrderProduct: Begin Commit Failed--->>>>]"<<m_sqlDb.lastError().text();
            if ( !query.exec( "rollback" ) ) {
                QLOG_ERROR()<<"[<<<<---insertOrderProduct::insertOrderProduct: Begin Rollback Failed--->>>>]"<<m_sqlDb.lastError().text();
            }
        }
    } else {
        if ( !query.exec( "rollback" ) ) {
            QLOG_ERROR()<<"[<<<<---insertOrderProduct::insertOrderProduct: Begin Rollback Failed--->>>>]"<<m_sqlDb.lastError().text();
        }
    }

    m_sqlDb.close();
    return retInsCoupProd || retInsNorProd;
}

bool PrintCupStickPosDB::insertCouponProd(OrderObject* orderObj, const QString& posCheckNo) {
    int inCoupProdSucNum = 0;
    int insertMainProdIndex = 0 ;
    bool retIntCoupSubProd = true;
    QSqlQuery query(m_sqlDb);
    QDateTime qdaTi = QDateTime::currentDateTimeUtc();

    for (int i=0; i < orderObj->coupList.count(); i++) {
        CouponsObject* coupon = orderObj->coupList.at(i);
        query.prepare("INSERT INTO tb_main_prod_refinfo(chk_num, order_id, order_status, create_datetime, "
                      " prod_seq, prod_code, prod_name, prod_resv0, prod_resv3, prod_resv5, prod_qty, prod_price, "
                      " coupon_seq, coupon_code, coupon_name, coupon_qty,"
                      " coupon_factPrice, coupon_discountPrice, coupon_discountCode, coupon_discountName ,"
                      " coupon_storeChannel, coupon_isCoupon, coupon_payMethodId, coupon_payMethodName,"
                      " coupon_showGiver, coupon_giver, coupon_wishes) "
                      " VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)  select @@identity ");
        query.addBindValue(posCheckNo.toInt());  // --小票号
        query.addBindValue(orderObj->id);  // --订单编号
        // query.addBindValue( orderObj->orderStatus );  // --订单状态(int);
        query.addBindValue( orderObj->orderSaleRefundStatus );  // --订单 销售退货状态 内存标识(int);
        query.addBindValue(qdaTi.addSecs(60*60*8).toString("yyyy-MM-dd hh:mm:ss")); // --商品入库时间

        query.addBindValue(i+1);   // --主商品序号;
        query.addBindValue(coupon->skus[0]->code);   // --主商品 SKU
        query.addBindValue(coupon->skus[0]->name);   // --主商品名称
        query.addBindValue(coupon->skus[0]->changePriceFlag);   // --主商品 改价标志
        query.addBindValue(coupon->skus[0]->nickname);   // --主商品昵称
        query.addBindValue(coupon->skus[0]->enProductName);   // --主商品英文名
        if ( OrderObject::Refunded == orderObj->orderStatus ) {
            query.addBindValue(0 - coupon->skus[0]->qty);   // --退货主商品数量需为 负数;
            query.addBindValue(0 - coupon->skus[0]->price);   // --退货主商品价格需为 负数;
        } else {
            query.addBindValue(coupon->skus[0]->qty);   // --主商品数量
            query.addBindValue(coupon->skus[0]->price);   // --主商品价格
        }
        query.addBindValue(i+1);   // --主商品序号;
        query.addBindValue(coupon->code);                    // 券号
        query.addBindValue(coupon->couponName);        // 券名
        query.addBindValue(1);                                         // 券数量
        query.addBindValue(coupon->consumeFactAmount);          // 券实际支付金额
        query.addBindValue(coupon->consumeDiscountAmount);    // 券折扣优惠金额
        query.addBindValue(coupon->discount);                              // 券折扣码
        query.addBindValue(coupon->discountName);                      // 券折扣名
        query.addBindValue(coupon->storeChannel);                        // 是否门店券
        query.addBindValue(coupon->skus[0]->isCoupon);              // 券 商品是否是券属性: 券属性输出券原价+非券属性输出0元客制化
        query.addBindValue(coupon->payMethodId);              // 券支付ID;
        query.addBindValue(coupon->payMethodName);         // 券支付Name;
        query.addBindValue(coupon->isShowGiver);        // -- 是否显示赠送者
        query.addBindValue(coupon->giverName);            // --券赠送者
        query.addBindValue(coupon->blessingWords);     // --券祝福

        if(!query.exec()) {
            QLOG_ERROR()<<"[<<<<---SqlServer Database: Insert tb_main_prod_refinfo Error--->>>>]"<<query.lastError().text()<<QString::number(query.lastError().type());
            QLOG_ERROR()<<QString("INSERT INTO tb_main_prod_refinfo(chk_num, order_id, order_status, create_datetime, "
                                 " prod_seq, prod_code, prod_name, prod_resv0, prod_resv3, prod_resv5, prod_qty, prod_price, "
                                 " coupon_seq, coupon_code, coupon_name, coupon_qty,"
                                 " coupon_factPrice, coupon_discountPrice, coupon_discountCode, coupon_discountName ,"
                                 " coupon_storeChannel, coupon_isCoupon, coupon_payMethodId, coupon_payMethodName,"
                                 " coupon_showGiver, coupon_giver, coupon_wishes) "
                                 "VALUES(%1, %2, %3, %4, %5, %6, %7, %8, %9, %10, %11, %12, %13, %14, %15, %16, %17, %18, %19, %20, "
                                 " %21, %22, %23, %24, %25, %26, %27)   select @@identity ").arg(posCheckNo.toInt())
                          .arg(orderObj->id).arg(orderObj->orderStatus).arg(qdaTi.addSecs(60*60*8).toString("yyyy-MM-dd hh:mm:ss"))
                          .arg(i+1).arg(coupon->skus[0]->code).arg(coupon->skus[0]->name).arg(coupon->skus[0]->changePriceFlag).arg(coupon->skus[0]->nickname)
                    .arg(coupon->skus[0]->enProductName).arg(coupon->skus[0]->qty).arg(coupon->skus[0]->price)
                    .arg(i+1).arg(coupon->code).arg(coupon->couponName).arg(1).arg(coupon->consumeFactAmount).arg(coupon->consumeDiscountAmount)
                    .arg(coupon->discount).arg(coupon->discountName).arg(coupon->storeChannel).arg(coupon->skus[0]->isCoupon)
                    .arg(coupon->payMethodId).arg(coupon->payMethodName).arg(coupon->isShowGiver).arg(coupon->giverName).arg(coupon->blessingWords);

            break;
        } else {
            if ( query.first()  ) {
                insertMainProdIndex = query.value(0).toInt();
                query.clear();
                QLOG_INFO()<<QString("[<<<<---SqlServer Database:Insert OrderId %1 coupDishCode:%2 retCoupProdIndex:%3 Into tb_main_prod_refinfo Success--->>>>]").arg(orderObj->id)
                             .arg(coupon->skus[0]->code).arg(insertMainProdIndex);

                // Coupon  skus [0]  Default Main Product, So Skus List size() Must > 1, then will Insert subProduct;
                if ( coupon->skus.size() > 1 ) {
                    retIntCoupSubProd = insertCouponSubProd(orderObj, insertMainProdIndex, coupon->skus, posCheckNo);
                }

                if ( retIntCoupSubProd ) {  ++inCoupProdSucNum; }
            }
        }
    }

    if ( inCoupProdSucNum != orderObj->coupList.count() ) {
        if ( inCoupProdSucNum > 0 ) {
            query.prepare("delete from tb_main_prod_refinfo where order_id =" + orderObj->id) ;
            if(!query.exec())
            {
                QLOG_ERROR()<<QString("[<<<<---clear tb_main_prod_refinfo data  OrderId %1 failed--->>>>]").arg(orderObj->id)
                           <<query.lastError().text()<<QString::number(query.lastError().type());
            } else {
                QLOG_INFO()<<QString("[<<<<---clear tb_main_prod_refinfo data  OrderId %1 Success--->>>>]").arg(orderObj->id);
            }
        }
        return false;
    } else {
        return true;
    }
}

bool PrintCupStickPosDB::insertCouponSubProd(OrderObject* orderObj, const int mainProdIndex, QList<SingleProductObject*> &couponSubProdList, const QString& posCheckNo) {
    int inCoupSubPordSucNum = 0;
    int insertSubProdIndex = 0 ;
    QSqlQuery query(m_sqlDb);
    QDateTime qdaTi = QDateTime::currentDateTimeUtc();

    // coupon  SingleProductObject  First sku  is Main Prod;  [0] -> mainProd,  [1]-> subProd-1, [2]-> subProd-2, [3]-> subProd-3 ...
    for (int i=1; i <couponSubProdList.count(); i++) {
        SingleProductObject* couponSubProd = couponSubProdList.at(i);
        query.prepare("INSERT INTO tb_main_prod_refinfo(chk_num, order_id, order_status, create_datetime, "
                      " prod_seq, prod_code, prod_name, prod_resv3, prod_resv5, prod_qty, prod_price, "
                      " coupon_storeChannel, coupon_isCoupon, parent_id) "
                      " VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ,? ,? ,?)   select @@identity ");
        query.addBindValue(posCheckNo.toInt());  // --小票号
        query.addBindValue(orderObj->id);  // --订单编号
        // query.addBindValue( orderObj->orderStatus );  // --订单状态(int);
        query.addBindValue( orderObj->orderSaleRefundStatus );  // --订单 销售退货状态 内存标识(int);
        query.addBindValue(qdaTi.addSecs(60*60*8).toString("yyyy-MM-dd hh:mm:ss")); // --商品入库时间

        query.addBindValue(0);   // --商品序号;
        query.addBindValue(couponSubProd->code);   // --商品 SKU
        query.addBindValue(couponSubProd->name);   // --商品名称
        query.addBindValue(couponSubProd->nickname);   // --商品昵称
        query.addBindValue(couponSubProd->enProductName);   // --商品英文名
        if ( OrderObject::Refunded == orderObj->orderStatus ) {
            query.addBindValue(0 - couponSubProd->qty);   // --退货单商品数量需为负数;
            query.addBindValue(0 - couponSubProd->price);   // --退货单商品价格需为负数;
        } else {
            query.addBindValue(couponSubProd->qty);   // --商品数量
            query.addBindValue(couponSubProd->price);   // --商品价格
        }
        query.addBindValue(0);      // 是否门店券
        query.addBindValue(couponSubProd->isCoupon);  // 券 商品是否是券属性: 券属性输出券原价+非券属性输出0元客制化
        query.addBindValue(mainProdIndex);  // --父商品ID； 表字段 parent_id;

        if(!query.exec()) {
            QLOG_ERROR()<<"[<<<<---SqlServer Database: Insert tb_main_prod_refinfo Error--->>>>]"<<query.lastError().text()<<QString::number(query.lastError().type());
            QLOG_ERROR()<<QString("INSERT INTO tb_main_prod_refinfo(chk_num, order_id, order_status, create_datetime, "
                                 " prod_seq, prod_code, prod_name, prod_resv3, prod_resv5, prod_qty, prod_price, "
                                 " coupon_storeChannel, coupon_isCoupon, parent_id) "
                                 "VALUES(%1, %2, %3, %4, %5, %6, %7, %8, %9, %10, %11, %12, %13, %14)   select @@identity ").arg(posCheckNo.toInt())
                         .arg(orderObj->id).arg(orderObj->orderStatus).arg(qdaTi.addSecs(60*60*8).toString("yyyy-MM-dd hh:mm:ss"))
                         .arg(0).arg(couponSubProd->code).arg(couponSubProd->name).arg(couponSubProd->nickname).arg(couponSubProd->enProductName)
                          .arg(couponSubProd->qty).arg(couponSubProd->price)
                         .arg(0).arg(couponSubProd->isCoupon).arg(mainProdIndex);

            break;
        } else {
            if ( query.first()  ) {
                insertSubProdIndex = query.value(0).toInt();
                query.clear();
                QLOG_INFO()<<QString("[<<<<---SqlServer Database:Insert OrderId %1 coupSubDishCode:%2  retCoupSubProdIndex: %3 Into tb_main_prod_refinfo Success--->>>>]")
                             .arg(orderObj->id).arg(couponSubProd->code).arg(insertSubProdIndex);

                ++inCoupSubPordSucNum;
            }
        }
    }

    if ( (inCoupSubPordSucNum+1) != couponSubProdList.count() ) {
        return false;
    } else {
        return true;
    }
}


bool PrintCupStickPosDB::checkCouponProdAllVaild(OrderObject* orderObj) {

    if (!orderObj) {
        QLOG_ERROR()<<"checkCouponProdAllVaild  Order Obj Point Is  Null";
        return false;
    }

    // 使用 PosKey 集合 与 POS数据库中进行校验, 每次校验前需要清空PosKey集合内容;
    orderObj->posKeyList.clear();

    QString tmpPosKey = "";
    QString tmpPosKeyName = "";
    QString tempPosKeyLeftHead = "";
    QStringList notExistPoskeyList;
    int tmpQty = 0;
    QString error = "";
    QString requestType = orderObj->orderStatus==6?QString::fromLocal8Bit("6"):QString::fromLocal8Bit("3");


    for (int i=0; i < orderObj->coupList.count(); i++) {
        CouponsObject* coupon = orderObj->coupList.at(i);

        for ( int j = 0; j < coupon->skus.count(); j++ ) {
            tmpPosKey = coupon->skus[j]->code;
            tmpPosKeyName = coupon->skus[j]->name;
            tmpQty = coupon->skus[j]->qty;
            // 检查: ①主商品属性：code中含有Default字符串(不区分大小写) + ②code中以非数字开头 + ③商品数量是0 + ④PosKey长度在 [3~9] 之间;
            tempPosKeyLeftHead = tmpPosKey.left(1);
            // 校验券-主商品;
            if ( 0 == j ) {
                if (tmpPosKey.contains("Default",Qt::CaseInsensitive) || (tempPosKeyLeftHead<QString('0') || tempPosKeyLeftHead>QString('9'))
                        || !tmpQty || tmpPosKey.length()<3 || tmpPosKey.length()>9 ) {

                    error = QString::fromLocal8Bit("This Order Has PosKey Is Combo Error Or Default*  Or  qty Is Zore  Or  Sku Length < 3 Or  Sku Length > 9");
                    FlowControl::GetInstance()._AddOrUpdateReportOmsList(orderObj->id,  orderObj->channel,requestType, QString("4"), QString(""), error, QString("1010"));
                    // 存储订单商品入库异常, 同步更新入机状态表数据, 便于退货单过来时 参考销售单入机情况;
                    FlowControl::GetInstance()._AddInputPosSuccessPresistList(orderObj->id, orderObj->channel, requestType, "4", QString(""), error, QString("1010") );

                    // 非法数据, 弹框告警;
                    QString  warnMsg =  QString::fromLocal8Bit("Illegal Goods data, Please Check...;    OrderId Last 5:  %1;    GoodsName:  %2;    GoodsPosKey:  %3;    GoodsQty:  %4")
                            .arg( orderObj->id.mid(orderObj->id.length() - 5, 5) ).arg(tmpPosKeyName).arg(tmpPosKey).arg(tmpQty);
                    emit triggerFlowContrlAlert(AlertForm::WARNNING,warnMsg);

                    return false;
                }

                // 追加主商品PosKey 到 PosKey集合
                if ( !orderObj->posKeyList.contains(tmpPosKey) ) {
                    orderObj->posKeyList.append(tmpPosKey);
                }

            }
            // 校验券-子商品;
            else {
                if( tmpPosKey.contains("Default",Qt::CaseInsensitive)  ) {
                    continue;
                } else {
                    if ( tempPosKeyLeftHead<QString('0') || tempPosKeyLeftHead>QString('9') || !tmpQty  ||  tmpPosKey.length()<3 ||  tmpPosKey.length()>9 ) {

                        error = QString::fromLocal8Bit("This Order SubProduct PosKey Is String And No Default* Or  qty Is Zore Or Sku Length < 3 Or Sku Length > 9 ");
                        QString requestType = orderObj->orderStatus==6?QString::fromLocal8Bit("6"):QString::fromLocal8Bit("3");
                        FlowControl::GetInstance()._AddOrUpdateReportOmsList(orderObj->id,  orderObj->channel,requestType, QString("4"), QString(""), error, QString("1011"));
                        // 存储订单商品入库异常, 同步更新入机状态表数据, 便于退货单过来时 参考销售单入机情况;
                        FlowControl::GetInstance()._AddInputPosSuccessPresistList(orderObj->id, orderObj->channel, requestType, "4", QString(""), error, QString("1011") );

                        // 非法数据, 弹框告警;
                        QString  warnMsg =  QString::fromLocal8Bit("Illegal Goods data, Please Check...;    OrderId Last 5:  %1;    GoodsName:  %2;    GoodsPosKey:  %3;    GoodsQty:  %4")
                                .arg( orderObj->id.mid(orderObj->id.length() - 5, 5) ).arg(tmpPosKeyName).arg(tmpPosKey).arg(tmpQty);
                        emit triggerFlowContrlAlert(AlertForm::WARNNING,warnMsg);

                        return false;
                    }

                    // 追加有效子商品的 PosKey 到 PosKey集合
                    if ( !orderObj->posKeyList.contains(tmpPosKey) ) {
                        orderObj->posKeyList.append(tmpPosKey);
                    }
                }

            }

        }

    }

    // 校验 PosKey 在POS数据库中的有效性: * 只有解耦2.0 版本才会一次性校验 PosKey 的有效性;
    bool bCheckAllPoskeyExistRet = false;
    if ( orderObj->decouplePosVersion < 20  && !ConfigManger::GetInstance().GetPoskeyExistVerify() ) {
        bCheckAllPoskeyExistRet = true;
    } else {

        if ( orderObj->posKeyList.isEmpty() ) {
            error = QString::fromLocal8Bit("This Order Coupon PosKey Is Empty");
        } else {
            bCheckAllPoskeyExistRet = CheckPoskeyExistPosDB::getInstance().allPoskeyExistDB( orderObj, notExistPoskeyList );
            QLOG_INFO()<<QString("[<<<<---SqlServer Database: checkCouponProdAllVaild,  orderId = %1  bCheckAllPoskeyExistRet = %2 , notExistPoskeyList: %3 --->>>>]")
                         .arg( orderObj->id ).arg( bCheckAllPoskeyExistRet?1:0 ).arg( notExistPoskeyList.join(",") );
            if ( ! bCheckAllPoskeyExistRet ) {
                error = QString::fromLocal8Bit("This Order PosKey No Real Exist Or Expired: %1 ").arg( notExistPoskeyList.join(",") );
            }
        }

        if ( orderObj->posKeyList.isEmpty() || ! bCheckAllPoskeyExistRet ) {
            FlowControl::GetInstance()._AddOrUpdateReportOmsList(orderObj->id,  orderObj->channel,requestType, QString("4"), QString(""), error, QString("1012"));
            // 存储订单商品入库异常, 同步更新入机状态表数据, 便于退货单过来时 参考销售单入机情况;
            FlowControl::GetInstance()._AddInputPosSuccessPresistList(orderObj->id, orderObj->channel, requestType, "4", QString(""), error, QString("1012") );
            // 非法数据, 弹框告警;
            QString  warnMsg =  QString::fromLocal8Bit("Illegal Goods data, Please Check...;    OrderId Last 5:  %1;    GoodsName:  %2;    GoodsPosKey:  %3;    GoodsQty:  %4")
                    .arg( orderObj->id.mid(orderObj->id.length() - 5, 5) ).arg("*").arg( notExistPoskeyList.join(",") ).arg("*");
            emit triggerFlowContrlAlert(AlertForm::WARNNING,warnMsg);
        }

    }

    return bCheckAllPoskeyExistRet;
}

bool PrintCupStickPosDB::insertNormalProd(OrderObject* orderObj, const QString& posCheckNo){

    int inProdSucNum = 0;
    int insertMainProdIndex = 0 ;
    bool retIntSubProd = true;
    bool retIntDeliveryPackageAndPack = false;
    QSqlQuery query(m_sqlDb);
    QDateTime qdaTi = QDateTime::currentDateTimeUtc();

    if (!orderObj) {
        QLOG_ERROR()<<"insertNormalProd:: orderObj  Is Null";
        return false;
    }

    for (int i=0; i < orderObj->proList.count(); i++) {
        dishesObject* dish=orderObj->proList.at(i);
        query.prepare("INSERT INTO tb_main_prod_refinfo(chk_num, order_id, order_status, create_datetime, "
                      " prod_seq, prod_code, prod_name, prod_resv0, prod_resv4, prod_resv5, prod_price, prod_qty, prod_optionsCode, prod_discount, prod_discountName,"
                      " prod_starDiscount, prod_starDiscountName, prod_owner ) "
                      "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)   select @@identity ");
        query.addBindValue(posCheckNo.toInt());  // --小票号
        query.addBindValue(orderObj->id);  // --订单编号
        // query.addBindValue( orderObj->orderStatus );  // --订单状态(int);
        query.addBindValue( orderObj->orderSaleRefundStatus );  // --订单 销售退货状态 内存标识(int);
        query.addBindValue(qdaTi.addSecs(60*60*8).toString("yyyy-MM-dd hh:mm:ss")); // --商品入库时间
        query.addBindValue(i+1);               // --主商品序号;
        query.addBindValue(dish->code);   // --主商品SKU
        query.addBindValue(dish->name);   // --主商品名称
        query.addBindValue(dish->changePriceFlag);   // --主商品改价标志
        query.addBindValue(dish->supplyChainSku);   // --主商品 SKU 编码
        query.addBindValue(dish->enProductName);   // --主商品英文名称
        if ( OrderObject::Refunded == orderObj->orderStatus ) {
            query.addBindValue(0 - dish->price);   // --退货单主商品价格需为负数;
            query.addBindValue(0 - dish->qty);      // --退货单主商品数量需为负数;
        } else {
            query.addBindValue(dish->price);   // --主商品价格
            query.addBindValue(dish->qty);      // --主商品数量
        }
        query.addBindValue(dish->options);      // --主商品客制换Options;
        query.addBindValue(dish->promotionPrice * dish->promotionQty);      // --主商品 优惠折扣金额;
        query.addBindValue( dish->promotionName.left(25) );      // --主商品 优惠折扣名;
        query.addBindValue(dish->starPromotionPrice * dish->starPromotionQty);      // --主商品 星星折扣金额;
        query.addBindValue( dish->starPromotionName.left(25) );      // --主商品 星星折扣名;
        // (默认主商品的拼单人 拆字)  拆口令分配的字  |#|   拼单人昵称     例："世" |#| "Kernel(邹伍洋)"     分割符为:  "|#|"
        query.addBindValue(dish->userName + ( dish->wechatName.length() ? "|#|" + dish->wechatName : "" ) );  // --主商品-Owner 拼单人: 拆字 + 微信昵称

        if(!query.exec()) {
            QLOG_ERROR()<<"[<<<<---SqlServer Database: Insert tb_main_prod_refinfo Error--->>>>]"<<query.lastError().text()<<QString::number(query.lastError().type());
            QLOG_ERROR()<<QString("INSERT INTO tb_main_prod_refinfo(chk_num, order_id, order_status, create_datetime, "
                                 " prod_seq, prod_code, prod_name, prod_resv0, prod_resv4, prod_resv5, prod_price, prod_qty, prod_optionsCode, prod_discount, prod_discountName,"
                                 " prod_starDiscount, prod_starDiscountName, prod_owner) "
                                 "VALUES(%1, %2, %3, %4, %5, %6, %7, %8, %9, %10, %11, %12, %13, %14, %15, %16, %17, %18)   select @@identity ").arg(posCheckNo.toInt())
                         .arg(orderObj->id).arg(orderObj->orderStatus).arg(qdaTi.addSecs(60*60*8).toString("yyyy-MM-dd hh:mm:ss"))
                         .arg(i+1).arg(dish->code).arg(dish->name).arg(dish->changePriceFlag).arg(dish->supplyChainSku).arg(dish->enProductName).arg(dish->price).arg(dish->qty).arg(dish->options)
                         .arg(dish->promotionPrice * dish->promotionQty).arg(dish->promotionName).arg(dish->starPromotionPrice * dish->starPromotionQty)
                         .arg(dish->starPromotionName).arg(dish->userName + ( dish->wechatName.length() ? "|#|" + dish->wechatName : "" ) );

            break;
        } else {
            if ( query.first()  ) {
                insertMainProdIndex = query.value(0).toInt();
                query.clear();
                QLOG_INFO()<<QString("[<<<<---SqlServer Database:Insert OrderId %1 prodDishCode:%2  retProdIndex:%3  Into tb_main_prod_refinfo Success--->>>>]")
                             .arg(orderObj->id).arg(dish->code).arg(insertMainProdIndex);

                if ( !dish->sub_products.empty() ) {
                    retIntSubProd = insertNormalSubProd(orderObj, insertMainProdIndex, dish->sub_products, posCheckNo);
                }

                if ( retIntSubProd ) {  ++inProdSucNum; }
            }
        }
    }

    // 插入 配送费+打包费+打包属性;
    retIntDeliveryPackageAndPack = insertDeliveryPackageAndPack(orderObj, posCheckNo);

    if (inProdSucNum != orderObj->proList.count() || !retIntDeliveryPackageAndPack) {
        if ( inProdSucNum > 0 ) {
            query.prepare("delete from tb_main_prod_refinfo where order_id =" + orderObj->id) ;
            if(!query.exec())
            {
                QLOG_ERROR()<<QString("[<<<<---clear tb_main_prod_refinfo data  OrderId %1 failed--->>>>]").arg(orderObj->id)
                           <<query.lastError().text()<<QString::number(query.lastError().type());
            } else {
                QLOG_INFO()<<QString("[<<<<---clear tb_main_prod_refinfo data  OrderId %1 Success--->>>>]").arg(orderObj->id);
            }
        }
        return false;
    } else {
        return true;
    }
}


bool PrintCupStickPosDB::insertNormalSubProd(OrderObject* orderObj, const int mainProdIndex, QList<dishesObject*> &subProdList, const QString& posCheckNo) {

    int inSubPordSucNum = 0;
    int insertSubProdIndex = 0 ;
    QSqlQuery query(m_sqlDb);
    QDateTime qdaTi = QDateTime::currentDateTimeUtc();

    for (int i=0; i < subProdList.count(); i++) {
        dishesObject* subdish=subProdList.at(i);

        if ( subdish->code.contains("Default",Qt::CaseInsensitive) ) {
            ++inSubPordSucNum;
            continue;
        }

        query.prepare("INSERT INTO tb_main_prod_refinfo(chk_num, order_id, order_status, create_datetime, "
                      " prod_seq, prod_code, prod_name, prod_resv5, prod_price, prod_qty, prod_optionsCode, parent_id ) "
                      "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)   select @@identity ");
        query.addBindValue(posCheckNo.toInt());  // --小票号
        query.addBindValue(orderObj->id);  // --订单编号
        // query.addBindValue( orderObj->orderStatus );  // --订单状态(int);
        query.addBindValue( orderObj->orderSaleRefundStatus );  // --订单 销售退货状态 内存标识(int);
        query.addBindValue(qdaTi.addSecs(60*60*8).toString("yyyy-MM-dd hh:mm:ss")); // --商品入库时间
        query.addBindValue(0);               // --商品序号;
        query.addBindValue(subdish->code);   // --商品SKU
        query.addBindValue(subdish->name);   // --商品名称
        query.addBindValue(subdish->enProductName);   // --商品英文名称
        if ( OrderObject::Refunded == orderObj->orderStatus ) {
            query.addBindValue(0 - subdish->price);   // --退货单商品价格需为负数;
            query.addBindValue(0 - subdish->qty);      // --退货单商品数量需为负数;
        } else {
            query.addBindValue(subdish->price);   // --商品价格
            query.addBindValue(subdish->qty);      // --商品数量
        }
        query.addBindValue(subdish->options);      // --商品客制换Options;
        query.addBindValue(mainProdIndex);   // --父商品ID； 表字段 parent_id;

        if(!query.exec()) {
            QLOG_ERROR()<<"[<<<<---SqlServer Database: Insert tb_main_prod_refinfo Error--->>>>]"<<query.lastError().text()<<QString::number(query.lastError().type());
            QLOG_ERROR()<<QString("INSERT INTO tb_main_prod_refinfo(chk_num, order_id, order_status, create_datetime, "
                                 " prod_seq, prod_code, prod_name, prod_resv5, prod_price, prod_qty, prod_optionsCode, parent_id) "
                                 "VALUES(%1, %2, %3, %4, %5, %6, %7, %8, %9, %10, %11, %12)   select @@identity ").arg(posCheckNo.toInt())
                         .arg(orderObj->id).arg(orderObj->orderStatus).arg(qdaTi.addSecs(60*60*8).toString("yyyy-MM-dd hh:mm:ss"))
                         .arg(0).arg(subdish->code).arg(subdish->name).arg(subdish->enProductName).arg(subdish->price).arg(subdish->qty).arg(subdish->options)
                         .arg(mainProdIndex);

            break;
        } else {
            if ( query.first() ) {
                insertSubProdIndex = query.value(0).toInt();
                QLOG_INFO()<<QString("[<<<<---SqlServer Database:Insert OrderId %1 subDishCode:%2  retSubProdIndex:%3  Into tb_main_prod_refinfo Success--->>>>]")
                             .arg(orderObj->id).arg(subdish->code).arg(insertSubProdIndex);

                ++inSubPordSucNum;
            }
        }
    }

    if (inSubPordSucNum != subProdList.count() ) {
        return false;
    } else {
        return true;
    }
}


bool PrintCupStickPosDB::checkNormalProdAllVaild(OrderObject* orderObj){

    if (!orderObj) {
        QLOG_ERROR()<<"checkNormalProdAllVaild  Order Obj Point Is  Null";
        return false;
    }

    // 使用 PosKey 集合 与 POS数据库中进行校验, 每次校验前需要清空PosKey集合内容;
    orderObj->posKeyList.clear();

    QString tmpPosKey = "";
    QString tmpPosKeyName = "";
    QString tempPosKeyLeftHead = "";
    QStringList notExistPoskeyList;
    int tmpQty = 0;
    QString error = "";
    QString requestType = orderObj->orderStatus==6?QString::fromLocal8Bit("6"):QString::fromLocal8Bit("3");

    // 主商品列表是空时, 向上游系统汇报异常;
    if ( orderObj->proList.empty() ) {
        error = QString::fromLocal8Bit("This Order Main Product List Is Empty, Product Data Is Invalid !!! ");        
        FlowControl::GetInstance()._AddOrUpdateReportOmsList(orderObj->id,  orderObj->channel,requestType, QString("4"), QString(""), error, QString("1110"));
        // 存储订单商品入库异常, 同步更新入机状态表数据, 便于退货单过来时 参考销售单入机情况;
        FlowControl::GetInstance()._AddInputPosSuccessPresistList(orderObj->id, orderObj->channel, requestType, "4", QString(""), error, QString("1110") );

        // 非法数据, 弹框告警;
        QString  warnMsg =  QString::fromLocal8Bit("Invalid Goods data, Please Check...;    OrderId Last 5:  %1;    GoodsName:  %2;    GoodsPosKey:  %3;    GoodsQty:  %4")
                .arg( orderObj->id.mid(orderObj->id.length() - 5, 5) ).arg("Empty").arg("Empty").arg("Empty");
        emit triggerFlowContrlAlert(AlertForm::WARNNING,warnMsg);
        return false;
    }

    // 校验商品 Poskey 是否在本地数据库中有效;
    for (int i=0; i < orderObj->proList.count(); i++) {
        dishesObject* dish=orderObj->proList.at(i);

        tmpPosKey = dish->code;
        tmpPosKeyName = dish->name;
        tmpQty = dish->qty;
        // 检查主商品: ①主商品属性：code中含有Default字符串(不区分大小写) + ②code中以非数字开头 + ③商品数量是0 + ④PosKey长度在 [3~9] 之间;
        tempPosKeyLeftHead = tmpPosKey.left(1);
        if (tmpPosKey.contains("Default",Qt::CaseInsensitive) || (tempPosKeyLeftHead<QString('0') || tempPosKeyLeftHead>QString('9'))
                || !tmpQty || tmpPosKey.length()<3 || tmpPosKey.length()>9 ) {

            error = QString::fromLocal8Bit("This Order Has PosKey Is Combo Error Or Default*  Or  qty Is Zore  Or  Sku Length < 3 Or  Sku Length > 9");
            FlowControl::GetInstance()._AddOrUpdateReportOmsList(orderObj->id,  orderObj->channel,requestType, QString("4"), QString(""), error, QString("1010"));
            // 存储订单商品入库异常, 同步更新入机状态表数据, 便于退货单过来时 参考销售单入机情况;
            FlowControl::GetInstance()._AddInputPosSuccessPresistList(orderObj->id, orderObj->channel, requestType, "4", QString(""), error, QString("1010") );

            // 非法数据, 弹框告警;
            QString  warnMsg =  QString::fromLocal8Bit("Illegal Goods data, Please Check...;    OrderId Last 5:  %1;    GoodsName:  %2;    GoodsPosKey:  %3;    GoodsQty:  %4")
                    .arg( orderObj->id.mid(orderObj->id.length() - 5, 5) ).arg(tmpPosKeyName).arg(tmpPosKey).arg(tmpQty);
            emit triggerFlowContrlAlert(AlertForm::WARNNING,warnMsg);

            return false;
        }

        // 追加主商品PosKey 到 PosKey集合
        if ( !orderObj->posKeyList.contains(tmpPosKey) ) {
            orderObj->posKeyList.append(tmpPosKey);
        }

        // 检查主商品的options有效性; ①主商品属性：code中含有Default字符串(不区分大小写) + ②code中以非数字开头 + ③PosKey长度在 [3~9] 之间;
        if ( dish->options.length() ) {
            tmpPosKey = dish->options;
            tempPosKeyLeftHead = tmpPosKey.left(1);

            if (tmpPosKey.contains("Default",Qt::CaseInsensitive) || (tempPosKeyLeftHead<QString('0') || tempPosKeyLeftHead>QString('9'))
                    || tmpPosKey.length()<3 || tmpPosKey.length()>9 ) {

                error = QString::fromLocal8Bit("This Order Has PosKey Is Combo Error Or Default*  Or  qty Is Zore  Or  Sku Length < 3 Or  Sku Length > 9");
                FlowControl::GetInstance()._AddOrUpdateReportOmsList(orderObj->id,  orderObj->channel,requestType, QString("4"), QString(""), error, QString("1010"));
                // 存储订单商品入库异常, 同步更新入机状态表数据, 便于退货单过来时 参考销售单入机情况;
                FlowControl::GetInstance()._AddInputPosSuccessPresistList(orderObj->id, orderObj->channel, requestType, "4", QString(""), error, QString("1010") );

                // 非法数据, 弹框告警;
                QString  warnMsg =  QString::fromLocal8Bit("Illegal Goods data, Please Check...;    OrderId Last 5:  %1;    GoodsName:  %2;    GoodsPosKey:  %3;    GoodsQty:  %4")
                        .arg( orderObj->id.mid(orderObj->id.length() - 5, 5) ).arg("*").arg(tmpPosKey).arg("*");
                emit triggerFlowContrlAlert(AlertForm::WARNNING,warnMsg);

                return false;
            }

            // 追加主商品的options PosKey 到 PosKey集合
            if ( !orderObj->posKeyList.contains(tmpPosKey) ) {
                orderObj->posKeyList.append(tmpPosKey);
            }

        }

        // 遍历检查子商品;
        for ( int j = 0; j < dish->sub_products.count(); j++ ) {
            dishesObject* subDish=dish->sub_products.at(j);
            tmpPosKey = subDish->code;
            tmpPosKeyName = subDish->name;
            tmpQty = subDish->qty;
            tempPosKeyLeftHead = tmpPosKey.left(1);
            // 检查子商品: ①允许子商品{code中含有Default字符串,不区分大小写} 属性: ①code中以非数字开头 + ②商品数量是0 + ③PosKey长度在 [3~9] 之间;
            if( tmpPosKey.contains("Default",Qt::CaseInsensitive)  ) {
                continue;
            } else {
                if ( tempPosKeyLeftHead<QString('0') || tempPosKeyLeftHead>QString('9') || !tmpQty  ||  tmpPosKey.length()<3 ||  tmpPosKey.length()>9 ) {

                    error = QString::fromLocal8Bit("This Order SubProduct PosKey Is String And No Default* Or  qty Is Zore Or Sku Length < 3 Or Sku Length > 9 ");
                    FlowControl::GetInstance()._AddOrUpdateReportOmsList(orderObj->id,  orderObj->channel,requestType, QString("4"), QString(""), error, QString("1011"));
                    // 存储订单商品入库异常, 同步更新入机状态表数据, 便于退货单过来时 参考销售单入机情况;
                    FlowControl::GetInstance()._AddInputPosSuccessPresistList(orderObj->id, orderObj->channel, requestType, "4", QString(""), error, QString("1011") );

                    // 非法数据, 弹框告警;
                    QString  warnMsg =  QString::fromLocal8Bit("Illegal Goods data, Please Check...;    OrderId Last 5:  %1;    GoodsName:  %2;    GoodsPosKey:  %3;    GoodsQty:  %4")
                            .arg( orderObj->id.mid(orderObj->id.length() - 5, 5) ).arg(tmpPosKeyName).arg(tmpPosKey).arg(tmpQty);
                    emit triggerFlowContrlAlert(AlertForm::WARNNING,warnMsg);

                    return false;
                }

                // 追加有效子商品的 PosKey 到 PosKey集合
                if ( !orderObj->posKeyList.contains(tmpPosKey) ) {
                    orderObj->posKeyList.append(tmpPosKey);
                }
            }
        }

    }


    // 校验 PosKey 在POS数据库中的有效性: * 只有解耦2.0 版本才会一次性校验 PosKey 的有效性;
    bool bCheckAllPoskeyExistRet = false;
    if ( orderObj->decouplePosVersion < 20  && !ConfigManger::GetInstance().GetPoskeyExistVerify() ) {
        bCheckAllPoskeyExistRet = true;
    } else {
        bCheckAllPoskeyExistRet = CheckPoskeyExistPosDB::getInstance().allPoskeyExistDB( orderObj, notExistPoskeyList );
        QLOG_INFO()<<QString("[<<<<---SqlServer Database: checkNormalProdAllVaild,  orderId = %1  bCheckAllPoskeyExistRet = %2 , "
                             "notExistPoskeyList: %3 --->>>>]").arg( orderObj->id ).arg( bCheckAllPoskeyExistRet?1:0 ).arg( notExistPoskeyList.join(",") );

        if ( ! bCheckAllPoskeyExistRet ) {

            error = QString::fromLocal8Bit("This Order PosKey No Real Exist Or Expired: %1 ").arg( notExistPoskeyList.join(",") );
            FlowControl::GetInstance()._AddOrUpdateReportOmsList(orderObj->id,  orderObj->channel,requestType, QString("4"), QString(""), error, QString("1012"));
            // 存储订单商品入库异常, 同步更新入机状态表数据, 便于退货单过来时 参考销售单入机情况;
            FlowControl::GetInstance()._AddInputPosSuccessPresistList(orderObj->id, orderObj->channel, requestType, "4", QString(""), error, QString("1012") );

            // 非法数据, 弹框告警;
            QString  warnMsg =  QString::fromLocal8Bit("Illegal Goods data, Please Check...;    OrderId Last 5:  %1;    GoodsName:  %2;    GoodsPosKey:  %3;    GoodsQty:  %4")
                    .arg( orderObj->id.mid(orderObj->id.length() - 5, 5) ).arg("*").arg( notExistPoskeyList.join(",") ).arg("*");
            emit triggerFlowContrlAlert(AlertForm::WARNNING,warnMsg);
        }
    }

    return bCheckAllPoskeyExistRet;
}


bool PrintCupStickPosDB::insertDeliveryPackageAndPack(OrderObject* orderObj, const QString& posCheckNo){
    bool insertPackRet = true ;
    int    insertPackPlaceHolderSeq = 0;
    bool insertPackageFeeRet = true ;

    QSqlQuery query(m_sqlDb);
    QDateTime qdaTi = QDateTime::currentDateTimeUtc();

    if( orderObj->isPackage && orderObj->packageSku.length() ) {
        // Insert Pack Flag Into tb_main_prod_refinfo;
        query.prepare("INSERT INTO tb_main_prod_refinfo(chk_num, order_id, order_status, create_datetime, "
                      " prod_seq, prod_code, prod_name, prod_resv5, prod_price, prod_qty, prod_optionsCode, parent_id ) "
                      "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
        query.addBindValue(posCheckNo.toInt());  // --小票号
        query.addBindValue(orderObj->id);  // --订单编号
        // query.addBindValue( orderObj->orderStatus );  // --订单状态(int);
        query.addBindValue( orderObj->orderSaleRefundStatus );  // --订单 销售退货状态 内存标识(int);
        query.addBindValue(qdaTi.addSecs(60*60*8).toString("yyyy-MM-dd hh:mm:ss")); // --商品入库时间
        query.addBindValue( orderObj->proList.count() + 1 );               // --商品序号;
        query.addBindValue(orderObj->packageSku);   // --商品SKU  //不入机模式,无需考虑入机POSkey限制
        query.addBindValue("Pack");   // --商品名称
        query.addBindValue("Pack");   // --商品英文名称
        query.addBindValue(0);   // --商品价格
        if ( OrderObject::Refunded == orderObj->orderStatus ) {
            query.addBindValue(-1);    // --退货单商品数量需为负数;
        } else {
            query.addBindValue(1);      // --商品数量
        }
        query.addBindValue("");      // --商品客制换Options;
        query.addBindValue(0);   // --父商品ID； 表字段 parent_id;

        if(!query.exec()) {
            QLOG_ERROR()<<"[<<<<---SqlServer Database: Insert tb_main_prod_refinfo Error--->>>>]"<<query.lastError().text()<<QString::number(query.lastError().type());
            QLOG_ERROR()<<QString("INSERT INTO tb_main_prod_refinfo(chk_num, order_id, order_status, create_datetime, "
                                 " prod_seq, prod_code, prod_name, prod_resv5, prod_price, prod_qty, prod_optionsCode, parent_id) "
                                 "VALUES(%1, %2, %3, %4, %5, %6, %7, %8, %9, %10, %11, %12)").arg(posCheckNo.toInt())
                         .arg(orderObj->id).arg(orderObj->orderStatus).arg(qdaTi.addSecs(60*60*8).toString("yyyy-MM-dd hh:mm:ss"))
                         .arg( orderObj->proList.count() +1).arg(orderObj->packageSku).arg("Pack").arg("Pack").arg(0).arg(1).arg("")
                         .arg(0);
            insertPackRet = false;
            return false;
        } else {
            insertPackPlaceHolderSeq = 1;
            QLOG_INFO()<<QString("[<<<<---SqlServer Database:Insert OrderId %1 Pack Flag :%2  Into tb_main_prod_refinfo Success--->>>>]")
                             .arg(orderObj->id).arg(orderObj->packageSku);
        }
    }

    if ( !orderObj->packageFeeAtProduct && ( orderObj->channel == "MOD" || orderObj->channel == "ELE"  || orderObj->channel == "MT-MOD" ) ) {

        // Insert Package Fee Into tb_main_prod_refinfo;
        query.prepare("INSERT INTO tb_main_prod_refinfo(chk_num, order_id, order_status, create_datetime, "
                      " prod_seq, prod_code, prod_name, prod_resv5, prod_price, prod_qty, prod_optionsCode, parent_id ) "
                      "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
        query.addBindValue(posCheckNo.toInt());  // --小票号
        query.addBindValue(orderObj->id);  // --订单编号
        // query.addBindValue( orderObj->orderStatus );  // --订单状态(int);
        query.addBindValue( orderObj->orderSaleRefundStatus );  // --订单 销售退货状态 内存标识(int);
        query.addBindValue(qdaTi.addSecs(60*60*8).toString("yyyy-MM-dd hh:mm:ss")); // --商品入库时间
        query.addBindValue( orderObj->proList.count() +1 + insertPackPlaceHolderSeq );               // --商品序号;
        query.addBindValue("6000201");   // --商品SKU  //不入机模式,无需考虑入机POSkey限制
        query.addBindValue("PackageFee");   // --商品名称
        query.addBindValue("PackageFee");   // --商品英文名称
        if ( OrderObject::Refunded == orderObj->orderStatus ) {
            query.addBindValue(0 - orderObj->packageFee);    // --退货单商品价格需为负数;
            query.addBindValue(-1);      // --退货单商品数量需为负数
        } else {
            query.addBindValue(orderObj->packageFee);   // --商品价格
            query.addBindValue(1);      // --商品数量
        }
        query.addBindValue("");      // --商品客制换Options;
        query.addBindValue(0);   // --父商品ID； 表字段 parent_id;

        if(!query.exec()) {
            QLOG_ERROR()<<"[<<<<---SqlServer Database: Insert tb_main_prod_refinfo Error--->>>>]"<<query.lastError().text()<<QString::number(query.lastError().type());
            QLOG_ERROR()<<QString("INSERT INTO tb_main_prod_refinfo(chk_num, order_id, order_status, create_datetime, "
                                 " prod_seq, prod_code, prod_name, prod_resv5, prod_price, prod_qty, prod_optionsCode, parent_id) "
                                 "VALUES(%1, %2, %3, %4, %5, %6, %7, %8, %9, %10, %11, %12)").arg(posCheckNo.toInt())
                         .arg(orderObj->id).arg(orderObj->orderStatus).arg(qdaTi.addSecs(60*60*8).toString("yyyy-MM-dd hh:mm:ss"))
                         .arg( orderObj->proList.count() +1 + insertPackPlaceHolderSeq ).arg("6000201").arg("PackageFee").arg("PackageFee").arg(orderObj->packageFee).arg(1).arg("")
                         .arg(0);
            insertPackageFeeRet = false;
            return false;
        } else {
            QLOG_INFO()<<QString("[<<<<---SqlServer Database:Insert OrderId %1 PackageFee:%2  Into tb_main_prod_refinfo Success--->>>>]")
                             .arg(orderObj->id).arg(orderObj->packageFee);
        }

        // 上游oms 开关已完全打开: 配送费已添加到商品列表中; 顾无需此处配送费整合逻辑;
    }

    if ( !insertPackageFeeRet ||  !insertPackRet ) {
        return false;
    } else {
        return true;
    }
}


bool PrintCupStickPosDB::updateOrderProductCheckNum(OrderObject* orderObj,const QString& posCheckNo){
    QMutexLocker mutex(&m_mutex);
    if(!m_sqlDb.open()) {
        QLOG_ERROR()<<"[<<<<---SqlServer Database:Open Failed--->>>>]"<<m_sqlDb.lastError().text();
        return false;
    }
    bool result;
    QSqlQuery query(m_sqlDb);
    if ( orderObj->orderStatus == OrderObject::Refunded) {
        query.prepare(QString("update tb_main_prod_refinfo set chk_num =%1 where order_status=6 and order_id='%2' ").arg( posCheckNo.toInt() ).arg(orderObj->id) );
    } else {
        query.prepare(QString("update tb_main_prod_refinfo set chk_num =%1 where order_status <> 6 and order_id='%2' ").arg( posCheckNo.toInt() ).arg(orderObj->id) );
    }

    if(!query.exec()) {
        QLOG_ERROR()<<"[<<<<---SqlServer Database:Update  tb_main_prod_refinfo  Failed --->>>>]"<<orderObj->id<<query.lastError().text();
        result= false;
    } else {
        QLOG_INFO()<<QString("[<<<<---SqlServer Database:Update tb_main_prod_refinfo OrderId %1 CheckNum:%2  Success--->>>>]")
                         .arg(orderObj->id).arg(posCheckNo);
         result= true;
    }

    m_sqlDb.close();
    return result;

}

bool PrintCupStickPosDB::isOrderProductExist( OrderObject* orderObj) {
    QMutexLocker mutex(&m_mutex);
    if(!m_sqlDb.open()) {
        QLOG_ERROR()<<"[<<<<---SqlServer Database:Open Failed--->>>>]"<<m_sqlDb.lastError().text();
        return false;
    }
    bool result;
    QSqlQuery query(m_sqlDb);
    if ( orderObj->orderStatus == OrderObject::Refunded ) {
        query.prepare(QString("select order_id from tb_main_prod_refinfo where order_id='%1' and order_status = 6 ").arg(orderObj->id) );
    } else {
        query.prepare(QString("select order_id from tb_main_prod_refinfo where order_id='%1' and order_status <> 6 ").arg(orderObj->id) );
    }

    if(!query.exec()) {
        QLOG_ERROR()<<"[<<<<---SqlServer Database:isOrderProductExist--->>>>] order_id: "<<orderObj->id
                   << " order_status: "<<orderObj->orderStatus<<query.lastError().text();
        result= false;
    }
    if(query.first()) {
        result= true;
    } else {
        result = false;
    }
    m_sqlDb.close();
    return result;
}

bool PrintCupStickPosDB::deleteProductRecord(QString creatTime)
{
    //QMutexLocker mutex(&m_mutex);
    bool retTryLock = m_mutex.tryLock(VALUE_TRYLOCKNETTIMEOUT);
    if(!retTryLock){
        QLOG_ERROR()<<"[<<<<---PrintCupStickPosDB::deleteProductRecord Try Lock Failed--->>>>]";
        return false;
    }
    if(!m_sqlDb.open()) {
        QLOG_ERROR()<<"[<<<<---PrintCupStickPosDB::deleteProductRecord Open Failed--->>>>]"<<m_sqlDb.lastError().text();
        m_mutex.unlock();
        return false;
    }
    bool result=true;
    QLOG_INFO()<<QString("[<<<<---PrintCupStickPosDB::begin deleteProductRecord create_datetime:%1--->>>>]").arg(creatTime);
    QSqlQuery query(m_sqlDb);
    query.prepare(QString("delete from tb_main_prod_refinfo where create_datetime<'%1'").arg(creatTime));
    if(!query.exec()) {
        QLOG_ERROR()<<query.lastError().text()<<__FUNCTION__;
        result= false;
    }
    m_sqlDb.close();
    m_mutex.unlock();
    return result;
}

bool PrintCupStickPosDB::queryValue(const QString& orderId, const QString& key, QString& error, QVariant &value){
    QMutexLocker mutex(&m_mutex);
    if(!m_sqlDb.open()) {
        error.append(QString("SqlServer Database:Open Failed").append(m_sqlDb.lastError().text()));
        return false;
    }
    QSqlQuery query(m_sqlDb);
    query.prepare(QString("select %1 from tb_main_prod_refinfo where order_id='%1'").arg(key).arg(orderId));
    if(!query.exec()) {
        error.append(query.lastError().text());
        m_sqlDb.close();
        return false;
    } else {
        while(query.next()) {
            value= query.value(0);
        }
    }
    m_sqlDb.close();
    return true;
}

bool PrintCupStickPosDB::queryIsNull(const QString &orderId, const QString& key,QString &error, bool &result){
    QMutexLocker mutex(&m_mutex);
    if(!m_sqlDb.open()) {
        error.append(QString("SqlServer Database:Open Failed").append(m_sqlDb.lastError().text()));
        return false;
    }
    QSqlQuery query(m_sqlDb);
    query.prepare(QString("select %1 from tb_main_prod_refinfo where order_id=%2 and %3 is null").arg(orderId,orderId,key));
    if(!query.exec()) {
        error.append(query.lastError().text());
        m_sqlDb.close();
        return false;
    } else {
        if(query.first()) {
            result= true;
        } else{
            result = false;
        }
    }
    m_sqlDb.close();
    return true;
}
