Compare commits
25 Commits
48885daed5
...
alpha-0.0.
| Author | SHA1 | Date | |
|---|---|---|---|
| 17a03606c5 | |||
| 83351698d6 | |||
| 2c99f422d3 | |||
| 41463c7f87 | |||
| c941264346 | |||
| c471cb3f62 | |||
| 7c021c90ee | |||
| e6cc4b9117 | |||
| c8e4f5ac54 | |||
| daa7d43c1b | |||
| b9a7808960 | |||
| 1a0f756efc | |||
| 362c70e695 | |||
| 88d849bee9 | |||
| b59b42a40c | |||
| fdfeb57049 | |||
| 22c6bed407 | |||
| d4b5b8d068 | |||
| 54020c0925 | |||
| 4d658a817b | |||
| 47dfc19395 | |||
| 1843479e6b | |||
| 8f511789d9 | |||
| a39a34852c | |||
| 3106479fcc |
5
.gitignore
vendored
5
.gitignore
vendored
@@ -99,7 +99,6 @@ cmake_install.cmake
|
||||
*.moc
|
||||
*.moc.cpp
|
||||
*.qrc.cpp
|
||||
*.ui
|
||||
|
||||
# CMake-specific files
|
||||
CMakeCache.txt
|
||||
@@ -118,3 +117,7 @@ install_manifest.txt
|
||||
*.sdf
|
||||
|
||||
checks-parser_autogen
|
||||
checks-parser
|
||||
|
||||
deploy/appimage/AppDir/usr/share/doc/
|
||||
deploy/appimage/AppDir/usr/share/
|
||||
|
||||
0
.lupdate/translations/en_US.ts.stamp
Normal file
0
.lupdate/translations/en_US.ts.stamp
Normal file
0
.lupdate/translations/ru_RU.ts.stamp
Normal file
0
.lupdate/translations/ru_RU.ts.stamp
Normal file
@@ -1,42 +1,60 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
|
||||
project(checks-parser VERSION 0.1 LANGUAGES CXX)
|
||||
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
set(CMAKE_AUTOUIC_SEARCH_PATHS Designer)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets)
|
||||
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets LinguistTools)
|
||||
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets)
|
||||
find_package(Qt5 COMPONENTS LinguistTools)
|
||||
|
||||
set(PROJECT_SOURCES
|
||||
main.cpp
|
||||
mainwindow.cpp
|
||||
mainwindow.h
|
||||
mainwindow.ui
|
||||
|
||||
# Add other source files here that contain translatable strings
|
||||
)
|
||||
|
||||
# Specify the UI files and source files for translation
|
||||
set(TRANSLATION_SOURCES
|
||||
main.cpp
|
||||
mainwindow.cpp mainwindow.h mainwindow.ui
|
||||
outputdialog.cpp outputdialog.h outputdialog.ui
|
||||
settingsdialog.cpp settingsdialog.h settingsdialog.ui
|
||||
solvecaptchadialog.cpp solvecaptchadialog.h solvecaptchadialog.ui
|
||||
adjustpicturedialog.cpp adjustpicturedialog.h adjustpicturedialog.ui
|
||||
|
||||
# Add other .cpp or .ui files that need translation here
|
||||
)
|
||||
|
||||
if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
|
||||
qt_add_executable(checks-parser
|
||||
MANUAL_FINALIZATION
|
||||
${PROJECT_SOURCES}
|
||||
)
|
||||
# Define target properties for Android with Qt 6 as:
|
||||
# set_property(TARGET checks-parser APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR
|
||||
# ${CMAKE_CURRENT_SOURCE_DIR}/android)
|
||||
# For more information, see https://doc.qt.io/qt-6/qt-add-executable.html#target-creation
|
||||
|
||||
# Generate translation files for Qt 6
|
||||
qt_add_translation(TRANSLATIONS "${TRANSLATION_SOURCES}")
|
||||
|
||||
else()
|
||||
if(ANDROID)
|
||||
add_library(checks-parser SHARED
|
||||
${PROJECT_SOURCES}
|
||||
)
|
||||
# Define properties for Android with Qt 5 after find_package() calls as:
|
||||
# set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android")
|
||||
|
||||
else()
|
||||
# Generate translation files for Qt 5
|
||||
# QT5_ADD_TRANSLATION()
|
||||
qt5_create_translation(QM_FILES "${TRANSLATION_SOURCES}" translations/en_US.ts translations/ru_RU.ts)
|
||||
add_executable(checks-parser
|
||||
${PROJECT_SOURCES}
|
||||
goods/goods.h goods/goods.cpp
|
||||
@@ -46,7 +64,6 @@ else()
|
||||
|
||||
outputdialog.h outputdialog.cpp outputdialog.ui
|
||||
output/output_options.h output/output_options.cpp
|
||||
ofd/ofd.h ofd/ofd.cpp
|
||||
|
||||
utils/utils.h utils/utils.cpp
|
||||
image/checkimage.h image/checkimage.cpp
|
||||
@@ -54,17 +71,21 @@ else()
|
||||
settings/settings.h settings/settings.cpp
|
||||
settingsdialog.h settingsdialog.cpp settingsdialog.ui
|
||||
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
|
||||
exceptions/ofdrequestexception.h exceptions/ofdrequestexception.cpp
|
||||
${QM_FILES}
|
||||
)
|
||||
|
||||
find_package(Qt5 REQUIRED COMPONENTS LinguistTools)
|
||||
qt_create_translation(QM_FILES checks_parser_en_US.ts)
|
||||
endif()
|
||||
|
||||
|
||||
# configure_file(translations.qrc ${CMAKE_BINARY_DIR} COPYONLY)
|
||||
# QT5_ADD_TRANSLATION(TRANSLATIONS ${CMAKE_SOURCE_DIR} translations/en_US.ts)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
target_link_libraries(checks-parser PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)
|
||||
|
||||
# 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
|
||||
# explicit, fixed bundle identifier manually though.
|
||||
@@ -90,18 +111,13 @@ if(QT_VERSION_MAJOR EQUAL 6)
|
||||
qt_finalize_executable(checks-parser)
|
||||
endif()
|
||||
|
||||
find_package(PkgConfig REQUIRED)
|
||||
find_package(OpenCV REQUIRED)
|
||||
|
||||
# include_directories("/usr/include/opencv4")
|
||||
include_directories( ${OpenCV_INCLUDE_DIRS})
|
||||
include_directories( ${OpenCV_INCLUDE_DIRS} )
|
||||
target_link_libraries(checks-parser PRIVATE -lzbar)
|
||||
target_link_libraries(checks-parser PRIVATE -ltesseract)
|
||||
target_link_libraries(checks-parser PRIVATE -lcurl)
|
||||
|
||||
# pkg_search_module(opencv REQUIRED IMPORTED_TARGET opencv)
|
||||
# target_link_libraries(checks-parser PRIVATE -lopencv4)
|
||||
target_link_libraries( checks-parser PRIVATE ${OpenCV_LIBS} )
|
||||
# target_link_libraries(checks-parser PRIVATE PkgConfig::opencv)
|
||||
# target_link_libraries(checks-parser PRIVATE ${OpenCV_LIBS})
|
||||
# target_link_libraries(checks-parser PRIVATE -lopencv)
|
||||
target_link_libraries(checks-parser PRIVATE ${OpenCV_LIBS} )
|
||||
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8)
|
||||
target_link_libraries(checks-parser PRIVATE -lstdc++fs)
|
||||
endif()
|
||||
|
||||
122
CMakeLists.txt.bck
Normal file
122
CMakeLists.txt.bck
Normal file
@@ -0,0 +1,122 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
project(checks-parser VERSION 0.1 LANGUAGES CXX)
|
||||
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
set(CMAKE_AUTOUIC_SEARCH_PATHS Designer)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets)
|
||||
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets)
|
||||
|
||||
set(PROJECT_SOURCES
|
||||
main.cpp
|
||||
mainwindow.cpp
|
||||
mainwindow.h
|
||||
mainwindow.ui
|
||||
)
|
||||
|
||||
if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
|
||||
qt_add_executable(checks-parser
|
||||
MANUAL_FINALIZATION
|
||||
${PROJECT_SOURCES}
|
||||
)
|
||||
|
||||
SET (LANGUAGES rus eng)
|
||||
SET (TRANSLATIONS_PATH "./translations")
|
||||
|
||||
foreach (LANGUAGE ${LANGUAGES})
|
||||
set (TS ${TRANSLATIONS_PATH}/${LANGUAGE}.ts)
|
||||
set (QM ${TRANSLATIONS_PATH}/${LANGUAGE}.qm)
|
||||
set (TRANSLATIONS ${TRANSLATIONS} ${TS})
|
||||
set (TRANSLATIONS_BINARY ${TRANSLATIONS_BINARY} ${QM})
|
||||
add_custom_command(
|
||||
OUTPUT ${QM}
|
||||
COMMAND ${QT_LRELEASE_EXECUTABLE} ${TS}
|
||||
MAIN_DEPENDENCY ${TS}
|
||||
)
|
||||
endforeach()
|
||||
|
||||
qt5_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} translations/english.ts)
|
||||
|
||||
# Define target properties for Android with Qt 6 as:
|
||||
# set_property(TARGET checks-parser APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR
|
||||
# ${CMAKE_CURRENT_SOURCE_DIR}/android)
|
||||
# For more information, see https://doc.qt.io/qt-6/qt-add-executable.html#target-creation
|
||||
else()
|
||||
if(ANDROID)
|
||||
add_library(checks-parser SHARED
|
||||
${PROJECT_SOURCES}
|
||||
)
|
||||
# Define properties for Android with Qt 5 after find_package() calls as:
|
||||
# set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android")
|
||||
else()
|
||||
add_executable(checks-parser
|
||||
${PROJECT_SOURCES}
|
||||
goods/goods.h goods/goods.cpp
|
||||
check/check.h check/check.cpp
|
||||
parser/parser.h parser/parser.cpp
|
||||
parser/module.h parser/module.cpp
|
||||
|
||||
outputdialog.h outputdialog.cpp outputdialog.ui
|
||||
output/output_options.h output/output_options.cpp
|
||||
|
||||
utils/utils.h utils/utils.cpp
|
||||
image/checkimage.h image/checkimage.cpp
|
||||
net/net.h net/net.cpp
|
||||
settings/settings.h settings/settings.cpp
|
||||
settingsdialog.h settingsdialog.cpp settingsdialog.ui
|
||||
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
|
||||
exceptions/ofdrequestexception.h exceptions/ofdrequestexception.cpp
|
||||
${TRANSLATIONS}
|
||||
${QM_FILES}
|
||||
${QM}
|
||||
${TS}
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_custom_target(translations DEPENDS ${QM_FILES})
|
||||
add_dependencies(checks-parser translations)
|
||||
|
||||
target_link_libraries(checks-parser PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)
|
||||
# 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
|
||||
# explicit, fixed bundle identifier manually though.
|
||||
if(${QT_VERSION} VERSION_LESS 6.1.0)
|
||||
set(BUNDLE_ID_OPTION MACOSX_BUNDLE_GUI_IDENTIFIER com.example.checks-parser)
|
||||
endif()
|
||||
set_target_properties(checks-parser PROPERTIES
|
||||
${BUNDLE_ID_OPTION}
|
||||
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
|
||||
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
|
||||
MACOSX_BUNDLE TRUE
|
||||
WIN32_EXECUTABLE TRUE
|
||||
)
|
||||
|
||||
include(GNUInstallDirs)
|
||||
install(TARGETS checks-parser
|
||||
BUNDLE DESTINATION .
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
)
|
||||
|
||||
if(QT_VERSION_MAJOR EQUAL 6)
|
||||
qt_finalize_executable(checks-parser)
|
||||
endif()
|
||||
|
||||
find_package(OpenCV REQUIRED)
|
||||
|
||||
include_directories( ${OpenCV_INCLUDE_DIRS} )
|
||||
target_link_libraries(checks-parser PRIVATE -lzbar)
|
||||
target_link_libraries(checks-parser PRIVATE -ltesseract)
|
||||
target_link_libraries(checks-parser PRIVATE -lcurl)
|
||||
target_link_libraries(checks-parser PRIVATE ${OpenCV_LIBS} )
|
||||
61
README.md
61
README.md
@@ -1,13 +1,16 @@
|
||||
# Checks parser
|
||||
checks parser is a program that help parsing different formats of checks to csv.
|
||||
checks parser is a program that help parsing different checks to csv.
|
||||
|
||||
!!!CURRENTLY SUPPORTED ONLY RUSSIAN CHECKS!!!
|
||||
To know why, see [this section](#Checks-from-different-countries)
|
||||
|
||||
# Usage
|
||||
### Input
|
||||
Ways you can input a check to this programm:
|
||||
* Via image (it uses OCR(Optical Character Recognition) to parse check content. The picture of a check must be contrast and well-lined (text must be perpendicular to right and left borders of an image) enough in order to be parsed well.)
|
||||
* Via plaintext, copied from an E-Mail. Just copy&paste text from your email, pick a correct store type (autodetect is in my plans!) and parse.
|
||||
* Via E-Mail file (.eml) **[!NOT IMPLEMENTED YET!]**
|
||||
* Via QrCode on check (OFD (ОФД, Оператор Фискальных Данных in Russian)). **[!NOT IMPLEMENTED YET!]**
|
||||
* Via a picture of a check. Be sure to make the image straight and sharp. OCR is not a magic wand :(
|
||||
* Via QrCode on check (OFD (ОФД, Оператор Фискальных Данных in Russian)).
|
||||
|
||||
### Output
|
||||
At the start of writing this program, I considered 3 or more output formats: csv, xlsx and ods. But throught the development I understood that most of modern table processor (i.e. electronic tables) can import csv much better than I'd be writing a shitty export module, adding more dependencies and shitty code to the codebase. So I decided that there's no need to use anything other than csv format.
|
||||
@@ -16,9 +19,10 @@ To export, you need to specify an output file path and, if you wish, you can cha
|
||||
|
||||
# Installing
|
||||
## Building
|
||||
In general, you need to install following dependencies in order to build that app(I suppose you have install all the build necessaries such as cmake, make, gcc, git, etc...):
|
||||
In general, you need to install following dependencies in order to build that app(I suppose you have installed all the build necessaries such as cmake, make, gcc, git, etc...):
|
||||
* tesseract (you also have to install appropriate for your needs language data)
|
||||
* opencv
|
||||
* zbar
|
||||
* curl
|
||||
* nlohmann-json
|
||||
* qt5
|
||||
@@ -26,27 +30,60 @@ In general, you need to install following dependencies in order to build that ap
|
||||
|
||||
Please, do not hesitate to open an issue if you cannot build that. I will help and if you are building on a distro that is not listed there, we can append that list as soon as we will solve your problem!
|
||||
### Linux
|
||||
##### Arch Linux
|
||||
##### Arch Linux-based
|
||||
I recommend using aur helper (I use yay) to install dependencies. Or, if you're masochist, you can build all by yourself /shrug
|
||||
```
|
||||
#Install dependencies
|
||||
yay -S sudo cmake git coreutils base-devel eigen qt5-base mbedtls gtkglext opencv opencv2 nlohmann-json tesseract tesseract-data-rus vtk
|
||||
yay -S sudo cmake git coreutils base-devel eigen qt5-base mbedtls gtkglext opencv opencv2 zbar nlohmann-json tesseract tesseract-data-rus vtk
|
||||
#Clone and compile an app
|
||||
git clone https://git.foxarmy.org/leca/checks-parser
|
||||
cd checks-parser
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
cmake .
|
||||
make -j{nproc}
|
||||
#If you wish to install that program system-wide, run
|
||||
sudo make install
|
||||
```
|
||||
##### Debian
|
||||
TODO
|
||||
##### Debian-based
|
||||
In debian-based distributions most, but not every, package names are the same.
|
||||
|
||||
Installation of dependencies for different debian-based distros:
|
||||
###### Ubuntu 18.04
|
||||
```apt install -y qtbase5-dev openssl libmbedtls-dev tesseract-ocr tesseract-ocr-rus libopencv-dev libzbar-dev qttools5-dev nlohmann-json-dev libcurl4-openssl-dev libtesseract-dev```
|
||||
###### Ubuntu 20.04, LMDE (tested only 6), Debian (tested only 12)
|
||||
```apt install -y qtbase5-dev openssl libmbedtls-dev tesseract-ocr tesseract-ocr-rus libopencv-dev libzbar-dev qttools5-dev nlohmann-json3-dev libcurl4-openssl-dev libtesseract-dev```
|
||||
|
||||
Next steps are identical for every debian-based distro
|
||||
```
|
||||
#Clone and compile an app
|
||||
git clone https://git.foxarmy.org/leca/checks-parser
|
||||
cd checks-parser
|
||||
cmake .
|
||||
make -j{nproc}
|
||||
#If you wish to install that program system-wide, run
|
||||
sudo make install
|
||||
```
|
||||
|
||||
### Windows
|
||||
Maybe
|
||||
### Mac OS
|
||||
Probably not, I do not have nor desire or time. But if you can maintain that program on Mac, I'd be grateful! Please, contact me, if you can!
|
||||
|
||||
## Precompiled
|
||||
## Precompiled binaries
|
||||
I plan to make precompiled binaries for Linux and Windows. Maybe I will put it on AUR. I also think that I will be making an AppImage
|
||||
|
||||
# Contribution
|
||||
|
||||
If you want to contribute to the project, you can do it by some of the following:
|
||||
## Checks from different countries
|
||||
|
||||
I live in Russia and only know how Russian state checks system works. If you live in another country and want to help me with adding support to checks from your country - feel free to contact me!
|
||||
## Issues and PRs
|
||||
|
||||
If you have found a bug, or want to suggest a feature - don't hesitate to open an issue / PR!
|
||||
|
||||
## Tell friends
|
||||
|
||||
You can help me by distributing that program. If you know people that are in search of such program, please let them know about its existance!
|
||||
## Donate
|
||||
|
||||
```XMR 45ZjyH5YWdRfKxLoKEBYaiHUTcP5Z8Gv64QQxmabbooPAa7KPBxZLmqft5ohKXn5VpHiVj1x9JKCcAcAjdu9jA8b5N8XqR7```
|
||||
|
||||
23
TODO
23
TODO
@@ -1,19 +1,30 @@
|
||||
Complete module "export":
|
||||
Complete module "export": [done]
|
||||
make UI; [done]
|
||||
make export to .csv [done]
|
||||
Complete module "image-to-text":
|
||||
|
||||
Complete module "image-to-text": [done]
|
||||
make UI; [done]
|
||||
make use of tesseract/opencv (https://learnopencv.com/deep-learning-based-text-recognition-ocr-using-tesseract-and-opencv/); [done]
|
||||
|
||||
Add features:
|
||||
autodetect store type
|
||||
auto download of stores modules [done]
|
||||
auto download of ofd modules [done]
|
||||
settings, a window for editing settings. [done]
|
||||
add ability to control contrast and rotation of a check image before passing it to OCR
|
||||
add ability to control contrast and rotation of a check image before passing it to OCR [done]
|
||||
add ability to scan a qr code and request data from ofd.ru [done]
|
||||
add ability to change language from preferences
|
||||
|
||||
Refactor:
|
||||
Get rid of CPR, use libcurl instead [done]
|
||||
|
||||
Build:
|
||||
Write script for AppImage deployment
|
||||
Find out dependencies packet names on different distros
|
||||
Ensure success of building on most popular distros
|
||||
Write script for AppImage deployment [done]
|
||||
Find out dependencies packet names on different distros [done for arch, ubuntu]
|
||||
Ensure success of building on most popular distros [done for arch, ubuntu]
|
||||
Try to compile it on Windows
|
||||
|
||||
Issues:
|
||||
Captcha is not showing when running in appimage [solved]
|
||||
Stores modules are not being downloaded
|
||||
I need to pack tesseract data for ru, en [solved]
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
#include <opencv2/imgcodecs.hpp>
|
||||
#include <opencv2/imgproc.hpp>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <opencv2/core/mat.hpp>
|
||||
#include <QFileDialog>
|
||||
#include <QMessageBox>
|
||||
@@ -12,15 +11,16 @@
|
||||
|
||||
AdjustPictureDialog::AdjustPictureDialog(QWidget *parent, std::string imagePath)
|
||||
: QDialog(parent)
|
||||
, ui(new Ui::AdjustPictureDialog){
|
||||
, ui(new Ui::AdjustPictureDialog)
|
||||
, pixmap(QString::fromStdString(imagePath))
|
||||
, img(pixmap.toImage()){
|
||||
ui->setupUi(this);
|
||||
|
||||
computeContrastLookupTable();
|
||||
|
||||
scene = new QGraphicsScene(this);
|
||||
|
||||
ui->graphicsView->setScene(scene);
|
||||
QGraphicsPixmapItem p;
|
||||
QString path = QString::fromStdString(imagePath);
|
||||
QPixmap pixmap = QPixmap(path);
|
||||
scene->addPixmap(pixmap);
|
||||
}
|
||||
|
||||
@@ -36,9 +36,9 @@ void AdjustPictureDialog::accept() {
|
||||
|
||||
if (result == "") {
|
||||
QMessageBox infoDialog;
|
||||
infoDialog.setText("QR code was not detected on that image. Please edit it again or enter data manually");
|
||||
infoDialog.setText(tr("QR code was not detected on that image. Please edit it again or enter data manually"));
|
||||
infoDialog.setIcon(QMessageBox::Warning);
|
||||
infoDialog.setWindowTitle("No QR code");
|
||||
infoDialog.setWindowTitle(tr("No QR code"));
|
||||
infoDialog.exec();
|
||||
} else {
|
||||
emit decodedData(result);
|
||||
@@ -52,13 +52,12 @@ std::string AdjustPictureDialog::decode() {
|
||||
|
||||
zbar::ImageScanner scanner;
|
||||
scanner.set_config(zbar::ZBAR_QRCODE, zbar::ZBAR_CFG_ENABLE, 1);
|
||||
scanner.set_config(zbar::ZBAR_QRCODE, zbar::ZBAR_CFG_TEST_INVERTED, 1);
|
||||
|
||||
cv::Mat imGray;
|
||||
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 = "";
|
||||
|
||||
@@ -66,7 +65,38 @@ std::string AdjustPictureDialog::decode() {
|
||||
result = symbol->get_data();
|
||||
}
|
||||
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void AdjustPictureDialog::computeContrastLookupTable() {
|
||||
|
||||
for (int contrastValue = 0; contrastValue < 100; ++contrastValue) {
|
||||
double contrast = contrastValue / 50.0;
|
||||
for (int i = 0; i < 256; ++i) {
|
||||
unsigned short correctedValue = std::clamp(static_cast<int>(128 + contrast * (i - 128)), 0, 255);
|
||||
contrastLUT[contrastValue].push_back(correctedValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AdjustPictureDialog::on_contrastSlider_sliderMoved(int position) {
|
||||
QImage image = img.copy();
|
||||
|
||||
uint32_t* pixels = reinterpret_cast<uint32_t*>(image.bits());
|
||||
int width = image.width();
|
||||
int height = image.height();
|
||||
|
||||
for (int y = 0; y < height; ++y) {
|
||||
for (int x = 0; x < width; ++x) {
|
||||
QRgb rgb = pixels[y * width + x];
|
||||
pixels[y * width + x] = qRgba(
|
||||
contrastLUT[position][qRed(rgb)],
|
||||
contrastLUT[position][qGreen(rgb)],
|
||||
contrastLUT[position][qBlue(rgb)],
|
||||
qAlpha(rgb));
|
||||
}
|
||||
}
|
||||
|
||||
scene->clear();
|
||||
scene->addPixmap(QPixmap::fromImage(image));
|
||||
}
|
||||
|
||||
@@ -16,7 +16,11 @@ public:
|
||||
explicit AdjustPictureDialog(QWidget *parent = nullptr, std::string imagePath = "");
|
||||
~AdjustPictureDialog();
|
||||
std::string decode();
|
||||
QPixmap pixmap;
|
||||
QImage img;
|
||||
|
||||
void computeContrastLookupTable();
|
||||
std::vector<unsigned short> contrastLUT[100];
|
||||
signals:
|
||||
void decodedData(std::string data);
|
||||
|
||||
@@ -25,6 +29,8 @@ private slots:
|
||||
// void on_buttonBox_accepted();
|
||||
void accept() override;
|
||||
|
||||
void on_contrastSlider_sliderMoved(int position);
|
||||
|
||||
private:
|
||||
Ui::AdjustPictureDialog *ui;
|
||||
QGraphicsScene *scene;
|
||||
|
||||
121
adjustpicturedialog.ui
Normal file
121
adjustpicturedialog.ui
Normal file
@@ -0,0 +1,121 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>AdjustPictureDialog</class>
|
||||
<widget class="QDialog" name="AdjustPictureDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>825</width>
|
||||
<height>497</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>450</x>
|
||||
<y>450</y>
|
||||
<width>341</width>
|
||||
<height>32</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QSlider" name="contrastSlider">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>460</y>
|
||||
<width>591</width>
|
||||
<height>16</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>50</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>0</y>
|
||||
<width>511</width>
|
||||
<height>18</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Please, zoom to qr code and adjust contrast so that qr code looks sharp</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="ImageRedactor" name="graphicsView">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>15</x>
|
||||
<y>41</y>
|
||||
<width>791</width>
|
||||
<height>391</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<zorder>buttonBox</zorder>
|
||||
<zorder>label</zorder>
|
||||
<zorder>contrastSlider</zorder>
|
||||
<zorder>graphicsView</zorder>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>ImageRedactor</class>
|
||||
<extends>QGraphicsView</extends>
|
||||
<header>../../image_redactor/imageredactor.h</header>
|
||||
<slots>
|
||||
<slot>slot1()</slot>
|
||||
</slots>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>AdjustPictureDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>AdjustPictureDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
@@ -1 +0,0 @@
|
||||
checks-parser.png
|
||||
|
Before Width: | Height: | Size: 17 B After Width: | Height: | Size: 627 KiB |
BIN
deploy/appimage/AppDir/.DirIcon
Normal file
BIN
deploy/appimage/AppDir/.DirIcon
Normal file
Binary file not shown.
|
Before Width: | Height: | Size: 17 B After Width: | Height: | Size: 627 KiB |
@@ -1 +0,0 @@
|
||||
usr/bin/checks-parser
|
||||
4
deploy/appimage/AppDir/AppRun
Executable file
4
deploy/appimage/AppDir/AppRun
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
export TESSDATA_PREFIX=$APPDIR/usr/share/tesseract-ocr/4.00/tessdata
|
||||
|
||||
$APPDIR/usr/bin/checks-parser
|
||||
@@ -1,8 +1,7 @@
|
||||
[Desktop Entry]
|
||||
Name=Checks parser
|
||||
Type=Application
|
||||
Terminal=false
|
||||
NoDisplay=false
|
||||
Exec=checks-parser
|
||||
Categories=Utility;
|
||||
Exec=usr/bin/checks-parser
|
||||
Icon=checks-parser
|
||||
Type=Application
|
||||
Categories=Utility;
|
||||
X-AppImage-Version=41463c7
|
||||
|
||||
7
deploy/appimage/AppDir/qt.conf
Normal file
7
deploy/appimage/AppDir/qt.conf
Normal file
@@ -0,0 +1,7 @@
|
||||
# Generated by linuxdeployqt
|
||||
# https://github.com/probonopd/linuxdeployqt/
|
||||
[Paths]
|
||||
Prefix = ./
|
||||
Plugins = plugins
|
||||
Imports = qml
|
||||
Qml2Imports = qml
|
||||
7
deploy/appimage/AppDir/usr/bin/qt.conf
Normal file
7
deploy/appimage/AppDir/usr/bin/qt.conf
Normal file
@@ -0,0 +1,7 @@
|
||||
# Generated by linuxdeployqt
|
||||
# https://github.com/probonopd/linuxdeployqt/
|
||||
[Paths]
|
||||
Prefix = ../
|
||||
Plugins = plugins
|
||||
Imports = qml
|
||||
Qml2Imports = qml
|
||||
26
deploy/appimage/deploy.sh
Executable file
26
deploy/appimage/deploy.sh
Executable file
@@ -0,0 +1,26 @@
|
||||
#!/usr/bin/env bash
|
||||
mkdir -p AppDir/usr/bin
|
||||
mkdir -p AppDir/usr/lib
|
||||
mkdir -p AppDir/usr/share/tesseract-ocr/4.00/tessdata
|
||||
cp -r /usr/share/tesseract-ocr/4.00/tessdata/* AppDir/usr/share/tesseract-ocr/4.00/tessdata
|
||||
cp ../../checks-parser AppDir/usr/bin
|
||||
|
||||
echo \
|
||||
"[Desktop Entry]
|
||||
Name=Checks parser
|
||||
Exec=usr/bin/checks-parser
|
||||
Icon=checks-parser
|
||||
Type=Application
|
||||
Categories=Utility;" \
|
||||
> AppDir/checks-parser.desktop
|
||||
|
||||
echo \
|
||||
"#!/bin/bash
|
||||
export TESSDATA_PREFIX=\$APPDIR/usr/share/tesseract-ocr/4.00/tessdata
|
||||
|
||||
\$APPDIR/usr/bin/checks-parser" \
|
||||
> AppDir/AppRun
|
||||
|
||||
chmod +x AppDir/AppRun
|
||||
cp ../../checks-parser AppDir/usr/bin
|
||||
linuxdeployqt AppDir/usr/bin/checks-parser -no-copy-copyright-files -appimage
|
||||
6
exceptions/ofdrequestexception.cpp
Normal file
6
exceptions/ofdrequestexception.cpp
Normal file
@@ -0,0 +1,6 @@
|
||||
#include "ofdrequestexception.h"
|
||||
|
||||
OfdRequestException::OfdRequestException(const char* msg) : message(msg) {}
|
||||
const char* OfdRequestException::what() throw() {
|
||||
return message.c_str();
|
||||
}
|
||||
16
exceptions/ofdrequestexception.h
Normal file
16
exceptions/ofdrequestexception.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef OFDREQUESTEXCEPTION_H
|
||||
#define OFDREQUESTEXCEPTION_H
|
||||
|
||||
#include <exception>
|
||||
#include <string>
|
||||
|
||||
class OfdRequestException : public std::exception
|
||||
{
|
||||
private:
|
||||
std::string message;
|
||||
public:
|
||||
OfdRequestException(const char* msg);
|
||||
const char* what() throw();
|
||||
};
|
||||
|
||||
#endif // OFDREQUESTEXCEPTION_H
|
||||
@@ -12,6 +12,7 @@ class ImageRedactor : public QGraphicsView
|
||||
Q_OBJECT
|
||||
public:
|
||||
ImageRedactor(QWidget *parent = nullptr);
|
||||
QGraphicsScene *scene;
|
||||
protected:
|
||||
void wheelEvent(QWheelEvent *event);
|
||||
|
||||
@@ -20,7 +21,6 @@ protected:
|
||||
void mouseReleaseEvent(QMouseEvent *event);
|
||||
|
||||
private:
|
||||
QGraphicsScene *scene;
|
||||
QGraphicsPixmapItem *item;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
#include <QWheelEvent>
|
||||
#include "imageview.h"
|
||||
#include <iostream>
|
||||
|
||||
|
||||
ImageView::ImageView(QWidget *parent) :
|
||||
QLabel(parent) {
|
||||
|
||||
// std::cout << this->geometry().height() << " " << this->geometry().width() << std::endl;
|
||||
}
|
||||
|
||||
// ImageView::ImageView(QWidget *parent, std::string path):
|
||||
// QLabel(parent) {
|
||||
// this->setPixmap(QPixmap(QString::fromStdString(path)));
|
||||
// }
|
||||
|
||||
void ImageView::wheelEvent(QWheelEvent *event) {
|
||||
QPointF shift = event->position();
|
||||
QRegion r = QRegion();
|
||||
// this->pixmap(Qt::ReturnByValueConstant::ReturnByValue).scroll(10, 10, this->rect(), &r);
|
||||
this->scroll(shift.x(), shift.y(), this->rect());
|
||||
// this->setPixmap(QPixmap());
|
||||
// pm.scroll(shift.x(), shift.y(), this->rect());
|
||||
|
||||
// pm.scroll();
|
||||
// this->setPixmap(pm);
|
||||
|
||||
//this->pixmap(Qt::ReturnByValueConstant::ReturnByValue).scroll(shift.x(), shift.y(), this->pixmap()->rect());
|
||||
|
||||
QPoint numDegrees = event->angleDelta() / 8;
|
||||
std::cout << numDegrees.x() << std::endl;
|
||||
event->accept();
|
||||
}
|
||||
|
||||
void ImageView::setImage(std::string image){
|
||||
//Commented is a way of scaling that is, as I understand, is lossless. If there'll be problems with current method's losses, I'll return to commented method
|
||||
|
||||
maxHeight = this->height();
|
||||
maxWidth = this->width();
|
||||
|
||||
QPixmap pixmap = QPixmap(QString::fromStdString(image));
|
||||
// double scaleFactor = pixmap.height() > pixmap.width()? static_cast<double>(maxHeight) / pixmap.height() : static_cast<double>(maxWidth) / pixmap.width();
|
||||
|
||||
pixmap = pixmap.scaled(maxWidth, maxHeight, Qt::AspectRatioMode::KeepAspectRatio);
|
||||
|
||||
|
||||
this->setPixmap(pixmap);
|
||||
|
||||
// this->setGeometry(this->geometry().x(), this->geometry().y(), pixmap.width() * scaleFactor, pixmap.height() * scaleFactor);
|
||||
// this->setScaledContents(true);
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
#ifndef IMAGEVIEW_H
|
||||
#define IMAGEVIEW_H
|
||||
|
||||
#include <QLabel>
|
||||
#include <QObject>
|
||||
#include <QWidget>
|
||||
|
||||
class ImageView : public QLabel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
double maxHeight, maxWidth;
|
||||
public:
|
||||
ImageView(QWidget *parent=nullptr);
|
||||
// ImageView(QWidget *parent=nullptr, std::string path="");
|
||||
void wheelEvent(QWheelEvent*);
|
||||
void setImage(std::string);
|
||||
};
|
||||
#endif // IMAGEVIEW_H
|
||||
34
main.cpp
34
main.cpp
@@ -1,40 +1,33 @@
|
||||
#include "mainwindow.h"
|
||||
#include "net/net.h"
|
||||
#include "ofd/ofd.h"
|
||||
#include "settings/settings.h"
|
||||
#include "utils/utils.h"
|
||||
#include <QApplication>
|
||||
#include <curl/curl.h>
|
||||
#include <iostream>
|
||||
#include <filesystem>
|
||||
#if __GNUC__ < 8 && __clang_major__ < 17
|
||||
# include <experimental/filesystem>
|
||||
using namespace std::experimental::filesystem;
|
||||
#else
|
||||
# include <filesystem>
|
||||
using namespace std::filesystem;
|
||||
#endif
|
||||
#include <QTranslator>
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
|
||||
std::string program_data_path = get_path_relative_to_home(".local/share/checks_parser");
|
||||
std::filesystem::create_directories(program_data_path);
|
||||
create_directories(program_data_path);
|
||||
|
||||
std::string settings_file_path =
|
||||
get_path_relative_to_home(".local/share/checks_parser/settings.json");
|
||||
|
||||
Settings s(settings_file_path);
|
||||
OFD ofd;
|
||||
Net n;
|
||||
|
||||
// std::vector<std::string> ofd_updates = ofd.check_updates();
|
||||
// for (const std::string &update : ofd_updates) {
|
||||
// std::cout << "Downloading "
|
||||
// << s.get_setting("ofds_modules_url") + update << " to "
|
||||
// << get_path_relative_to_home(s.get_setting("ofds_modules_dir") +
|
||||
// "/" + update)
|
||||
// << std::endl;
|
||||
// n.get_file(s.get_setting("ofds_modules_url") + "/" + update,
|
||||
// get_path_relative_to_home(s.get_setting("ofds_modules_dir") +
|
||||
// "/" + update));
|
||||
// }
|
||||
|
||||
Parser p;
|
||||
std::vector<std::string> stores_updates = p.check_updates();\
|
||||
std::vector<std::string> stores_updates = p.check_updates();
|
||||
for (const std::string &update : stores_updates) {
|
||||
std::cout << "Downloading "
|
||||
<< s.get_setting("stores_modules_url") + update << " to "
|
||||
@@ -48,7 +41,14 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
|
||||
QApplication a(argc, argv);
|
||||
|
||||
QTranslator translator;
|
||||
if(!translator.load(QLocale::system().name())) {
|
||||
translator.load("en_US");
|
||||
}
|
||||
a.installTranslator(&translator);
|
||||
MainWindow w;
|
||||
w.update();
|
||||
w.show();
|
||||
|
||||
return a.exec();
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
#include "mainwindow.h"
|
||||
#include "./ui_mainwindow.h"
|
||||
#include "check/check.h"
|
||||
#include "exceptions/ofdrequestexception.h"
|
||||
#include "goods/goods.h"
|
||||
#include "outputdialog.h"
|
||||
#include "adjustpicturedialog.h"
|
||||
#include "settingsdialog.h"
|
||||
#include <iostream>
|
||||
#include "solvecaptchadialog.h"
|
||||
#include <QFileDialog>
|
||||
#include <QMessageBox>
|
||||
#include "image/checkimage.h"
|
||||
@@ -36,25 +37,73 @@ void MainWindow::setupStoresList() {
|
||||
QString s = QString::fromStdWString(module_name);
|
||||
ui->storeType->addItem(s);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
for (auto module : parser.search_modules()) {
|
||||
std::cout << "Module: " << module << std::endl;
|
||||
}
|
||||
#endif
|
||||
return checkContent;
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
std::string solved_captcha = "";
|
||||
bool success = true;
|
||||
bool is_captcha_solved = true;
|
||||
|
||||
do {
|
||||
SolveCaptchaDialog dialog = SolveCaptchaDialog(this, &solved_captcha);
|
||||
dialog.exec();
|
||||
is_captcha_solved = true;
|
||||
|
||||
try {
|
||||
std::string check_content = makeRequestToOfd(solved_captcha);
|
||||
check = parseOfdRuAnswer(check_content);
|
||||
} catch(OfdRequestException e) {
|
||||
success = false;
|
||||
if (!strcmp(e.what(), "Incorrect captcha")) {
|
||||
is_captcha_solved = false;
|
||||
QMessageBox infoDialog;
|
||||
infoDialog.setText(tr("Captcha was not solved correctly!"));
|
||||
infoDialog.setIcon(QMessageBox::Critical);
|
||||
infoDialog.setWindowTitle(tr("Captcha is incorrect"));
|
||||
infoDialog.exec();
|
||||
break;
|
||||
} else if (!strcmp(e.what(), "Does not exist")) {
|
||||
QMessageBox infoDialog;
|
||||
infoDialog.setText(tr("Check not found. Please, ensure correctness of entered data."));
|
||||
infoDialog.setIcon(QMessageBox::Critical);
|
||||
infoDialog.setWindowTitle(tr("Check was not found"));
|
||||
infoDialog.exec();
|
||||
return;
|
||||
}
|
||||
}
|
||||
} while (!is_captcha_solved);
|
||||
|
||||
if (success) {
|
||||
OutputDialog d = OutputDialog(this, check);
|
||||
d.exec();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
std::wstring check_plaintext = s.toStdWString();
|
||||
@@ -67,8 +116,6 @@ void MainWindow::on_parseButton_clicked() {
|
||||
return;
|
||||
}
|
||||
|
||||
Check check;
|
||||
|
||||
for (auto& g : c) {
|
||||
check.add_goods(g);
|
||||
}
|
||||
@@ -93,6 +140,15 @@ void MainWindow::on_preferencesButton_clicked() {
|
||||
void MainWindow::on_chooseImageButton_ofd_clicked() {
|
||||
QString filename = QFileDialog::getOpenFileName();
|
||||
|
||||
if (filename == "") {
|
||||
QMessageBox infoDialog;
|
||||
infoDialog.setText(tr("Please, select a picture where QR code that contains info about check is present"));
|
||||
infoDialog.setIcon(QMessageBox::Critical);
|
||||
infoDialog.setWindowTitle(tr("Picture was not selected"));
|
||||
infoDialog.exec();
|
||||
return;
|
||||
}
|
||||
|
||||
std::string new_text = "Selected: " + filename.toStdString();
|
||||
ui->pathLabel_ofd->setText(QString::fromStdString(new_text));
|
||||
|
||||
@@ -118,12 +174,27 @@ 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()
|
||||
{
|
||||
QString filename = QFileDialog::getOpenFileName();
|
||||
|
||||
if (filename == "") {
|
||||
QMessageBox infoDialog;
|
||||
infoDialog.setText(tr("Please, select a picture to scan"));
|
||||
infoDialog.setIcon(QMessageBox::Critical);
|
||||
infoDialog.setWindowTitle(tr("Picture was not selected"));
|
||||
infoDialog.exec();
|
||||
return;
|
||||
}
|
||||
|
||||
std::string new_text = "Selected: " + filename.toStdString();
|
||||
ui->pathLabel_ocr->setText(QString::fromStdString(new_text));
|
||||
|
||||
|
||||
@@ -26,13 +26,12 @@ public:
|
||||
Check get_check();
|
||||
void onDecodedData(std::string);
|
||||
|
||||
std::string makeRequestToOfd(std::string captcha);
|
||||
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();
|
||||
|
||||
401
mainwindow.ui
Normal file
401
mainwindow.ui
Normal file
@@ -0,0 +1,401 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MainWindow</class>
|
||||
<widget class="QMainWindow" name="MainWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>817</width>
|
||||
<height>659</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>MainWindow</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<widget class="QComboBox" name="storeType">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>90</x>
|
||||
<y>10</y>
|
||||
<width>211</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="storeTypeLabel">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>10</y>
|
||||
<width>81</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Store type</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="parseButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>30</x>
|
||||
<y>560</y>
|
||||
<width>80</width>
|
||||
<height>26</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Parse</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="preferencesButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>730</x>
|
||||
<y>0</y>
|
||||
<width>81</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Preferences</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>50</y>
|
||||
<width>801</width>
|
||||
<height>511</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="Text">
|
||||
<attribute name="title">
|
||||
<string>Text</string>
|
||||
</attribute>
|
||||
<widget class="QLabel" name="checkContentLabel">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>101</width>
|
||||
<height>18</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Check content</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPlainTextEdit" name="checkContent">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>30</y>
|
||||
<width>611</width>
|
||||
<height>441</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QWidget" name="OCR">
|
||||
<attribute name="title">
|
||||
<string>OCR</string>
|
||||
</attribute>
|
||||
<widget class="QPushButton" name="chooseImageButton_ocr">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>80</width>
|
||||
<height>26</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Choose</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPlainTextEdit" name="checkContentFromImage">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>60</y>
|
||||
<width>511</width>
|
||||
<height>401</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="pathLabel_ocr">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>100</x>
|
||||
<y>0</y>
|
||||
<width>381</width>
|
||||
<height>18</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Path to image: </string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>30</y>
|
||||
<width>571</width>
|
||||
<height>18</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Here is recognised check text. Please, edit it if something's wrong:</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="picture_ocr">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>490</x>
|
||||
<y>10</y>
|
||||
<width>291</width>
|
||||
<height>421</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QWidget" name="OFD">
|
||||
<attribute name="title">
|
||||
<string>OFD</string>
|
||||
</attribute>
|
||||
<widget class="QLabel" name="picture_ofd">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>490</x>
|
||||
<y>10</y>
|
||||
<width>291</width>
|
||||
<height>421</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="pathLabel_ofd">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>100</x>
|
||||
<y>0</y>
|
||||
<width>381</width>
|
||||
<height>18</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Path to image: </string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="chooseImageButton_ofd">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>0</y>
|
||||
<width>80</width>
|
||||
<height>26</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Choose</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLineEdit" name="fn_edit">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>180</x>
|
||||
<y>50</y>
|
||||
<width>261</width>
|
||||
<height>26</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="inputMask">
|
||||
<string>0000000000000000</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="fn_label">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>50</y>
|
||||
<width>161</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>FN (Fiscal Number)</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="fd_label">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>90</y>
|
||||
<width>161</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>FD (Fiscal Document)</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLineEdit" name="fd_edit">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>180</x>
|
||||
<y>90</y>
|
||||
<width>261</width>
|
||||
<height>26</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="inputMask">
|
||||
<string>0000000000</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="fi_label">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>130</y>
|
||||
<width>161</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>FI (Fiscal Identifier)</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLineEdit" name="fi_edit">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>180</x>
|
||||
<y>130</y>
|
||||
<width>261</width>
|
||||
<height>26</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="inputMask">
|
||||
<string>0000000000</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QDateTimeEdit" name="dateTimeEdit">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>170</y>
|
||||
<width>194</width>
|
||||
<height>27</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QComboBox" name="fundIncomeCombo">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>210</y>
|
||||
<width>191</width>
|
||||
<height>26</height>
|
||||
</rect>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Funds income</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Funds return</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Funds spend</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Spends return</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
<widget class="QLineEdit" name="total_edit">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>90</x>
|
||||
<y>250</y>
|
||||
<width>113</width>
|
||||
<height>26</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="inputMask">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="total_label">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>250</y>
|
||||
<width>66</width>
|
||||
<height>18</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Total</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="menubar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>817</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuchecks_parser">
|
||||
<property name="title">
|
||||
<string>checks parser</string>
|
||||
</property>
|
||||
</widget>
|
||||
<addaction name="menuchecks_parser"/>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusbar"/>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
52
net/net.cpp
52
net/net.cpp
@@ -1,5 +1,6 @@
|
||||
#include "net.h"
|
||||
#include <curl/curl.h>
|
||||
#include "../utils/utils.h"
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <regex>
|
||||
@@ -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<std::string> Net::get_all_modules(std::string url) {
|
||||
CURL *handle = curl_easy_init();
|
||||
|
||||
@@ -47,7 +54,7 @@ std::vector<std::string> 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.jpg"));
|
||||
}
|
||||
|
||||
@@ -11,7 +11,9 @@ class Net
|
||||
public:
|
||||
Net();
|
||||
std::vector<std::string> 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
|
||||
|
||||
2
ofd.desc
2
ofd.desc
@@ -1,2 +0,0 @@
|
||||
1. curl -X GET https://check.ofd.ru/api/captcha/common/img
|
||||
2. curl 'https://check.ofd.ru/Document/FetchReceiptFromFns' -H 'content-type: application/json;charset=UTF-8' --data-raw '{"TotalSum":52344,"FnNumber":"7281440701327430","ReceiptOperationType":"1","DocNumber":"25955","DocFiscalSign":"2518183888","Captcha":"INSERT SOLVED CAPTCHA","DocDateTime":"2024-08-16T19:36:00.000Z"}'
|
||||
@@ -1,24 +0,0 @@
|
||||
#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;
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
#include "ofd.h"
|
||||
|
||||
OFD::OFD() {}
|
||||
13
ofd/ofd.h
13
ofd/ofd.h
@@ -1,13 +0,0 @@
|
||||
#ifndef OFD_H
|
||||
#define OFD_H
|
||||
|
||||
#include <string>
|
||||
|
||||
class OFD {
|
||||
|
||||
public:
|
||||
OFD();
|
||||
void ask_captcha();
|
||||
std::string request_and_parse_check(long fiscal_number, long fiscal_document, long fiscal_sign, std::string datetime, double total, std::string captcha);
|
||||
};
|
||||
#endif // OFD_H
|
||||
@@ -3,7 +3,11 @@
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <filesystem>
|
||||
#if __GNUC__ < 8
|
||||
# include <experimental/filesystem>
|
||||
#else
|
||||
# include <filesystem>
|
||||
#endif
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include <QFileDialog>
|
||||
#include <QMainWindow>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include "settings/settings.h"
|
||||
#include "utils/utils.h"
|
||||
|
||||
@@ -50,8 +49,6 @@ void OutputDialog::on_buttonBox_accepted() {
|
||||
int position = ui->tableWidget->item(i, 0)->text().toInt();
|
||||
std::string name = ui->tableWidget->item(i, 1)->text().toStdString();
|
||||
|
||||
std::cout << position << " " << name << std::endl;
|
||||
|
||||
Column c;
|
||||
c.type = static_cast<ColumnType>(i);
|
||||
c.position = position;
|
||||
@@ -75,38 +72,35 @@ void OutputDialog::on_buttonBox_accepted() {
|
||||
|
||||
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();
|
||||
output_file << goods.get_name();
|
||||
break;
|
||||
case ColumnType::goods_price_per_unit:
|
||||
output_str = std::to_string(goods.get_price_per_unit());
|
||||
output_file << std::fixed << std::setprecision(2) << goods.get_price_per_unit();
|
||||
break;
|
||||
case ColumnType::goods_quantity:
|
||||
output_str = std::to_string(goods.get_quantity());
|
||||
output_file << std::fixed << std::setprecision(2) << goods.get_quantity();
|
||||
break;
|
||||
case ColumnType::goods_net_weight:
|
||||
output_str = "TODO";
|
||||
output_file << "TODO";
|
||||
// TODO
|
||||
break;
|
||||
case ColumnType::goods_total:
|
||||
output_str = std::to_string(goods.calculate_total_price());
|
||||
output_file << std::fixed << std::setprecision(2) << goods.calculate_total_price();
|
||||
break;
|
||||
}
|
||||
|
||||
if (column.position != this->options.get_columns().size()) {
|
||||
output_str += ",";
|
||||
output_file << ",";
|
||||
} else {
|
||||
output_str += "\n";
|
||||
output_file << "\n";
|
||||
}
|
||||
output_file << output_str;
|
||||
}
|
||||
}
|
||||
|
||||
if (this->options.get_print_total()) {
|
||||
output_file << "Total: " << std::to_string(check.calculae_total_price());
|
||||
output_file << "Total: " << std::fixed << std::setprecision(2) << check.calculae_total_price() << std::endl;
|
||||
}
|
||||
|
||||
output_file.close();
|
||||
|
||||
215
outputdialog.ui
Normal file
215
outputdialog.ui
Normal file
@@ -0,0 +1,215 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>OutputDialog</class>
|
||||
<widget class="QDialog" name="OutputDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>586</width>
|
||||
<height>431</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>410</x>
|
||||
<y>390</y>
|
||||
<width>166</width>
|
||||
<height>26</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="pathLabel">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>20</y>
|
||||
<width>271</width>
|
||||
<height>18</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Path to export: </string>
|
||||
</property>
|
||||
</widget>
|
||||
<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">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>50</y>
|
||||
<width>111</width>
|
||||
<height>24</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Print header</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QTableWidget" name="tableWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>130</y>
|
||||
<width>401</width>
|
||||
<height>221</height>
|
||||
</rect>
|
||||
</property>
|
||||
<row>
|
||||
<property name="text">
|
||||
<string>Goods name</string>
|
||||
</property>
|
||||
</row>
|
||||
<row>
|
||||
<property name="text">
|
||||
<string>Goods price</string>
|
||||
</property>
|
||||
</row>
|
||||
<row>
|
||||
<property name="text">
|
||||
<string>Goods quantity</string>
|
||||
</property>
|
||||
</row>
|
||||
<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">
|
||||
<property name="text">
|
||||
<string>1</string>
|
||||
</property>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<property name="text">
|
||||
<string>Name</string>
|
||||
</property>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<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>
|
||||
</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>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>OutputDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>OutputDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
@@ -3,18 +3,26 @@
|
||||
#include "../net/net.h"
|
||||
#include "../settings/settings.h"
|
||||
#include "../utils/utils.h"
|
||||
#include <filesystem>
|
||||
#include <iostream>
|
||||
|
||||
#if __GNUC__ < 8 && __clang_major__ < 17
|
||||
# include <experimental/filesystem>
|
||||
using namespace std::experimental;
|
||||
using namespace std::experimental::filesystem;
|
||||
#else
|
||||
# include <filesystem>
|
||||
using namespace std::filesystem;
|
||||
#endif
|
||||
|
||||
Parser::Parser() {}
|
||||
|
||||
std::vector<std::string> Parser::search_modules() {
|
||||
Settings s(get_path_relative_to_home(".local/share/checks_parser/settings.json"));
|
||||
std::string path = get_path_relative_to_home(s.get_setting("stores_modules_dir"));//std::string(std::getenv("HOME")) + "/" + STORES_MODULES_DIR;
|
||||
std::filesystem::directory_entry modules_dir(path);
|
||||
directory_entry modules_dir(path);
|
||||
|
||||
if (!modules_dir.exists()) {
|
||||
std::filesystem::create_directories(path);
|
||||
if (!exists(modules_dir)) {
|
||||
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."
|
||||
@@ -23,7 +31,7 @@ std::vector<std::string> Parser::search_modules() {
|
||||
|
||||
std::vector<std::string> modules_files;
|
||||
|
||||
for (auto file : std::filesystem::directory_iterator(path)) {
|
||||
for (auto file : directory_iterator(path)) {
|
||||
modules_files.push_back(file.path());
|
||||
}
|
||||
|
||||
@@ -67,17 +75,17 @@ std::vector<std::string> Parser::check_updates() {
|
||||
std::vector<std::string> to_download;
|
||||
std::vector<std::string> stored_modules;
|
||||
|
||||
std::filesystem::directory_entry modules_dir(path);
|
||||
if (!modules_dir.exists()) {
|
||||
std::filesystem::create_directories(path);
|
||||
directory_entry modules_dir(path);
|
||||
if (!exists(modules_dir)) {
|
||||
create_directories(path);
|
||||
}
|
||||
for (const auto& file : std::filesystem::directory_iterator(path)) {
|
||||
if (!file.is_regular_file()) continue;
|
||||
for (const auto& file : directory_iterator(path)) {
|
||||
if (!is_regular_file(file)) continue;
|
||||
stored_modules.push_back(file.path().filename());
|
||||
std::cout << file.path().filename() << " detected store module" << std::endl;
|
||||
}
|
||||
Net n;
|
||||
std::cerr << "Downloading modules list from: " << s.get_setting("stores_modules_url");
|
||||
std::cerr << "Downloading modules list from: " << s.get_setting("stores_modules_url") << std::endl;
|
||||
std::vector<std::string> remote_modules = n.get_all_modules(s.get_setting("stores_modules_url"));
|
||||
if (stored_modules.empty()) {
|
||||
std::cout << "I need to download everything" << std::endl;
|
||||
|
||||
@@ -1,21 +1,29 @@
|
||||
#include "settings.h"
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <string>
|
||||
#include "../utils/utils.h"
|
||||
|
||||
#if __GNUC__ < 8 && __clang_major__ < 17
|
||||
# include <experimental/filesystem>
|
||||
using namespace std::experimental;
|
||||
using namespace std::experimental::filesystem;
|
||||
#else
|
||||
# include <filesystem>
|
||||
using namespace std::filesystem;
|
||||
#endif
|
||||
|
||||
Settings::Settings(std::string path) {
|
||||
this->settings_file_path = path;
|
||||
|
||||
if (!std::filesystem::exists(path)) {
|
||||
if (!exists(path)) {
|
||||
std::ofstream output(path);
|
||||
|
||||
nlohmann::json settings = R"({
|
||||
"ofds_modules_dir":".local/share/checks_parser/modules/ofd",
|
||||
"stores_modules_dir":".local/share/checks_parser/modules/stores",
|
||||
"ofds_modules_url":"https://foxarmy.org/checks-parser/modules/ofd/",
|
||||
"stores_modules_url":"https://foxarmy.org/checks-parser/modules/modules/",
|
||||
"stores_modules_url":"https://foxarmy.org/checks-parser/modules/stores/",
|
||||
"print_header": true,
|
||||
"print_total": true,
|
||||
"output_order": {
|
||||
@@ -53,8 +61,8 @@ Settings::Settings(std::string path) {
|
||||
this->settings = settings;
|
||||
}
|
||||
|
||||
std::filesystem::create_directories(get_path_relative_to_home(this->settings["ofds_modules_dir"]));
|
||||
std::filesystem::create_directories(get_path_relative_to_home(this->settings["stores_modules_dir"]));
|
||||
create_directories(get_path_relative_to_home(this->settings["ofds_modules_dir"]));
|
||||
create_directories(get_path_relative_to_home(this->settings["stores_modules_dir"]));
|
||||
}
|
||||
|
||||
void Settings::write_setting(std::string setting, std::string value) {
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#include "settings/settings.h"
|
||||
#include "ui_settingsdialog.h"
|
||||
#include "utils/utils.h"
|
||||
#include <iostream>
|
||||
|
||||
SettingsDialog::SettingsDialog(QWidget *parent)
|
||||
: QDialog(parent), ui(new Ui::settingsdialog),
|
||||
|
||||
285
settingsdialog.ui
Normal file
285
settingsdialog.ui
Normal file
@@ -0,0 +1,285 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>settingsdialog</class>
|
||||
<widget class="QDialog" name="settingsdialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>599</width>
|
||||
<height>727</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>310</x>
|
||||
<y>690</y>
|
||||
<width>251</width>
|
||||
<height>32</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Save</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QScrollArea" name="scrollArea">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>0</y>
|
||||
<width>541</width>
|
||||
<height>661</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QWidget" name="scrollAreaWidgetContents">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>539</width>
|
||||
<height>659</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QWidget" name="gridLayoutWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>531</width>
|
||||
<height>651</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="11" column="1">
|
||||
<widget class="QLineEdit" name="goodsNetWeightAliasEdit"/>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="storesModulesDirEdit"/>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="text">
|
||||
<string>Goods name position</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="label_12">
|
||||
<property name="text">
|
||||
<string>Goods price per unit alias</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QPushButton" name="storedModulesDirChooseButton">
|
||||
<property name="text">
|
||||
<string>Choose</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="13" column="1">
|
||||
<widget class="QLineEdit" name="goodsTotalAliasEdit"/>
|
||||
</item>
|
||||
<item row="14" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Print header</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="0">
|
||||
<widget class="QLabel" name="label_16">
|
||||
<property name="text">
|
||||
<string>Goods net weight alias</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string>Stores modules url</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLineEdit" name="storesModulesURLEdit"/>
|
||||
</item>
|
||||
<item row="13" column="0">
|
||||
<widget class="QLabel" name="label_18">
|
||||
<property name="text">
|
||||
<string>Goods total alias</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="text">
|
||||
<string>Goods name alias</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="1">
|
||||
<widget class="QSpinBox" name="goodsTotalPositionSpin"/>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
<widget class="QLabel" name="label_14">
|
||||
<property name="text">
|
||||
<string>Goods quantity alias</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Stores modules directory</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QLineEdit" name="goodsNameAliasEdit"/>
|
||||
</item>
|
||||
<item row="10" column="1">
|
||||
<widget class="QSpinBox" name="goodsNetWeightPositionSpin"/>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>OFD modules directory</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QSpinBox" name="goodsNamePositionSpin"/>
|
||||
</item>
|
||||
<item row="9" column="1">
|
||||
<widget class="QLineEdit" name="goodsQuantityAliasEdit"/>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QLineEdit" name="goodsPricePerUnitAliasEdit"/>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_11">
|
||||
<property name="text">
|
||||
<string>Goods price per unit position</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="0">
|
||||
<widget class="QLabel" name="label_15">
|
||||
<property name="text">
|
||||
<string>Goods net weight position</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>OFD modules url</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="OFDModulesDirEdit"/>
|
||||
</item>
|
||||
<item row="12" column="0">
|
||||
<widget class="QLabel" name="label_17">
|
||||
<property name="text">
|
||||
<string>Goods total position</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="label_13">
|
||||
<property name="text">
|
||||
<string>Goods quantity position</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="OFDModulesURLEdit"/>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<widget class="QSpinBox" name="goodsQuantityPositionSpin"/>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QPushButton" name="OFDModulesDirChooseButton">
|
||||
<property name="text">
|
||||
<string>Choose</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QSpinBox" name="goodsPricePerUnitPositionSpin"/>
|
||||
</item>
|
||||
<item row="15" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Print total</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="14" column="1">
|
||||
<widget class="QCheckBox" name="printHeaderCheckBox">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="15" column="1">
|
||||
<widget class="QCheckBox" name="printTotalCheckBox">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>settingsdialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>settingsdialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
36
solvecaptchadialog.cpp
Normal file
36
solvecaptchadialog.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
#include "solvecaptchadialog.h"
|
||||
#include "ui_solvecaptchadialog.h"
|
||||
#include "utils/utils.h"
|
||||
#include <iostream>
|
||||
#include <QMessageBox>
|
||||
|
||||
SolveCaptchaDialog::SolveCaptchaDialog(QWidget *parent, std::string* solved_captcha) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::SolveCaptchaDialog),
|
||||
solved_captcha(solved_captcha) {
|
||||
ui->setupUi(this);
|
||||
|
||||
QString captcha_path = QString::fromStdString(get_path_relative_to_home(".local/share/checks_parser/captcha.jpg"));
|
||||
std::cout << captcha_path.toStdString() << std::endl;
|
||||
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(tr("Please, enter a valid captcha"));
|
||||
infoDialog.setIcon(QMessageBox::Warning);
|
||||
infoDialog.setWindowTitle(tr("No captcha"));
|
||||
infoDialog.exec();
|
||||
} else {
|
||||
solved_captcha->erase();
|
||||
solved_captcha->append(userInput);
|
||||
QDialog::accept();
|
||||
}
|
||||
}
|
||||
|
||||
SolveCaptchaDialog::~SolveCaptchaDialog() {
|
||||
delete ui;
|
||||
}
|
||||
26
solvecaptchadialog.h
Normal file
26
solvecaptchadialog.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef SOLVECAPTCHADIALOG_H
|
||||
#define SOLVECAPTCHADIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
namespace Ui {
|
||||
class SolveCaptchaDialog;
|
||||
}
|
||||
|
||||
class SolveCaptchaDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SolveCaptchaDialog(QWidget *parent = nullptr, std::string* = nullptr) ;
|
||||
~SolveCaptchaDialog();
|
||||
|
||||
private:
|
||||
Ui::SolveCaptchaDialog *ui;
|
||||
std::string* solved_captcha;
|
||||
|
||||
private slots:
|
||||
void accept() override;
|
||||
};
|
||||
|
||||
#endif // SOLVECAPTCHADIALOG_H
|
||||
91
solvecaptchadialog.ui
Normal file
91
solvecaptchadialog.ui
Normal file
@@ -0,0 +1,91 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>SolveCaptchaDialog</class>
|
||||
<widget class="QDialog" name="SolveCaptchaDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>503</width>
|
||||
<height>350</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>130</x>
|
||||
<y>310</y>
|
||||
<width>341</width>
|
||||
<height>32</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="captcha_picture">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>20</y>
|
||||
<width>451</width>
|
||||
<height>221</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLineEdit" name="captcha_edit">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>80</x>
|
||||
<y>260</y>
|
||||
<width>321</width>
|
||||
<height>26</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>SolveCaptchaDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>SolveCaptchaDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
404
translations/en_US.ts
Normal file
404
translations/en_US.ts
Normal file
@@ -0,0 +1,404 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1">
|
||||
<context>
|
||||
<name>AdjustPictureDialog</name>
|
||||
<message>
|
||||
<location filename="../adjustpicturedialog.ui" line="14"/>
|
||||
<source>Dialog</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../adjustpicturedialog.ui" line="58"/>
|
||||
<source>Please, zoom to qr code and adjust contrast so that qr code looks sharp</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../adjustpicturedialog.cpp" line="39"/>
|
||||
<source>QR code was not detected on that image. Please edit it again or enter data manually</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../adjustpicturedialog.cpp" line="41"/>
|
||||
<source>No QR code</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MainWindow</name>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="14"/>
|
||||
<source>MainWindow</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="37"/>
|
||||
<source>Store type</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="50"/>
|
||||
<source>Parse</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="63"/>
|
||||
<source>Preferences</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="80"/>
|
||||
<source>Text</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="92"/>
|
||||
<source>Check content</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="108"/>
|
||||
<source>OCR</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="120"/>
|
||||
<location filename="../mainwindow.ui" line="213"/>
|
||||
<source>Choose</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="143"/>
|
||||
<location filename="../mainwindow.ui" line="200"/>
|
||||
<source>Path to image: </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="156"/>
|
||||
<source>Here is recognised check text. Please, edit it if something's wrong:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="175"/>
|
||||
<source>OFD</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="226"/>
|
||||
<source>0000000000000000</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="245"/>
|
||||
<source>FN (Fiscal Number)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="264"/>
|
||||
<source>FD (Fiscal Document)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="277"/>
|
||||
<location filename="../mainwindow.ui" line="309"/>
|
||||
<source>0000000000</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="296"/>
|
||||
<source>FI (Fiscal Identifier)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="333"/>
|
||||
<source>Funds income</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="338"/>
|
||||
<source>Funds return</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="343"/>
|
||||
<source>Funds spend</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="348"/>
|
||||
<source>Spends return</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="375"/>
|
||||
<source>Total</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="392"/>
|
||||
<source>checks parser</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="85"/>
|
||||
<source>Captcha was not solved correctly!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="87"/>
|
||||
<source>Captcha is incorrect</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="92"/>
|
||||
<source>Check not found. Please, ensure correctness of entered data.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="94"/>
|
||||
<source>Check was not found</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="145"/>
|
||||
<source>Please, select a picture where QR code that contains info about check is present</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="147"/>
|
||||
<location filename="../mainwindow.cpp" line="193"/>
|
||||
<source>Picture was not selected</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="191"/>
|
||||
<source>Please, select a picture to scan</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>OutputDialog</name>
|
||||
<message>
|
||||
<location filename="../outputdialog.ui" line="14"/>
|
||||
<source>Dialog</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../outputdialog.ui" line="42"/>
|
||||
<source>Path to export: </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../outputdialog.ui" line="55"/>
|
||||
<source>Choose</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../outputdialog.ui" line="68"/>
|
||||
<source>Print header</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../outputdialog.ui" line="82"/>
|
||||
<source>Goods name</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../outputdialog.ui" line="87"/>
|
||||
<source>Goods price</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../outputdialog.ui" line="92"/>
|
||||
<source>Goods quantity</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../outputdialog.ui" line="97"/>
|
||||
<source>Goods net weight</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../outputdialog.ui" line="102"/>
|
||||
<source>Goods total</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../outputdialog.ui" line="107"/>
|
||||
<source>position</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../outputdialog.ui" line="112"/>
|
||||
<source>name</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../outputdialog.ui" line="117"/>
|
||||
<source>1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../outputdialog.ui" line="122"/>
|
||||
<source>Name</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../outputdialog.ui" line="127"/>
|
||||
<source>2</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../outputdialog.ui" line="132"/>
|
||||
<source>Price</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../outputdialog.ui" line="137"/>
|
||||
<source>3</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../outputdialog.ui" line="142"/>
|
||||
<source>Quantity</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../outputdialog.ui" line="147"/>
|
||||
<source>4</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../outputdialog.ui" line="152"/>
|
||||
<source>Net weight</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../outputdialog.ui" line="157"/>
|
||||
<source>5</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../outputdialog.ui" line="162"/>
|
||||
<source>Total price</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../outputdialog.ui" line="176"/>
|
||||
<source>Print total</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>SolveCaptchaDialog</name>
|
||||
<message>
|
||||
<location filename="../solvecaptchadialog.ui" line="14"/>
|
||||
<source>Dialog</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../solvecaptchadialog.cpp" line="23"/>
|
||||
<source>Please, enter a valid captcha</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../solvecaptchadialog.cpp" line="25"/>
|
||||
<source>No captcha</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>settingsdialog</name>
|
||||
<message>
|
||||
<location filename="../settingsdialog.ui" line="14"/>
|
||||
<source>Dialog</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.ui" line="72"/>
|
||||
<source>Goods name position</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.ui" line="79"/>
|
||||
<source>Goods price per unit alias</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.ui" line="86"/>
|
||||
<location filename="../settingsdialog.ui" line="217"/>
|
||||
<source>Choose</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.ui" line="96"/>
|
||||
<source>Print header</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.ui" line="103"/>
|
||||
<source>Goods net weight alias</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.ui" line="110"/>
|
||||
<source>Stores modules url</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.ui" line="120"/>
|
||||
<source>Goods total alias</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.ui" line="127"/>
|
||||
<source>Goods name alias</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.ui" line="137"/>
|
||||
<source>Goods quantity alias</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.ui" line="144"/>
|
||||
<source>Stores modules directory</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.ui" line="157"/>
|
||||
<source>OFD modules directory</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.ui" line="173"/>
|
||||
<source>Goods price per unit position</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.ui" line="180"/>
|
||||
<source>Goods net weight position</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.ui" line="187"/>
|
||||
<source>OFD modules url</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.ui" line="197"/>
|
||||
<source>Goods total position</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.ui" line="204"/>
|
||||
<source>Goods quantity position</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.ui" line="227"/>
|
||||
<source>Print total</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
404
translations/ru_RU.ts
Normal file
404
translations/ru_RU.ts
Normal file
@@ -0,0 +1,404 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1" language="ru_RU">
|
||||
<context>
|
||||
<name>AdjustPictureDialog</name>
|
||||
<message>
|
||||
<location filename="../adjustpicturedialog.ui" line="14"/>
|
||||
<source>Dialog</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../adjustpicturedialog.ui" line="58"/>
|
||||
<source>Please, zoom to qr code and adjust contrast so that qr code looks sharp</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../adjustpicturedialog.cpp" line="39"/>
|
||||
<source>QR code was not detected on that image. Please edit it again or enter data manually</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../adjustpicturedialog.cpp" line="41"/>
|
||||
<source>No QR code</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MainWindow</name>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="14"/>
|
||||
<source>MainWindow</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="37"/>
|
||||
<source>Store type</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="50"/>
|
||||
<source>Parse</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="63"/>
|
||||
<source>Preferences</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="80"/>
|
||||
<source>Text</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="92"/>
|
||||
<source>Check content</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="108"/>
|
||||
<source>OCR</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="120"/>
|
||||
<location filename="../mainwindow.ui" line="213"/>
|
||||
<source>Choose</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="143"/>
|
||||
<location filename="../mainwindow.ui" line="200"/>
|
||||
<source>Path to image: </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="156"/>
|
||||
<source>Here is recognised check text. Please, edit it if something's wrong:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="175"/>
|
||||
<source>OFD</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="226"/>
|
||||
<source>0000000000000000</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="245"/>
|
||||
<source>FN (Fiscal Number)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="264"/>
|
||||
<source>FD (Fiscal Document)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="277"/>
|
||||
<location filename="../mainwindow.ui" line="309"/>
|
||||
<source>0000000000</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="296"/>
|
||||
<source>FI (Fiscal Identifier)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="333"/>
|
||||
<source>Funds income</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="338"/>
|
||||
<source>Funds return</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="343"/>
|
||||
<source>Funds spend</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="348"/>
|
||||
<source>Spends return</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="375"/>
|
||||
<source>Total</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="392"/>
|
||||
<source>checks parser</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="85"/>
|
||||
<source>Captcha was not solved correctly!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="87"/>
|
||||
<source>Captcha is incorrect</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="92"/>
|
||||
<source>Check not found. Please, ensure correctness of entered data.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="94"/>
|
||||
<source>Check was not found</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="145"/>
|
||||
<source>Please, select a picture where QR code that contains info about check is present</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="147"/>
|
||||
<location filename="../mainwindow.cpp" line="193"/>
|
||||
<source>Picture was not selected</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="191"/>
|
||||
<source>Please, select a picture to scan</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>OutputDialog</name>
|
||||
<message>
|
||||
<location filename="../outputdialog.ui" line="14"/>
|
||||
<source>Dialog</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../outputdialog.ui" line="42"/>
|
||||
<source>Path to export: </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../outputdialog.ui" line="55"/>
|
||||
<source>Choose</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../outputdialog.ui" line="68"/>
|
||||
<source>Print header</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../outputdialog.ui" line="82"/>
|
||||
<source>Goods name</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../outputdialog.ui" line="87"/>
|
||||
<source>Goods price</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../outputdialog.ui" line="92"/>
|
||||
<source>Goods quantity</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../outputdialog.ui" line="97"/>
|
||||
<source>Goods net weight</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../outputdialog.ui" line="102"/>
|
||||
<source>Goods total</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../outputdialog.ui" line="107"/>
|
||||
<source>position</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../outputdialog.ui" line="112"/>
|
||||
<source>name</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../outputdialog.ui" line="117"/>
|
||||
<source>1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../outputdialog.ui" line="122"/>
|
||||
<source>Name</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../outputdialog.ui" line="127"/>
|
||||
<source>2</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../outputdialog.ui" line="132"/>
|
||||
<source>Price</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../outputdialog.ui" line="137"/>
|
||||
<source>3</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../outputdialog.ui" line="142"/>
|
||||
<source>Quantity</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../outputdialog.ui" line="147"/>
|
||||
<source>4</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../outputdialog.ui" line="152"/>
|
||||
<source>Net weight</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../outputdialog.ui" line="157"/>
|
||||
<source>5</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../outputdialog.ui" line="162"/>
|
||||
<source>Total price</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../outputdialog.ui" line="176"/>
|
||||
<source>Print total</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>SolveCaptchaDialog</name>
|
||||
<message>
|
||||
<location filename="../solvecaptchadialog.ui" line="14"/>
|
||||
<source>Dialog</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../solvecaptchadialog.cpp" line="23"/>
|
||||
<source>Please, enter a valid captcha</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../solvecaptchadialog.cpp" line="25"/>
|
||||
<source>No captcha</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>settingsdialog</name>
|
||||
<message>
|
||||
<location filename="../settingsdialog.ui" line="14"/>
|
||||
<source>Dialog</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.ui" line="72"/>
|
||||
<source>Goods name position</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.ui" line="79"/>
|
||||
<source>Goods price per unit alias</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.ui" line="86"/>
|
||||
<location filename="../settingsdialog.ui" line="217"/>
|
||||
<source>Choose</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.ui" line="96"/>
|
||||
<source>Print header</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.ui" line="103"/>
|
||||
<source>Goods net weight alias</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.ui" line="110"/>
|
||||
<source>Stores modules url</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.ui" line="120"/>
|
||||
<source>Goods total alias</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.ui" line="127"/>
|
||||
<source>Goods name alias</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.ui" line="137"/>
|
||||
<source>Goods quantity alias</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.ui" line="144"/>
|
||||
<source>Stores modules directory</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.ui" line="157"/>
|
||||
<source>OFD modules directory</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.ui" line="173"/>
|
||||
<source>Goods price per unit position</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.ui" line="180"/>
|
||||
<source>Goods net weight position</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.ui" line="187"/>
|
||||
<source>OFD modules url</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.ui" line="197"/>
|
||||
<source>Goods total position</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.ui" line="204"/>
|
||||
<source>Goods quantity position</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.ui" line="227"/>
|
||||
<source>Print total</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
102
utils/utils.cpp
102
utils/utils.cpp
@@ -1,8 +1,12 @@
|
||||
#include "utils.h"
|
||||
|
||||
#include <codecvt>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <locale>
|
||||
#include <regex>
|
||||
#include <string>
|
||||
#include "../exceptions/ofdrequestexception.h"
|
||||
|
||||
std::string to_utf8(std::wstring wide_string) {
|
||||
static std::wstring_convert<std::codecvt_utf8<wchar_t>> utf8_conv;
|
||||
@@ -42,3 +46,101 @@ std::vector<std::string> split(std::string s, std::string delimiter) {
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::wstring substring_from_to(std::wstring& text, std::wstring from, std::wstring to) {
|
||||
unsigned int start_pos = 0;
|
||||
unsigned int end_pos = 0;
|
||||
|
||||
std::wstring substring;
|
||||
|
||||
std::wregex start_regex(from);
|
||||
std::wregex end_regex(to);
|
||||
|
||||
for (std::wsregex_iterator it{text.begin(), text.end(), start_regex}, end{};
|
||||
it != end; it++) {
|
||||
start_pos = it->position() + it->str().size();
|
||||
break;
|
||||
}
|
||||
|
||||
if(text == from_utf8("")) return text;
|
||||
substring = text.substr(start_pos, text.size());
|
||||
|
||||
for (std::wsregex_iterator it{substring.begin(), substring.end(), end_regex}, end{};
|
||||
it != end; it++) {
|
||||
end_pos = it->position();
|
||||
break;
|
||||
}
|
||||
|
||||
if (end_pos == 0) return substring;
|
||||
|
||||
substring = substring.substr(0, end_pos);
|
||||
|
||||
return substring;
|
||||
}
|
||||
|
||||
std::wstring trim_html_response(std::wstring& check) {
|
||||
std::wstring begin_check_marker = from_utf8("<!-- Products -->");
|
||||
std::wstring end_check_marker = from_utf8("<!-- \\/Products -->");
|
||||
std::wstring trimmed = substring_from_to(check, begin_check_marker, end_check_marker);
|
||||
trimmed += from_utf8("\n</div>");
|
||||
return trimmed;
|
||||
}
|
||||
|
||||
std::vector<std::wstring> find_in_html(std::string& html, std::string regex, std::string html_start, std::string html_end) {
|
||||
std::regex searching_regex(regex);
|
||||
|
||||
std::vector<std::wstring> parsed;
|
||||
for (std::sregex_iterator it{html.begin(), html.end(), searching_regex}, end{};
|
||||
it != end; it++) {
|
||||
|
||||
std::wstring found_entry = from_utf8(it->str());
|
||||
std::wstring extracted = substring_from_to(found_entry, from_utf8(html_start), from_utf8(html_end));
|
||||
|
||||
parsed.push_back(extracted);
|
||||
}
|
||||
return parsed;
|
||||
}
|
||||
|
||||
std::vector<std::wstring> find_products_in_html(std::string html) {
|
||||
return find_in_html(html, "<div class=\"ifw-col ifw-col-1 text-left\"><b>.*<\\/b><\\/div>", "<div class=\"ifw-col ifw-col-1 text-left\"><b>", "<\\/b><\\/div>");
|
||||
}
|
||||
|
||||
std::vector<std::wstring> find_amounts_in_html(std::string html) {
|
||||
return find_in_html(html, "<span>\\d+<\\/span>", "<span>", "<\\/span>");
|
||||
}
|
||||
|
||||
std::vector<std::wstring> find_prices_in_html(std::string html) {
|
||||
return find_in_html(html, "X <\\/span><span>\\d+\\.\\d{2}<\\/span>", "X <\\/span><span>", "<\\/span>");
|
||||
}
|
||||
|
||||
Check parseOfdRuAnswer(std::string html) {
|
||||
std::wstring wstr_html = from_utf8(html);
|
||||
std::string trimmed = to_utf8(trim_html_response(wstr_html));
|
||||
|
||||
std::vector<std::wstring> products = find_products_in_html(trimmed);
|
||||
std::vector<std::wstring> amounts = find_amounts_in_html(trimmed);
|
||||
std::vector<std::wstring> prices = find_prices_in_html(trimmed);
|
||||
|
||||
if ((products.size() + amounts.size() + prices.size()) == 0) {
|
||||
if (html == "Bad Request4") { // Failed to solve a captcha
|
||||
throw OfdRequestException("Incorrect captcha");
|
||||
} else { // Most likely that the check does not exist
|
||||
throw OfdRequestException("Does not exist");
|
||||
}
|
||||
return Check();
|
||||
}
|
||||
|
||||
if ((products.size() + amounts.size() + prices.size())/products.size() != 3) {
|
||||
std::cerr << "An error has occured during the parsing of html. Please, contact the developer." << std::endl;
|
||||
std::exit(-1);
|
||||
}
|
||||
|
||||
Check c;
|
||||
|
||||
for (int i = 0; i < products.size(); i ++) {
|
||||
Goods goods(to_utf8(products[i]), std::stod(prices[i]), std::stod(amounts[i]));
|
||||
c.add_goods(goods);
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "../check/check.h"
|
||||
|
||||
std::string to_utf8(std::wstring wide_string);
|
||||
std::wstring from_utf8(std::string string);
|
||||
@@ -14,4 +15,8 @@ bool vector_contains_element(const std::vector<T> &vector, const T &to_find);
|
||||
|
||||
std::vector<std::string> split(std::string, std::string);
|
||||
|
||||
Check parseOfdRuAnswer(std::string);
|
||||
|
||||
std::wstring trim_html_response(std::wstring& check);
|
||||
|
||||
#endif // UTILS_H
|
||||
|
||||
Reference in New Issue
Block a user