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
+
+
+
+
+
+
+ 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
+
+
+
+
+
+
+
+
+
+
+
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
+
+
+
+
+