Commit 0f3fd8b1 by wuyang.zou

1、Roastery Store Support Input Simphony Pos Contain Whole Order

Discount

Version:8.2023.10.18
parent 34e96fe0
1、 sku -> posKey 关联关系导入
1.1 表格基础数据列:【SalesItem(posKey) | SKU | OriginPrice | 商城商品名 | OriginPrice (仅前三个有用)】
1.2 程序界面按钮名:"导入SKU"
1.3 程序关于导入SKU的主逻辑链路:MainForm.cpp -> ::on_importSkuBtn_clicked() -> ReadExcel::getInstance().SelectSkuExcelFile(*,*) -> ::openSkuExcelRead() -> getSkufromExcel();
2、导入订单数据并开始进行录单操作;
【单品折扣】【订单编号|商品总额|结算总额|订单状态|商品名称|单价|数量|SKU 8个字段;】
【整单折扣】【订单编号|商品总额|结算总额|整单优惠金额|订单状态|商品名称|单价|数量|SKU 9个字段;】
【config.ini -> Software/promotionType = 1 】
2.1 【选择...】 [bookPosPlugin] 选择订单数据excel,并向 [posPlugin] 开始发送待入机的订单数据:
MainForm::on_mainBtnSelfCheck_clicked() -> ReadExcel::getInstance().SelectOrderExcelFile(this) -> openOrderExcel() -> m_readOrderExcelTimer->start(1000*5) [5s 后开始读取文件内容 -> ReadExcel::onReadOrdersFromExcel() [开始循环读取订单数据] ->
onPostExcelOrderListData() :: 将之前发送失败的数据,重发给 [posPlugin]
+
getAllOrderFromExcel() :: 分批读取 Excel 表格中的订单数据;
+
onPostExcelOrderListData() :: 将最新读取的订单数据,发给 [posPlugin]
2.2 【开始录】[posPlugin]开始向POS,进行模拟入机;
MainForm::on_mainBtnSet_clicked() -> emit sendBeginRecordOrderToPos(); -> FlowControl::onBeginRecordOrderToPos()
2.3 【跳过】[posPlugin] 在入机过程中,碰到异常订单,可以跳过此异常订单,不会block后续订单入机;
MainForm::on_mainBtnDishManager_clicked() -> SkipThisOrderToPos() -> FlowControl::onSkipThisOrderToPos()
3、插件导出POS的录入结果:未知是否好使【skip】;
3.1 【导出结果】 [bookPosPlugin] 通过 http 请求向 [posPlugin] 获取订单入机结果,分批请求获取;
MainForm::on_mainBtnSyncOrder_clicked -> onPostExportExcelOrderResult() + ReadExcel::getInstance().onExportOrderPosResult() ->
......@@ -344,6 +344,7 @@ void FlowControl::_OrderAnalysis(const QJsonObject& jsonObject)
orderObject->inAdvanceTakemeal = 0;
orderObject->globalServiceType = 0;
orderObject->globalOrderType = 0;
orderObject->decouplePosVersion = 0;
orderObject->FromJson(jsonObject);
orderObject->pushOrderType=0;
......@@ -476,15 +477,7 @@ void FlowControl::_OrderAnalysis(const QJsonObject& jsonObject)
orderObject->pushOrderTimes = 0;
}
// 针对新订单肯定没有在POS里录入过;
if(!m_simValidOrdersList.contains(orderObject->id)) {
bRetOrderEntryMutex =m_OrderEntryMutex.tryLock(VALUE_TRYLOCKMEMTIMEOUT);
if(!bRetOrderEntryMutex) {
QLOG_INFO() << QString("[<<<<---FmTakeout _OrderAnalysis:orderId:%1 m_OrderEntryMutex.tryLock Failed --->>>>]").arg(orderObject->id);
return;
}
m_simValidOrdersList.append(orderObject->id);
m_OrderEntryMutex.unlock();
}
QLOG_INFO() << QString("[<<<<---FmTakeout _OrderAnalysis:orderId:%1 Order Status Is 2, No Need Record Simphony.... --->>>>]").arg(orderObject->id);
QLOG_INFO() << QString("[<<<<---FmTakeout _OrderAnalysis:NewOrder m_simValidOrdersList.num:%1 --->>>>]")<< m_simValidOrdersList.count();
QLOG_INFO() << QString("[<<<<---FmTakeout _OrderAnalysis:NewOrder m_simValidOrdersList:%1 --->>>>]")<< m_simValidOrdersList;
//避免压测时把插件程序频繁点击致崩溃;顾此处通过8s一次的定时器触发录单;
......@@ -504,6 +497,11 @@ void FlowControl::_OrderAnalysis(const QJsonObject& jsonObject)
orderObject->pushOrderTimes = 0;
}
if ( orderObject->decouplePosVersion >= 20 ) {
QLOG_INFO() << QString("[<<<<---FmTakeout _OrderAnalysis:orderId: %1 decouplePosVersion >= 20, No Need Record Simphony.... --->>>>]").arg(orderObject->id);
return;
}
if(!m_simValidOrdersList.contains(orderObject->id)) {
bRetOrderEntryMutex =m_OrderEntryMutex.tryLock(VALUE_TRYLOCKMEMTIMEOUT);
if(!bRetOrderEntryMutex) {
......@@ -531,6 +529,11 @@ void FlowControl::_OrderAnalysis(const QJsonObject& jsonObject)
orderObject->pushOrderTimes = 0;
}
if ( orderObject->decouplePosVersion >= 20 ) {
QLOG_INFO() << QString("[<<<<---FmTakeout _OrderAnalysis:orderId: %1 decouplePosVersion >= 20, No Need Record Simphony.... --->>>>]").arg(orderObject->id);
return;
}
if(!m_simValidOrdersList.contains(orderObject->id)) {
bRetOrderEntryMutex =m_OrderEntryMutex.tryLock(VALUE_TRYLOCKMEMTIMEOUT);
if(!bRetOrderEntryMutex) {
......@@ -558,6 +561,11 @@ void FlowControl::_OrderAnalysis(const QJsonObject& jsonObject)
orderObject->pushOrderTimes = 0;
}
if ( orderObject->decouplePosVersion >= 20 ) {
QLOG_INFO() << QString("[<<<<---FmTakeout _OrderAnalysis:orderId: %1 decouplePosVersion >= 20, No Need Record Simphony.... --->>>>]").arg(orderObject->id);
return;
}
if(!m_simValidOrdersList.contains(orderObject->id)) {
bRetOrderEntryMutex =m_OrderEntryMutex.tryLock(VALUE_TRYLOCKMEMTIMEOUT);
if(!bRetOrderEntryMutex) {
......@@ -629,6 +637,11 @@ void FlowControl::_OrderAnalysis(const QJsonObject& jsonObject)
orderObject->orsPushOrderType = 0; //标记预约实物-准备退单动作;
orderObject->orsPushOrderTimes = 0;
if ( orderObject->decouplePosVersion >= 20 ) {
QLOG_INFO() << QString("[<<<<---FmTakeout _OrderAnalysis:orderId: %1 decouplePosVersion >= 20, No Need Record Simphony.... --->>>>]").arg(orderObject->id);
return;
}
if(!m_simValidOrdersList.contains(orderObject->id)) {
bRetOrderEntryMutex =m_OrderEntryMutex.tryLock(VALUE_TRYLOCKMEMTIMEOUT);
if(!bRetOrderEntryMutex) {
......
......@@ -200,3 +200,9 @@ int ConfigManger::GetPostOrderLimitSize()
return m_config->value(INI_LIMITSIZE).toInt();
}
int ConfigManger::GetPromotaionType()
{
return m_config->value(INI_PROMOTION_TYPE, 0).toInt();
}
......@@ -144,6 +144,7 @@ public:
bool GetNoUseDb();
int GetExportExcelPageSize();
int GetPostOrderLimitSize();
int GetPromotaionType();
private:
ConfigManger();
......
......@@ -56,7 +56,7 @@ public:
static ReadExcel& getInstance();
//选择 导入 Excel 文件
bool SelectExcelFile(QWidget* p);
bool SelectOrderExcelFile(QWidget* p);
//选择 导入 SKU Excel 文件
bool SelectSkuExcelFile(QWidget* p, int &suc, int &fail);
......@@ -65,18 +65,24 @@ public:
bool SelectExportExcelFile(QWidget* p);
//打开excel文件
bool openExcel();
bool openOrderExcel();
//打开Sku Excel文件
bool openSkuExcelRead(QString strFile, int &suc, int &fail);
bool fillWholeOrderPromotion(QJsonArray &orderList );
// 转换生成订单数据;
bool convertOrderObjectForSingleItemPromotion(QString &curOrderId, QJsonObject &OrderJson , QJsonObject &productJson , int &rowNum , int &colNum,
QVariant &cellValue , bool &bIgnoreRow, bool &bLastRow );
// 转换生成订单数据;
bool convertOrderObject(QString &curOrderId, QJsonObject &OrderJson , QJsonObject &productJson , int &rowNum , int &colNum,
bool convertOrderObjectForWholeOrderPromotion(QString &curOrderId, QJsonObject &OrderJson , QJsonObject &productJson , int &rowNum , int &colNum,
QVariant &cellValue , bool &bIgnoreRow, bool &bLastRow );
bool getSkufromExcel(bool &bLastRow, int &lastRowNum);
bool getALLfromExcel(QJsonArray &exlOrderList, bool &bLastRow);
bool getAllOrderFromExcel(QJsonArray &exlOrderList, bool &bLastRow);
signals:
......@@ -104,7 +110,7 @@ public slots:
bool onExportOrderPosResult(QStringList &titles, QVector<QStringList> &vec);
private:
QTimer *m_readExcelTimer;
QTimer *m_readOrderExcelTimer;
QMutex m_ReadMutex;
BillSocket *m_postExcelSocket;
......@@ -124,6 +130,7 @@ private:
int m_vaildOrderNum; //累计有效订单总数;
//一次读取最多读取多少行记录; 需要考虑恰好切断 一笔订单多条商品数据记录;
int m_readMaxRowLimit;
int m_promotionType; // 订单优惠类型 0: 单品优惠; 1: 整单优惠;
bool m_readExcelOrderFinish; //每批读取Excel 表结束的标识;
bool m_continueReadExcelRet; //定时器触发读取Excel时机
......
#include "jqdeclare.hpp"
#include "jqhttpserver.h"
/*
This file is part of JQLibrary
Copyright: Jason and others
Contact email: 188080501@qq.com
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef JQLIBRARY_INCLUDE_JQDECLARE_HPP_
#define JQLIBRARY_INCLUDE_JQDECLARE_HPP_
// Macro define
#define JQPROPERTYDECLARE( Type, name, setName, ... ) \
private: \
Type name##_ __VA_ARGS__; \
\
public: \
inline const Type &name() const { return name##_; } \
inline void setName( const Type &name ) { name##_ = name; } \
\
private:
#define JQPROPERTYDECLAREWITHSLOT( Type, name, setName, ... ) \
private: \
Type name##_ __VA_ARGS__; \
public Q_SLOTS: \
Type name() const { return name##_; } \
void setName( const Type &name ) { name##_ = name; } \
\
private:
#define JQPTRPROPERTYDECLARE( Type, name, setName, ... ) \
private: \
Type *name##_ __VA_ARGS__; \
\
public: \
inline const Type *name() const { return name##_; } \
inline void setName( const Type &name ) \
{ \
if ( name##_ ) \
{ \
delete name##_; \
} \
name##_ = new Type( name ); \
} \
\
private:
#define JQ_READ_AND_SET_PROPERTY( Type, name, setName ) \
public: \
inline const Type &name() const { return name##_; } \
inline void setName( const Type &name ) { name##_ = name; } \
\
private:
#define JQ_STATIC_READ_AND_SET_PROPERTY( Type, name, setName ) \
public: \
static inline const Type &name() { return name##_; } \
static inline void setName( const Type &name ) { name##_ = name; } \
\
private:
#define JQ_STATIC_SET_PROPERTY( Type, name, setName ) \
public: \
static inline void setName( const Type &name ) { name##_ = name; } \
\
private:
#define RUNONOUTRANGEHELPER2( x, y ) x##y
#define RUNONOUTRANGEHELPER( x, y ) RUNONOUTRANGEHELPER2( x, y )
#define RUNONOUTRANGE( ... ) \
auto RUNONOUTRANGEHELPER( runOnOutRangeCallback, __LINE__ ) = __VA_ARGS__; \
QSharedPointer< int > RUNONOUTRANGEHELPER( runOnOutRange, __LINE__ )( \
new int, \
[ RUNONOUTRANGEHELPER( runOnOutRangeCallback, __LINE__ ) ]( int *data ) { \
RUNONOUTRANGEHELPER( runOnOutRangeCallback, __LINE__ ) \
(); \
delete data; \
} ); \
if ( RUNONOUTRANGEHELPER( runOnOutRange, __LINE__ ).data() == nullptr ) \
{ \
exit( -1 ); \
}
#define RUNONOUTRANGETIMER( message ) \
const auto &&runOnOutRangeTimerTime = QDateTime::currentMSecsSinceEpoch(); \
RUNONOUTRANGE( [ = ]() { \
qDebug() << message << ( QDateTime::currentMSecsSinceEpoch() - runOnOutRangeTimerTime ); \
} )
#define JQCONST( property ) static_cast< const decltype( property ) >( property )
#define JQTICKCOUNTERMESSAGE( message ) \
{ \
static JQTickCounter tickCounter; \
tickCounter.tick(); \
qDebug() << message << tickCounter.tickPerSecond(); \
}
#define JQBUILDDATETIMESTRING \
( QDateTime( \
QLocale( QLocale::English ).toDate( QString( __DATE__ ).replace( " ", " 0" ), "MMM dd yyyy" ), \
QTime::fromString( __TIME__, "hh:mm:ss" ) ) \
.toString( "yyyy-MM-dd hh:mm:ss" ) \
.toLatin1() \
.data() )
#define JQONLYONCE \
if ( []() { \
static auto flag = true; \
if ( flag ) \
{ \
flag = false; \
return true; \
} \
return false; \
}() )
#define JQSKIPFIRST \
if ( []() { \
static auto flag = true; \
if ( flag ) \
{ \
flag = false; \
return false; \
} \
return true; \
}() )
#define JQINTERVAL( timeInterval ) \
if ( []() { \
static qint64 lastTime = 0; \
const auto && currentTime = QDateTime::currentMSecsSinceEpoch(); \
if ( qAbs( currentTime - lastTime ) > timeInterval ) \
{ \
lastTime = currentTime; \
return true; \
} \
return false; \
}() )
// Export
#ifdef JQLIBRARY_EXPORT_ENABLE
# ifdef JQLIBRARY_EXPORT_MODE
# define JQLIBRARY_EXPORT Q_DECL_EXPORT
# else
# define JQLIBRARY_EXPORT Q_DECL_IMPORT
# endif
#else
# define JQLIBRARY_EXPORT
#endif
#endif // JQLIBRARY_INCLUDE_JQDECLARE_HPP_
......@@ -21,7 +21,8 @@ void LoaclHttpServer::run()
/***解析FM外卖插件HTTP服务与Http请求的会话连接是否断开: 会话连接未断开***/
if(!session.isNull())
{
QString recvData = QString::fromUtf8(session->requestRawData());
// QString recvData = QString::fromUtf8(session->requestRawData());
QString recvData = QString::fromUtf8( session->requestBody() );
QLOG_INFO() << QString::fromLocal8Bit("[<<<<---Receive Http Request recvData: %1--->>>>]").arg(recvData);
QJsonParseError jsonError;
QJsonObject recvObject;
......
......@@ -89,6 +89,8 @@ class OrderObject : public QObject
Q_PROPERTY (int inAdvanceTakemeal READ getInAdvanceTakemeal WRITE setInAdvanceTakemeal)
Q_PROPERTY (QString subStoreId READ getSubStoreId WRITE setSubStoreId)
Q_PROPERTY (int decouplePosVersion READ getDecouplePosVersion WRITE setDecouplePosVersion)
Q_PROPERTY (int globalServiceType READ getGlobalServiceType WRITE setGlobalServiceType)
Q_PROPERTY (int globalOrderType READ getGlobalOrderType WRITE setGlobalOrderType)
......@@ -190,6 +192,7 @@ public:
int inAdvanceTakemeal; // 预约单提前到店标志【新增字段:int】
QString subStoreId; // 子门店号 【新增字段:string】
int decouplePosVersion; // 解耦POS版本
int globalServiceType; // 全链路服务类型: globalServiceType【新增字段:int】
int globalOrderType; // 全链路订单类型: globalOrderType 【新增字段:int】
......@@ -450,6 +453,9 @@ public:
inline int getGlobalOrderType()const{return globalOrderType;}
inline void setGlobalOrderType(const int& v){globalOrderType = v;}
inline int getDecouplePosVersion()const{return decouplePosVersion;}
inline void setDecouplePosVersion(const int& v){decouplePosVersion = v;}
};
#endif // ORDEROBJECT_H
......@@ -7,8 +7,8 @@ IDI_ICON ICON DISCARDABLE "logo.ico"
#endif
VS_VERSION_INFO VERSIONINFO
//***每次修改后编译发版必须变更版本号(preDefine.h中APP_VERSION 需要一致)***//
FILEVERSION 8,2020,8,23
PRODUCTVERSION 8,2020,8,23
FILEVERSION 8,2023,10,18
PRODUCTVERSION 8,2023,10,18
//*************************************************************************//
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
......@@ -27,12 +27,12 @@ VS_VERSION_INFO VERSIONINFO
VALUE "CompanyName", "ShangHai.Freemud Co., Ltd."
VALUE "FileDescription", "Delivery Order Plugin Application"
VALUE "InternalName", "fmTakeout.exe"
VALUE "LegalCopyright", "Copyright (C)2014-2020"
VALUE "LegalCopyright", "Copyright (C)2014-2023"
VALUE "OriginalFilename", "fmTakeout.exe"
VALUE "ProductName", "Delivery Order Plugin"
//***每次修改后编译发版必须变更版本号(preDefine.h中APP_VERSION 需要一致)***//
VALUE "ProductVersion", "8.2020.8.23"
VALUE "FileVersion", "8.2020.8.23"
VALUE "ProductVersion", "8.2023.10.18"
VALUE "FileVersion", "8.2023.10.18"
//*************************************************************************//
END
END
......
......@@ -781,22 +781,23 @@ bool MainForm::onPostExportExcelOrderResult(){
return postExportRet;
}
void MainForm::on_mainBtnSelfCheck_clicked()
{
//emit sendSelfCheck();
//选择 Excel文件并导入订单数据;
//选择 Order Excel文件并导入订单数据;
ReadExcel::getInstance();
if ( ReadExcel::getInstance().SelectExcelFile(this) ) {
QLOG_INFO() << QString("[<<<<---MainForm::on_mainBtnSelfCheck_clicked: openExcel Finished: --->>>>]");
if ( ReadExcel::getInstance().SelectOrderExcelFile(this) ) {
QLOG_INFO() << QString("[<<<<---MainForm::on_mainBtnSelfCheck_clicked: openOrderExcel Finished: --->>>>]");
}
QMessageBox::information(this, QString("Had Select Read Excel: Sale Order Data ..... "), QString("OK") );
}
void MainForm::on_importSkuBtn_clicked()
{
//选择 Excel文件并导入SKU数据;
int suc=0;
int fail = 0;
int suc=0 , fail = 0;
ReadExcel::getInstance();
if ( ReadExcel::getInstance().SelectSkuExcelFile(this, suc, fail ) ) {
QLOG_INFO() << QString("[<<<<---MainForm::on_importSkuBtn_clicked: Open SKU Excel Finished: --->>>>]");
......
......@@ -28,7 +28,8 @@
//#define APP_VERSION "2.2020.312.1"
//#define APP_VERSION "2.2020.5.26"
//#define APP_VERSION "2.2020.6.29"
#define APP_VERSION "8.2020.8.23"
//#define APP_VERSION "8.2020.8.23"
#define APP_VERSION "8.2023.10.18"
//修正版本号时,切记修正 FmTakeout.rc 中的版本号
......@@ -69,6 +70,7 @@
#define INI_NOUSEDB "Software/noUseDb"
#define INI_EXPORTPAGESIZE "Software/exportPageSize"
#define INI_LIMITSIZE "Software/limitSize"
#define INI_PROMOTION_TYPE "Software/promotionType"
#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