Commit 939ebb5b by wuyang.zou

New Feature And Fix Bug

<1> 现有POS插件隔日预约单不打印预约时间的bug修复
<2> 插件支持将配送费添加到 商品列表中【且支持微信非现金折扣】
<3> 校验退货订单入机时,配送费金额被篡改;
<4> 参数化配置:支持订单先存储打印数据,后入机模式;
<5> 修正低概率 下单立刻被取消导致订单缺少入机退货单的单边账Bug;

Version: 2.2021.5.11
parent 26bc1646
Pipeline #32698 failed with stage
in 0 seconds
......@@ -60,6 +60,12 @@ private:
QString orderId;
}PullOrderInfo;
typedef struct TO_DELAY_PULL_ORDER
{
QString channel;
QString orderId;
}DelayPullOrderInfo;
typedef struct ORDER_OPERATION
{
int operation;//1:接单,0:取消订单
......@@ -108,6 +114,8 @@ private:
int m_orderCount;
int m_clickPosCount;
// int m_skipRecordPos; //使用订单级别: OrderObject->decouplePosVersion 标识;
// 标识是否着急打印汇总单; 1:着急打印,提前将汇总单和打印记录添加到数据库; 0:默认,不着急打印,入机后才会将汇总单和打印记录添加到数据库
int m_hurryPrintSum;
//订单清除定时器
QTimer *m_clearTimer;
QTimer *m_heartTimer;
......@@ -116,6 +124,7 @@ private:
QTimer *m_loginTimer;
QTimer *m_notifySimPullTimer;
QTimer *m_storageOrderTimer;
QTimer *m_delayGetRefundDetailTimer;
QTimer *m_remindCasherBlinkFloatTimer; //插件程序收到外卖订单后,需要一致提醒店员[直到此外卖订单被全部录入到POS系统]
// 网络通信
BillSocket *m_loginSocket;
......@@ -145,6 +154,15 @@ private:
//等待Simphony拉取的有效订单队列list[orderId]
QStringList m_simValidOrdersList;
// 延迟拉取订单详情的 延迟队列list [DelayPullOrderInfo]
// 场景描述: 在入机销售单时,Action1 Action5 已完成, Action4 未完成; 此时拉取退单的订单详情后,
// DB 中销售单未标识入机成功,导致入机小票是销售单, 汇报入机是退货标识; 【退单入机出现遗漏】
// 解决方案: 将所有 OMS 推送的 退单请求 添加到 延迟获取退单详情队列中; 15s 中进行筛选,给销售单入机预留更多时间,避免冲突;
// 没有冲突时,添加到 正常获取订单详情队列进行排队获取订单详情,走后续流程。
// 有冲突时,继续添加到 延迟退单队列的尾部;直到 通过筛选条件,进入正常获取订单详情队列;
QList<DelayPullOrderInfo*> m_delayGetRefundDetailList;
QMutex m_delayGetRefundDetailMutex;
//订单号与pos短号映射:[可能同时存在两种状态:1:新单记录;2:退单记录;但是小票号就存一个;]
QMap<QString,QString> m_orderIdToPosCheckNoMap;
//记录当前订单操作
......@@ -401,6 +419,10 @@ private slots:
// 功能:将队列 m_storagePosOrdersList 中的订单数据 持久化存储到POS本地数据库;
void _StoragePosOrderData();
// 功能:扫描 延迟获取退单详情list, 从而保证退单入机不出现单边账(退单更新了销售单的标志与汇报结果了);
// 无效的退单请求,将被再次追加在 本延迟队列尾部;等待10s后的下次扫描;
void _ScanDelayGetRefundDetailList();
void _RemindCasherBlinkFloatForm();
void _OrderAnalysis(const QJsonObject &jsonObject);
......
......@@ -180,9 +180,9 @@ int ConfigManger::GetSubStoreSkipVerify()
return m_config->value(INI_SUBSTORESKIPVERIFY).toInt();
}
int ConfigManger::GetSkipRecordPos()
int ConfigManger::GetHurryPrintSum()
{
return m_config->value(INI_SKIPRECORDPOS).toInt();
return m_config->value(INI_HURRYPRINTSUM).toInt();
}
int ConfigManger::GetNoHurryRecordPos()
......
......@@ -141,8 +141,8 @@ public:
int GetOrderSslConfig();
int GetSubStoreSkipVerify();
int GetSkipRecordPos();
int GetNoHurryRecordPos();
int GetHurryPrintSum();
// 长连接连接 PosAgent 配置端口;
int GetPosAgentSvrPort();
......
......@@ -569,43 +569,49 @@ bool PrintCupStickPosDB::insertDeliveryPackageAndPack(OrderObject* orderObj, con
}
// Insert Delivery 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(qdaTi.addSecs(60*60*8).toString("yyyy-MM-dd hh:mm:ss")); // --商品入库时间
query.addBindValue( orderObj->proList.count() + 1 + insertPackPlaceHolderSeq + insertPackageFeePlaceHolderSeq ); // --商品序号;
query.addBindValue("710000268"); // --商品SKU //不入机模式,无需考虑入机POSkey限制
query.addBindValue("DeliveryFee"); // --商品名称
query.addBindValue("DeliveryFee"); // --商品英文名称
if ( OrderObject::Refunded == orderObj->orderStatus ) {
query.addBindValue(0 - orderObj->deliveryPrice); // --退货单商品价格需为负数;
query.addBindValue(-1); // --商品数量
if ( orderObj->deliveryAtProd ) {
QLOG_INFO()<<QString("[<<<<---SqlServer Database: OrderId %1 deliveryAtProd:%2 Is True, No Need Insert DeliveryFee Into tb_main_prod_refinfo --->>>>]")
.arg(orderObj->id).arg(orderObj->deliveryAtProd?1:0);
} else {
query.addBindValue(orderObj->deliveryPrice); // --商品价格
query.addBindValue(1); // --商品数量
// Insert Delivery 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(qdaTi.addSecs(60*60*8).toString("yyyy-MM-dd hh:mm:ss")); // --商品入库时间
query.addBindValue( orderObj->proList.count() + 1 + insertPackPlaceHolderSeq + insertPackageFeePlaceHolderSeq ); // --商品序号;
query.addBindValue("710000268"); // --商品SKU //不入机模式,无需考虑入机POSkey限制
query.addBindValue("DeliveryFee"); // --商品名称
query.addBindValue("DeliveryFee"); // --商品英文名称
if ( OrderObject::Refunded == orderObj->orderStatus ) {
query.addBindValue(0 - orderObj->deliveryPrice); // --退货单商品价格需为负数;
query.addBindValue(-1); // --商品数量
} else {
query.addBindValue(orderObj->deliveryPrice); // --商品价格
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 + insertPackageFeePlaceHolderSeq ).arg("710000268")
.arg("DeliveryFee").arg("DeliveryFee").arg(orderObj->deliveryPrice).arg(1).arg("")
.arg(0);
insertDeliveryFeeRet = false;
return false;
} else {
QLOG_INFO()<<QString("[<<<<---SqlServer Database:Insert OrderId %1 DeliveryFee:%2 Into tb_main_prod_refinfo Success--->>>>]")
.arg(orderObj->id).arg(orderObj->deliveryPrice);
}
}
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 + insertPackageFeePlaceHolderSeq ).arg("710000268")
.arg("DeliveryFee").arg("DeliveryFee").arg(orderObj->deliveryPrice).arg(1).arg("")
.arg(0);
insertDeliveryFeeRet = false;
return false;
} else {
QLOG_INFO()<<QString("[<<<<---SqlServer Database:Insert OrderId %1 DeliveryFee:%2 Into tb_main_prod_refinfo Success--->>>>]")
.arg(orderObj->id).arg(orderObj->deliveryPrice);
}
}
if ( !insertDeliveryFeeRet || !insertPackageFeeRet || !insertPackRet ) {
......
......@@ -794,7 +794,7 @@ bool PrintSumBillPosDB::insertOrderSumBill(OrderObject* orderObj, const QString&
int tempBusinessType = orderObj->businessType.toInt();
if ( "WSG-MOD" == orderObj->channel && "4" == orderObj->platformSource)
tempBusinessType = 20;
if ( 7 == orderObj->orderType ) {
if ( 7 == orderObj->orderType || 11 == orderObj->orderType) {
tempBusinessType = 10;
} else if ( 8 == orderObj->orderType ) {
tempBusinessType = 30;
......@@ -890,7 +890,7 @@ bool PrintSumBillPosDB::insertOrderSumBill(OrderObject* orderObj, const QString&
}
// 订单解耦前需入机订单 && 订单状态为取消 && 预约订单时,需要更新 该订单在tb_msr_customer_info表中全部记录的订单状态;
if ( orderObj->decouplePosVersion < 20 && OrderObject::Refunded ==orderObj->orderStatus && 7 == orderObj->orderType) {
if ( orderObj->decouplePosVersion < 20 && OrderObject::Refunded ==orderObj->orderStatus && ( 7 == orderObj->orderType || 11 == orderObj->orderType ) ) {
QSqlQuery updateQuery(m_sqlDb);
// 销售单存 1 记录(自定义组装 小票号); 退货时 也会存 1 记录(自定义组装 小票号); 该订单号将会出现两个退货记录 且 小票号还不一致
// 2021-04-11 存在此类潜在Bug(在入口添加 仅 解耦前会有此逻辑): 预约单退货场景[或许删除 销售单记录 会避免此类问题];
......@@ -935,7 +935,7 @@ bool PrintSumBillPosDB::updateSumBillCknoAndCktime(OrderObject* orderObj, const
.arg( posCheckNo.toInt() ).arg( posCheckOpenTime ).arg( orderObj->id ) );
}
} else {
if (OrderObject::Refunded ==orderObj->orderStatus && 7 == orderObj->orderType) {
if (OrderObject::Refunded ==orderObj->orderStatus && ( 7 == orderObj->orderType || 11 == orderObj->orderType ) ) {
updateQuery.prepare(QString("update tb_msr_customer_info set chk_num = %1, create_datetime = '%2', order_status = 6 where order_id = '%3' ")
.arg( posCheckNo.toInt() ).arg( posCheckOpenTime ).arg(orderObj->id));
} else {
......@@ -963,7 +963,7 @@ int PrintSumBillPosDB::syncOrderDataToDB(OrderObject* orderObj) {
// 0: 同步失败;1: 无需同步;2: 同步成功;
int syncAppointOrder = 1;
// 1、同步 预约当日订单的 "提前到店" 信息,避免出现 遗漏;
if ( OrderObject::Refunded != orderObj->orderStatus && 7 == orderObj->orderType && orderObj->inAdvanceTakemeal ) {
if ( OrderObject::Refunded != orderObj->orderStatus && ( 7 == orderObj->orderType || 11 == orderObj->orderType ) && orderObj->inAdvanceTakemeal ) {
syncAppointOrder = syncAppointOrderInfo(orderObj);
QLOG_INFO()<<QString("[<<<<---syncOrderDataToDB syncAppointOrderInfo OrderId %1 ArriverAhead:%2 syncAppointOrder:%3--->>>>]")
.arg(orderObj->id).arg(orderObj->inAdvanceTakemeal).arg(syncAppointOrder);
......@@ -1036,7 +1036,7 @@ int PrintSumBillPosDB::updateOrderDataToDB(OrderObject* orderObj, const QString
int updateAppointOrder = 1;
if ("appointed_remindTemplate"==cloumnName ) {
// 1、更新 预约当日订单的 "提前到店" 信息,避免出现 遗漏;
if ( OrderObject::Refunded != orderObj->orderStatus && 7 == orderObj->orderType && orderObj->inAdvanceTakemeal ) {
if ( OrderObject::Refunded != orderObj->orderStatus && ( 7 == orderObj->orderType || 11 == orderObj->orderType ) && orderObj->inAdvanceTakemeal ) {
updateAppointOrder = updateAppointOrderInfo(orderObj) ? 2: 0 ;
QLOG_INFO()<<QString("[<<<<---updateOrderDataToDB updateAppointOrderInfo OrderId %1 "
"ArriverAhead:%2 updateAppointOrder:%3 lastExpectDate:%4 --->>>>]")
......@@ -1142,6 +1142,33 @@ bool PrintSumBillPosDB::isOrderSumBillExist(OrderObject* orderObj){
return result;
}
bool PrintSumBillPosDB::deleteSumBillRecord(QString creatTime)
{
bool retTryLock = m_mutex.tryLock(VALUE_TRYLOCKNETTIMEOUT);
if(!retTryLock){
QLOG_ERROR()<<"[<<<<---PrintSumBillPosDB::deleteSumBillRecord Try Lock Failed--->>>>]";
return false;
}
if(!m_sqlDb.open()) {
QLOG_ERROR()<<"[<<<<---PrintSumBillPosDB::deleteSumBillRecord Open Failed--->>>>]"<<m_sqlDb.lastError().text();
m_mutex.unlock();
return false;
}
bool result=true;
QLOG_INFO()<<QString("[<<<<---PrintSumBillPosDB::begin deleteSumBillRecord create_datetime:%1--->>>>]").arg(creatTime);
QSqlQuery query(m_sqlDb);
query.prepare(QString("delete from tb_msr_customer_info 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 PrintSumBillPosDB::queryValue(const QString& orderId, const QString& key, QString& error, QVariant &value){
QMutexLocker mutex(&m_mutex);
if(!m_sqlDb.open()) {
......
......@@ -121,6 +121,13 @@ public:
**/
bool isOrderSumBillExist(OrderObject* orderObj);
/**
*功能:清除汇总账单DB 中过期记录;
*参数:[1]记录创建时间
*返回:true是,false否
**/
bool deleteSumBillRecord(QString creatTime);
bool queryValue(const QString& orderId, const QString& key, QString& error, QVariant &value);
bool queryIsNull(const QString &orderId, const QString& key,QString &error, bool &result);
......
......@@ -55,7 +55,11 @@ void LoaclHttpServer::run()
/***将FM外卖插件中的合法有效数据返回给上面Http发过来的请求***/
replyObject = FlowControl::GetInstance()._PackHttpReplyJson(status, msg, data, iscontinue, orderId);
QLOG_INFO() << QString::fromLocal8Bit("[<<<<---FM外卖插件回应Http拉单请求后的返回结果:--->>>>]") << replyObject;
session->replyJsonObject(replyObject);
if( !session.isNull() ) {
session->replyJsonObject(replyObject);
} else {
QLOG_INFO() << QString::fromLocal8Bit("[<<<<---FM外卖插件回应Http拉单请求, Session Is Null, Skip Response --->>>>]");
}
}
/***解析FM外卖插件HTTP服务与Http请求的会话连接是否断开: 会话连接断开***/
else{
......
......@@ -249,7 +249,9 @@ QString OrderObject::getChannelName()
if ( 3 == orderType ) {
return QString::fromLocal8Bit("星-客诉");
}else if ( 7 == orderType ) {
return QString::fromLocal8Bit("预-MOD");
return QString::fromLocal8Bit("预-MOD-当日");
}else if ( 11 == orderType ) {
return QString::fromLocal8Bit("预-MOD-隔日");
}else if ( 8 == orderType ) {
return QString::fromLocal8Bit("拼-MOD");
} else {
......@@ -265,7 +267,9 @@ QString OrderObject::getChannelName()
}else if("ELE" == channel){
if ( 7 == orderType ) {
return QString::fromLocal8Bit("预-饿了么");
return QString::fromLocal8Bit("预-饿了么-当日");
}else if ( 11 == orderType ) {
return QString::fromLocal8Bit("预-饿了么-隔日");
} else {
return QString::fromLocal8Bit("饿了么");
}
......@@ -274,7 +278,9 @@ QString OrderObject::getChannelName()
if ( 4 == orderType ) {
return QString::fromLocal8Bit("星-自测");
} else if ( 7 == orderType ) {
return QString::fromLocal8Bit("预-MOP");
return QString::fromLocal8Bit("预-MOP-当日");
} else if ( 11 == orderType ) {
return QString::fromLocal8Bit("预-MOP-隔日");
} else if ( 8 == orderType ) {
return QString::fromLocal8Bit("拼-MOP");
} else if (10 == orderType) {
......
......@@ -96,6 +96,7 @@ class OrderObject : public QObject
Q_PROPERTY (QString tenderDeliveryDiscountBSku READ getTenderDeliveryDiscountBSku WRITE setTenderDeliveryDiscountBSku)
Q_PROPERTY (int decouplePosVersion READ getDecouplePosVersion WRITE setDecouplePosVersion)
Q_PROPERTY (bool deliveryAtProd READ getDeliveryAtProd WRITE setDeliveryAtProd)
Q_PROPERTY (int globalServiceType READ getGlobalServiceType WRITE setGlobalServiceType)
Q_PROPERTY (int globalOrderType READ getGlobalOrderType WRITE setGlobalOrderType)
......@@ -209,6 +210,7 @@ public:
int tenderDeliveryDiscountB; // 配送费 B账户优惠金额
QString tenderDeliveryDiscountBSku; // 配送费 B账户优惠SKU;
int decouplePosVersion; // 解耦POS版本
bool deliveryAtProd; // 配送费已添加到商品列表标志;
int globalServiceType; // 全链路服务类型: globalServiceType【新增字段:int】
int globalOrderType; // 全链路订单类型: globalOrderType 【新增字段:int】
......@@ -480,6 +482,9 @@ public:
inline int getDecouplePosVersion()const{return decouplePosVersion;}
inline void setDecouplePosVersion(const int& v){decouplePosVersion = v;}
inline bool getDeliveryAtProd()const{return deliveryAtProd;}
inline void setDeliveryAtProd(const bool& v){deliveryAtProd = v;}
inline QString getTenderDeliveryDiscountBSku()const{return tenderDeliveryDiscountBSku;}
inline void setTenderDeliveryDiscountBSku(const QString& v){tenderDeliveryDiscountBSku = v;}
......
......@@ -53,7 +53,7 @@ void DetailForm::InitData(OrderObject *orderObject)
} else {
deliveryFinishTime = orderObject->deliveryTime;
}
if (7 == orderObject->orderType) {
if ( 7 == orderObject->orderType || 11 == orderObject->orderType ) {
deliveryFinishTime = deliveryFinishTime + QString::fromLocal8Bit("预约时间: ") + orderObject->expectDate;
}
ui->detailLab2->setText(deliveryFinishTime);
......
......@@ -7,8 +7,8 @@ IDI_ICON ICON DISCARDABLE "logo.ico"
#endif
VS_VERSION_INFO VERSIONINFO
//***每次修改后编译发版必须变更版本号(preDefine.h中APP_VERSION 需要一致)***//
FILEVERSION 2,2021,4,19
PRODUCTVERSION 2,2021,4,19
FILEVERSION 2,2021,5,11
PRODUCTVERSION 2,2021,5,11
//*************************************************************************//
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
......@@ -31,8 +31,8 @@ VS_VERSION_INFO VERSIONINFO
VALUE "OriginalFilename", "fmTakeout.exe"
VALUE "ProductName", "Delivery Order Plugin"
//***每次修改后编译发版必须变更版本号(preDefine.h中APP_VERSION 需要一致)***//
VALUE "ProductVersion", "2.2021.4.19"
VALUE "FileVersion", "2.2021.4.19"
VALUE "ProductVersion", "2.2021.5.11"
VALUE "FileVersion", "2.2021.5.11"
//*************************************************************************//
END
END
......
......@@ -35,7 +35,8 @@
//#define APP_VERSION "2.2021.1.11"
//#define APP_VERSION "2.2021.2.22"
//#define APP_VERSION "2.2021.2.26"
#define APP_VERSION "2.2021.4.19"
//#define APP_VERSION "2.2021.4.19"
#define APP_VERSION "2.2021.5.11"
//修正版本号时,切记修正 FmTakeout.rc 中的版本号
......@@ -71,7 +72,7 @@
#define INI_POSNO "Software/posno"
#define INI_SUBSTOREID "Software/substoreid"
#define INI_SUBSTORESKIPVERIFY "Software/substoreSkipVerify"
#define INI_SKIPRECORDPOS "Software/skipRecordPos"
#define INI_HURRYPRINTSUM "Software/hurryPrintSum"
#define INI_NOHURRYRECORDPOS "Software/noHurryRecordPos"
#define INI_PASSWORD "Software/password"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment