From 3106479fcc4c2ea6a852bfb2fa998bf7b9e8e4c8 Mon Sep 17 00:00:00 2001 From: leca Date: Sun, 24 Nov 2024 19:07:28 +0300 Subject: [PATCH] completed requests to ofd.ru --- .gitignore | 1 - CMakeLists.txt | 1 + adjustpicturedialog.cpp | 7 +- adjustpicturedialog.h | 2 + adjustpicturedialog.ui | 115 ++++++++++++ mainwindow.cpp | 36 +++- mainwindow.h | 4 +- mainwindow.ui | 401 ++++++++++++++++++++++++++++++++++++++++ nano.42371.save | 6 + net/net.cpp | 52 +++++- net/net.h | 4 +- outputdialog.ui | 215 +++++++++++++++++++++ settingsdialog.ui | 285 ++++++++++++++++++++++++++++ solvecaptchadialog.cpp | 33 ++++ solvecaptchadialog.h | 30 +++ solvecaptchadialog.ui | 91 +++++++++ 16 files changed, 1274 insertions(+), 9 deletions(-) create mode 100644 adjustpicturedialog.ui create mode 100644 mainwindow.ui create mode 100644 nano.42371.save create mode 100644 outputdialog.ui create mode 100644 settingsdialog.ui create mode 100644 solvecaptchadialog.cpp create mode 100644 solvecaptchadialog.h create mode 100644 solvecaptchadialog.ui diff --git a/.gitignore b/.gitignore index da3b274..9598828 100644 --- a/.gitignore +++ b/.gitignore @@ -99,7 +99,6 @@ cmake_install.cmake *.moc *.moc.cpp *.qrc.cpp -*.ui # CMake-specific files CMakeCache.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index c611c15..2695750 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,6 +56,7 @@ else() adjustpicturedialog.h adjustpicturedialog.cpp adjustpicturedialog.ui imageview/imageview.h imageview/imageview.cpp image_redactor/imageredactor.h image_redactor/imageredactor.cpp + solvecaptchadialog.h solvecaptchadialog.cpp solvecaptchadialog.ui ) diff --git a/adjustpicturedialog.cpp b/adjustpicturedialog.cpp index d6e8d8e..9f50413 100644 --- a/adjustpicturedialog.cpp +++ b/adjustpicturedialog.cpp @@ -58,7 +58,7 @@ std::string AdjustPictureDialog::decode() { cv::cvtColor(im, imGray, cv::COLOR_BGR2GRAY); zbar::Image image(im.cols, im.rows, "Y800", (uchar *) imGray.data, im.cols * im.rows); - int n = scanner.scan(image); + scanner.scan(image); std::string result = ""; @@ -70,3 +70,8 @@ std::string AdjustPictureDialog::decode() { return result; } + +void AdjustPictureDialog::on_contrastSlider_sliderMoved(int position) { + +} + diff --git a/adjustpicturedialog.h b/adjustpicturedialog.h index 7e1e17b..9fefcb2 100644 --- a/adjustpicturedialog.h +++ b/adjustpicturedialog.h @@ -25,6 +25,8 @@ private slots: // void on_buttonBox_accepted(); void accept() override; + void on_contrastSlider_sliderMoved(int position); + private: Ui::AdjustPictureDialog *ui; QGraphicsScene *scene; diff --git a/adjustpicturedialog.ui b/adjustpicturedialog.ui new file mode 100644 index 0000000..3272985 --- /dev/null +++ b/adjustpicturedialog.ui @@ -0,0 +1,115 @@ + + + AdjustPictureDialog + + + + 0 + 0 + 825 + 497 + + + + Dialog + + + + + 450 + 450 + 341 + 32 + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + 10 + 460 + 591 + 16 + + + + Qt::Horizontal + + + + + + 10 + 0 + 511 + 18 + + + + Please, zoom to qr code and adjust contrast so that qr code looks sharp + + + + + + 15 + 41 + 791 + 391 + + + + buttonBox + label + contrastSlider + graphicsView + + + + ImageRedactor + QGraphicsView +
imageredactor.h
+
+
+ + + + buttonBox + accepted() + AdjustPictureDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + AdjustPictureDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + +
diff --git a/mainwindow.cpp b/mainwindow.cpp index 324896a..ed3b1cb 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -5,6 +5,7 @@ #include "outputdialog.h" #include "adjustpicturedialog.h" #include "settingsdialog.h" +#include "solvecaptchadialog.h" #include #include #include @@ -46,15 +47,42 @@ void MainWindow::setupStoresList() { #endif } +std::string MainWindow::makeRequestToOfd(std::string captcha) { + std::string checkContent = Net().fetch_check_data_from_ofdru( + ui->fn_edit->text().toStdString(), + ui->fd_edit->text().toStdString(), + ui->fi_edit->text().toStdString(), + ui->dateTimeEdit->dateTime().toString(Qt::ISODate).toStdString(), + ui->fundIncomeCombo->currentIndex() + 1, + // In the request to ofd.ru, total is in a strange format, like a string of a format where 2 last digits represent decimal part of a number. + ui->total_edit->text().toDouble() * 100, + captcha); + + return checkContent +} + +void MainWindow::receiveSolvedCaptcha(std::string captcha) { + + std::string check_content = makeRequestToOfd(captcha); + + +} + void MainWindow::on_parseButton_clicked() { QString s; - switch (ui->checkType->currentIndex()) { + switch (ui->tabWidget->currentIndex()) { case 0: s = ui->checkContent->toPlainText(); break; case 1: s = ui->checkContentFromImage->toPlainText(); break; + case 2: + Net().get_captcha_from_ofdru(); + SolveCaptchaDialog dialog = SolveCaptchaDialog(this); + connect(&dialog, &SolveCaptchaDialog::solvedCaptcha, this, &MainWindow::receiveSolvedCaptcha); + dialog.exec(); + return; } std::wstring check_plaintext = s.toStdWString(); @@ -118,6 +146,12 @@ void MainWindow::onDecodedData(std::string data) { QDateTime datetime = QDateTime::fromString(extractedDateTime, "yyyyMMddThhmm"); ui->dateTimeEdit->setDateTime(datetime); + int type = std::stoi(split(dataSplit[5], "=")[1]); + ui->fundIncomeCombo->setCurrentIndex(type - 1); + + std::string total = split(dataSplit[1], "=")[1]; + + ui->total_edit->setText(QString::fromStdString(total)); } void MainWindow::on_chooseImageButton_ocr_clicked() diff --git a/mainwindow.h b/mainwindow.h index e10b92d..92d7c3f 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -26,13 +26,13 @@ public: Check get_check(); void onDecodedData(std::string); + std::string makeRequestToOfd(std::string captcha); + void receiveSolvedCaptcha(std::string); private slots: void on_parseButton_clicked(); void on_storeType_currentIndexChanged(int index); - // void on_chooseImageButton_clicked(); - void on_preferencesButton_clicked(); void on_chooseImageButton_ofd_clicked(); diff --git a/mainwindow.ui b/mainwindow.ui new file mode 100644 index 0000000..7bcc3ce --- /dev/null +++ b/mainwindow.ui @@ -0,0 +1,401 @@ + + + MainWindow + + + + 0 + 0 + 817 + 659 + + + + MainWindow + + + + + + 90 + 10 + 211 + 31 + + + + + + + 10 + 10 + 81 + 31 + + + + Store + + + + + + 30 + 560 + 80 + 26 + + + + Parse + + + + + + 730 + 0 + 81 + 31 + + + + Preferences + + + + + + 10 + 50 + 801 + 511 + + + + 2 + + + + Text + + + + + 0 + 0 + 101 + 18 + + + + Check content + + + + + + 0 + 30 + 611 + 441 + + + + + + + OCR + + + + + 0 + 0 + 80 + 26 + + + + Choose + + + + + + 0 + 60 + 511 + 401 + + + + + + + 100 + 0 + 381 + 18 + + + + Path to image: + + + + + + 0 + 30 + 571 + 18 + + + + Here is recognised check text. Please, edit it if something's wrong: + + + + + + 490 + 10 + 291 + 421 + + + + + + + + + + OFD + + + + + 490 + 10 + 291 + 421 + + + + + + + + + + 100 + 0 + 381 + 18 + + + + Path to image: + + + + + + 10 + 0 + 80 + 26 + + + + Choose + + + + + + 180 + 50 + 261 + 26 + + + + 0000000000000000 + + + + + + 10 + 50 + 161 + 21 + + + + + 0 + 0 + + + + FN (Fiscal Number) + + + + + + 10 + 90 + 161 + 21 + + + + + 0 + 0 + + + + FD (Fiscal Document) + + + + + + 180 + 90 + 261 + 26 + + + + 0000000000 + + + + + + 10 + 130 + 161 + 21 + + + + + 0 + 0 + + + + FI (Fiscal Identifier) + + + + + + 180 + 130 + 261 + 26 + + + + 0000000000 + + + + + + 10 + 170 + 194 + 27 + + + + + + + 10 + 210 + 191 + 26 + + + + + Funds income + + + + + Funds return + + + + + Funds spend + + + + + Spends return + + + + + + + 90 + 250 + 113 + 26 + + + + + + + + + + 10 + 250 + 66 + 18 + + + + Total + + + + + + + + + 0 + 0 + 817 + 23 + + + + + checks parser + + + + + + + + + diff --git a/nano.42371.save b/nano.42371.save new file mode 100644 index 0000000..f8de794 --- /dev/null +++ b/nano.42371.save @@ -0,0 +1,6 @@ +t=20240828T2033 +s=895.50 +fn=7380440700069236 +i=21386 +fp=1292383731 +n=1 diff --git a/net/net.cpp b/net/net.cpp index ecf88bc..bed4d21 100644 --- a/net/net.cpp +++ b/net/net.cpp @@ -1,5 +1,6 @@ #include "net.h" #include +#include "../utils/utils.h" #include #include #include @@ -32,6 +33,12 @@ void write_modules(void *buffer, size_t size, size_t nmemb, void *modules) { } } +size_t writeCallback(void* contents, size_t size, size_t nmemb, void* userp) { + size_t totalSize = size * nmemb; + ((std::string*)userp)->append(std::string((char*)contents)); + return totalSize; +} + std::vector Net::get_all_modules(std::string url) { CURL *handle = curl_easy_init(); @@ -47,7 +54,7 @@ std::vector Net::get_all_modules(std::string url) { return modules; } -std::string Net::get_file(std::string url, std::string filename) { +void Net::get_file(std::string url, std::string filename) { CURL *handle = curl_easy_init(); curl_easy_setopt(handle, CURLOPT_URL, url.c_str()); @@ -58,6 +65,45 @@ std::string Net::get_file(std::string url, std::string filename) { auto success = curl_easy_perform(handle); curl_easy_cleanup(handle); - - return ""; +} + +std::string Net::fetch_check_data_from_ofdru(std::string fn, std::string fd, std::string fi, std::string datetime, int operation, int total, std::string captcha) { + CURL *handle = curl_easy_init(); + if (handle == nullptr) { + std::cerr << "cannot initialize curl" << std::endl; + return ""; + } + struct curl_slist *headers = NULL; + std::string readBuffer = ""; + + curl_easy_setopt(handle, CURLOPT_URL, "https://check.ofd.ru/Document/FetchReceiptFromFns"); + + headers = curl_slist_append(headers, "Content-Type: application/json;charset=UTF-8"); + curl_easy_setopt(handle, CURLOPT_HTTPHEADER, headers); + + std::string dataJSON = + "{" + "\"TotalSum\":" + std::to_string(total) + "," + "\"FnNumber\":\"" + fn + "\"," + "\"ReceiptOperationType\":\"" + std::to_string(operation) + "\"," + "\"DocNumber\":\"" + fd + "\"," + "\"DocFiscalSign\":\"" + fi + "\"," + "\"Captcha\":\"" + captcha + "\"," + "\"DocDateTime\":\"" + datetime + ".000Z\"" + "}"; + + curl_easy_setopt(handle, CURLOPT_POSTFIELDS, dataJSON.c_str()); + curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, writeCallback); + curl_easy_setopt(handle, CURLOPT_WRITEDATA, &readBuffer); + + auto answer = curl_easy_perform(handle); + + delete headers; + curl_easy_cleanup(handle); + + return readBuffer; +} + +void Net::get_captcha_from_ofdru() { + get_file("https://check.ofd.ru/api/captcha/common/img", get_path_relative_to_home(".local/share/checks_parser/captcha.png")); } diff --git a/net/net.h b/net/net.h index d2ff34b..5ce64e9 100644 --- a/net/net.h +++ b/net/net.h @@ -11,7 +11,9 @@ class Net public: Net(); std::vector get_all_modules(std::string url); - std::string get_file(std::string url, std::string filename); + void get_file(std::string url, std::string filename); + std::string fetch_check_data_from_ofdru(std::string fn, std::string fd, std::string fi, std::string datetime, int operation, int total, std::string captcha); + void get_captcha_from_ofdru(); }; #endif // NET_H diff --git a/outputdialog.ui b/outputdialog.ui new file mode 100644 index 0000000..f09f5da --- /dev/null +++ b/outputdialog.ui @@ -0,0 +1,215 @@ + + + OutputDialog + + + + 0 + 0 + 586 + 431 + + + + Dialog + + + + + 410 + 390 + 166 + 26 + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + 10 + 20 + 271 + 18 + + + + Path to export: + + + + + + 290 + 20 + 80 + 26 + + + + Choose + + + + + + 10 + 50 + 111 + 24 + + + + Print header + + + + + + 10 + 130 + 401 + 221 + + + + + Goods name + + + + + Goods price + + + + + Goods quantity + + + + + Goods net weight + + + + + Goods total + + + + + position + + + + + name + + + + + 1 + + + + + Name + + + + + 2 + + + + + Price + + + + + 3 + + + + + Quantity + + + + + 4 + + + + + Net weight + + + + + 5 + + + + + Total price + + + + + + + 10 + 90 + 111 + 24 + + + + Print total + + + + + + + buttonBox + accepted() + OutputDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + OutputDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/settingsdialog.ui b/settingsdialog.ui new file mode 100644 index 0000000..c6379b8 --- /dev/null +++ b/settingsdialog.ui @@ -0,0 +1,285 @@ + + + settingsdialog + + + + 0 + 0 + 599 + 727 + + + + Dialog + + + + + 310 + 690 + 251 + 32 + + + + Qt::Orientation::Horizontal + + + QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Save + + + + + + 10 + 0 + 541 + 661 + + + + true + + + + + 0 + 0 + 539 + 659 + + + + + + 0 + 0 + 531 + 651 + + + + + + + + + + + + + Goods name position + + + + + + + Goods price per unit alias + + + + + + + Choose + + + + + + + + + + Print header + + + + + + + Goods net weight alias + + + + + + + Stores modules url + + + + + + + + + + Goods total alias + + + + + + + Goods name alias + + + + + + + + + + Goods quantity alias + + + + + + + Stores modules directory + + + + + + + + + + + + + OFD modules directory + + + + + + + + + + + + + + + + Goods price per unit position + + + + + + + Goods net weight position + + + + + + + OFD modules url + + + + + + + + + + Goods total position + + + + + + + Goods quantity position + + + + + + + + + + + + + Choose + + + + + + + + + + Print total + + + + + + + + + + + + + + + + + + + + + + + + + + buttonBox + accepted() + settingsdialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + settingsdialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/solvecaptchadialog.cpp b/solvecaptchadialog.cpp new file mode 100644 index 0000000..a30c090 --- /dev/null +++ b/solvecaptchadialog.cpp @@ -0,0 +1,33 @@ +#include "solvecaptchadialog.h" +#include "ui_solvecaptchadialog.h" +#include "utils/utils.h" + +#include + +SolveCaptchaDialog::SolveCaptchaDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::SolveCaptchaDialog) { + ui->setupUi(this); + + QString captcha_path = QString::fromStdString(get_path_relative_to_home(".local/share/checks_parser/captcha.png")); + ui->captcha_picture->setPixmap(captcha_path); + ui->captcha_picture->setScaledContents(true); +} + +void SolveCaptchaDialog::accept() { + std::string userInput = ui->captcha_edit->text().toStdString(); + if (userInput.length() < 6) { + QMessageBox infoDialog; + infoDialog.setText("Please, enter a valid captcha"); + infoDialog.setIcon(QMessageBox::Warning); + infoDialog.setWindowTitle("No captcha"); + infoDialog.exec(); + } else { + emit solvedCaptcha(userInput); + QDialog::accept(); + } +} + +SolveCaptchaDialog::~SolveCaptchaDialog() { + delete ui; +} diff --git a/solvecaptchadialog.h b/solvecaptchadialog.h new file mode 100644 index 0000000..8b0555e --- /dev/null +++ b/solvecaptchadialog.h @@ -0,0 +1,30 @@ +#ifndef SOLVECAPTCHADIALOG_H +#define SOLVECAPTCHADIALOG_H + +#include + +namespace Ui { +class SolveCaptchaDialog; +} + +class SolveCaptchaDialog : public QDialog +{ + Q_OBJECT + +public: + explicit SolveCaptchaDialog(QWidget *parent = nullptr); + ~SolveCaptchaDialog(); + + +signals: + void solvedCaptcha(std::string); + + +private: + Ui::SolveCaptchaDialog *ui; + +private slots: + void accept() override; +}; + +#endif // SOLVECAPTCHADIALOG_H diff --git a/solvecaptchadialog.ui b/solvecaptchadialog.ui new file mode 100644 index 0000000..c587811 --- /dev/null +++ b/solvecaptchadialog.ui @@ -0,0 +1,91 @@ + + + SolveCaptchaDialog + + + + 0 + 0 + 503 + 350 + + + + Dialog + + + + + 130 + 310 + 341 + 32 + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + 20 + 20 + 451 + 221 + + + + + + + + + + 80 + 260 + 321 + 26 + + + + + + + + buttonBox + accepted() + SolveCaptchaDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + SolveCaptchaDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + +