From ddf906fbbc761620dae5a1b88789dbb77bb6935a Mon Sep 17 00:00:00 2001 From: leca Date: Sat, 24 Aug 2024 00:45:47 +0300 Subject: [PATCH] starting work on export module, added check trimming --- CMakeLists.txt | 1 + CMakeLists.txt.user | 62 +++++++------- check/check.cpp | 6 ++ check/check.h | 2 + main.cpp | 1 + mainwindow.cpp | 27 ++++++- mainwindow.h | 3 + mainwindow.ui | 23 +----- modules/magnit.json | 8 ++ modules/pyaterochka.json | 6 +- outputdialog.cpp | 15 ++++ outputdialog.h | 23 ++++++ outputdialog.ui | 171 +++++++++++++++++++++++++++++++++++++++ parser/module.cpp | 49 +++++++++-- parser/module.h | 4 + parser/parser.cpp | 6 +- 16 files changed, 346 insertions(+), 61 deletions(-) create mode 100644 modules/magnit.json create mode 100644 outputdialog.cpp create mode 100644 outputdialog.h create mode 100644 outputdialog.ui diff --git a/CMakeLists.txt b/CMakeLists.txt index 5779bb5..8a46284 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,6 +43,7 @@ else() parser/parser.h parser/parser.cpp parser/module.h parser/module.cpp settings.h + outputdialog.h outputdialog.cpp outputdialog.ui ) endif() endif() diff --git a/CMakeLists.txt.user b/CMakeLists.txt.user index 76fe84d..06071b1 100644 --- a/CMakeLists.txt.user +++ b/CMakeLists.txt.user @@ -1,6 +1,6 @@ - + EnvironmentId @@ -102,13 +102,13 @@ 2 false - -DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} --DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} --DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} --DCMAKE_BUILD_TYPE:STRING=Debug --DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} --DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} + -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_GENERATOR:STRING=Ninja +-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} +-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} +-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} +-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} +-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} -DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake 0 /home/leca/projects/qt/checks-parser/build/Desktop-Debug @@ -159,13 +159,13 @@ 2 false - -DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} --DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} --DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} --DCMAKE_BUILD_TYPE:STRING=Release --DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} --DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} + -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_GENERATOR:STRING=Ninja +-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} +-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} +-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} +-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} +-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} -DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake /home/leca/projects/qt/checks-parser/build/Desktop-Release @@ -213,13 +213,13 @@ 2 false - -DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} --DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} --DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} --DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo --DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} --DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} + -DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo -DCMAKE_GENERATOR:STRING=Ninja +-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} +-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} +-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} +-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} +-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} -DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake /home/leca/projects/qt/checks-parser/build/Desktop-RelWithDebInfo @@ -267,13 +267,13 @@ 2 false - -DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} --DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} --DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} --DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo --DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} --DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} + -DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo -DCMAKE_GENERATOR:STRING=Ninja +-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} +-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} +-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} +-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} +-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} -DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake 0 /home/leca/projects/qt/checks-parser/build/Desktop-Profile @@ -322,13 +322,13 @@ 2 false - -DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} --DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} --DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} --DCMAKE_BUILD_TYPE:STRING=MinSizeRel --DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} --DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} + -DCMAKE_BUILD_TYPE:STRING=MinSizeRel -DCMAKE_GENERATOR:STRING=Ninja +-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} +-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} +-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} +-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} +-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} -DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake /home/leca/projects/qt/checks-parser/build/Desktop-MinSizeRel diff --git a/check/check.cpp b/check/check.cpp index e0d1073..6a1881a 100644 --- a/check/check.cpp +++ b/check/check.cpp @@ -2,7 +2,9 @@ #include "../goods/goods.h" Check::Check() {} + void Check::add_goods(Goods goods) { this->goods.push_back(goods); } + double Check::calculae_total_price() { double total = 0.0; @@ -12,3 +14,7 @@ double Check::calculae_total_price() { return total; } + +std::vector& Check::get_goods() { + return goods; +} diff --git a/check/check.h b/check/check.h index 3b08614..58a2684 100644 --- a/check/check.h +++ b/check/check.h @@ -11,6 +11,8 @@ public: void add_goods(Goods); double calculae_total_price(); + + std::vector& get_goods(); }; #endif // CHECK_H diff --git a/main.cpp b/main.cpp index 3fcdf23..17dfc6c 100644 --- a/main.cpp +++ b/main.cpp @@ -6,5 +6,6 @@ int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); + return a.exec(); } diff --git a/mainwindow.cpp b/mainwindow.cpp index d0fb3cb..4ac1f45 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -1,7 +1,8 @@ #include "mainwindow.h" #include "./ui_mainwindow.h" -#include "goods/goods.h" #include "check/check.h" +#include "goods/goods.h" +#include "outputdialog.h" #include "settings.h" #include @@ -17,6 +18,17 @@ void MainWindow::setupStoresList() { // Make file format that is a regeeex which parse check, load these files // here parser = *(new Parser()); + + std::vector modules_names = parser.search_modules(); + + for (std::string name : modules_names) { + Module m(name); + std::wstring module_name = m.get_name(); + + QString s = QString::fromStdWString(module_name); + ui->storeType->addItem(s); + } + #ifdef DEBUG for (auto module : parser.search_modules()) { std::cout << "Module: " << module << std::endl; @@ -42,9 +54,22 @@ void MainWindow::on_parseButton_clicked() { std::vector c = parser.parse(check_plaintext); + if (c.size() == 0) { + std::cerr << "An error has occured. Check was matched incorrectly. Vector sizes are different" << std::endl; + return; + } + Check check; for (auto g : c) { check.add_goods(g); } + + OutputDialog *d = new OutputDialog(this, check); + d->exec(); +} + +void MainWindow::on_storeType_currentIndexChanged(int index) { + std::string module = parser.search_modules()[index]; + parser.set_module(module); } diff --git a/mainwindow.h b/mainwindow.h index 4526165..5725330 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -19,6 +19,7 @@ class MainWindow : public QMainWindow { Parser parser; public: + MainWindow(QWidget *parent = nullptr); ~MainWindow(); void setupStoresList(); @@ -29,6 +30,8 @@ private slots: void on_parseButton_clicked(); + void on_storeType_currentIndexChanged(int index); + private: Ui::MainWindow *ui; }; diff --git a/mainwindow.ui b/mainwindow.ui index fc9316a..0b4d814 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -6,8 +6,8 @@ 0 0 - 827 - 680 + 817 + 659 @@ -23,21 +23,6 @@ 31 - - - Pyaterochka (Пятёрочка) - - - - - Perekrestok (Перекрёсток) - - - - - FixPrice - - @@ -58,7 +43,7 @@ 0 90 801 - 551 + 511 @@ -140,7 +125,7 @@ 0 0 - 827 + 817 23 diff --git a/modules/magnit.json b/modules/magnit.json new file mode 100644 index 0000000..4992590 --- /dev/null +++ b/modules/magnit.json @@ -0,0 +1,8 @@ +{ + "name":"Магнит", + "goods_name_regex": "([\\(\\)\\%\\*a-zA-Z0-9\u0401\u0451\u0410-\u044f \\.\\-\/]{17,100})", + "goods_price_regex": "[0-9]{0,4}[^%]\\.[0-9]{2} ", + "goods_quantity_regex": "([0-9]{0,4}[^%]\\.[0-9]{3} )|(\t\\d )", + "check_start_regex": "", + "check_end_regex":"" +} diff --git a/modules/pyaterochka.json b/modules/pyaterochka.json index 55f5c3f..f25b8e8 100644 --- a/modules/pyaterochka.json +++ b/modules/pyaterochka.json @@ -1,6 +1,8 @@ { "name":"Пятёрочка", - "goods_name_regex": "([0-9]+ \t[\\%\\*a-zA-Z0-9\u0401\u0451\u0410-\u044f \\.\\-\/]{10,100})", + "goods_name_regex": "([\\(\\)\\%\\*a-zA-Z0-9\u0401\u0451\u0410-\u044f \\.\\-\/]{17,100})", "goods_price_regex": "[0-9]{0,4}[^%]\\.[0-9]{2} ", - "goods_quantity_regex": "([0-9]{0,4}[^%]\\.[0-9]{3} )|(\t\\d )" + "goods_quantity_regex": "([0-9]{0,4}[^%]\\.[0-9]{3} )|(\t\\d )", + "check_start_regex": "КАССОВЫЙ ЧЕК\nприход", + "check_end_regex": "Итог\\:.{0,3}[0-9]{0,6}\\.[0-9]{2}" } diff --git a/outputdialog.cpp b/outputdialog.cpp new file mode 100644 index 0000000..76d96bf --- /dev/null +++ b/outputdialog.cpp @@ -0,0 +1,15 @@ +#include "outputdialog.h" +#include "ui_outputdialog.h" +#include +#include +#include "check/check.h" + +OutputDialog::OutputDialog(QWidget *parent, Check check) + : QDialog(parent), ui(new Ui::OutputDialog) { + ui->setupUi(this); + for (auto goods : check.get_goods()) { + std::cout << "From dialog:" << goods.get_name() << std::endl; + } +} + +OutputDialog::~OutputDialog() { delete ui; } diff --git a/outputdialog.h b/outputdialog.h new file mode 100644 index 0000000..955e7e1 --- /dev/null +++ b/outputdialog.h @@ -0,0 +1,23 @@ +#ifndef OUTPUTDIALOG_H +#define OUTPUTDIALOG_H + +#include +#include "check/check.h" + +namespace Ui { +class OutputDialog; +} + +class OutputDialog : public QDialog +{ + Q_OBJECT + +public: + explicit OutputDialog(QWidget *parent = nullptr, Check = Check()); + ~OutputDialog(); + +private: + Ui::OutputDialog *ui; +}; + +#endif // OUTPUTDIALOG_H diff --git a/outputdialog.ui b/outputdialog.ui new file mode 100644 index 0000000..609d185 --- /dev/null +++ b/outputdialog.ui @@ -0,0 +1,171 @@ + + + OutputDialog + + + + 0 + 0 + 602 + 436 + + + + Dialog + + + + + 410 + 390 + 166 + 26 + + + + Qt::Orientation::Horizontal + + + QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok + + + + + + 60 + 20 + 261 + 26 + + + + + ods + + + + + csv + + + + + xlsx (Not implemented) + + + + + + + 10 + 20 + 45 + 21 + + + + Format + + + + + + 10 + 50 + 441 + 191 + + + + Columns + + + + + 0 + 20 + 441 + 171 + + + + + + + + + + + + + + + + Price + + + + + + + Net weight + + + + + + + Quantity + + + + + + + Name + + + + + + + + + + + + + + buttonBox + accepted() + OutputDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + OutputDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/parser/module.cpp b/parser/module.cpp index 93860dc..293d46b 100644 --- a/parser/module.cpp +++ b/parser/module.cpp @@ -1,12 +1,12 @@ #include "module.h" #include "../settings.h" +#include #include #include +#include #include #include #include -#include -#include std::string to_utf8(std::wstring wide_string) { static std::wstring_convert> utf8_conv; @@ -28,11 +28,17 @@ Module::Module(std::string path) { this->goods_name_regex = from_utf8(settings["goods_name_regex"]); this->goods_price_regex = from_utf8(settings["goods_price_regex"]); this->goods_quantity_regex = from_utf8(settings["goods_quantity_regex"]); + this->check_start_regex = from_utf8(settings["check_start_regex"]); + this->check_end_regex = from_utf8(settings["check_end_regex"]); + #ifdef DEBUG std::wcout << "Name: " << this->name << std::endl; std::wcout << "Goods name regex: " << this->goods_name_regex << std::endl; std::wcout << "Goods price regex: " << this->goods_price_regex << std::endl; - std::wcout << "Goods quantity regex: " << this->goods_quantity_regex << std::endl; + std::wcout << "Goods quantity regex: " << this->goods_quantity_regex + << std::endl; + std::wcout << "Check start regex: " << this->check_start_regex << std::endl; + std::wcout << "Check end regex: " << this->check_end_regex << std::endl; #endif } @@ -40,30 +46,61 @@ std::vector Module::parse_name(std::wstring str) { std::vector result; std::wregex r(this->goods_name_regex, std::regex::collate); - for (std::wsregex_iterator it {str.begin(), str.end(), r}, end {}; it != end; it ++) { + for (std::wsregex_iterator it{str.begin(), str.end(), r}, end{}; it != end; + it++) { result.push_back(to_utf8(it->str())); } return result; } + std::vector Module::parse_price(std::wstring str) { std::vector result; std::wregex r(this->goods_price_regex, std::regex::collate); - for (std::wsregex_iterator it {str.begin(), str.end(), r}, end {}; it != end; it ++) { + for (std::wsregex_iterator it{str.begin(), str.end(), r}, end{}; it != end; + it++) { result.push_back(to_utf8(it->str())); } return result; } + std::vector Module::parse_quantity(std::wstring str) { std::vector result; std::wregex r(this->goods_quantity_regex, std::regex::collate); - for (std::wsregex_iterator it {str.begin(), str.end(), r}, end {}; it != end; it ++) { + for (std::wsregex_iterator it{str.begin(), str.end(), r}, end{}; it != end; + it++) { result.push_back(to_utf8(it->str())); } return result; } +std::wstring Module::trim_check(std::wstring& check) { + unsigned int start_pos; + unsigned int end_pos; + + std::wregex start_regex(this->check_start_regex, std::regex::collate); + std::wregex end_regex(this->check_end_regex, std::regex::collate); + + for (std::wsregex_iterator it{check.begin(), check.end(), start_regex}, end{}; + it != end; it++) { + start_pos = it->position() + it->str().size(); + break; + } + + check = check.substr(start_pos, check.size()); + + for (std::wsregex_iterator it{check.begin(), check.end(), end_regex}, end{}; + it != end; it++) { + end_pos = it->position() - 1; + break; + } + + check = check.substr(0, end_pos); + + return check; +} + std::wstring Module::get_name() { return this->name; } diff --git a/parser/module.h b/parser/module.h index c4506c6..99c61de 100644 --- a/parser/module.h +++ b/parser/module.h @@ -10,6 +10,8 @@ class Module { std::wstring goods_name_regex; std::wstring goods_price_regex; std::wstring goods_quantity_regex; + std::wstring check_start_regex; + std::wstring check_end_regex; public: Module(std::string); Module(); @@ -17,6 +19,8 @@ public: std::vector parse_name(std::wstring); std::vector parse_price(std::wstring); std::vector parse_quantity(std::wstring); + std::wstring trim_check(std::wstring&); + std::wstring get_name(); }; diff --git a/parser/parser.cpp b/parser/parser.cpp index 9b856d4..8bef01f 100644 --- a/parser/parser.cpp +++ b/parser/parser.cpp @@ -27,11 +27,13 @@ std::vector Parser::search_modules() { return modules_files; } -void Parser::set_module(std::string path) { module = *(new Module(path)); } +void Parser::set_module(std::string path) { module = Module(path); } std::vector Parser::parse(std::wstring check_plaintext) { std::vector result; + module.trim_check(check_plaintext); + std::vector goods_names = module.parse_name(check_plaintext); std::vector goods_prices = module.parse_price(check_plaintext); std::vector goods_quantities = @@ -42,7 +44,7 @@ std::vector Parser::parse(std::wstring check_plaintext) { if (goods_names.size() != goods_prices.size() || goods_names.size() != goods_quantities.size() || goods_prices.size() != goods_quantities.size()) { - std::cerr << "An error has occured. Check was matched incorrectly. Vector sizes are different" << std::endl; + //Error. Amount of names, prices or quantities are not equal. That means, that some regex(es) has mismatched. return {}; } short goods_amount = goods_names.size();