Output to csv, started work on OFD module

This commit is contained in:
leca 2024-08-30 05:03:32 +03:00
parent 64e40071b2
commit d9fca88af3
21 changed files with 606 additions and 163 deletions

View File

@ -44,12 +44,18 @@ else()
parser/module.h parser/module.cpp parser/module.h parser/module.cpp
settings.h settings.h
outputdialog.h outputdialog.cpp outputdialog.ui outputdialog.h outputdialog.cpp outputdialog.ui
output/output_options.h output/output_options.cpp
ofd/ofd.h ofd/ofd.cpp
ofd/module.h ofd/module.cpp
utils/utils.h utils/utils.cpp
) )
endif() endif()
endif() endif()
target_link_libraries(checks-parser PRIVATE Qt${QT_VERSION_MAJOR}::Widgets) target_link_libraries(checks-parser PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)
# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1. # Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1.
# If you are developing for iOS or macOS you should consider setting an # If you are developing for iOS or macOS you should consider setting an
# explicit, fixed bundle identifier manually though. # explicit, fixed bundle identifier manually though.
@ -74,3 +80,13 @@ install(TARGETS checks-parser
if(QT_VERSION_MAJOR EQUAL 6) if(QT_VERSION_MAJOR EQUAL 6)
qt_finalize_executable(checks-parser) qt_finalize_executable(checks-parser)
endif() endif()
include(FetchContent)
FetchContent_Declare(cpr GIT_REPOSITORY https://github.com/libcpr/cpr.git
GIT_TAG 3b15fa82ea74739b574d705fea44959b58142eb8)
FetchContent_MakeAvailable(cpr)
target_link_libraries(checks-parser PRIVATE cpr::cpr)
find_package(KF${QT_VERSION_MAJOR}WidgetsAddons)
target_link_libraries(checks-parser PRIVATE KF${QT_VERSION_MAJOR}::WidgetsAddons)

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject> <!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 14.0.0, 2024-08-21T19:24:51. --> <!-- Written by QtCreator 14.0.0, 2024-08-30T01:20:43. -->
<qtcreator> <qtcreator>
<data> <data>
<variable>EnvironmentId</variable> <variable>EnvironmentId</variable>
@ -104,12 +104,12 @@
<valuelist type="QVariantList" key="CMake.Configure.UserEnvironmentChanges"/> <valuelist type="QVariantList" key="CMake.Configure.UserEnvironmentChanges"/>
<value type="QString" key="CMake.Initial.Parameters">-DCMAKE_BUILD_TYPE:STRING=Debug <value type="QString" key="CMake.Initial.Parameters">-DCMAKE_BUILD_TYPE:STRING=Debug
-DCMAKE_GENERATOR:STRING=Ninja -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_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX}
-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} -DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable}
-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake</value> -DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx}
-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake
-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG}
-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C}</value>
<value type="int" key="EnableQmlDebugging">0</value> <value type="int" key="EnableQmlDebugging">0</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/leca/projects/qt/checks-parser/build/Desktop-Debug</value> <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/leca/projects/qt/checks-parser/build/Desktop-Debug</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
@ -161,12 +161,12 @@
<valuelist type="QVariantList" key="CMake.Configure.UserEnvironmentChanges"/> <valuelist type="QVariantList" key="CMake.Configure.UserEnvironmentChanges"/>
<value type="QString" key="CMake.Initial.Parameters">-DCMAKE_BUILD_TYPE:STRING=Release <value type="QString" key="CMake.Initial.Parameters">-DCMAKE_BUILD_TYPE:STRING=Release
-DCMAKE_GENERATOR:STRING=Ninja -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_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX}
-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} -DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable}
-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake</value> -DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx}
-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake
-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG}
-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C}</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/leca/projects/qt/checks-parser/build/Desktop-Release</value> <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/leca/projects/qt/checks-parser/build/Desktop-Release</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
@ -215,12 +215,12 @@
<valuelist type="QVariantList" key="CMake.Configure.UserEnvironmentChanges"/> <valuelist type="QVariantList" key="CMake.Configure.UserEnvironmentChanges"/>
<value type="QString" key="CMake.Initial.Parameters">-DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo <value type="QString" key="CMake.Initial.Parameters">-DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo
-DCMAKE_GENERATOR:STRING=Ninja -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_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX}
-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} -DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable}
-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake</value> -DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx}
-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake
-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG}
-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C}</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/leca/projects/qt/checks-parser/build/Desktop-RelWithDebInfo</value> <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/leca/projects/qt/checks-parser/build/Desktop-RelWithDebInfo</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
@ -269,12 +269,12 @@
<valuelist type="QVariantList" key="CMake.Configure.UserEnvironmentChanges"/> <valuelist type="QVariantList" key="CMake.Configure.UserEnvironmentChanges"/>
<value type="QString" key="CMake.Initial.Parameters">-DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo <value type="QString" key="CMake.Initial.Parameters">-DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo
-DCMAKE_GENERATOR:STRING=Ninja -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_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX}
-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} -DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable}
-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake</value> -DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx}
-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake
-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG}
-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C}</value>
<value type="int" key="EnableQmlDebugging">0</value> <value type="int" key="EnableQmlDebugging">0</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/leca/projects/qt/checks-parser/build/Desktop-Profile</value> <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/leca/projects/qt/checks-parser/build/Desktop-Profile</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
@ -324,12 +324,12 @@
<valuelist type="QVariantList" key="CMake.Configure.UserEnvironmentChanges"/> <valuelist type="QVariantList" key="CMake.Configure.UserEnvironmentChanges"/>
<value type="QString" key="CMake.Initial.Parameters">-DCMAKE_BUILD_TYPE:STRING=MinSizeRel <value type="QString" key="CMake.Initial.Parameters">-DCMAKE_BUILD_TYPE:STRING=MinSizeRel
-DCMAKE_GENERATOR:STRING=Ninja -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_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX}
-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} -DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable}
-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake</value> -DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx}
-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake
-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG}
-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C}</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/leca/projects/qt/checks-parser/build/Desktop-MinSizeRel</value> <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/leca/projects/qt/checks-parser/build/Desktop-MinSizeRel</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0"> <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0"> <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">

View File

@ -1,4 +1,7 @@
#include "mainwindow.h" #include "mainwindow.h"
#include "ofd/ofd.h"
#include "utils/utils.h"
#include <iostream>
#include <QApplication> #include <QApplication>
@ -7,5 +10,12 @@ int main(int argc, char *argv[]) {
MainWindow w; MainWindow w;
w.show(); w.show();
OFD ofd;
std::vector<std::string> ofds = ofd.search_ofds();
for (OFDModule o : ofds) {
std::cout << to_utf8(o.get_name()) << ": " << to_utf8(o.get_url()) << std::endl;
}
return a.exec(); return a.exec();
} }

View File

@ -22,7 +22,7 @@ void MainWindow::setupStoresList() {
std::vector<std::string> modules_names = parser.search_modules(); std::vector<std::string> modules_names = parser.search_modules();
for (std::string name : modules_names) { for (std::string name : modules_names) {
Module m(name); StoreModule m(name);
std::wstring module_name = m.get_name(); std::wstring module_name = m.get_name();
QString s = QString::fromStdWString(module_name); QString s = QString::fromStdWString(module_name);
@ -66,6 +66,7 @@ void MainWindow::on_parseButton_clicked() {
} }
OutputDialog *d = new OutputDialog(this, check); OutputDialog *d = new OutputDialog(this, check);
d->show();
d->exec(); d->exec();
} }

View File

@ -19,7 +19,6 @@ class MainWindow : public QMainWindow {
Parser parser; Parser parser;
public: public:
MainWindow(QWidget *parent = nullptr); MainWindow(QWidget *parent = nullptr);
~MainWindow(); ~MainWindow();
void setupStoresList(); void setupStoresList();

24
ofd/module.cpp Normal file
View File

@ -0,0 +1,24 @@
#include "module.h"
#include <nlohmann/json.hpp>
#include <fstream>
#include "../utils/utils.h"
OFDModule::OFDModule() {}
OFDModule::OFDModule(std::string path) {
this->path = path;
std::ifstream settings_file(path);
nlohmann::json settings = nlohmann::json::parse(settings_file);
this->name = from_utf8(settings["name"]);
this->url = from_utf8(settings["url"]);
}
std::wstring OFDModule::get_name() {
return this->name;
}
std::wstring OFDModule::get_url() {
return this->url;
}

18
ofd/module.h Normal file
View File

@ -0,0 +1,18 @@
#ifndef OFD_MODULE_H
#define OFD_MODULE_H
#include <string>
class OFDModule {
std::string path;
std::wstring name;
std::wstring url;
public:
OFDModule(std::string);
OFDModule();
std::wstring get_name();
std::wstring get_url();
};
#endif // OFDMODULE_H

62
ofd/ofd.cpp Normal file
View File

@ -0,0 +1,62 @@
#include "ofd.h"
#include "../settings.h"
#include "../utils/utils.h"
#include <cpr/cpr.h>
#include <filesystem>
#include <iostream>
#include <string>
#include <vector>
OFD::OFD() {}
OFD::OFD(std::string path) { this->module = OFDModule(path); };
std::vector<std::string> OFD::search_ofds() {
std::vector<std::string> result{};
std::string path = std::string(std::getenv("HOME")) + "/" + OFDS_MODULES_DIR;
std::filesystem::directory_entry modules_dir(path);
if (!modules_dir.exists()) {
std::filesystem::create_directories(path);
std::cout << "No modules directory found. Created one at " << path
<< std::endl;
std::cout << "Please, download modules to that directory from my git."
<< std::endl;
}
for (auto file : std::filesystem::directory_iterator(path)) {
result.push_back(file.path());
}
return result;
}
void OFD::set_module(std::string path) { this->module = OFDModule(path); }
std::string OFD::get_check_data(std::string fn, std::string fd,
std::string fp) {
//curl 'https://ofd.beeline.ru/api/ofdcheck/checkf?fn=7281440701327430&fp=2518183888&fd=25955&format=4' \
-H 'Accept: application/json, text/plain, */*' \
-H 'Accept-Language: en-US,en;q=0.9,eo;q=0.8,ru;q=0.7' \
-H 'Authorization: bearer null' \
-H 'Connection: keep-alive' \
-H 'Content-Type: application/json' \
-H 'DNT: 1' \
-H 'Referer: https://ofd.beeline.ru/check-order?fn=7281440701327430&fp=2518183888&fd=25955' \
-H 'Sec-Fetch-Dest: empty' \
-H 'Sec-Fetch-Mode: cors' \
-H 'Sec-Fetch-Site: same-origin' \
-H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36' \
-H 'sec-ch-ua: "Chromium";v="127", "Not)A;Brand";v="99"' \
-H 'sec-ch-ua-mobile: ?0' \
-H 'sec-ch-ua-platform: "Linux"'
cpr::Response r =
cpr::Get(cpr::Url{to_utf8(module.get_url())},
cpr::Parameters{{"fn", fn}, {"fd", fd}, {"fp", fp}});
std::cout << r.text << std::endl;
return r.text;
}

22
ofd/ofd.h Normal file
View File

@ -0,0 +1,22 @@
#ifndef OFD_H
#define OFD_H
#include <string>
#include <vector>
#include "module.h"
class OFD {
OFDModule module;
public:
OFD();
OFD(std::string);
std::vector<std::string> search_ofds();
void set_module(std::string);
std::string get_check_data(std::string, std::string, std::string);
};
#endif // OFD_H

61
output/output_options.cpp Normal file
View File

@ -0,0 +1,61 @@
#include "output_options.h"
OutputOptions::OutputOptions() {}
void OutputOptions::add_or_update_column(Column &column) {
if (column_exist(column.type)) {
update_column(column, find_column(column.type));
} else {
this->order.push_back(column);
}
}
void OutputOptions::update_column(Column& column, unsigned short index) {
this->order[index] = column;
}
void OutputOptions::remove_column(unsigned short index) {
this->order.erase(this->order.begin() + index);
}
void OutputOptions::remove_column(ColumnType t) {
this->order.erase(this->order.begin() + find_column(t));
}
unsigned short OutputOptions::find_column(ColumnType t) {
for (unsigned short i = 0; i < this->order.size(); i++) {
if (this->order[i].type == t)
return i;
}
return -1;
}
bool OutputOptions::column_exist(ColumnType t) {
for (unsigned short i = 0; i < this->order.size(); i++) {
if (this->order[i].type == t)
return true;
}
return false;
}
Column& OutputOptions::get_column (ColumnType t){
return this->order[find_column(t)];
}
std::vector<Column>& OutputOptions::get_columns() {
return this->order;
}
void OutputOptions::set_print_header(bool value) { this->print_header = value; }
bool OutputOptions::get_print_header() { return this->print_header; }
void OutputOptions::set_print_total(bool value) { this->print_total = value; }
bool OutputOptions::get_print_total() { return this->print_total; }
OutputFormat OutputOptions::get_output_format() { return this->format; }
void OutputOptions::set_output_format(OutputFormat format) {
this->format = format;
}
void OutputOptions::set_path(std::string path) { this->path = path; }
std::string &OutputOptions::get_path() { return this->path; }

57
output/output_options.h Normal file
View File

@ -0,0 +1,57 @@
#ifndef OUTPUT_OPTIONS_H
#define OUTPUT_OPTIONS_H
#include <string>
#include <vector>
enum class ColumnType {
goods_name,
goods_price_per_unit,
goods_quantity,
goods_net_weight,
goods_total
};
struct Column { // Example:
ColumnType type; // goods_name
std::string name; // "Товар"
unsigned int position; // "0" <-- 0 = "A", 1 = "B", etc.. column letter in
// table processor (i.e. excel or libreoffice)
} typedef Column;
enum class OutputFormat { csv, ods, xlsx, plaintext } typedef OutputFormat;
class OutputOptions {
std::vector<Column> order;
bool print_header;
bool print_total;
OutputFormat format;
std::string path;
public:
OutputOptions();
void add_or_update_column(Column &);
void update_column(Column&, unsigned short);
void remove_column(unsigned short);
void remove_column(ColumnType);
unsigned short find_column(ColumnType);
bool column_exist(ColumnType);
Column& get_column(ColumnType);
std::vector<Column>& get_columns();
void set_print_header(bool);
bool get_print_header();
void set_print_total(bool);
bool get_print_total();
void set_output_format(OutputFormat);
OutputFormat get_output_format();
void set_path(std::string);
std::string &get_path();
};
#endif // OUTPUT_OPTIONS_H

View File

@ -1,15 +1,119 @@
#include "outputdialog.h" // TODO: refactor that shit with custom qt widget(line edit + combo box)
#include "ui_outputdialog.h"
#include <iostream>
#include <QMainWindow>
#include "check/check.h"
OutputDialog::OutputDialog(QWidget *parent, Check check) #include "outputdialog.h"
: QDialog(parent), ui(new Ui::OutputDialog) { #include "check/check.h"
#include "output/output_options.h"
#include "ui_outputdialog.h"
#include <QFileDialog>
#include <QMainWindow>
#include <fstream>
#include <iostream>
OutputDialog::OutputDialog(QWidget *parent, Check &check)
: QDialog(parent), ui(new Ui::OutputDialog), check(check),
options(*(new OutputOptions())) {
ui->setupUi(this); ui->setupUi(this);
for (auto goods : check.get_goods()) {
std::cout << "From dialog:" << goods.get_name() << std::endl;
}
} }
OutputDialog::~OutputDialog() { delete ui; } OutputDialog::~OutputDialog() { delete ui; }
bool compare_position(Column &c1, Column &c2) {
return c1.position < c2.position;
}
void OutputDialog::on_buttonBox_accepted() {
std::ofstream output_file(this->options.get_path());
for (int i = 0; i < ui->tableWidget->rowCount(); i ++) {
int position = ui->tableWidget->item(i, 0)->text().toInt();
std::string name = ui->tableWidget->item(i, 1)->text().toStdString();
Column c;
c.type = static_cast<ColumnType>(i);
c.position = position;
c.name = name;
this->options.add_or_update_column(c);
}
std::sort(this->options.get_columns().begin(),
this->options.get_columns().end(), compare_position);
if (options.get_print_header()) {
for (auto& column : this->options.get_columns()) {
output_file << column.name
<< (column.position == this->options.get_columns().size()
? ""
: ",");
}
output_file << std::endl;
}
for (auto goods : this->check.get_goods()) {
for (auto& column : this->options.get_columns()) {
std::string output_str;
switch (column.type) {
case ColumnType::goods_name:
output_str = goods.get_name();
break;
case ColumnType::goods_price_per_unit:
output_str = std::to_string(goods.get_price_per_unit());
break;
case ColumnType::goods_quantity:
output_str = std::to_string(goods.get_quantity());
break;
case ColumnType::goods_net_weight:
output_str = "TODO";
// TODO
break;
case ColumnType::goods_total:
output_str = std::to_string(goods.calculate_total_price());
break;
}
if (column.position != this->options.get_columns().size()) {
output_str += ",";
} else {
output_str += "\n";
}
output_file << output_str;
}
}
if (this->options.get_print_total()) {
output_file << "Total: " << std::to_string(check.calculae_total_price());
}
output_file.close();
}
void update_settings(OutputOptions &options, ColumnType t, std::string name,
int value) {
Column column;
column.type = t;
column.name = name;
column.position = value;
if (value) {
options.add_or_update_column(column);
} else {
options.remove_column(t);
}
}
void OutputDialog::on_chooseFileButton_clicked() {
QString filename = QFileDialog::getSaveFileName();
std::cout << filename.toStdString() << std::endl;
this->options.set_path(filename.toStdString());
ui->pathLabel->setText("Path to export: " + filename);
}
void OutputDialog::on_printHeaderCheckBox_stateChanged(int value) {
this->options.set_print_header(value);
}
void OutputDialog::on_printTotalCheckBox_stateChanged(int value) {
this->options.set_print_total(value);
}

View File

@ -1,21 +1,35 @@
#ifndef OUTPUTDIALOG_H #ifndef OUTPUTDIALOG_H
#define OUTPUTDIALOG_H #define OUTPUTDIALOG_H
#include <QDialog>
#include "check/check.h" #include "check/check.h"
#include "output/output_options.h"
#include <QDialog>
#include <QComboBox>
namespace Ui { namespace Ui {
class OutputDialog; class OutputDialog;
} }
class OutputDialog : public QDialog class OutputDialog : public QDialog {
{
Q_OBJECT Q_OBJECT
OutputOptions options;
Check &check;
public: public:
explicit OutputDialog(QWidget *parent = nullptr, Check = Check()); explicit OutputDialog(QWidget *parent = nullptr, Check & = *(new Check()));
~OutputDialog(); ~OutputDialog();
private slots:
void on_buttonBox_accepted();
void on_chooseFileButton_clicked();
void on_printHeaderCheckBox_stateChanged(int arg1);
void on_printTotalCheckBox_stateChanged(int arg1);
private: private:
Ui::OutputDialog *ui; Ui::OutputDialog *ui;
}; };

View File

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>602</width> <width>586</width>
<height>436</height> <height>431</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -29,108 +29,152 @@
<set>QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok</set> <set>QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok</set>
</property> </property>
</widget> </widget>
<widget class="QComboBox" name="formatSelect"> <widget class="QLabel" name="pathLabel">
<property name="geometry">
<rect>
<x>60</x>
<y>20</y>
<width>261</width>
<height>26</height>
</rect>
</property>
<item>
<property name="text">
<string>ods</string>
</property>
</item>
<item>
<property name="text">
<string>csv</string>
</property>
</item>
<item>
<property name="text">
<string>xlsx (Not implemented)</string>
</property>
</item>
</widget>
<widget class="QLabel" name="formatLabel">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>10</x> <x>10</x>
<y>20</y> <y>20</y>
<width>45</width> <width>271</width>
<height>21</height> <height>18</height>
</rect> </rect>
</property> </property>
<property name="text"> <property name="text">
<string>Format</string> <string>Path to export: </string>
</property> </property>
</widget> </widget>
<widget class="QGroupBox" name="groupBox"> <widget class="QPushButton" name="chooseFileButton">
<property name="geometry">
<rect>
<x>290</x>
<y>20</y>
<width>80</width>
<height>26</height>
</rect>
</property>
<property name="text">
<string>Choose</string>
</property>
</widget>
<widget class="QCheckBox" name="printHeaderCheckBox">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>10</x> <x>10</x>
<y>50</y> <y>50</y>
<width>441</width> <width>111</width>
<height>191</height> <height>24</height>
</rect> </rect>
</property> </property>
<property name="title"> <property name="text">
<string>Columns</string> <string>Print header</string>
</property> </property>
<widget class="QWidget" name="gridLayoutWidget"> </widget>
<widget class="QTableWidget" name="tableWidget">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>0</x> <x>10</x>
<y>20</y> <y>130</y>
<width>441</width> <width>321</width>
<height>171</height> <height>181</height>
</rect> </rect>
</property> </property>
<layout class="QGridLayout" name="gridLayout"> <row>
<item row="0" column="1">
<widget class="QSpinBox" name="spinBox"/>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="spinBox_3"/>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="spinBox_2"/>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="priceCheckBox">
<property name="text"> <property name="text">
<string>Price</string> <string>Goods name</string>
</property> </property>
</widget> </row>
</item> <row>
<item row="0" column="2">
<widget class="QCheckBox" name="netWeightCheckBox">
<property name="text"> <property name="text">
<string>Net weight</string> <string>Goods price</string>
</property> </property>
</widget> </row>
</item> <row>
<item row="1" column="0">
<widget class="QCheckBox" name="quantityCheckBox">
<property name="text"> <property name="text">
<string>Quantity</string> <string>Goods quantity</string>
</property> </property>
</widget> </row>
</item> <row>
<property name="text">
<string>Goods net weight</string>
</property>
</row>
<row>
<property name="text">
<string>Goods total</string>
</property>
</row>
<column>
<property name="text">
<string>position</string>
</property>
</column>
<column>
<property name="text">
<string>name</string>
</property>
</column>
<item row="0" column="0"> <item row="0" column="0">
<widget class="QCheckBox" name="nameCheckBox"> <property name="text">
<string>1</string>
</property>
</item>
<item row="0" column="1">
<property name="text"> <property name="text">
<string>Name</string> <string>Name</string>
</property> </property>
</widget>
</item> </item>
<item row="0" column="3"> <item row="1" column="0">
<widget class="QSpinBox" name="spinBox_4"/> <property name="text">
<string>2</string>
</property>
</item>
<item row="1" column="1">
<property name="text">
<string>Price</string>
</property>
</item>
<item row="2" column="0">
<property name="text">
<string>3</string>
</property>
</item>
<item row="2" column="1">
<property name="text">
<string>Quantity</string>
</property>
</item>
<item row="3" column="0">
<property name="text">
<string>4</string>
</property>
</item>
<item row="3" column="1">
<property name="text">
<string>Net weight</string>
</property>
</item>
<item row="4" column="0">
<property name="text">
<string>5</string>
</property>
</item>
<item row="4" column="1">
<property name="text">
<string>Total price</string>
</property>
</item> </item>
</layout>
</widget> </widget>
<widget class="QCheckBox" name="printTotalCheckBox">
<property name="geometry">
<rect>
<x>10</x>
<y>90</y>
<width>111</width>
<height>24</height>
</rect>
</property>
<property name="text">
<string>Print total</string>
</property>
</widget> </widget>
</widget> </widget>
<resources/> <resources/>

View File

@ -1,26 +1,13 @@
#include "module.h" #include "module.h"
#include "../settings.h"
#include <codecvt>
#include <fstream> #include <fstream>
#include <iostream>
#include <locale>
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
#include <regex> #include <regex>
#include <string> #include <string>
#include "../utils/utils.h"
std::string to_utf8(std::wstring wide_string) { StoreModule::StoreModule() {}
static std::wstring_convert<std::codecvt_utf8<wchar_t>> utf8_conv;
return utf8_conv.to_bytes(wide_string);
}
std::wstring from_utf8(std::string string) { StoreModule::StoreModule(std::string path) {
static std::wstring_convert<std::codecvt_utf8<wchar_t>> utf8_conv;
return utf8_conv.from_bytes(string);
}
Module::Module() {}
Module::Module(std::string path) {
std::ifstream settings_file(path); std::ifstream settings_file(path);
nlohmann::json settings = nlohmann::json::parse(settings_file); nlohmann::json settings = nlohmann::json::parse(settings_file);
@ -42,7 +29,7 @@ Module::Module(std::string path) {
#endif #endif
} }
std::vector<std::string> Module::parse_name(std::wstring str) { std::vector<std::string> StoreModule::parse_name(std::wstring str) {
std::vector<std::string> result; std::vector<std::string> result;
std::wregex r(this->goods_name_regex, std::regex::collate); std::wregex r(this->goods_name_regex, std::regex::collate);
@ -54,7 +41,7 @@ std::vector<std::string> Module::parse_name(std::wstring str) {
return result; return result;
} }
std::vector<std::string> Module::parse_price(std::wstring str) { std::vector<std::string> StoreModule::parse_price(std::wstring str) {
std::vector<std::string> result; std::vector<std::string> result;
std::wregex r(this->goods_price_regex, std::regex::collate); std::wregex r(this->goods_price_regex, std::regex::collate);
@ -66,7 +53,7 @@ std::vector<std::string> Module::parse_price(std::wstring str) {
return result; return result;
} }
std::vector<std::string> Module::parse_quantity(std::wstring str) { std::vector<std::string> StoreModule::parse_quantity(std::wstring str) {
std::vector<std::string> result; std::vector<std::string> result;
std::wregex r(this->goods_quantity_regex, std::regex::collate); std::wregex r(this->goods_quantity_regex, std::regex::collate);
@ -77,7 +64,7 @@ std::vector<std::string> Module::parse_quantity(std::wstring str) {
return result; return result;
} }
std::wstring Module::trim_check(std::wstring& check) { std::wstring StoreModule::trim_check(std::wstring& check) {
unsigned int start_pos; unsigned int start_pos;
unsigned int end_pos; unsigned int end_pos;
@ -103,4 +90,4 @@ std::wstring Module::trim_check(std::wstring& check) {
return check; return check;
} }
std::wstring Module::get_name() { return this->name; } std::wstring StoreModule::get_name() { return this->name; }

View File

@ -1,10 +1,10 @@
#ifndef MODULE_H #ifndef STORE_MODULE_H
#define MODULE_H #define STORE_MODULE_H
#include <string> #include <string>
#include <nlohmann/json.hpp> #include <vector>
class Module { class StoreModule {
std::string path; std::string path;
std::wstring name; std::wstring name;
std::wstring goods_name_regex; std::wstring goods_name_regex;
@ -13,8 +13,8 @@ class Module {
std::wstring check_start_regex; std::wstring check_start_regex;
std::wstring check_end_regex; std::wstring check_end_regex;
public: public:
Module(std::string); StoreModule(std::string);
Module(); StoreModule();
std::vector<std::string> parse_name(std::wstring); std::vector<std::string> parse_name(std::wstring);
std::vector<std::string> parse_price(std::wstring); std::vector<std::string> parse_price(std::wstring);
@ -25,4 +25,4 @@ public:
std::wstring get_name(); std::wstring get_name();
}; };
#endif // MODULE_H #endif // STORE_MODULE_H

View File

@ -7,7 +7,7 @@
Parser::Parser() {} Parser::Parser() {}
std::vector<std::string> Parser::search_modules() { std::vector<std::string> Parser::search_modules() {
std::string path = std::string(std::getenv("HOME")) + "/" + MODULES_DIR; std::string path = std::string(std::getenv("HOME")) + "/" + STORES_MODULES_DIR;
std::filesystem::directory_entry modules_dir(path); std::filesystem::directory_entry modules_dir(path);
if (!modules_dir.exists()) { if (!modules_dir.exists()) {
@ -27,7 +27,7 @@ std::vector<std::string> Parser::search_modules() {
return modules_files; return modules_files;
} }
void Parser::set_module(std::string path) { module = Module(path); } void Parser::set_module(std::string path) { module = StoreModule(path); }
std::vector<Goods> Parser::parse(std::wstring check_plaintext) { std::vector<Goods> Parser::parse(std::wstring check_plaintext) {
std::vector<Goods> result; std::vector<Goods> result;

View File

@ -1,7 +1,6 @@
#ifndef PARSER_H #ifndef PARSER_H
#define PARSER_H #define PARSER_H
#include <iostream>
#include "module.h" #include "module.h"
#include <string> #include <string>
#include <vector> #include <vector>
@ -9,7 +8,7 @@
class Parser { class Parser {
Module module; StoreModule module;
public: public:
Parser(); Parser();

View File

@ -1,7 +1,8 @@
#ifndef SETTINGS_H #ifndef SETTINGS_H
#define SETTINGS_H #define SETTINGS_H
#define MODULES_DIR ".local/share/checks_parser/modules" #define OFDS_MODULES_DIR ".local/share/checks_parser/modules/ofd"
#define DEBUG #define STORES_MODULES_DIR ".local/share/checks_parser/modules/stores"
// #define DEBUG
#endif // SETTINGS_H #endif // SETTINGS_H

15
utils/utils.cpp Normal file
View File

@ -0,0 +1,15 @@
#include "utils.h"
#include <codecvt>
#include <string>
#include <locale>
std::string to_utf8(std::wstring wide_string) {
static std::wstring_convert<std::codecvt_utf8<wchar_t>> utf8_conv;
return utf8_conv.to_bytes(wide_string);
}
std::wstring from_utf8(std::string string) {
static std::wstring_convert<std::codecvt_utf8<wchar_t>> utf8_conv;
return utf8_conv.from_bytes(string);
}

9
utils/utils.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef UTILS_H
#define UTILS_H
#include <string>
std::string to_utf8(std::wstring wide_string);
std::wstring from_utf8(std::string string);
#endif // UTILS_H