-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPersonsWorkingInfo.cpp
More file actions
173 lines (161 loc) · 6.81 KB
/
Copy pathPersonsWorkingInfo.cpp
File metadata and controls
173 lines (161 loc) · 6.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
#include "PersonsWorkingInfo.h"
#include <QSqlDatabase>
#include <QSqlError>
#include <QtQml>
#include <QSqlQuery>
static void connectToDatabase()
{
QSqlDatabase database = QSqlDatabase::database();
if ( !database.isValid() )
{
database = QSqlDatabase::addDatabase("QSQLITE");
if ( !database.isValid() )
qFatal( "Cannot add database: %s", qPrintable( database.lastError().text() ) );
}
const QDir writeDir = QStandardPaths::writableLocation( QStandardPaths::AppDataLocation );
if ( !writeDir.mkpath(".") )
qFatal( "Failed to create writable directory at %s", qPrintable( writeDir.absolutePath() ) );
// Ensure that we have a writable location on all devices.
const QString fileName = writeDir.absolutePath() + "/Working_Database";
// When using the SQLite driver, open() will create the SQLite database if it doesn't exist.
database.setDatabaseName( fileName );
if ( !database.open() )
{
qFatal( "Cannot open database: %s", qPrintable( database.lastError().text() ) );
QFile::remove( fileName );
}
}
static void createTableArchive()
{
//create this table for testing program
if ( QSqlDatabase::database().tables().contains( QStringLiteral( "archive" ) ) )
return;
QSqlQuery query;
if ( !query.exec(
"CREATE TABLE IF NOT EXISTS 'archive' ("
" '_id' INT NOT NULL,"
" 'datetime' DATETIME NOT NULL,"
" 'card_id' INT NOT NULL,"
"FOREIGN KEY(card_id) REFERENCES card_id(_id)"
" PRIMARY KEY (_id)"
")")) {
qFatal( "Failed to query database: %s", qPrintable( query.lastError().text() ) );
}
//TEXT as ISO8601 strings ("YYYY-MM-DD HH:MM:SS.SSS").
query.exec( "INSERT INTO archive VALUES(1,'2021-04-09 08:55:10', 2)" );
query.exec( "INSERT INTO archive VALUES(2,'2021-04-09 13:01:10', 2)" );
query.exec( "INSERT INTO archive VALUES(3,'2021-04-09 09:01:10', 1)" );
query.exec( "INSERT INTO archive VALUES(4,'2021-04-09 18:01:10', 2)" );
query.exec( "INSERT INTO archive VALUES(5,'2021-04-09 17:59:10', 1)" );
query.exec( "INSERT INTO archive VALUES(6,'2021-04-08 09:00:10', 1)" );
query.exec( "INSERT INTO archive VALUES(7,'2021-04-08 17:59:10', 1)" );
query.exec( "INSERT INTO archive VALUES(8,'2021-04-01 09:00:10', 3)" );
query.exec( "INSERT INTO archive VALUES(9,'2021-04-01 17:59:10', 3)" );
query.exec( "INSERT INTO archive VALUES(10,'2021-04-09 09:00:10', 4)" );
query.exec( "INSERT INTO archive VALUES(11,'2021-04-09 13:00:00', 4)" );
query.exec( "INSERT INTO archive VALUES(12,'2021-04-09 14:00:00', 4)" );
query.exec( "INSERT INTO archive VALUES(13,'2021-04-09 18:05:10', 4)" );
}
static void createTableCard()
{
//create this table for testing program
if ( QSqlDatabase::database().tables().contains( QStringLiteral( "card_id" ) ) )
return;
QSqlQuery query;
if ( !query.exec(
"CREATE TABLE IF NOT EXISTS 'card_id' ("
" '_id' INT NOT NULL,"
" 'info' TEXT NOT NULL,"
" PRIMARY KEY(_id)"
")")) {
qFatal( "Failed to query database: %s", qPrintable( query.lastError().text() ) );
}
query.exec( "INSERT INTO card_id VALUES(1,'Rodin')" );
query.exec( "INSERT INTO card_id VALUES(2,'Petrov')" );
query.exec( "INSERT INTO card_id VALUES(3,'Ivanov')" );
query.exec( "INSERT INTO card_id VALUES(4,'Sidorov')" );
}
//TEXT as ISO8601 strings ("YYYY-MM-DD HH:MM:SS.SSS").
PersonsWorkingInfo::PersonsWorkingInfo ( QObject *parent )
: QSqlQueryModel( parent )
{
connectToDatabase();
createTableArchive();
createTableCard();
}
QString PersonsWorkingInfo::GiveMeWorkingDataByNameAndDate( const QString &name, const QString &date )
{
if ( QSqlDatabase::database().tables().contains( QStringLiteral( "card_id" ) ) )
return;
QSqlQuery query;
query.prepare( "SELECT archive.datetime, card_id.info, card_id._id, archive.card_id FROM card_id, "
"archive WHERE card_id._id = archive.card_id AND card_id.info = :name" );
query.bindValue( ":name", name );
query.exec();
m_time_check_vector.clear();
QVector < QString > time_check_QVector;
while ( query.next() )
{
if ( name == query.value( 1 ).toString() )
{
QString time_check = query.value( 0 ).toString();
std::string time_in_std = time_check.toUtf8().constData();
std::string data = time_in_std.substr( 0, 10 );
if ( data == date.toUtf8().constData() )
{
std::string temp = time_in_std.substr( 11, 18 );
m_time_check_vector.push_back( temp ); // In one line
}
}
}
setQuery( query );
if ( lastError().isValid() )
return "There are problems with the database or communication with it";
if ( m_time_check_vector.size() == 0)
return QStringLiteral("Employee %1 didn't work on %3. \n It is "
"recommended to check the spelling of the employee's surname"
" or check if the date is entered correctly").arg(name).arg(date);
if ( ( m_time_check_vector.size() % 2 ) != 0 )
return "not enough timestamps for correct timing. "
"Perhaps the employee forgot to check in, "
"when he came in or went to office with colleagues."
"Click \"show all time records\"";
int working_time_in_minuts = getMinutsFromWorkingData();
QString message_with_working_min = QStringLiteral( "Employee %1 worked for %2 minutes "
"on %3." ).arg( name ).arg( working_time_in_minuts ).arg( date );
return message_with_working_min;
}
}
int PersonsWorkingInfo::getMinutsFromWorkingData()
{
enum class check_description{ in, out };
check_description check_mark = check_description::in;
int working_time_in_minuts = 0;
for ( const auto& time_check: m_time_check_vector )
{
std::string hour_string = time_check.substr( 0, 2 );
std::string min_string = time_check.substr( 3, 2 );
std::string sec_string = time_check.substr( 6, 2 );
int hour = stoi( hour_string );
int min = stoi( min_string );
int sec = stoi( sec_string );
if ( sec >= 30)
min++;
int total_min = hour * 60 + min;
if ( check_mark == check_description::in )
{
working_time_in_minuts -= total_min;
check_mark = check_description::out;
}
else
{
working_time_in_minuts += total_min;
check_mark = check_description::in;
}
}
return working_time_in_minuts;
}
std::vector< std::string > PersonsWorkingInfo::GetTimeCheckVector()
{
return m_time_check_vector;
}