Merge pull request 'UI rework' (#3) from ui_rework into master

This commit is contained in:
leca 2025-03-14 01:27:59 +03:00
commit 453f907bfa
38 changed files with 3323 additions and 941 deletions

View File

@ -4,11 +4,15 @@ project(checks-parser VERSION 0.1 LANGUAGES CXX)
option(BUILD_TRANSLATIONS "Build translations?" ON)
include(FetchContent)
SET(CMAKE_BUILD_TYPE Debug)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC OFF)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOUIC_SEARCH_PATHS Designer)
set(CMAKE_AUTOUIC_SEARCH_PATHS scenes)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
@ -17,39 +21,43 @@ find_package(Qt5Core REQUIRED)
find_package(Qt5 REQUIRED COMPONENTS LinguistTools)
find_package(Qt5Gui REQUIRED)
find_package(Qt5Widgets REQUIRED)
find_package(Qt5UiTools REQUIRED)
set(PROJECT_SOURCES
main.cpp
mainwindow.cpp
mainwindow.h
mainwindow.ui
mainwindow.h mainwindow.cpp scenes/mainwindow.ui
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
image_redactor/imageredactor.h image_redactor/imageredactor.cpp
solvecaptchadialog.h solvecaptchadialog.cpp solvecaptchadialog.ui
exceptions/ofdrequestexception.h exceptions/ofdrequestexception.cpp
emailtextscene.h emailtextscene.cpp scenes/emailtextscene.ui
ocrscene.h ocrscene.cpp scenes/ocrscene.ui
ofdscene.h ofdscene.cpp scenes/ofdscene.ui
outputdialog.h outputdialog.cpp scenes/outputdialog.ui
adjustpicturedialog.h adjustpicturedialog.cpp scenes/adjustpicturedialog.ui
image_redactor/imageredactor.h image_redactor/imageredactor.cpp
solvecaptchadialog.h solvecaptchadialog.cpp scenes/solvecaptchadialog.ui
)
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
mainwindow.cpp mainwindow.h scenes/mainwindow.ui
emailtextscene.cpp emailtextscene.h scenes/emailtextscene.ui
ocrscene.cpp ocrscene.h scenes/ocrscene.ui
ofdscene.cpp ofdscene.h scenes/ofdscene.ui
outputdialog.h outputdialog.cpp scenes/outputdialog.ui
adjustpicturedialog.h adjustpicturedialog.cpp scenes/adjustpicturedialog.ui
solvecaptchadialog.h solvecaptchadialog.cpp scenes/solvecaptchadialog.ui
)
set(TS_FILES
@ -66,7 +74,23 @@ if (BUILD_TRANSLATIONS)
add_dependencies(resources translations)
endif()
# Media QRC
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/media.qrc ${CMAKE_CURRENT_BINARY_DIR}/media.qrc COPYONLY)
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/assets DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
qt5_add_resources(MEDIAQRC ${CMAKE_CURRENT_BINARY_DIR}/media.qrc)
add_custom_target(mediaresource ALL DEPENDS ${MEDIAQRC})
#Scenes QRC
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scenes.qrc ${CMAKE_CURRENT_BINARY_DIR}/scenes.qrc COPYONLY)
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/scenes DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
qt5_add_resources(SCENESQRC ${CMAKE_CURRENT_BINARY_DIR}/scenes.qrc)
add_custom_target(scenessource ALL DEPENDS ${SCENESQRC})
set(SOURCES "")
list(APPEND SOURCES ${MEDIAQRC})
list(APPEND SOURCES ${SCENESQRC})
if (BUILD_TRANSLATIONS)
list(APPEND SOURCES ${TRANSLATIONQRC})
endif()
@ -83,7 +107,7 @@ else()
)
endif()
target_link_libraries(checks-parser PRIVATE Qt5::Widgets)
target_link_libraries(checks-parser PRIVATE Qt5::Widgets Qt5::UiTools)
target_include_directories(checks-parser PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/image_redactor)
@ -104,20 +128,28 @@ install(TARGETS checks-parser
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
if(WIN32)
#????
set(OpenCV_DIR /usr/local/lib/cmake/opencv4)
endif()
FetchContent_Declare(httplib SYSTEM
GIT_REPOSITORY https://github.com/yhirose/cpp-httplib
GIT_TAG 2eaa2ea64f9fb12773306534d461d9ed63cb76b6 # v0.14.1
GIT_SHALLOW TRUE)
FetchContent_MakeAvailable(httplib)
find_package(OpenCV REQUIRED COMPONENTS core imgproc imgcodecs)
include_directories( ${OpenCV_INCLUDE_DIRS} )
target_include_directories(checks-parser PUBLIC ${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} )
target_link_libraries(checks-parser PRIVATE ${OpenCV_LIBS})
target_link_libraries(checks-parser PRIVATE httplib)
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8)
target_link_libraries(checks-parser PRIVATE -lstdc++fs)
endif()

View File

@ -4,25 +4,25 @@
Чек парсер - это приложение, позволяющее доставать содержимое чека и переводить его в .csv файлы.
!!!НА ДАННЫЙ МОМЕНТ ПОДДЕРЖИВАЮТСЯ ТОЛЬКО РУССКИЕ ЧЕКИ!!!
Чтобы узнать, почему [смотрите здесь](https://git.foxarmy.org/leca/checks-parser/src/branch/master/README.ru.md#checks-from-different-countries)
Чтобы узнать почему [смотрите здесь](https://git.foxarmy.org/leca/checks-parser/src/branch/master/README.ru.md#checks-from-different-countries)
# Пользование
Для более детального описания, пожалуйста, обратитесь к [вики](https://git.foxarmy.org/leca/checks-parser/wiki/Description-%5BRU%5D)
### Ввод данных
Доступны следующие способы ввода данных:
* Через изображениие (используется OCR(Optical Character Recognition, Оптическое распознавание символов) чтобы прочитать содержимое чека. Изображение чека должно быть контрастным и выровненным (текст обязан быть перпендикулярным к границам изображения) хорошо, чтобы нормально прочитаться.) OCR - не волшебная палочка :(
* Через просто текст, скопированный из эл. письма. Просто скопируйте и вставьте текст с вашего письма, выберите подходящий магазин (автодетект в планах!) и парсите.
* Через QRCode на чеке (этот метод запрашивает данные у ОФД (Оператор Фискальных Данных) (В данном конкретном случае, к ofd.ru)).
* Через изображениие (используется OCR(Optical Character Recognition, Оптическое распознавание символов), чтобы прочитать содержимое чека. Изображение чека должно быть контрастным и выровненным (текст обязан быть перпендикулярным к границам изображения) хорошо, чтобы нормально прочитаться. OCR - не волшебная палочка :(
* Через простой текст, скопированный из эл. письма. Скопируйте и вставьте текст с вашего письма, выберите подходящий магазин (автодетект в планах!) и парсите.
* Через QRCode на чеке (этот метод запрашивает данные у ОФД (Оператор Фискальных Данных), в данном конкретном случае, к ofd.ru).
### Вывод данных
На начальном этапе разработки программы, Я задумывался о 3 или более форматов вывода: csv, xlsx и ods. Но по мере разработки, я понял, что большинство современных табличных процессоров (электронных таблиц) способны импортировать в себя csv гораздо лучше, чем смог бы написать я сам. Так что я решил не делать вывод во все остальные форматы, кроме csv.
На начальном этапе разработки программы, Я задумывался о 3-х или более форматов вывода: csv, xlsx и ods. Но, по мере разработки, я понял, что большинство современных табличных процессоров (электронных таблиц) способны импортировать в себя csv гораздо лучше, чем смог бы написать я сам. Так что я решил не делать вывод во все остальные форматы, кроме csv.
Чтобы экспортировать, вам нужно указать путь до файла, если вы желаете, вы можете изменить порядок и/или переименовать (алиасы) столбцы, выбрать печатать или не печатать заголовок (алиасы столбцов) и "итого"
Чтобы экспортировать вам нужно: указать путь до файла, если вы желаете, вы можете изменить порядок и/или переименовать (алиасы) столбцы, выбрать печатать или не печатать заголовок (алиасы столбцов) и "итого".
# Установка
## Сборка из исходников
В целом, вам нужно установить следующие зависимости чтобы собрать приложение (я предполагаю, что вы уже имеете на системе базовые пакеты вроде cmake, make, gcc, git и так далее):
В целом, вам нужно установить следующие зависимости, чтобы собрать приложение (я предполагаю, что вы уже имеете на системе базовые пакеты вроде cmake, make, gcc, git и так далее):
* tesseract (также вам нужно будет установить языковой пакет для него, например tesseract-data-rus на Arch Linux или tesseract-ocr-rus на Debian Linux.)
* opencv
* zbar

131
assets/icons/OCR.svg Normal file
View File

@ -0,0 +1,131 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="159.62572mm"
height="146.77805mm"
viewBox="0 0 159.62572 146.77805"
version="1.1"
id="svg1"
inkscape:version="1.4 (e7c3feb100, 2024-10-09)"
sodipodi:docname="OCR.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="true"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
inkscape:zoom="0.50000001"
inkscape:cx="187"
inkscape:cy="261.99999"
inkscape:window-width="1920"
inkscape:window-height="1029"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:current-layer="layer4" />
<defs
id="defs1">
<linearGradient
id="swatch50"
inkscape:swatch="solid">
<stop
style="stop-color:#00b2c3;stop-opacity:0;"
offset="0"
id="stop50" />
</linearGradient>
<linearGradient
id="linearGradient5"
inkscape:collect="always">
<stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop5" />
<stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop6" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient5"
id="radialGradient6"
cx="178.3111"
cy="60.733166"
fx="178.3111"
fy="60.733166"
r="14.328103"
gradientTransform="matrix(1,0,0,0.566866,0,26.305599)"
gradientUnits="userSpaceOnUse" />
</defs>
<g
inkscape:groupmode="layer"
id="layer4"
inkscape:label="eye"
transform="translate(-20.738154,-52.70636)">
<ellipse
style="display:none;fill:#ffffff;fill-opacity:1;stroke:url(#radialGradient6);stroke-width:0.418956;stroke-opacity:1"
id="ellipse5"
ry="7.9126363"
rx="16.896055"
cy="60.733166"
cx="178.3111"
inkscape:label="inner" />
<path
id="path48"
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.499999;stroke-dasharray:none;stroke-opacity:1"
d="m 163.03445,62.853096 c -5.5416,0.04533 -10.97868,2.888123 -16.31735,8.383468 -0.12314,0.157876 0.0243,0.318843 0.0243,0.318843 11.50919,11.568278 22.55969,11.493788 33.23673,0 0.18303,-0.169745 0.18055,-0.163774 -0.005,-0.331246 -5.75329,-5.664436 -11.39834,-8.416392 -16.93902,-8.371065 z"
inkscape:label="outer"
sodipodi:nodetypes="sccccss" />
<ellipse
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.0723045"
id="ellipse4"
inkscape:label="pupil"
ry="1.7112623"
rx="1.9444314"
cy="72.71582"
cx="160.92181" />
</g>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-20.738154,-52.70636)">
<rect
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.499999"
id="rect1"
width="101.46883"
height="146.27805"
x="21.108479"
y="52.95636"
ry="0"
inkscape:label="receipt" />
<path
style="fill:#ee0000;fill-opacity:0.51545;stroke:none;stroke-width:0.499999"
d="M 20.738154,121.46633 160.93664,72.756923 122.6633,120.9805 Z"
id="path1"
sodipodi:nodetypes="cccc"
inkscape:label="scan_ray" />
<text
xml:space="preserve"
style="font-size:13.7201px;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.16063"
x="47.53178"
y="66.945511"
id="text2"
inkscape:label="receipt text"><tspan
sodipodi:role="line"
style="fill:#000000;fill-opacity:1;stroke-width:2.16064"
x="47.53178"
y="66.945511"
id="tspan3">Receipt</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.2 KiB

181
assets/icons/OFD.svg Normal file
View File

@ -0,0 +1,181 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="180.75754mm"
height="172.34297mm"
viewBox="0 0 180.75754 172.34297"
version="1.1"
id="svg1"
inkscape:version="1.4 (e7c3feb100, 2024-10-09)"
sodipodi:docname="OFD.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
inkscape:zoom="1.0104048"
inkscape:cx="241.98222"
inkscape:cy="365.20017"
inkscape:window-width="1920"
inkscape:window-height="1029"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs1">
<marker
style="overflow:visible"
id="marker13"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Wide arrow"
markerWidth="1"
markerHeight="1"
viewBox="0 0 1 1"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
style="fill:none;stroke:context-stroke;stroke-width:1;stroke-linecap:butt"
d="M 3,-3 0,0 3,3"
transform="rotate(180,0.125,0)"
sodipodi:nodetypes="ccc"
id="path13" />
</marker>
<marker
style="overflow:visible"
id="ArrowWide"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Wide arrow"
markerWidth="1"
markerHeight="1"
viewBox="0 0 1 1"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
style="fill:none;stroke:context-stroke;stroke-width:1;stroke-linecap:butt"
d="M 3,-3 0,0 3,3"
transform="rotate(180,0.125,0)"
sodipodi:nodetypes="ccc"
id="path1" />
</marker>
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-12.622354,-8.2059073)">
<g
id="g3"
inkscape:label="laptop"
transform="translate(3.1423049,5.2371749)">
<rect
style="fill:#ffffff;stroke:#000000;stroke-width:4;stroke-dasharray:none;stroke-opacity:1;fill-opacity:1"
id="rect1"
width="83.00206"
height="51.927536"
x="12.220698"
y="109.98628"
ry="2.8804462" />
<rect
style="fill:#ffffff;stroke:#000000;stroke-width:4;stroke-dasharray:none"
id="rect2"
width="85.730049"
height="4.8142142"
x="11.480049"
y="168.4975"
ry="2.4071071" />
<rect
style="fill:#ffffff;stroke:#000000;stroke-width:0;stroke-dasharray:none"
id="rect3"
width="8.389514"
height="1.2071242"
x="49.959942"
y="161.32069"
ry="0.60356212" />
</g>
<path
id="rect5"
style="fill:#ffffff;stroke:#000000;stroke-width:1.77913;stroke-dasharray:none"
d="m 135.00181,57.565658 c -1.57959,0 -2.85099,1.271404 -2.85099,2.850988 v 8.277531 c 0,1.579585 1.2714,2.851506 2.85099,2.851506 h 26.56478 v 3.891752 h -26.56478 c -1.57959,0 -2.85099,1.271404 -2.85099,2.850989 v 8.277531 c 0,1.579586 1.2714,2.851506 2.85099,2.851506 h 26.56478 v 3.575495 h -26.56478 c -1.57959,0 -2.85099,1.27141 -2.85099,2.85099 v 8.277534 c 0,1.57959 1.2714,2.85151 2.85099,2.85151 h 26.56478 v 7.61504 a 4.0588107,4.0588107 0 0 0 -1.20923,0.30489 4.0588107,4.0588107 0 0 0 -2.42569,3.32434 h -23.53344 c -1.66831,0 -3.01119,0.24778 -3.01119,0.55552 0,0.30774 1.34288,0.55552 3.01119,0.55552 h 23.57478 a 4.0588107,4.0588107 0 0 0 0.25477,0.88936 l 0.0114,0.0269 a 4.0588107,4.0588107 0 0 0 5.33611,2.10065 4.0588107,4.0588107 0 0 0 2.38073,-3.01688 h 23.52311 c 1.6683,0 3.01119,-0.24778 3.01119,-0.55552 0,-0.30774 -1.34289,-0.55552 -3.01119,-0.55552 h -23.48177 a 4.0588107,4.0588107 0 0 0 -0.31161,-1.20406 4.0588107,4.0588107 0 0 0 -3.20239,-2.40864 v -7.63157 h 26.2816 c 1.57959,0 2.85099,-1.27192 2.85099,-2.85151 v -8.277534 c 0,-1.57958 -1.2714,-2.85099 -2.85099,-2.85099 h -26.2816 v -3.575495 h 26.2816 c 1.57959,0 2.85099,-1.27192 2.85099,-2.851506 v -8.277531 c 0,-1.579585 -1.2714,-2.850989 -2.85099,-2.850989 h -26.2816 v -3.891752 h 26.2816 c 1.57959,0 2.85099,-1.271921 2.85099,-2.851506 v -8.277561 c 0,-1.579584 -1.2714,-2.850988 -2.85099,-2.850988 z"
inkscape:label="OFD" />
<path
id="path9"
style="fill:#ffffff;stroke:#000000;stroke-width:1.77913;stroke-dasharray:none"
d="m 34.83473,9.0954723 c -1.57959,0 -2.85099,1.2714037 -2.85099,2.8509877 v 8.277531 c 0,1.579585 1.2714,2.851506 2.85099,2.851506 h 26.56478 v 3.891752 H 34.83473 c -1.57959,0 -2.85099,1.271404 -2.85099,2.850989 v 8.277531 c 0,1.579586 1.2714,2.851506 2.85099,2.851506 H 61.39951 V 44.52277 H 34.83473 c -1.57959,0 -2.85099,1.27141 -2.85099,2.85099 v 8.27753 c 0,1.57959 1.2714,2.85151 2.85099,2.85151 h 26.56478 v 7.61504 a 4.0588107,4.0588107 0 0 0 -1.20923,0.30489 4.0588107,4.0588107 0 0 0 -2.42569,3.32434 H 34.23115 c -1.66831,0 -3.01119,0.24778 -3.01119,0.55552 0,0.30774 1.34288,0.55552 3.01119,0.55552 h 23.57478 a 4.0588107,4.0588107 0 0 0 0.25477,0.88936 l 0.0114,0.0269 a 4.0588107,4.0588107 0 0 0 5.33611,2.10065 4.0588107,4.0588107 0 0 0 2.38073,-3.01688 h 23.523106 c 1.6683,0 3.01119,-0.24778 3.01119,-0.55552 0,-0.30774 -1.34289,-0.55552 -3.01119,-0.55552 H 65.83028 A 4.0588107,4.0588107 0 0 0 65.51867,68.54304 4.0588107,4.0588107 0 0 0 62.31628,66.1344 v -7.63157 h 26.281596 c 1.57959,0 2.85099,-1.27192 2.85099,-2.85151 v -8.27753 c 0,-1.57958 -1.2714,-2.85099 -2.85099,-2.85099 H 62.31628 v -3.575495 h 26.281596 c 1.57959,0 2.85099,-1.27192 2.85099,-2.851506 v -8.277531 c 0,-1.579585 -1.2714,-2.850989 -2.85099,-2.850989 H 62.31628 v -3.891752 h 26.281596 c 1.57959,0 2.85099,-1.271921 2.85099,-2.851506 V 11.94646 c 0,-1.579584 -1.2714,-2.8509877 -2.85099,-2.8509877 z"
inkscape:label="FNS" />
<g
id="g13"
inkscape:label="two arrows">
<path
style="fill:#ffffff;stroke:#000000;stroke-width:1.5;stroke-dasharray:none;marker-start:url(#ArrowWide)"
d="m 100.17269,112.57855 25.9227,-13.146507 z"
id="path10" />
<path
style="fill:#ffffff;stroke:#000000;stroke-width:1.5;stroke-dasharray:none;marker-end:url(#marker13)"
d="m 128.92299,105.88982 -25.9227,13.14651 z"
id="path10-5" />
</g>
<text
xml:space="preserve"
style="font-size:13.7103px;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;stroke:none;stroke-width:1;stroke-dasharray:none;fill-opacity:1"
x="144.47009"
y="86.974228"
id="text10"><tspan
sodipodi:role="line"
id="tspan10"
style="stroke-width:1;stroke-dasharray:none;stroke:none;fill:#000000;fill-opacity:1"
x="144.47009"
y="86.974228">ofd.ru</tspan></text>
<text
xml:space="preserve"
style="font-size:13.3232px;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;stroke:none;stroke-width:1;stroke-dasharray:none;fill-opacity:1"
x="46.742268"
y="38.150463"
id="text11"><tspan
sodipodi:role="line"
id="tspan11"
style="stroke-width:1;stroke-dasharray:none;stroke:none;fill:#000000;fill-opacity:1"
x="46.742268"
y="38.150463">ФНС</tspan></text>
<g
id="g15"
inkscape:label="two arrows"
transform="rotate(45.923414,168.3245,81.037241)">
<path
style="fill:#ffffff;stroke:#000000;stroke-width:1.5;stroke-dasharray:none;marker-start:url(#ArrowWide)"
d="m 100.17269,112.57855 25.9227,-13.146507 z"
id="path14" />
<path
style="fill:#ffffff;stroke:#000000;stroke-width:1.5;stroke-dasharray:none;marker-end:url(#marker13)"
d="m 128.92299,105.88982 -25.9227,13.14651 z"
id="path15" />
</g>
<text
xml:space="preserve"
style="font-size:11.8523px;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;stroke:none;stroke-width:1;stroke-dasharray:none;fill-opacity:1"
x="18.578594"
y="144.58119"
id="text15"><tspan
sodipodi:role="line"
id="tspan15"
style="stroke-width:1;stroke-dasharray:none;fill:#000000;fill-opacity:1;stroke:none"
x="18.578594"
y="144.58119">Checks parser</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.7 KiB

285
assets/icons/email-text.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 27 KiB

View File

@ -0,0 +1,219 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="182.87955mm"
height="144.54501mm"
viewBox="0 0 182.87955 144.54501"
version="1.1"
id="svg1"
xml:space="preserve"
inkscape:version="1.4 (e7c3feb100, 2024-10-09)"
sodipodi:docname="using_binary_eye.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
inkscape:zoom="0.5052024"
inkscape:cx="555.22302"
inkscape:cy="211.7963"
inkscape:window-width="1920"
inkscape:window-height="1029"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:current-layer="g3" /><defs
id="defs1"><marker
style="overflow:visible"
id="ArrowWide"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Wide arrow"
markerWidth="1"
markerHeight="1"
viewBox="0 0 1 1"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid"><path
style="fill:none;stroke:context-stroke;stroke-width:1;stroke-linecap:butt"
d="M 3,-3 0,0 3,3"
transform="rotate(180,0.125,0)"
sodipodi:nodetypes="ccc"
id="path1" /></marker><marker
style="overflow:visible"
id="marker13"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Wide arrow"
markerWidth="1"
markerHeight="1"
viewBox="0 0 1 1"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid"><path
style="fill:none;stroke:context-stroke;stroke-width:1;stroke-linecap:butt"
d="M 3,-3 0,0 3,3"
transform="rotate(180,0.125,0)"
sodipodi:nodetypes="ccc"
id="path13" /></marker></defs><g
inkscape:label="Phone"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-25.853363,-48.893891)"><rect
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-opacity:1"
id="rect1"
width="57.029922"
height="97.02494"
x="26.353363"
y="95.913963"
rx="7.7330093"
ry="7.3138995"
inkscape:label="border" /><g
id="g1837"
inkscape:label="binary eye logo"
transform="translate(-69.392567,-90.079408)"><circle
r="23.283333"
cy="234.73807"
cx="123.78944"
id="circle-1"
style="fill:#a6c45f;fill-opacity:1;stroke:none;stroke-width:1.05833;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /><circle
style="fill:#b6d46f;fill-opacity:1;stroke:none;stroke-width:1.05833;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="circle-2"
cx="123.78944"
cy="234.20889"
r="23.283333" /><path
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:0.12549;fill-rule:nonzero;stroke:none;stroke-width:2.27733;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 124.32389,217.397 c -4.43071,0 -8.86142,1.68857 -12.2391,5.06624 -6.7556,6.75587 -6.7556,17.72311 0,24.47872 l 10.48915,10.48941 c 0.40454,0.0307 0.80989,0.0511 1.21549,0.0609 12.85901,0 23.28333,-10.42432 23.28333,-23.28333 -0.003,-0.42731 -0.0185,-0.85461 -0.0455,-1.28112 l -10.46453,-10.46453 c -3.37767,-3.37767 -7.80838,-5.06624 -12.23883,-5.06624 z"
id="path-1" /><circle
r="17.155054"
cy="234.55074"
cx="124.12916"
id="circle-3"
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.05833;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /><path
d="m 136.31216,234.55073 c 0,2.98132 -1.07077,5.71262 -2.84903,7.83008 v -15.66016 c 1.77826,2.11746 2.84903,4.84875 2.84903,7.83008 z m -12.183,12.183 c -0.34925,0 -0.69506,-0.0148 -1.0369,-0.0434 v -24.27922 c 0.34184,-0.0286 0.68765,-0.0434 1.0369,-0.0434 0.34925,0 0.69506,0.0148 1.0369,0.0434 v 24.27922 c -0.34184,0.0286 -0.68765,0.0434 -1.0369,0.0434 z m -12.18301,-12.183 c 0,-2.98133 1.07077,-5.71262 2.84904,-7.83008 v 15.66016 c -1.77827,-2.11746 -2.84904,-4.84876 -2.84904,-7.83008 z m 17.36858,11.02757 c -0.6612,0.31141 -1.35494,0.56515 -2.0746,0.75459 v -23.56432 c 0.71966,0.18944 1.4134,0.44317 2.0746,0.75459 z m -8.29707,0.75459 c -1.51898,-0.40005 -2.92206,-1.08612 -4.14788,-1.99708 v -19.57017 c 1.22582,-0.91096 2.6289,-1.59702 4.14788,-1.99707 z"
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.05833;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="circle-6" /></g></g><g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="QR code"
transform="translate(-30.254583,-85.236427)"><rect
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-opacity:1"
id="rect1837"
width="14.072319"
height="14.072319"
x="42.246078"
y="85.736427"
rx="0"
ry="0" /><rect
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.484034;stroke-opacity:1"
id="rect1838"
width="6.8114772"
height="6.8114772"
x="45.876503"
y="89.366852"
rx="0"
ry="0" /><rect
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-opacity:1"
id="rect1839"
width="14.072319"
height="14.072319"
x="62.243584"
y="85.736427"
rx="0"
ry="0" /><rect
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.484034;stroke-opacity:1"
id="rect1840"
width="6.8114772"
height="6.8114772"
x="65.874008"
y="89.366852"
rx="0"
ry="0" /><rect
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-opacity:1"
id="rect1841"
width="14.072319"
height="14.072319"
x="42.246078"
y="105.54877"
rx="0"
ry="0" /><rect
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.484034;stroke-opacity:1"
id="rect1842"
width="6.8114772"
height="6.8114772"
x="45.876503"
y="109.17919"
rx="0"
ry="0" /><rect
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.484034;stroke-opacity:1"
id="rect1844"
width="6.8114772"
height="6.8114772"
x="61.846733"
y="105.52224"
rx="0"
ry="0" /><rect
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.484034;stroke-opacity:1"
id="rect1845"
width="6.8114772"
height="6.8114772"
x="69.130707"
y="112.81159"
rx="0"
ry="0" /><g
id="g3"
inkscape:label="laptop"
transform="translate(82.762838,125.57409)"><rect
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:4;stroke-dasharray:none;stroke-opacity:1"
id="rect1-6"
width="83.00206"
height="51.927536"
x="43.381889"
y="35.094681"
ry="2.8804462" /><rect
style="fill:#ffffff;stroke:#000000;stroke-width:4;stroke-dasharray:none"
id="rect2"
width="85.730049"
height="4.8142142"
x="42.641239"
y="93.605896"
ry="2.4071071" /><rect
style="fill:#ffffff;stroke:#000000;stroke-width:0;stroke-dasharray:none"
id="rect3"
width="8.389514"
height="1.2071242"
x="81.12114"
y="86.429092"
ry="0.60356212" /><g
id="g1"
transform="translate(27.69601,-81.170421)"><text
xml:space="preserve"
style="font-size:11.8523px;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1;stroke-dasharray:none"
x="18.578594"
y="144.58119"
id="text15"><tspan
sodipodi:role="line"
id="tspan15"
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:1;stroke-dasharray:none"
x="18.578594"
y="144.58119">Checks parser</tspan></text></g><g
id="g13"
inkscape:label="two arrows"
transform="rotate(30,151.73824,-82.354999)"><path
style="fill:#ffffff;stroke:#000000;stroke-width:1.5;stroke-dasharray:none;marker-start:url(#ArrowWide)"
d="m 100.17269,112.57855 25.9227,-13.146507 z"
id="path10" /><path
style="fill:#ffffff;stroke:#000000;stroke-width:1.5;stroke-dasharray:none;marker-end:url(#marker13)"
d="m 128.92299,105.88982 -25.9227,13.14651 z"
id="path10-5" /></g></g></g></svg>

After

Width:  |  Height:  |  Size: 9.9 KiB

View File

@ -5,10 +5,16 @@ Check::Check() {}
void Check::add_goods(Goods goods) { this->goods.push_back(goods); }
void Check::add_goods(std::vector<Goods> &goods) {
for (auto g : goods) {
this->goods.push_back(g);
}
}
double Check::calculae_total_price() {
double total = 0.0;
for (Goods g : this->goods) {
for (Goods &g : goods) {
total += g.calculate_total_price();
}

View File

@ -9,6 +9,7 @@ class Check {
public:
Check();
void add_goods(Goods);
void add_goods(std::vector<Goods> &goods);
double calculae_total_price();

45
emailtextscene.cpp Normal file
View File

@ -0,0 +1,45 @@
#include "emailtextscene.h"
#include "ui_emailtextscene.h"
#include <QMessageBox>
#include <iostream>
#include <outputdialog.h>
#include <check/check.h>
EmailTextScene::EmailTextScene(QWidget *parent)
: QWidget(parent)
, ui(new Ui::EmailTextScene) {
ui->setupUi(this);
auto modules = parser.get_modules_names();
for (auto &module : modules) {
ui->store_combo_box->addItem(QString::fromStdString(module));
}
}
EmailTextScene::~EmailTextScene() {
delete ui;
}
void EmailTextScene::on_parse_button_clicked() {
std::wstring checkContent = ui->check_content->toPlainText().toStdWString();
parser.set_module(parser.search_modules()[ui->store_combo_box->currentIndex()]);
std::vector<Goods> goods = parser.parse(checkContent);
if (goods.size() == 0) {
QMessageBox infoDialog;
infoDialog.setText(tr("An error has occured. Check was matched incorrectly. Vector sizes are different. Please, contact the developer."));
infoDialog.setIcon(QMessageBox::Critical);
infoDialog.setWindowTitle(tr("Error in parsing"));
infoDialog.exec();
return;
}
Check check;
check.add_goods(goods);
OutputDialog d(this, check);
d.show();
d.exec();
}

27
emailtextscene.h Normal file
View File

@ -0,0 +1,27 @@
#ifndef EMAILTEXTSCENE_H
#define EMAILTEXTSCENE_H
#include "parser/parser.h"
#include <QWidget>
namespace Ui {
class EmailTextScene;
}
class EmailTextScene : public QWidget
{
Q_OBJECT
public:
explicit EmailTextScene(QWidget *parent = nullptr);
~EmailTextScene();
private slots:
void on_parse_button_clicked();
private:
Ui::EmailTextScene *ui;
Parser parser;
};
#endif // EMAILTEXTSCENE_H

View File

@ -1,7 +1,6 @@
#include <opencv2/imgcodecs.hpp>
#include <string>
#include <tesseract/baseapi.h>
#include <leptonica/allheaders.h>
#include <opencv2/opencv.hpp>
#include "checkimage.h"
CheckImage::CheckImage(std::string path) {

172
main.cpp
View File

@ -12,20 +12,162 @@
# include <filesystem>
using namespace std::filesystem;
#endif
#include <QDateTime>
#include <QFile>
#include <QStackedLayout>
#include <QTextStream>
#include <QTranslator>
#include <emailtextscene.h>
#include <ocrscene.h>
#include <ofdscene.h>
#include <qpushbutton.h>
#include <parser/parser.h>
static QWidget *loadUI(QWidget *parent, std::string filename) {
QUiLoader loader;
QFile file(QString::fromStdString(filename));
file.open(QIODevice::ReadOnly);
return loader.load(&file, parent);
}
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");
create_directories(program_data_path);
QApplication app(argc, argv);
std::string settings_file_path =
get_path_relative_to_home(".local/share/checks_parser/settings.json");
Settings s(settings_file_path);
QTranslator translator;
QString lang = "en_US";
if (s.get_all_settings().contains("language")) {
lang = QString::fromStdString(s.get_all_settings()["language"]);
} else if (translator.load(":/translation/"+QLocale::system().name()+".qm")) {
lang = QLocale::system().name();
} else {
lang = QString::fromStdString("en_US");
}
std::cout << "Using locale: " << lang.toStdString() << std::endl;
translator.load(":/translation/" + lang + ".qm");
app.installTranslator(&translator);
QUiLoader loader;
QWidget *window = new QWidget();
QStackedLayout *sceneLayout = new QStackedLayout;
// Main Window setup
QWidget *mainwindowscene = loadUI(window, ":/scenes/scenes/mainwindow.ui");
// Main Window buttons setup
QPushButton *text_from_email_button = ((MainWindow *)mainwindowscene)->findChild<QPushButton *>("text_from_email_button");
QPushButton *ocr_button = ((MainWindow *)mainwindowscene)->findChild<QPushButton *>("ocr_button");
QPushButton *ofd_button = ((MainWindow *)mainwindowscene)->findChild<QPushButton *>("ofd_button");
QObject::connect(text_from_email_button, &QPushButton::clicked, [&]() {
// Text from email scene
sceneLayout->setCurrentIndex(1);
sceneLayout->widget(1)->show();
});
QObject::connect(ocr_button, &QPushButton::clicked, [&]() {
// OCR scene
sceneLayout->setCurrentIndex(2);
sceneLayout->widget(2)->show();
});
QObject::connect(ofd_button, &QPushButton::clicked, [&]() {
// OFD scene
sceneLayout->setCurrentIndex(3);
sceneLayout->widget(3)->show();
});
EmailTextScene *emailTextScene = new EmailTextScene();
OCRScene *ocrscene = new OCRScene();
OFDScene *ofdscene = new OFDScene();
// ofdscene->startHttpServer();
// get_local_ip_address();
sceneLayout->addWidget(mainwindowscene);
sceneLayout->addWidget(emailTextScene);
sceneLayout->addWidget(ocrscene);
sceneLayout->addWidget(ofdscene);
//Setting all back buttons
for (uint32_t sceneIndex = 0; sceneIndex < sceneLayout->count(); sceneIndex ++) {
auto scene = sceneLayout->widget(sceneIndex);
QPushButton *back_button = scene->findChild<QPushButton *>("back_button");
if (back_button == nullptr) continue;
QObject::connect(back_button, &QPushButton::clicked, [&]() {
sceneLayout->setCurrentIndex(0);
});
}
window->setLayout(sceneLayout);
window->show();
app.exec();
return 0;
// QApplication app(argc, argv);
// QWidget *window = new QWidget;
// QStackedLayout *stackedLayout = new QStackedLayout;
// QWidget *scene1 = new QWidget;
// QWidget *scene2 = new QWidget;
// // Add some widgets to each scene
// QPushButton *button1 = new QPushButton("Switch to Scene 2");
// scene1->setLayout(new QVBoxLayout);
// scene1->layout()->addWidget(button1);
// QPushButton *button2 = new QPushButton("Switch to Scene 1");
// scene2->setLayout(new QVBoxLayout);
// scene2->layout()->addWidget(button2);
// // Add the scenes to the stacked layout
// stackedLayout->addWidget(scene1);
// stackedLayout->addWidget(scene2);
// // Set the layout of the window
// window->setLayout(stackedLayout);
// // Connect the buttons to switch scenes
// QObject::connect(button1, &QPushButton::clicked, [&]() {
// stackedLayout->setCurrentIndex(1);
// });
// QObject::connect(button2, &QPushButton::clicked, [&]() {
// stackedLayout->setCurrentIndex(0);
// });
// window->show();
// app.exec();
// return 0;
curl_global_init(CURL_GLOBAL_ALL);
std::string program_data_path = get_path_relative_to_home(".local/share/checks_parser");
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);
Net n;
Parser p;
@ -44,22 +186,22 @@ int main(int argc, char *argv[]) {
QApplication a(argc, argv);
QTranslator translator;
QString lang = "en_US";
// QTranslator translator;
// QString lang = "en_US";
if (s.get_all_settings().contains("language")) {
lang = QString::fromStdString(s.get_all_settings()["language"]);
} else if (translator.load(":/translation/"+QLocale::system().name()+".qm")) {
lang = QLocale::system().name();
} else {
lang = QString::fromStdString("en_US");
}
// if (s.get_all_settings().contains("language")) {
// lang = QString::fromStdString(s.get_all_settings()["language"]);
// } else if (translator.load(":/translation/"+QLocale::system().name()+".qm")) {
// lang = QLocale::system().name();
// } else {
// lang = QString::fromStdString("en_US");
// }
std::cout << "Using locale: " << lang.toStdString() << std::endl;
// std::cout << "Using locale: " << lang.toStdString() << std::endl;
translator.load(":/translation/" + lang + ".qm");
// translator.load(":/translation/" + lang + ".qm");
a.installTranslator(&translator);
// a.installTranslator(&translator);
MainWindow w;
w.update();
w.show();

View File

@ -1,219 +1,15 @@
#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 "solvecaptchadialog.h"
#include <QFileDialog>
#include <QMessageBox>
#include "image/checkimage.h"
#include "utils/utils.h"
#include <opencv2/objdetect.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <zbar.h>
#include "ui_mainwindow.h"
#include <iostream>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), ui(new Ui::MainWindow) {
: QWidget(parent)
, ui(new Ui::MainWindow) {
ui->setupUi(this);
this->setupStoresList();
std::cout << "test" << std::endl;
}
MainWindow::~MainWindow() { delete ui; }
void MainWindow::setupStoresList() {
parser = *(new Parser());
std::vector<std::string> modules_names = parser.search_modules();
for (std::string name : modules_names) {
StoreModule m(name);
std::wstring module_name = m.get_name();
QString s = QString::fromStdWString(module_name);
ui->storeType->addItem(s);
}
MainWindow::~MainWindow() {
delete ui;
}
std::string MainWindow::makeRequestToOfd(std::string captcha) {
std::string checkContent = Net().fetch_check_data_from_ofdru(
ui->fn_edit->text().toStdString(),
ui->fd_edit->text().toStdString(),
ui->fi_edit->text().toStdString(),
ui->dateTimeEdit->dateTime().toString(Qt::ISODate).toStdString(),
ui->fundIncomeCombo->currentIndex() + 1,
// In the request to ofd.ru, total is in a strange format, like a string of a format where 2 last digits represent decimal part of a number.
ui->total_edit->text().toDouble() * 100,
captcha);
return checkContent;
}
void MainWindow::on_parseButton_clicked() {
QString s;
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(), "Internal server error")) {
QMessageBox infoDialog;
infoDialog.setText(tr("Internal server error. Please, try again later."));
infoDialog.setIcon(QMessageBox::Critical);
infoDialog.setWindowTitle(tr("Internal server error"));
infoDialog.exec();
return;
} 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();
parser.set_module(parser.search_modules()[0]);
std::vector<Goods> c = parser.parse(check_plaintext);
if (c.size() == 0) {
QMessageBox infoDialog;
infoDialog.setText(tr("An error has occured. Check was matched incorrectly. Vector sizes are different. Please, contact the developer."));
infoDialog.setIcon(QMessageBox::Critical);
infoDialog.setWindowTitle(tr("Error in parsing"));
infoDialog.exec();
return;
}
for (auto& g : c) {
check.add_goods(g);
}
OutputDialog d = OutputDialog(this, check);
d.show();
d.exec();
}
void MainWindow::on_storeType_currentIndexChanged(int index) {
std::string module = parser.search_modules()[index];
parser.set_module(module);
}
void MainWindow::on_preferencesButton_clicked() {
SettingsDialog s = SettingsDialog();
s.show();
s.exec();
}
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));
AdjustPictureDialog dialog = AdjustPictureDialog(this, filename.toStdString());
connect(&dialog, &AdjustPictureDialog::decodedData, this, &MainWindow::onDecodedData);
dialog.exec();
ui->picture_ofd->setPixmap(QPixmap(filename));
ui->picture_ofd->setScaledContents(true);
}
void MainWindow::onDecodedData(std::string data) {
std::string delimiter = "&";
std::vector<std::string> dataSplit = split(data, delimiter);
std::cout << data << std::endl;
ui->fn_edit->setText(QString::fromStdString(dataSplit[2]));
ui->fd_edit->setText(QString::fromStdString(dataSplit[3]));
ui->fi_edit->setText(QString::fromStdString(dataSplit[4]));
QString extractedDateTime = QString::fromStdString(split(dataSplit[0], "=")[1]);
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));
CheckImage i(filename.toStdString());
std::string parsed = i.parse_text();
ui->picture_ocr->setPixmap(QPixmap(filename));
ui->picture_ocr->setScaledContents(true);
ui->checkContentFromImage->setPlainText(QString::fromStdString(parsed));
}

219
mainwindow.cpp.old Normal file
View File

@ -0,0 +1,219 @@
#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 "solvecaptchadialog.h"
#include <QFileDialog>
#include <QMessageBox>
#include "image/checkimage.h"
#include "utils/utils.h"
#include <opencv2/objdetect.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <zbar.h>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), ui(new Ui::MainWindow) {
ui->setupUi(this);
// this->setupStoresList();
}
MainWindow::~MainWindow() { delete ui; }
// void MainWindow::setupStoresList() {
// parser = *(new Parser());
// std::vector<std::string> modules_names = parser.search_modules();
// for (std::string name : modules_names) {
// StoreModule m(name);
// std::wstring module_name = m.get_name();
// 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);
// return checkContent;
// }
// void MainWindow::on_parseButton_clicked() {
// QString s;
// 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(), "Internal server error")) {
// QMessageBox infoDialog;
// infoDialog.setText(tr("Internal server error. Please, try again later."));
// infoDialog.setIcon(QMessageBox::Critical);
// infoDialog.setWindowTitle(tr("Internal server error"));
// infoDialog.exec();
// return;
// } 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();
// parser.set_module(parser.search_modules()[0]);
// std::vector<Goods> c = parser.parse(check_plaintext);
// if (c.size() == 0) {
// QMessageBox infoDialog;
// infoDialog.setText(tr("An error has occured. Check was matched incorrectly. Vector sizes are different. Please, contact the developer."));
// infoDialog.setIcon(QMessageBox::Critical);
// infoDialog.setWindowTitle(tr("Error in parsing"));
// infoDialog.exec();
// return;
// }
// for (auto& g : c) {
// check.add_goods(g);
// }
// OutputDialog d = OutputDialog(this, check);
// d.show();
// d.exec();
// }
// void MainWindow::on_storeType_currentIndexChanged(int index) {
// std::string module = parser.search_modules()[index];
// parser.set_module(module);
// }
// void MainWindow::on_preferencesButton_clicked() {
// SettingsDialog s = SettingsDialog();
// s.show();
// s.exec();
// }
// 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));
// AdjustPictureDialog dialog = AdjustPictureDialog(this, filename.toStdString());
// connect(&dialog, &AdjustPictureDialog::decodedData, this, &MainWindow::onDecodedData);
// dialog.exec();
// ui->picture_ofd->setPixmap(QPixmap(filename));
// ui->picture_ofd->setScaledContents(true);
// }
// void MainWindow::onDecodedData(std::string data) {
// std::string delimiter = "&";
// std::vector<std::string> dataSplit = split(data, delimiter);
// std::cout << data << std::endl;
// ui->fn_edit->setText(QString::fromStdString(dataSplit[2]));
// ui->fd_edit->setText(QString::fromStdString(dataSplit[3]));
// ui->fi_edit->setText(QString::fromStdString(dataSplit[4]));
// QString extractedDateTime = QString::fromStdString(split(dataSplit[0], "=")[1]);
// 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));
// CheckImage i(filename.toStdString());
// std::string parsed = i.parse_text();
// ui->picture_ocr->setPixmap(QPixmap(filename));
// ui->picture_ocr->setScaledContents(true);
// ui->checkContentFromImage->setPlainText(QString::fromStdString(parsed));
// }

View File

@ -1,44 +1,25 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QWidget>
#include <qevent.h>
#include <QtUiTools/quiloader.h>
#include "check/check.h"
#include "parser/parser.h"
QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE
class MainWindow : public QMainWindow {
class MainWindow : public QWidget
{
Q_OBJECT
Check check;
Parser parser;
public:
MainWindow(QWidget *parent = nullptr);
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
void setupStoresList();
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_preferencesButton_clicked();
void on_chooseImageButton_ofd_clicked();
void on_chooseImageButton_ocr_clicked();
private:
Ui::MainWindow *ui;
private slots:
private:
};
#endif // MAINWINDOW_H

44
mainwindow.h.old Normal file
View File

@ -0,0 +1,44 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "check/check.h"
#include "parser/parser.h"
QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE
class MainWindow : public QMainWindow {
Q_OBJECT
Check check;
Parser parser;
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
// void setupStoresList();
// 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_preferencesButton_clicked();
// void on_chooseImageButton_ofd_clicked();
// void on_chooseImageButton_ocr_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

7
media.qrc Normal file
View File

@ -0,0 +1,7 @@
<RCC>
<qresource prefix="/icons">
<file>assets/icons/email-text.svg</file>
<file>assets/icons/OCR.svg</file>
<file>assets/icons/OFD.svg</file>
</qresource>
</RCC>

73
ocrscene.cpp Normal file
View File

@ -0,0 +1,73 @@
#include "ocrscene.h"
#include "ui_ocrscene.h"
#include <QFileDialog>
#include <QMessageBox>
#include <outputdialog.h>
#include <image/checkimage.h>
#include <check/check.h>
OCRScene::OCRScene(QWidget *parent)
: QWidget(parent)
, ui(new Ui::OCRScene) {
ui->setupUi(this);
auto modules = parser.get_modules_names();
for (auto &module : modules) {
ui->store_combo_box->addItem(QString::fromStdString(module));
}
}
OCRScene::~OCRScene() {
delete ui;
}
void OCRScene::on_parse_button_clicked() {
std::wstring checkContent = ui->check_text_edit->toPlainText().toStdWString();
parser.set_module(parser.search_modules()[ui->store_combo_box->currentIndex()]);
std::vector<Goods> goods = parser.parse(checkContent);
if (goods.size() == 0) {
QMessageBox infoDialog;
infoDialog.setText(tr("An error has occured. Check was matched incorrectly. Vector sizes are different. Please, contact the developer."));
infoDialog.setIcon(QMessageBox::Critical);
infoDialog.setWindowTitle(tr("Error in parsing"));
infoDialog.exec();
return;
}
Check check;
check.add_goods(goods);
OutputDialog d(this, check);
d.show();
d.exec();
}
void OCRScene::on_choose_image_button_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->path_to_image_label->setText(tr("Path to image: ")+ filename);
CheckImage i(filename.toStdString());
std::string parsed = i.parse_text();
ui->check_text_edit->setPlainText(QString::fromStdString(parsed));
}

29
ocrscene.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef OCRSCENE_H
#define OCRSCENE_H
#include "parser/parser.h"
#include <QWidget>
namespace Ui {
class OCRScene;
}
class OCRScene : public QWidget
{
Q_OBJECT
public:
explicit OCRScene(QWidget *parent = nullptr);
~OCRScene();
private slots:
void on_parse_button_clicked();
void on_choose_image_button_clicked();
private:
Ui::OCRScene *ui;
Parser parser;
};
#endif // OCRSCENE_H

150
ofdscene.cpp Normal file
View File

@ -0,0 +1,150 @@
#include "ofdscene.h"
#include "ui_ofdscene.h"
#include "utils/utils.h"
#include <QFileDialog>
#include <QMessageBox>
#include <adjustpicturedialog.h>
#include <httplib.h>
#include <outputdialog.h>
#include <solvecaptchadialog.h>
#include <net/net.h>
#include <exceptions/ofdrequestexception.h>
OFDScene::OFDScene(QWidget *parent)
: QWidget(parent)
, ui(new Ui::OFDScene) {
ui->setupUi(this);
}
OFDScene::~OFDScene() {
delete ui;
}
void OFDScene::startHttpServer() {
std::string localIp = "";
try {
localIp = get_local_ip_address();
} catch(std::exception e) {
std::cerr << e.what() << std::endl;
return;
}
httplib::Server svr;
//TODO: generate random port from 1024 to 65535 and check if its used.
svr.Get("/", [&](const httplib::Request &, httplib::Response &res){
res.set_redirect("http://"+ localIp +":8080/", 301);
});
svr.listen("0.0.0.0", 8080);
}
void OFDScene::on_choose_image_button_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;
}
ui->info_label->setText(tr("Selected image: ") + filename);
AdjustPictureDialog dialog = AdjustPictureDialog(this, filename.toStdString());
connect(&dialog, &AdjustPictureDialog::decodedData, this, &OFDScene::onDataDecode);
dialog.exec();
}
void OFDScene::onDataDecode(std::string data) {
std::vector<std::string> dataSplit = split(data, "&");
ui->fn_line_edit->setText(QString::fromStdString(split(dataSplit[2], "=")[1]));
ui->fd_line_edit->setText(QString::fromStdString(split(dataSplit[3], "=")[1]));
ui->fi_line_edit->setText(QString::fromStdString(split(dataSplit[4], "=")[1]));
QString extractedDateTime = QString::fromStdString(split(dataSplit[0], "=")[1]);
//TODO: some QRs contain datetime in format yyyyMMddThhmmss. Perhaps there is more different formats, should write function to detect them.
QDateTime datetime = QDateTime::fromString(extractedDateTime, "yyyyMMddThhmm");
ui->purchase_datetime_edit->setDateTime(datetime);
int type = std::stoi(split(dataSplit[5], "=")[1]);
ui->operation_type_combo_box->setCurrentIndex(type - 1);
std::string total = split(dataSplit[1], "=")[1];
ui->total_spin_box->setValue(std::stod(total));
}
void OFDScene::on_parse_button_clicked() {
Net net;
net.get_captcha_from_ofdru();
std::string solved_captcha = "";
bool success = true;
bool is_captcha_solved = true;
Check check;
do {
SolveCaptchaDialog dialog = SolveCaptchaDialog(this, &solved_captcha);
dialog.exec();
is_captcha_solved = true;
try {
std::string check_content = net.fetch_check_data_from_ofdru(
ui->fn_line_edit->text().toStdString(),
ui->fd_line_edit->text().toStdString(),
ui->fi_line_edit->text().toStdString(),
ui->purchase_datetime_edit->dateTime().toString(Qt::ISODate).toStdString(),
ui->operation_type_combo_box->currentIndex() + 1,
// In the request to ofd.ru, total is in a format with 2 last digits represent decimal part of a number.
ui->total_spin_box->text().toDouble() * 100,
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(), "Internal server error")) {
QMessageBox infoDialog;
infoDialog.setText(tr("Internal server error. Please, try again later."));
infoDialog.setIcon(QMessageBox::Critical);
infoDialog.setWindowTitle(tr("Internal server error"));
infoDialog.exec();
return;
} 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();
}
}
void OFDScene::on_binary_eye_button_clicked() {
}

30
ofdscene.h Normal file
View File

@ -0,0 +1,30 @@
#ifndef OFDSCENE_H
#define OFDSCENE_H
#include <QWidget>
namespace Ui {
class OFDScene;
}
class OFDScene : public QWidget
{
Q_OBJECT
public:
explicit OFDScene(QWidget *parent = nullptr);
~OFDScene();
void startHttpServer();
private slots:
void on_choose_image_button_clicked();
void onDataDecode(std::string data);
void on_parse_button_clicked();
void on_binary_eye_button_clicked();
private:
Ui::OFDScene *ui;
};
#endif // OFDSCENE_H

View File

@ -73,7 +73,7 @@
</rect>
</property>
<property name="currentIndex">
<number>2</number>
<number>1</number>
</property>
<widget class="QWidget" name="Text">
<attribute name="title">
@ -384,7 +384,7 @@
<x>0</x>
<y>0</y>
<width>817</width>
<height>23</height>
<height>33</height>
</rect>
</property>
<widget class="QMenu" name="menuchecks_parser">

View File

@ -1,215 +0,0 @@
<?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>371</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>381</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>

View File

@ -31,7 +31,7 @@ StoreModule::StoreModule(std::string path) {
std::vector<std::string> StoreModule::parse_name(std::wstring str) {
std::vector<std::string> result;
std::wregex r(this->goods_name_regex, std::regex::collate);
std::wregex r(this->goods_name_regex, std::regex_constants::multiline);
for (std::wsregex_iterator it{str.begin(), str.end(), r}, end{}; it != end;
it++) {

View File

@ -4,6 +4,7 @@
#include "../settings/settings.h"
#include "../utils/utils.h"
#include <iostream>
#include <fstream>
#if __GNUC__ < 8 && __clang_major__ < 17
# include <experimental/filesystem>
@ -14,6 +15,27 @@
using namespace std::filesystem;
#endif
static void dumpVectorsToStdErr(std::vector<std::string> &goods_names, std::vector<std::string> &goods_prices, std::vector<std::string>& goods_quantities) {
std::cerr << goods_names.size() << " " << goods_prices.size() << " " << goods_quantities.size() << std::endl;
std::cerr << "Found goods names: ";
for (auto &goods_name : goods_names) {
std::cerr << goods_name << " ";
}
std::cerr << std::endl;
std::cerr << "Found goods prices: ";
for (auto &goods_price : goods_prices) {
std::cerr << goods_price << " ";
}
std::cerr << std::endl;
std::cerr << "Found goods names: ";
for (auto &goods_quantity : goods_quantities) {
std::cerr << goods_quantity << " ";
}
std::cerr << std::endl;
}
Parser::Parser() {}
std::vector<std::string> Parser::search_modules() {
@ -31,13 +53,28 @@ std::vector<std::string> Parser::search_modules() {
std::vector<std::string> modules_files;
for (auto file : directory_iterator(path)) {
for (auto &file : directory_iterator(path)) {
modules_files.push_back(file.path());
}
return modules_files;
}
std::vector<std::string> Parser::get_modules_names() {
std::vector<std::string> modules = this->search_modules();
std::vector<std::string> names = {};
for (std::string &modulePath : modules) {
std::ifstream inputFile(modulePath);
nlohmann::json module = nlohmann::json::parse(inputFile);
std::string name = module["name"];
names.push_back(name);
}
return names;
}
void Parser::set_module(std::string path) { module = StoreModule(path); }
std::vector<Goods> Parser::parse(std::wstring check_plaintext) {
@ -53,6 +90,9 @@ std::vector<Goods> Parser::parse(std::wstring check_plaintext) {
if (goods_names.size() != goods_prices.size() ||
goods_names.size() != goods_quantities.size() ||
goods_prices.size() != goods_quantities.size()) {
dumpVectorsToStdErr(goods_names, goods_prices, goods_quantities);
//Error. Amount of names, prices or quantities are not equal. That means, that some regex(es) has mismatched.
return {};
}

View File

@ -15,6 +15,8 @@ public:
std::vector<std::string> search_modules();
std::vector<std::string> get_modules_names();
std::vector<std::string> check_updates();
void set_module(std::string);

10
scenes.qrc Normal file
View File

@ -0,0 +1,10 @@
<RCC>
<qresource prefix="/scenes">
<file>scenes/outputdialog.ui</file>
<file>scenes/emailtextscene.ui</file>
<file>scenes/ocrscene.ui</file>
<file>scenes/mainwindow.ui</file>
<file>scenes/ofdscene.ui</file>
<file>scenes/solvecaptchadialog.ui</file>
</qresource>
</RCC>

80
scenes/emailtextscene.ui Normal file
View File

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>EmailTextScene</class>
<widget class="QWidget" name="EmailTextScene">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1077</width>
<height>608</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="2" column="0" colspan="3">
<widget class="QLabel" name="check_content_label">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Check content</string>
</property>
</widget>
</item>
<item row="4" column="0" colspan="3">
<widget class="QPushButton" name="parse_button">
<property name="text">
<string>Parse</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="store_label">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Store:</string>
</property>
</widget>
</item>
<item row="3" column="0" colspan="3">
<widget class="QTextEdit" name="check_content"/>
</item>
<item row="0" column="0">
<widget class="QPushButton" name="back_button">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Back</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="store_combo_box">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

121
scenes/mainwindow.ui Normal file
View File

@ -0,0 +1,121 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QWidget" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1039</width>
<height>693</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>971</width>
<height>0</height>
</size>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="2" column="0">
<layout class="QGridLayout" name="root_layout">
<property name="verticalSpacing">
<number>6</number>
</property>
<item row="0" column="1">
<widget class="QPushButton" name="ocr_button">
<property name="toolTip">
<string>Optical Character Recognition</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normaloff>:/icons/assets/icons/OCR.svg</normaloff>:/icons/assets/icons/OCR.svg</iconset>
</property>
<property name="iconSize">
<size>
<width>128</width>
<height>128</height>
</size>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QPushButton" name="text_from_email_button">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Text from E-Mail</string>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normaloff>:/icons/assets/icons/email-text.svg</normaloff>:/icons/assets/icons/email-text.svg</iconset>
</property>
<property name="iconSize">
<size>
<width>128</width>
<height>128</height>
</size>
</property>
<property name="autoRepeat">
<bool>false</bool>
</property>
<property name="autoExclusive">
<bool>false</bool>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
<property name="default">
<bool>false</bool>
</property>
<property name="flat">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QPushButton" name="ofd_button">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normaloff>:/icons/assets/icons/OFD.svg</normaloff>:/icons/assets/icons/OFD.svg</iconset>
</property>
<property name="iconSize">
<size>
<width>128</width>
<height>128</height>
</size>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

127
scenes/ocrscene.ui Normal file
View File

@ -0,0 +1,127 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>OCRScene</class>
<widget class="QWidget" name="OCRScene">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>992</width>
<height>634</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="topMargin">
<number>8</number>
</property>
<item row="1" column="2">
<widget class="QComboBox" name="store_combo_box">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="5" column="0" colspan="3">
<widget class="QPushButton" name="parse_button">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Parse</string>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QPushButton" name="choose_image_button">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="baseSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Choose</string>
</property>
</widget>
</item>
<item row="0" column="0" colspan="3">
<widget class="QPushButton" name="back_button">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Back</string>
</property>
</widget>
</item>
<item row="3" column="0" colspan="3">
<widget class="QLabel" name="instructions_label">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Recognized text will be shown below as soon as image will be processed. Please, edit it</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QLabel" name="path_to_image_label">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Path to image:</string>
</property>
</widget>
</item>
<item row="4" column="0" colspan="3">
<widget class="QTextEdit" name="check_text_edit"/>
</item>
<item row="1" column="0" colspan="2">
<widget class="QLabel" name="store_label">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Store:</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

194
scenes/ofdscene.ui Normal file
View File

@ -0,0 +1,194 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>OFDScene</class>
<widget class="QWidget" name="OFDScene">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>894</width>
<height>625</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="sizeConstraint">
<enum>QLayout::SizeConstraint::SetDefaultConstraint</enum>
</property>
<item row="8" column="0">
<widget class="QLabel" name="total_label">
<property name="text">
<string>Total</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QPushButton" name="back_button">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Back</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="or_label">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>or</string>
</property>
</widget>
</item>
<item row="8" column="2">
<widget class="QDoubleSpinBox" name="total_spin_box">
<property name="maximum">
<double>4294967296.000000000000000</double>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="fd_label">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>FD (Fiscal Document)</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="datetime_label">
<property name="text">
<string>Date and time of purchase</string>
</property>
</widget>
</item>
<item row="7" column="2">
<widget class="QComboBox" name="operation_type_combo_box">
<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>
</item>
<item row="4" column="2">
<widget class="QLineEdit" name="fd_line_edit"/>
</item>
<item row="2" column="0" colspan="3">
<widget class="QLabel" name="info_label">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QLineEdit" name="fn_line_edit">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="5" column="2">
<widget class="QLineEdit" name="fi_line_edit"/>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="binary_eye_button">
<property name="text">
<string>Use your phone as a QR code scanner</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="fn_label">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>FN (Fiscal Number)</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="fi_label">
<property name="text">
<string>FI (Fiscal Identifier)</string>
</property>
</widget>
</item>
<item row="6" column="2">
<widget class="QDateTimeEdit" name="purchase_datetime_edit"/>
</item>
<item row="1" column="0">
<widget class="QPushButton" name="choose_image_button">
<property name="text">
<string>Choose image on your PC</string>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="operation_type_label">
<property name="text">
<string>Operation type</string>
</property>
</widget>
</item>
<item row="9" column="0" colspan="3">
<widget class="QPushButton" name="parse_button">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Parse</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

187
scenes/outputdialog.ui Normal file
View File

@ -0,0 +1,187 @@
<?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>892</width>
<height>537</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="pathLabel">
<property name="text">
<string>Path to export: </string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="chooseFileButton">
<property name="text">
<string>Choose</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="printHeaderCheckBox">
<property name="text">
<string>Print header</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="printTotalCheckBox">
<property name="text">
<string>Print total</string>
</property>
</widget>
</item>
<item row="3" column="0" colspan="3">
<widget class="QTableWidget" name="tableWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</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>
</item>
<item row="4" column="2">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok</set>
</property>
</widget>
</item>
</layout>
</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>

View File

@ -4,12 +4,12 @@
<context>
<name>AdjustPictureDialog</name>
<message>
<location filename="../adjustpicturedialog.ui" line="14"/>
<location filename="../scenes/adjustpicturedialog.ui" line="14"/>
<source>Dialog</source>
<translation>Dialog</translation>
</message>
<message>
<location filename="../adjustpicturedialog.ui" line="58"/>
<location filename="../scenes/adjustpicturedialog.ui" line="58"/>
<source>Please, zoom to qr code and adjust contrast so that qr code looks sharp</source>
<translation>Please, zoom to qr code and adjust contrast so that qr code looks sharp</translation>
</message>
@ -25,295 +25,502 @@
</message>
</context>
<context>
<name>MainWindow</name>
<name>EmailTextScene</name>
<message>
<location filename="../mainwindow.ui" line="14"/>
<source>MainWindow</source>
<translation>Главное окно</translation>
<location filename="../scenes/emailtextscene.ui" line="14"/>
<source>Form</source>
<translation>Form</translation>
</message>
<message>
<location filename="../mainwindow.ui" line="37"/>
<source>Store type</source>
<translation>Store type</translation>
<translation type="obsolete">Store type</translation>
</message>
<message>
<location filename="../mainwindow.ui" line="50"/>
<source>Parse</source>
<translation>Parse</translation>
</message>
<message>
<location filename="../mainwindow.ui" line="63"/>
<source>Preferences</source>
<translation>Preferences</translation>
</message>
<message>
<location filename="../mainwindow.ui" line="80"/>
<source>Text</source>
<translation>Text</translation>
</message>
<message>
<location filename="../mainwindow.ui" line="92"/>
<location filename="../scenes/emailtextscene.ui" line="26"/>
<source>Check content</source>
<translation>Check content</translation>
</message>
<message>
<location filename="../mainwindow.ui" line="108"/>
<source>OCR</source>
<translatorcomment>OCR = Optical Character Recognition</translatorcomment>
<translation>OCR</translation>
<location filename="../scenes/emailtextscene.ui" line="33"/>
<source>Parse</source>
<translation>Parse</translation>
</message>
<message>
<location filename="../mainwindow.ui" line="120"/>
<location filename="../mainwindow.ui" line="213"/>
<source>Choose</source>
<translation>Choose</translation>
<location filename="../scenes/emailtextscene.ui" line="46"/>
<source>Store:</source>
<translation>Store:</translation>
</message>
<message>
<location filename="../mainwindow.ui" line="143"/>
<location filename="../mainwindow.ui" line="200"/>
<source>Path to image: </source>
<translation>Path to image: </translation>
<location filename="../scenes/emailtextscene.ui" line="62"/>
<source>Back</source>
<translation>Back</translation>
</message>
<message>
<location filename="../mainwindow.ui" line="156"/>
<source>Here is recognised check text. Please, edit it if something&apos;s wrong:</source>
<translation>Here is recognised check text. Please, edit it if something&apos;s wrong:</translation>
</message>
<message>
<location filename="../mainwindow.ui" line="175"/>
<source>OFD</source>
<translatorcomment>OFD = Оператор Фискальных Данных</translatorcomment>
<translation>OFD</translation>
</message>
<message>
<location filename="../mainwindow.ui" line="226"/>
<source>0000000000000000</source>
<translation>0000000000000000</translation>
</message>
<message>
<location filename="../mainwindow.ui" line="245"/>
<source>FN (Fiscal Number)</source>
<translatorcomment>FN = Фискальный Номер</translatorcomment>
<translation>FN (Fiscal Number)</translation>
</message>
<message>
<location filename="../mainwindow.ui" line="264"/>
<source>FD (Fiscal Document)</source>
<translatorcomment>FD = Фискальный Документ</translatorcomment>
<translation>FD (Fiscal Document)</translation>
</message>
<message>
<location filename="../mainwindow.ui" line="277"/>
<location filename="../mainwindow.ui" line="309"/>
<source>0000000000</source>
<translation>000000000</translation>
</message>
<message>
<location filename="../mainwindow.ui" line="296"/>
<source>FI (Fiscal Identifier)</source>
<translatorcomment>FI = Фискальный Признак</translatorcomment>
<translation>FI (Fiscal Identifier)</translation>
</message>
<message>
<location filename="../mainwindow.ui" line="333"/>
<source>Funds income</source>
<translatorcomment>Приход средств</translatorcomment>
<translation>Funds income</translation>
</message>
<message>
<location filename="../mainwindow.ui" line="338"/>
<source>Funds return</source>
<translatorcomment>Возврат средств</translatorcomment>
<translation>Funds return</translation>
</message>
<message>
<location filename="../mainwindow.ui" line="343"/>
<source>Funds spend</source>
<translatorcomment>Расход средств</translatorcomment>
<translation>Funds spend</translation>
</message>
<message>
<location filename="../mainwindow.ui" line="348"/>
<source>Spends return</source>
<translatorcomment>Возврат расхода</translatorcomment>
<translation>Spends return</translation>
</message>
<message>
<location filename="../mainwindow.ui" line="375"/>
<source>Total</source>
<translation>Total</translation>
</message>
<message>
<location filename="../mainwindow.ui" line="392"/>
<source>checks parser</source>
<translation>checks parser</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="85"/>
<source>Captcha was not solved correctly!</source>
<translation>Captcha was not solved correctly!</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="87"/>
<source>Captcha is incorrect</source>
<translation>Captcha is incorrect</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="92"/>
<source>Internal server error. Please, try again later.</source>
<translation>Internal server error. Please, try again later.</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="94"/>
<source>Internal server error</source>
<translation>Internal server error</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="99"/>
<source>Check not found. Please, ensure correctness of entered data.</source>
<translation>Check not found. Please, ensure correctness of entered data.</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="101"/>
<source>Check was not found</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="123"/>
<location filename="../emailtextscene.cpp" line="31"/>
<source>An error has occured. Check was matched incorrectly. Vector sizes are different. Please, contact the developer.</source>
<translation>An error has occured. Check was matched incorrectly. Vector sizes are different. Please, contact the developer.</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="125"/>
<location filename="../emailtextscene.cpp" line="33"/>
<source>Error in parsing</source>
<translation>Error in parsing</translation>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
<source>MainWindow</source>
<translation type="vanished">Главное окно</translation>
</message>
<message>
<source>Store type</source>
<translation type="vanished">Store type</translation>
</message>
<message>
<source>Parse</source>
<translation type="vanished">Parse</translation>
</message>
<message>
<source>Preferences</source>
<translation type="vanished">Preferences</translation>
</message>
<message>
<source>Text</source>
<translation type="vanished">Text</translation>
</message>
<message>
<source>Check content</source>
<translation type="vanished">Check content</translation>
</message>
<message>
<source>OCR</source>
<translatorcomment>OCR = Optical Character Recognition</translatorcomment>
<translation type="vanished">OCR</translation>
</message>
<message>
<source>Choose</source>
<translation type="vanished">Choose</translation>
</message>
<message>
<source>Path to image: </source>
<translation type="vanished">Path to image: </translation>
</message>
<message>
<source>Here is recognised check text. Please, edit it if something&apos;s wrong:</source>
<translation type="vanished">Here is recognised check text. Please, edit it if something&apos;s wrong:</translation>
</message>
<message>
<source>OFD</source>
<translatorcomment>OFD = Оператор Фискальных Данных</translatorcomment>
<translation type="vanished">OFD</translation>
</message>
<message>
<source>0000000000000000</source>
<translation type="vanished">0000000000000000</translation>
</message>
<message>
<source>FN (Fiscal Number)</source>
<translatorcomment>FN = Фискальный Номер</translatorcomment>
<translation type="vanished">FN (Fiscal Number)</translation>
</message>
<message>
<source>FD (Fiscal Document)</source>
<translatorcomment>FD = Фискальный Документ</translatorcomment>
<translation type="vanished">FD (Fiscal Document)</translation>
</message>
<message>
<source>0000000000</source>
<translation type="vanished">000000000</translation>
</message>
<message>
<source>FI (Fiscal Identifier)</source>
<translatorcomment>FI = Фискальный Признак</translatorcomment>
<translation type="vanished">FI (Fiscal Identifier)</translation>
</message>
<message>
<source>Funds income</source>
<translatorcomment>Приход средств</translatorcomment>
<translation type="vanished">Funds income</translation>
</message>
<message>
<source>Funds return</source>
<translatorcomment>Возврат средств</translatorcomment>
<translation type="vanished">Funds return</translation>
</message>
<message>
<source>Funds spend</source>
<translatorcomment>Расход средств</translatorcomment>
<translation type="vanished">Funds spend</translation>
</message>
<message>
<source>Spends return</source>
<translatorcomment>Возврат расхода</translatorcomment>
<translation type="vanished">Spends return</translation>
</message>
<message>
<source>Total</source>
<translation type="vanished">Total</translation>
</message>
<message>
<source>checks parser</source>
<translation type="vanished">checks parser</translation>
</message>
<message>
<source>Captcha was not solved correctly!</source>
<translation type="vanished">Captcha was not solved correctly!</translation>
</message>
<message>
<source>Captcha is incorrect</source>
<translation type="vanished">Captcha is incorrect</translation>
</message>
<message>
<source>Internal server error. Please, try again later.</source>
<translation type="vanished">Internal server error. Please, try again later.</translation>
</message>
<message>
<source>Internal server error</source>
<translation type="vanished">Internal server error</translation>
</message>
<message>
<source>Check not found. Please, ensure correctness of entered data.</source>
<translation type="vanished">Check not found. Please, ensure correctness of entered data.</translation>
</message>
<message>
<source>An error has occured. Check was matched incorrectly. Vector sizes are different. Please, contact the developer.</source>
<translation type="vanished">An error has occured. Check was matched incorrectly. Vector sizes are different. Please, contact the developer.</translation>
</message>
<message>
<source>Error in parsing</source>
<translation type="vanished">Error in parsing</translation>
</message>
<message>
<source>Please, select a picture where QR code that contains info about check is present</source>
<translation type="vanished">Please, select a picture where QR code that contains info about check is present</translation>
</message>
<message>
<source>Picture was not selected</source>
<translation type="vanished">Picture was not selected</translation>
</message>
<message>
<source>Please, select a picture to scan</source>
<translation type="vanished">Please, select a picture to scan</translation>
</message>
<message>
<location filename="../scenes/mainwindow.ui" line="26"/>
<source>Form</source>
<translation>Form</translation>
</message>
<message>
<location filename="../scenes/mainwindow.ui" line="37"/>
<source>Optical Character Recognition</source>
<translation>Optical Character Recognition</translation>
</message>
<message>
<location filename="../scenes/mainwindow.ui" line="63"/>
<source>Text from E-Mail</source>
<translation>Text from E-Mail</translation>
</message>
</context>
<context>
<name>OCRScene</name>
<message>
<location filename="../scenes/ocrscene.ui" line="20"/>
<source>Form</source>
<translation>Form</translation>
</message>
<message>
<location filename="../scenes/ocrscene.ui" line="64"/>
<source>Choose</source>
<translation>Choose</translation>
</message>
<message>
<location filename="../scenes/ocrscene.ui" line="103"/>
<source>Path to image:</source>
<translation>Path to image:</translation>
</message>
<message>
<location filename="../scenes/ocrscene.ui" line="119"/>
<source>Store:</source>
<translation>Store:</translation>
</message>
<message>
<location filename="../scenes/ocrscene.ui" line="90"/>
<source>Recognized text will be shown below as soon as image will be processed. Please, edit it</source>
<translation>Recognized text will be shown below as soon as image will be processed. Please, edit it</translation>
</message>
<message>
<location filename="../scenes/ocrscene.ui" line="77"/>
<source>Back</source>
<translation>Back</translation>
</message>
<message>
<location filename="../scenes/ocrscene.ui" line="45"/>
<source>Parse</source>
<translation>Parse</translation>
</message>
<message>
<location filename="../ocrscene.cpp" line="36"/>
<source>An error has occured. Check was matched incorrectly. Vector sizes are different. Please, contact the developer.</source>
<translation>An error has occured. Check was matched incorrectly. Vector sizes are different. Please, contact the developer.</translation>
</message>
<message>
<location filename="../ocrscene.cpp" line="38"/>
<source>Error in parsing</source>
<translation>Error in parsing</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="156"/>
<source>Please, select a picture where QR code that contains info about check is present</source>
<translation>Please, select a picture where QR code that contains info about check is present</translation>
<location filename="../ocrscene.cpp" line="56"/>
<source>Please, select a picture to scan</source>
<translation>Please, select a picture to scan</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="158"/>
<location filename="../mainwindow.cpp" line="204"/>
<location filename="../ocrscene.cpp" line="58"/>
<source>Picture was not selected</source>
<translation>Picture was not selected</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="202"/>
<source>Please, select a picture to scan</source>
<translation>Please, select a picture to scan</translation>
<location filename="../ocrscene.cpp" line="64"/>
<source>Path to image: </source>
<translation>Path to image: </translation>
</message>
</context>
<context>
<name>OFDScene</name>
<message>
<location filename="../scenes/ofdscene.ui" line="14"/>
<source>Form</source>
<translation>Form</translation>
</message>
<message>
<location filename="../scenes/ofdscene.ui" line="23"/>
<source>Total</source>
<translation>Total</translation>
</message>
<message>
<location filename="../scenes/ofdscene.ui" line="36"/>
<source>Back</source>
<translation>Back</translation>
</message>
<message>
<location filename="../scenes/ofdscene.ui" line="49"/>
<source>or</source>
<translation>or</translation>
</message>
<message>
<location filename="../scenes/ofdscene.ui" line="69"/>
<source>FD (Fiscal Document)</source>
<translation>FD (Fiscal Document)</translation>
</message>
<message>
<location filename="../scenes/ofdscene.ui" line="76"/>
<source>Date and time of purchase</source>
<translation>Date and time of purchase</translation>
</message>
<message>
<location filename="../scenes/ofdscene.ui" line="84"/>
<source>Funds income</source>
<translation>Funds income</translation>
</message>
<message>
<location filename="../scenes/ofdscene.ui" line="89"/>
<source>Funds return</source>
<translation>Funds return</translation>
</message>
<message>
<location filename="../scenes/ofdscene.ui" line="94"/>
<source>Funds spend</source>
<translation>Funds spend</translation>
</message>
<message>
<location filename="../scenes/ofdscene.ui" line="99"/>
<source>Spends return</source>
<translation>Spends return</translation>
</message>
<message>
<location filename="../scenes/ofdscene.ui" line="136"/>
<source>Use your phone as a QR code scanner</source>
<translation>Use your phone as a QR code scanner</translation>
</message>
<message>
<location filename="../scenes/ofdscene.ui" line="149"/>
<source>FN (Fiscal Number)</source>
<translation>FN (Fiscal Number)</translation>
</message>
<message>
<location filename="../scenes/ofdscene.ui" line="156"/>
<source>FI (Fiscal Identifier)</source>
<translation>FI (Fiscal Identifier)</translation>
</message>
<message>
<location filename="../scenes/ofdscene.ui" line="166"/>
<source>Choose image on your PC</source>
<translation>Choose image on your PC</translation>
</message>
<message>
<location filename="../scenes/ofdscene.ui" line="173"/>
<source>Operation type</source>
<translation>Operation type</translation>
</message>
<message>
<location filename="../scenes/ofdscene.ui" line="186"/>
<source>Parse</source>
<translation>Parse</translation>
</message>
<message>
<location filename="../ofdscene.cpp" line="49"/>
<source>Please, select a picture where QR code that contains info about check is present</source>
<translation>Please, select a picture where QR code that contains info about check is present</translation>
</message>
<message>
<location filename="../ofdscene.cpp" line="51"/>
<source>Picture was not selected</source>
<translation>Picture was not selected</translation>
</message>
<message>
<location filename="../ofdscene.cpp" line="57"/>
<source>Selected image: </source>
<translation>Selected image: </translation>
</message>
<message>
<location filename="../ofdscene.cpp" line="116"/>
<source>Captcha was not solved correctly!</source>
<translation>Captcha was not solved correctly!</translation>
</message>
<message>
<location filename="../ofdscene.cpp" line="118"/>
<source>Captcha is incorrect</source>
<translation>Captcha is incorrect</translation>
</message>
<message>
<location filename="../ofdscene.cpp" line="123"/>
<source>Internal server error. Please, try again later.</source>
<translation>Internal server error. Please, try again later.</translation>
</message>
<message>
<location filename="../ofdscene.cpp" line="125"/>
<source>Internal server error</source>
<translation>Internal server error</translation>
</message>
<message>
<location filename="../ofdscene.cpp" line="130"/>
<source>Check not found. Please, ensure correctness of entered data.</source>
<translation>Check not found. Please, ensure correctness of entered data.</translation>
</message>
<message>
<location filename="../ofdscene.cpp" line="132"/>
<source>Check was not found</source>
<translation>Check was not found</translation>
</message>
</context>
<context>
<name>OutputDialog</name>
<message>
<location filename="../outputdialog.ui" line="14"/>
<location filename="../scenes/outputdialog.ui" line="14"/>
<source>Dialog</source>
<translation>Dialog</translation>
</message>
<message>
<location filename="../outputdialog.ui" line="42"/>
<location filename="../scenes/outputdialog.ui" line="20"/>
<source>Path to export: </source>
<translation>Path to export: </translation>
</message>
<message>
<location filename="../outputdialog.ui" line="55"/>
<location filename="../scenes/outputdialog.ui" line="27"/>
<source>Choose</source>
<translation>Choose</translation>
</message>
<message>
<location filename="../outputdialog.ui" line="68"/>
<location filename="../scenes/outputdialog.ui" line="34"/>
<source>Print header</source>
<translation>Print header</translation>
</message>
<message>
<location filename="../outputdialog.ui" line="82"/>
<location filename="../scenes/outputdialog.ui" line="55"/>
<source>Goods name</source>
<translation>Goods name</translation>
</message>
<message>
<location filename="../outputdialog.ui" line="87"/>
<location filename="../scenes/outputdialog.ui" line="60"/>
<source>Goods price</source>
<translation>Goods price</translation>
</message>
<message>
<location filename="../outputdialog.ui" line="92"/>
<location filename="../scenes/outputdialog.ui" line="65"/>
<source>Goods quantity</source>
<translation>Goods quality</translation>
</message>
<message>
<location filename="../outputdialog.ui" line="97"/>
<location filename="../scenes/outputdialog.ui" line="70"/>
<source>Goods net weight</source>
<translation>Goods net weight</translation>
</message>
<message>
<location filename="../outputdialog.ui" line="102"/>
<location filename="../scenes/outputdialog.ui" line="75"/>
<source>Goods total</source>
<translation>Goods total</translation>
</message>
<message>
<location filename="../outputdialog.ui" line="107"/>
<location filename="../scenes/outputdialog.ui" line="80"/>
<source>position</source>
<translation>position</translation>
</message>
<message>
<location filename="../outputdialog.ui" line="112"/>
<location filename="../scenes/outputdialog.ui" line="85"/>
<source>name</source>
<translation>name</translation>
</message>
<message>
<location filename="../outputdialog.ui" line="117"/>
<location filename="../scenes/outputdialog.ui" line="90"/>
<source>1</source>
<translation>1</translation>
</message>
<message>
<location filename="../outputdialog.ui" line="122"/>
<location filename="../scenes/outputdialog.ui" line="95"/>
<source>Name</source>
<translation>Name</translation>
</message>
<message>
<location filename="../outputdialog.ui" line="127"/>
<location filename="../scenes/outputdialog.ui" line="100"/>
<source>2</source>
<translation>2</translation>
</message>
<message>
<location filename="../outputdialog.ui" line="132"/>
<location filename="../scenes/outputdialog.ui" line="105"/>
<source>Price</source>
<translation>Price</translation>
</message>
<message>
<location filename="../outputdialog.ui" line="137"/>
<location filename="../scenes/outputdialog.ui" line="110"/>
<source>3</source>
<translation>3</translation>
</message>
<message>
<location filename="../outputdialog.ui" line="142"/>
<location filename="../scenes/outputdialog.ui" line="115"/>
<source>Quantity</source>
<translation>Quantity</translation>
</message>
<message>
<location filename="../outputdialog.ui" line="147"/>
<location filename="../scenes/outputdialog.ui" line="120"/>
<source>4</source>
<translation>4</translation>
</message>
<message>
<location filename="../outputdialog.ui" line="152"/>
<location filename="../scenes/outputdialog.ui" line="125"/>
<source>Net weight</source>
<translation>Net Weight</translation>
</message>
<message>
<location filename="../outputdialog.ui" line="157"/>
<location filename="../scenes/outputdialog.ui" line="130"/>
<source>5</source>
<translation>5</translation>
</message>
<message>
<location filename="../outputdialog.ui" line="162"/>
<location filename="../scenes/outputdialog.ui" line="135"/>
<source>Total price</source>
<translation>Total price</translation>
</message>
<message>
<location filename="../outputdialog.ui" line="176"/>
<location filename="../scenes/outputdialog.ui" line="41"/>
<source>Print total</source>
<translation>Print total</translation>
</message>
@ -321,20 +528,18 @@
<context>
<name>SettingsDialog</name>
<message>
<location filename="../settingsdialog.cpp" line="149"/>
<source>You need to restart program to apply language changes</source>
<translation>You need to restart program to apply language changes</translation>
<translation type="vanished">You need to restart program to apply language changes</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="151"/>
<source>Restart required</source>
<translation>Restart required</translation>
<translation type="vanished">Restart required</translation>
</message>
</context>
<context>
<name>SolveCaptchaDialog</name>
<message>
<location filename="../solvecaptchadialog.ui" line="14"/>
<location filename="../scenes/solvecaptchadialog.ui" line="14"/>
<source>Dialog</source>
<translation>Dialog</translation>
</message>
@ -352,110 +557,88 @@
<context>
<name>settingsdialog</name>
<message>
<location filename="../settingsdialog.ui" line="14"/>
<source>Dialog</source>
<translation>Dialog</translation>
<translation type="vanished">Dialog</translation>
</message>
<message>
<location filename="../settingsdialog.ui" line="182"/>
<source>Goods name position</source>
<translation>Goods name position</translation>
<translation type="vanished">Goods name position</translation>
</message>
<message>
<location filename="../settingsdialog.ui" line="234"/>
<source>Goods price per unit alias</source>
<translation>Goods price per unit alias</translation>
<translation type="vanished">Goods price per unit alias</translation>
</message>
<message>
<location filename="../settingsdialog.ui" line="248"/>
<source>TextLabel</source>
<translation>Language</translation>
<translation type="vanished">Language</translation>
</message>
<message>
<location filename="../settingsdialog.ui" line="256"/>
<source>en_US</source>
<translation>en_US</translation>
<translation type="vanished">en_US</translation>
</message>
<message>
<location filename="../settingsdialog.ui" line="261"/>
<source>ru_RU</source>
<translation>ru_RU</translation>
<translation type="vanished">ru_RU</translation>
</message>
<message>
<location filename="../settingsdialog.ui" line="224"/>
<location filename="../settingsdialog.ui" line="241"/>
<source>Choose</source>
<translation>Choose</translation>
<translation type="vanished">Choose</translation>
</message>
<message>
<location filename="../settingsdialog.ui" line="107"/>
<source>Print header</source>
<translation>Print header</translation>
<translation type="vanished">Print header</translation>
</message>
<message>
<location filename="../settingsdialog.ui" line="150"/>
<source>Goods net weight alias</source>
<translation>Goods net weight alias</translation>
<translation type="vanished">Goods net weight alias</translation>
</message>
<message>
<location filename="../settingsdialog.ui" line="83"/>
<source>Stores modules url</source>
<translation>Stores modules url</translation>
<translation type="vanished">Stores modules url</translation>
</message>
<message>
<location filename="../settingsdialog.ui" line="163"/>
<source>Goods total alias</source>
<translation>Goods total alias</translation>
<translation type="vanished">Goods total alias</translation>
</message>
<message>
<location filename="../settingsdialog.ui" line="196"/>
<source>Goods name alias</source>
<translation>Goods name alias</translation>
<translation type="vanished">Goods name alias</translation>
</message>
<message>
<location filename="../settingsdialog.ui" line="120"/>
<source>Goods quantity alias</source>
<translation>Goods quantity alias</translation>
<translation type="vanished">Goods quantity alias</translation>
</message>
<message>
<location filename="../settingsdialog.ui" line="210"/>
<source>Stores modules directory</source>
<translation>Stores modules directory</translation>
<translation type="vanished">Stores modules directory</translation>
</message>
<message>
<location filename="../settingsdialog.ui" line="127"/>
<source>OFD modules directory</source>
<translation>OFD modules directory</translation>
<translation type="vanished">OFD modules directory</translation>
</message>
<message>
<location filename="../settingsdialog.ui" line="203"/>
<source>Goods price per unit position</source>
<translation>Goods price per unit position</translation>
<translation type="vanished">Goods price per unit position</translation>
</message>
<message>
<location filename="../settingsdialog.ui" line="73"/>
<source>Goods net weight position</source>
<translation>Goods net weight position</translation>
<translation type="vanished">Goods net weight position</translation>
</message>
<message>
<location filename="../settingsdialog.ui" line="100"/>
<source>OFD modules url</source>
<translation>OFD modules url</translation>
<translation type="vanished">OFD modules url</translation>
</message>
<message>
<location filename="../settingsdialog.ui" line="217"/>
<source>Goods total position</source>
<translation>Goods total position</translation>
<translation type="vanished">Goods total position</translation>
</message>
<message>
<location filename="../settingsdialog.ui" line="90"/>
<source>Goods quantity position</source>
<translation>Goods quantity position</translation>
<translation type="vanished">Goods quantity position</translation>
</message>
<message>
<location filename="../settingsdialog.ui" line="137"/>
<source>Print total</source>
<translation>Print total</translation>
<translation type="vanished">Print total</translation>
</message>
</context>
</TS>

View File

@ -4,12 +4,12 @@
<context>
<name>AdjustPictureDialog</name>
<message>
<location filename="../adjustpicturedialog.ui" line="14"/>
<location filename="../scenes/adjustpicturedialog.ui" line="14"/>
<source>Dialog</source>
<translation>Диалог</translation>
</message>
<message>
<location filename="../adjustpicturedialog.ui" line="58"/>
<location filename="../scenes/adjustpicturedialog.ui" line="58"/>
<source>Please, zoom to qr code and adjust contrast so that qr code looks sharp</source>
<translation>Пожалуйста, приблизьте QR код и настройте контраст, чтобы он читался</translation>
</message>
@ -25,291 +25,502 @@
</message>
</context>
<context>
<name>MainWindow</name>
<name>EmailTextScene</name>
<message>
<location filename="../mainwindow.ui" line="14"/>
<source>MainWindow</source>
<translation>ГлавноеОкно</translation>
<location filename="../scenes/emailtextscene.ui" line="14"/>
<source>Form</source>
<translation>Форма</translation>
</message>
<message>
<location filename="../mainwindow.ui" line="37"/>
<source>Store type</source>
<translation>Магазин</translation>
<translation type="obsolete">Магазин</translation>
</message>
<message>
<location filename="../mainwindow.ui" line="50"/>
<source>Parse</source>
<translation>Парсить</translation>
</message>
<message>
<location filename="../mainwindow.ui" line="63"/>
<source>Preferences</source>
<translation>Настройки</translation>
</message>
<message>
<location filename="../mainwindow.ui" line="80"/>
<source>Text</source>
<translation>Текст</translation>
</message>
<message>
<location filename="../mainwindow.ui" line="92"/>
<location filename="../scenes/emailtextscene.ui" line="26"/>
<source>Check content</source>
<translation>Контент чека</translation>
</message>
<message>
<location filename="../mainwindow.ui" line="108"/>
<source>OCR</source>
<translatorcomment>Оптическое Распознавание Символов</translatorcomment>
<translation>ОРС</translation>
<location filename="../scenes/emailtextscene.ui" line="33"/>
<source>Parse</source>
<translation>Парсить</translation>
</message>
<message>
<location filename="../mainwindow.ui" line="120"/>
<location filename="../mainwindow.ui" line="213"/>
<source>Choose</source>
<translation>Выбрать</translation>
<location filename="../scenes/emailtextscene.ui" line="46"/>
<source>Store:</source>
<translation>Магазин:</translation>
</message>
<message>
<location filename="../mainwindow.ui" line="143"/>
<location filename="../mainwindow.ui" line="200"/>
<source>Path to image: </source>
<translation>Путь к изображению: </translation>
<location filename="../scenes/emailtextscene.ui" line="62"/>
<source>Back</source>
<translation>Назад</translation>
</message>
<message>
<location filename="../mainwindow.ui" line="156"/>
<source>Here is recognised check text. Please, edit it if something&apos;s wrong:</source>
<translation>Ниже приведён распознанный текст. Пожалуйста, отредактируйте его:</translation>
</message>
<message>
<location filename="../mainwindow.ui" line="175"/>
<source>OFD</source>
<translatorcomment>Оператор Фискальных Данных</translatorcomment>
<translation>ОФД</translation>
</message>
<message>
<location filename="../mainwindow.ui" line="226"/>
<source>0000000000000000</source>
<translation>0000000000000000</translation>
</message>
<message>
<location filename="../mainwindow.ui" line="245"/>
<source>FN (Fiscal Number)</source>
<translatorcomment>Фискальный Норма</translatorcomment>
<translation>ФН</translation>
</message>
<message>
<location filename="../mainwindow.ui" line="264"/>
<source>FD (Fiscal Document)</source>
<translatorcomment>Фискальный Документ</translatorcomment>
<translation>ФД</translation>
</message>
<message>
<location filename="../mainwindow.ui" line="277"/>
<location filename="../mainwindow.ui" line="309"/>
<source>0000000000</source>
<translation>000000000</translation>
</message>
<message>
<location filename="../mainwindow.ui" line="296"/>
<source>FI (Fiscal Identifier)</source>
<translatorcomment>Фискальный Признак</translatorcomment>
<translation>ФП</translation>
</message>
<message>
<location filename="../mainwindow.ui" line="333"/>
<source>Funds income</source>
<translation>Приход средств</translation>
</message>
<message>
<location filename="../mainwindow.ui" line="338"/>
<source>Funds return</source>
<translation>Возврат средств</translation>
</message>
<message>
<location filename="../mainwindow.ui" line="343"/>
<source>Funds spend</source>
<translation>Расход средств</translation>
</message>
<message>
<location filename="../mainwindow.ui" line="348"/>
<source>Spends return</source>
<translation>Возврат расхода</translation>
</message>
<message>
<location filename="../mainwindow.ui" line="375"/>
<source>Total</source>
<translation>Итого</translation>
</message>
<message>
<location filename="../mainwindow.ui" line="392"/>
<source>checks parser</source>
<translation>Парсер чеков</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="85"/>
<source>Captcha was not solved correctly!</source>
<translation>Капча была решена неверно!</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="87"/>
<source>Captcha is incorrect</source>
<translation>Капча введена неверно</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="92"/>
<source>Internal server error. Please, try again later.</source>
<translation>Внутренняя ошибка сервера. Пожалуйста, попробуйте снова позже.</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="94"/>
<source>Internal server error</source>
<translation>Внутренняя ошибка сервера</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="99"/>
<source>Check not found. Please, ensure correctness of entered data.</source>
<translation>Чек не найден. Пожалуйста, убедитесь в правильности введённых данных.</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="101"/>
<source>Check was not found</source>
<translation>Чек не найден</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="123"/>
<location filename="../emailtextscene.cpp" line="31"/>
<source>An error has occured. Check was matched incorrectly. Vector sizes are different. Please, contact the developer.</source>
<translation>Произошла ошибка. Чек был прочитан неверно. Размеры векторов различаются. Пожалуйста, сообщите об этом разработчику.</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="125"/>
<location filename="../emailtextscene.cpp" line="33"/>
<source>Error in parsing</source>
<translation>Ошибка в парсинге</translation>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
<source>MainWindow</source>
<translation type="vanished">ГлавноеОкно</translation>
</message>
<message>
<source>Store type</source>
<translation type="vanished">Магазин</translation>
</message>
<message>
<source>Parse</source>
<translation type="vanished">Парсить</translation>
</message>
<message>
<source>Preferences</source>
<translation type="vanished">Настройки</translation>
</message>
<message>
<source>Text</source>
<translation type="vanished">Текст</translation>
</message>
<message>
<source>Check content</source>
<translation type="vanished">Контент чека</translation>
</message>
<message>
<source>OCR</source>
<translatorcomment>Оптическое Распознавание Символов</translatorcomment>
<translation type="vanished">ОРС</translation>
</message>
<message>
<source>Choose</source>
<translation type="vanished">Выбрать</translation>
</message>
<message>
<source>Path to image: </source>
<translation type="vanished">Путь к изображению: </translation>
</message>
<message>
<source>Here is recognised check text. Please, edit it if something&apos;s wrong:</source>
<translation type="vanished">Ниже приведён распознанный текст. Пожалуйста, отредактируйте его:</translation>
</message>
<message>
<source>OFD</source>
<translatorcomment>Оператор Фискальных Данных</translatorcomment>
<translation type="vanished">ОФД</translation>
</message>
<message>
<source>0000000000000000</source>
<translation type="vanished">0000000000000000</translation>
</message>
<message>
<source>FN (Fiscal Number)</source>
<translatorcomment>Фискальный Норма</translatorcomment>
<translation type="vanished">ФН</translation>
</message>
<message>
<source>FD (Fiscal Document)</source>
<translatorcomment>Фискальный Документ</translatorcomment>
<translation type="vanished">ФД</translation>
</message>
<message>
<source>0000000000</source>
<translation type="vanished">000000000</translation>
</message>
<message>
<source>FI (Fiscal Identifier)</source>
<translatorcomment>Фискальный Признак</translatorcomment>
<translation type="vanished">ФП</translation>
</message>
<message>
<source>Funds income</source>
<translation type="vanished">Приход средств</translation>
</message>
<message>
<source>Funds return</source>
<translation type="vanished">Возврат средств</translation>
</message>
<message>
<source>Funds spend</source>
<translation type="vanished">Расход средств</translation>
</message>
<message>
<source>Spends return</source>
<translation type="vanished">Возврат расхода</translation>
</message>
<message>
<source>Total</source>
<translation type="vanished">Итого</translation>
</message>
<message>
<source>checks parser</source>
<translation type="vanished">Парсер чеков</translation>
</message>
<message>
<source>Captcha was not solved correctly!</source>
<translation type="vanished">Капча была решена неверно!</translation>
</message>
<message>
<source>Captcha is incorrect</source>
<translation type="vanished">Капча введена неверно</translation>
</message>
<message>
<source>Internal server error. Please, try again later.</source>
<translation type="vanished">Внутренняя ошибка сервера. Пожалуйста, попробуйте снова позже.</translation>
</message>
<message>
<source>Internal server error</source>
<translation type="vanished">Внутренняя ошибка сервера</translation>
</message>
<message>
<source>Check not found. Please, ensure correctness of entered data.</source>
<translation type="vanished">Чек не найден. Пожалуйста, убедитесь в правильности введённых данных.</translation>
</message>
<message>
<source>Check was not found</source>
<translation type="vanished">Чек не найден</translation>
</message>
<message>
<source>An error has occured. Check was matched incorrectly. Vector sizes are different. Please, contact the developer.</source>
<translation type="vanished">Произошла ошибка. Чек был прочитан неверно. Размеры векторов различаются. Пожалуйста, сообщите об этом разработчику.</translation>
</message>
<message>
<source>Error in parsing</source>
<translation type="vanished">Ошибка в парсинге</translation>
</message>
<message>
<source>Please, select a picture where QR code that contains info about check is present</source>
<translation type="vanished">Пожалуйста, выберете изображение, содержащее QR код с информацией о чеке</translation>
</message>
<message>
<source>Picture was not selected</source>
<translation type="vanished">Изображение не было выбрано</translation>
</message>
<message>
<source>Please, select a picture to scan</source>
<translation type="vanished">Пожалуйста, выберете изображение для сканирования</translation>
</message>
<message>
<location filename="../scenes/mainwindow.ui" line="26"/>
<source>Form</source>
<translation>Форма</translation>
</message>
<message>
<location filename="../scenes/mainwindow.ui" line="37"/>
<source>Optical Character Recognition</source>
<translation>Оптическое распознавание символов</translation>
</message>
<message>
<location filename="../scenes/mainwindow.ui" line="63"/>
<source>Text from E-Mail</source>
<translation>Текст из электронного письма</translation>
</message>
</context>
<context>
<name>OCRScene</name>
<message>
<location filename="../scenes/ocrscene.ui" line="20"/>
<source>Form</source>
<translation>Форма</translation>
</message>
<message>
<location filename="../scenes/ocrscene.ui" line="64"/>
<source>Choose</source>
<translation>Выбрать</translation>
</message>
<message>
<location filename="../scenes/ocrscene.ui" line="103"/>
<source>Path to image:</source>
<translation>Путь к изображению:</translation>
</message>
<message>
<location filename="../scenes/ocrscene.ui" line="119"/>
<source>Store:</source>
<translation>Магазин:</translation>
</message>
<message>
<location filename="../scenes/ocrscene.ui" line="90"/>
<source>Recognized text will be shown below as soon as image will be processed. Please, edit it</source>
<translation>Распознанный текст будет показан ниже как только изображение обработается. Пожалуйста, отредактируйте</translation>
</message>
<message>
<location filename="../scenes/ocrscene.ui" line="77"/>
<source>Back</source>
<translation>Назад</translation>
</message>
<message>
<location filename="../scenes/ocrscene.ui" line="45"/>
<source>Parse</source>
<translation>Парсить</translation>
</message>
<message>
<location filename="../ocrscene.cpp" line="36"/>
<source>An error has occured. Check was matched incorrectly. Vector sizes are different. Please, contact the developer.</source>
<translation>Произошла ошибка. Чек был прочитан неверно. Размеры векторов различаются. Пожалуйста, сообщите об этом разработчику.</translation>
</message>
<message>
<location filename="../ocrscene.cpp" line="38"/>
<source>Error in parsing</source>
<translation>Ошибка в парсинге</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="156"/>
<source>Please, select a picture where QR code that contains info about check is present</source>
<translation>Пожалуйста, выберете изображение, содержащее QR код с информацией о чеке</translation>
<location filename="../ocrscene.cpp" line="56"/>
<source>Please, select a picture to scan</source>
<translation>Пожалуйста, выберете изображение для сканирования</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="158"/>
<location filename="../mainwindow.cpp" line="204"/>
<location filename="../ocrscene.cpp" line="58"/>
<source>Picture was not selected</source>
<translation>Изображение не было выбрано</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="202"/>
<source>Please, select a picture to scan</source>
<translation>Пожалуйста, выберете изображение для сканирования</translation>
<location filename="../ocrscene.cpp" line="64"/>
<source>Path to image: </source>
<translation>Путь к изображению: </translation>
</message>
</context>
<context>
<name>OFDScene</name>
<message>
<location filename="../scenes/ofdscene.ui" line="14"/>
<source>Form</source>
<translation>Форма</translation>
</message>
<message>
<location filename="../scenes/ofdscene.ui" line="23"/>
<source>Total</source>
<translation>Итого</translation>
</message>
<message>
<location filename="../scenes/ofdscene.ui" line="36"/>
<source>Back</source>
<translation>Назад</translation>
</message>
<message>
<location filename="../scenes/ofdscene.ui" line="49"/>
<source>or</source>
<translation>или</translation>
</message>
<message>
<location filename="../scenes/ofdscene.ui" line="69"/>
<source>FD (Fiscal Document)</source>
<translation>ФД</translation>
</message>
<message>
<location filename="../scenes/ofdscene.ui" line="76"/>
<source>Date and time of purchase</source>
<translation>Дата и время покупки</translation>
</message>
<message>
<location filename="../scenes/ofdscene.ui" line="84"/>
<source>Funds income</source>
<translation>Приход средств</translation>
</message>
<message>
<location filename="../scenes/ofdscene.ui" line="89"/>
<source>Funds return</source>
<translation>Возврат средств</translation>
</message>
<message>
<location filename="../scenes/ofdscene.ui" line="94"/>
<source>Funds spend</source>
<translation>Расход средств</translation>
</message>
<message>
<location filename="../scenes/ofdscene.ui" line="99"/>
<source>Spends return</source>
<translation>Возврат расхода</translation>
</message>
<message>
<location filename="../scenes/ofdscene.ui" line="136"/>
<source>Use your phone as a QR code scanner</source>
<translation>Использовать телефон как сканнер QR</translation>
</message>
<message>
<location filename="../scenes/ofdscene.ui" line="149"/>
<source>FN (Fiscal Number)</source>
<translation>ФН</translation>
</message>
<message>
<location filename="../scenes/ofdscene.ui" line="156"/>
<source>FI (Fiscal Identifier)</source>
<translation>ФП</translation>
</message>
<message>
<location filename="../scenes/ofdscene.ui" line="166"/>
<source>Choose image on your PC</source>
<translation>Выбрать изображение на компьютере</translation>
</message>
<message>
<location filename="../scenes/ofdscene.ui" line="173"/>
<source>Operation type</source>
<translation>Тип операции</translation>
</message>
<message>
<location filename="../scenes/ofdscene.ui" line="186"/>
<source>Parse</source>
<translation>Парсить</translation>
</message>
<message>
<location filename="../ofdscene.cpp" line="49"/>
<source>Please, select a picture where QR code that contains info about check is present</source>
<translation>Пожалуйста, выберете изображение, содержащее QR код с информацией о чеке</translation>
</message>
<message>
<location filename="../ofdscene.cpp" line="51"/>
<source>Picture was not selected</source>
<translation>Изображение не было выбрано</translation>
</message>
<message>
<location filename="../ofdscene.cpp" line="57"/>
<source>Selected image: </source>
<translation>Выбранное изображение: </translation>
</message>
<message>
<location filename="../ofdscene.cpp" line="116"/>
<source>Captcha was not solved correctly!</source>
<translation>Капча была решена неверно!</translation>
</message>
<message>
<location filename="../ofdscene.cpp" line="118"/>
<source>Captcha is incorrect</source>
<translation>Капча введена неверно</translation>
</message>
<message>
<location filename="../ofdscene.cpp" line="123"/>
<source>Internal server error. Please, try again later.</source>
<translation>Внутренняя ошибка сервера. Пожалуйста, попробуйте снова позже.</translation>
</message>
<message>
<location filename="../ofdscene.cpp" line="125"/>
<source>Internal server error</source>
<translation>Внутренняя ошибка сервера</translation>
</message>
<message>
<location filename="../ofdscene.cpp" line="130"/>
<source>Check not found. Please, ensure correctness of entered data.</source>
<translation>Чек не найден. Пожалуйста, убедитесь в правильности введённых данных.</translation>
</message>
<message>
<location filename="../ofdscene.cpp" line="132"/>
<source>Check was not found</source>
<translation>Чек не найден</translation>
</message>
</context>
<context>
<name>OutputDialog</name>
<message>
<location filename="../outputdialog.ui" line="14"/>
<location filename="../scenes/outputdialog.ui" line="14"/>
<source>Dialog</source>
<translation>Диалог</translation>
</message>
<message>
<location filename="../outputdialog.ui" line="42"/>
<location filename="../scenes/outputdialog.ui" line="20"/>
<source>Path to export: </source>
<translation>Путь для экспорта: </translation>
</message>
<message>
<location filename="../outputdialog.ui" line="55"/>
<location filename="../scenes/outputdialog.ui" line="27"/>
<source>Choose</source>
<translation>Выбрать</translation>
</message>
<message>
<location filename="../outputdialog.ui" line="68"/>
<location filename="../scenes/outputdialog.ui" line="34"/>
<source>Print header</source>
<translation>Печатать заголовок</translation>
</message>
<message>
<location filename="../outputdialog.ui" line="82"/>
<location filename="../scenes/outputdialog.ui" line="55"/>
<source>Goods name</source>
<translation>Имя товара</translation>
</message>
<message>
<location filename="../outputdialog.ui" line="87"/>
<location filename="../scenes/outputdialog.ui" line="60"/>
<source>Goods price</source>
<translation>Цена товара</translation>
</message>
<message>
<location filename="../outputdialog.ui" line="92"/>
<location filename="../scenes/outputdialog.ui" line="65"/>
<source>Goods quantity</source>
<translation>Количество товара</translation>
</message>
<message>
<location filename="../outputdialog.ui" line="97"/>
<location filename="../scenes/outputdialog.ui" line="70"/>
<source>Goods net weight</source>
<translation>Масса нетто товара</translation>
</message>
<message>
<location filename="../outputdialog.ui" line="102"/>
<location filename="../scenes/outputdialog.ui" line="75"/>
<source>Goods total</source>
<translation>Всего за товар</translation>
</message>
<message>
<location filename="../outputdialog.ui" line="107"/>
<location filename="../scenes/outputdialog.ui" line="80"/>
<source>position</source>
<translation>позиция</translation>
</message>
<message>
<location filename="../outputdialog.ui" line="112"/>
<location filename="../scenes/outputdialog.ui" line="85"/>
<source>name</source>
<translation>алиас</translation>
</message>
<message>
<location filename="../outputdialog.ui" line="117"/>
<location filename="../scenes/outputdialog.ui" line="90"/>
<source>1</source>
<translation>1</translation>
</message>
<message>
<location filename="../outputdialog.ui" line="122"/>
<location filename="../scenes/outputdialog.ui" line="95"/>
<source>Name</source>
<translation>Имя</translation>
</message>
<message>
<location filename="../outputdialog.ui" line="127"/>
<location filename="../scenes/outputdialog.ui" line="100"/>
<source>2</source>
<translation>2</translation>
</message>
<message>
<location filename="../outputdialog.ui" line="132"/>
<location filename="../scenes/outputdialog.ui" line="105"/>
<source>Price</source>
<translation>Цена</translation>
</message>
<message>
<location filename="../outputdialog.ui" line="137"/>
<location filename="../scenes/outputdialog.ui" line="110"/>
<source>3</source>
<translation>3</translation>
</message>
<message>
<location filename="../outputdialog.ui" line="142"/>
<location filename="../scenes/outputdialog.ui" line="115"/>
<source>Quantity</source>
<translation>Количество</translation>
</message>
<message>
<location filename="../outputdialog.ui" line="147"/>
<location filename="../scenes/outputdialog.ui" line="120"/>
<source>4</source>
<translation>4</translation>
</message>
<message>
<location filename="../outputdialog.ui" line="152"/>
<location filename="../scenes/outputdialog.ui" line="125"/>
<source>Net weight</source>
<translation>Масса нетто</translation>
</message>
<message>
<location filename="../outputdialog.ui" line="157"/>
<location filename="../scenes/outputdialog.ui" line="130"/>
<source>5</source>
<translation>5</translation>
</message>
<message>
<location filename="../outputdialog.ui" line="162"/>
<location filename="../scenes/outputdialog.ui" line="135"/>
<source>Total price</source>
<translation>Всего</translation>
</message>
<message>
<location filename="../outputdialog.ui" line="176"/>
<location filename="../scenes/outputdialog.ui" line="41"/>
<source>Print total</source>
<translation>Печатать Итого</translation>
</message>
@ -317,20 +528,18 @@
<context>
<name>SettingsDialog</name>
<message>
<location filename="../settingsdialog.cpp" line="149"/>
<source>You need to restart program to apply language changes</source>
<translation>Требуется перезагрузить программу, чтобы применить изменения языка</translation>
<translation type="vanished">Требуется перезагрузить программу, чтобы применить изменения языка</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="151"/>
<source>Restart required</source>
<translation>Требуется перезагрузка</translation>
<translation type="vanished">Требуется перезагрузка</translation>
</message>
</context>
<context>
<name>SolveCaptchaDialog</name>
<message>
<location filename="../solvecaptchadialog.ui" line="14"/>
<location filename="../scenes/solvecaptchadialog.ui" line="14"/>
<source>Dialog</source>
<translation>Диалог</translation>
</message>
@ -348,110 +557,88 @@
<context>
<name>settingsdialog</name>
<message>
<location filename="../settingsdialog.ui" line="14"/>
<source>Dialog</source>
<translation>Диалог</translation>
<translation type="vanished">Диалог</translation>
</message>
<message>
<location filename="../settingsdialog.ui" line="182"/>
<source>Goods name position</source>
<translation>Позиция имени товара</translation>
<translation type="vanished">Позиция имени товара</translation>
</message>
<message>
<location filename="../settingsdialog.ui" line="234"/>
<source>Goods price per unit alias</source>
<translation>Алиас цены товара</translation>
<translation type="vanished">Алиас цены товара</translation>
</message>
<message>
<location filename="../settingsdialog.ui" line="248"/>
<source>TextLabel</source>
<translation>Язык</translation>
<translation type="vanished">Язык</translation>
</message>
<message>
<location filename="../settingsdialog.ui" line="256"/>
<source>en_US</source>
<translation>en_US</translation>
<translation type="vanished">en_US</translation>
</message>
<message>
<location filename="../settingsdialog.ui" line="261"/>
<source>ru_RU</source>
<translation>ru_RU</translation>
<translation type="vanished">ru_RU</translation>
</message>
<message>
<location filename="../settingsdialog.ui" line="224"/>
<location filename="../settingsdialog.ui" line="241"/>
<source>Choose</source>
<translation>Выбрать</translation>
<translation type="vanished">Выбрать</translation>
</message>
<message>
<location filename="../settingsdialog.ui" line="107"/>
<source>Print header</source>
<translation>Печатать заголовок</translation>
<translation type="vanished">Печатать заголовок</translation>
</message>
<message>
<location filename="../settingsdialog.ui" line="150"/>
<source>Goods net weight alias</source>
<translation>Алиас массы нетто товара</translation>
<translation type="vanished">Алиас массы нетто товара</translation>
</message>
<message>
<location filename="../settingsdialog.ui" line="83"/>
<source>Stores modules url</source>
<translation>URL модулей магазина</translation>
<translation type="vanished">URL модулей магазина</translation>
</message>
<message>
<location filename="../settingsdialog.ui" line="163"/>
<source>Goods total alias</source>
<translation>Алиас всего за продукт</translation>
<translation type="vanished">Алиас всего за продукт</translation>
</message>
<message>
<location filename="../settingsdialog.ui" line="196"/>
<source>Goods name alias</source>
<translation>Алиас имени товара</translation>
<translation type="vanished">Алиас имени товара</translation>
</message>
<message>
<location filename="../settingsdialog.ui" line="120"/>
<source>Goods quantity alias</source>
<translation>Алиас количества товара</translation>
<translation type="vanished">Алиас количества товара</translation>
</message>
<message>
<location filename="../settingsdialog.ui" line="210"/>
<source>Stores modules directory</source>
<translation>Директория модулей магазина</translation>
<translation type="vanished">Директория модулей магазина</translation>
</message>
<message>
<location filename="../settingsdialog.ui" line="127"/>
<source>OFD modules directory</source>
<translation>Директория модулей ОФД</translation>
<translation type="vanished">Директория модулей ОФД</translation>
</message>
<message>
<location filename="../settingsdialog.ui" line="203"/>
<source>Goods price per unit position</source>
<translation>Позиция центы товара</translation>
<translation type="vanished">Позиция центы товара</translation>
</message>
<message>
<location filename="../settingsdialog.ui" line="73"/>
<source>Goods net weight position</source>
<translation>Позиция массы нетто товара</translation>
<translation type="vanished">Позиция массы нетто товара</translation>
</message>
<message>
<location filename="../settingsdialog.ui" line="100"/>
<source>OFD modules url</source>
<translation>URL модулей ОФД</translation>
<translation type="vanished">URL модулей ОФД</translation>
</message>
<message>
<location filename="../settingsdialog.ui" line="217"/>
<source>Goods total position</source>
<translation>Позиция всего за товар</translation>
<translation type="vanished">Позиция всего за товар</translation>
</message>
<message>
<location filename="../settingsdialog.ui" line="90"/>
<source>Goods quantity position</source>
<translation>Позиция количества товара</translation>
<translation type="vanished">Позиция количества товара</translation>
</message>
<message>
<location filename="../settingsdialog.ui" line="137"/>
<source>Print total</source>
<translation>Печатать Итого</translation>
<translation type="vanished">Печатать Итого</translation>
</message>
</context>
</TS>

View File

@ -1,5 +1,6 @@
#include "utils.h"
#include <arpa/inet.h>
#include <codecvt>
#include <cstring>
#include <iostream>
@ -7,6 +8,37 @@
#include <regex>
#include <string>
#include "../exceptions/ofdrequestexception.h"
#include "settings/settings.h"
#include <QWidget>
#include <fstream>
#include <ifaddrs.h>
#include <netinet/in.h>
std::string get_local_ip_address() {
struct ifaddrs * ifAddrStruct=NULL;
struct ifaddrs * ifa=NULL;
void * tmpAddrPtr=NULL;
getifaddrs(&ifAddrStruct);
for (ifa = ifAddrStruct; ifa != NULL; ifa = ifa->ifa_next) {
if (ifa->ifa_addr == nullptr) continue;
if (ifa->ifa_addr->sa_family==AF_INET) {
tmpAddrPtr=&((struct sockaddr_in *)ifa->ifa_addr)->sin_addr;
char addressBuffer[128];
inet_ntop(AF_INET, tmpAddrPtr, addressBuffer, INET_ADDRSTRLEN);
std::string value(addressBuffer);
if (!strncmp(value.c_str(), "192.168", 7)) {
return value;
}
}
}
if (ifAddrStruct!=NULL)
freeifaddrs(ifAddrStruct);
throw std::runtime_error(QWidget::tr("Could not find any usable local IP address. If you beleive that this is problem with the program, please, contact the developer.").toStdString());
}
std::string to_utf8(std::wstring wide_string) {
static std::wstring_convert<std::codecvt_utf8<wchar_t>> utf8_conv;
@ -94,8 +126,9 @@ std::vector<std::wstring> find_in_html(std::string& html, std::string regex, std
it != end; it++) {
std::wstring found_entry = from_utf8(it->str());
std::wcout << "Found: " << found_entry << std::endl;
std::wstring extracted = substring_from_to(found_entry, from_utf8(html_start), from_utf8(html_end));
std::wcout << "Extracted: " << extracted << std::endl;
parsed.push_back(extracted);
}
return parsed;
@ -106,11 +139,42 @@ std::vector<std::wstring> find_products_in_html(std::string html) {
}
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> founds = find_in_html(html, "<div><span>\\d+(\\.|\\,)?\\d{0,3}<\\/span>", "<span>", "<\\/span>");
for (auto &found : founds) {
std::replace(found.begin(), found.end(), ',', '.');
}
return founds;
}
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>");
std::vector<std::wstring> founds = find_in_html(html, "X <\\/span><span>\\d+(\\.|,)\\d{2}<\\/span>", "X <\\/span><span>", "<\\/span>");
for (auto &found : founds) {
std::replace(found.begin(), found.end(), ',', '.');
}
return founds;
}
void dumpVectorsToStderr(std::vector<std::wstring> &products, std::vector<std::wstring> &amounts, std::vector<std::wstring> &prices) {
std::cerr << "Products: ";
for (auto &product : products) {
std::cerr << to_utf8(product) << "|[]|";
}
std::cerr << std::endl;
std::cerr << "Amounts: ";
for (auto &amount : amounts) {
std::wcerr << amount << " ";
}
std::cerr << std::endl;
std::cerr << "Prices: ";
for (auto &price : prices) {
std::wcerr << price << " ";
}
std::cerr << std::endl;
}
Check parseOfdRuAnswer(std::string html) {
@ -133,6 +197,10 @@ Check parseOfdRuAnswer(std::string html) {
}
if ((products.size() + amounts.size() + prices.size())/products.size() != 3) {
dumpVectorsToStderr(products, amounts, prices);
//TOOD: make new setting "app_home" and get all path using it.
std::ofstream error_log(get_path_relative_to_home(".local/share/checks_parser/error_log.txt"), std::ios_base::app);
error_log << trimmed << std::endl;
std::cerr << "An error has occured during the parsing of html. Please, contact the developer." << std::endl;
std::exit(-1);
}

View File

@ -5,6 +5,7 @@
#include <vector>
#include "../check/check.h"
std::string get_local_ip_address();
std::string to_utf8(std::wstring wide_string);
std::wstring from_utf8(std::string string);