13#include <QCryptographicHash>
18using namespace Db::Plugins;
21DatabasePluginFotomon::~DatabasePluginFotomon() {
26DatabasePluginFotomon::DatabasePluginFotomon(QObject *parent) : Db::Plugins::
DatabasePlugin(parent) {
27 Q_ASSERT(parent != NULL);
28 setObjectName(
"DatabasePluginFotomon");
29 m_temporaryTableTicketsCreated =
false;
33bool DatabasePluginFotomon::open() {
34 m_db = QSqlDatabase::addDatabase(
"QPSQL", QUuid::createUuid().toString().toUtf8());
36 m_db.setDatabaseName ( m_databasename );
37 m_db.setHostName ( m_hostname );
38 m_db.setPort ( m_port );
39 m_db.setUserName ( m_username );
40 m_db.setPassword ( m_password );
43 PDEBUG <<
"Cannot connect to database Fotomon";
44 PDEBUG << m_db.lastError().text();
52bool DatabasePluginFotomon::close() {
58void DatabasePluginFotomon::begin() {
64void DatabasePluginFotomon::commit() {
70QVariant DatabasePluginFotomon::currval(
const QString& sequence) {
73 q.prepare(R
"'(select currval(:sequence);)'");
74 q.bindValue(":sequence", sequence);
83void DatabasePluginFotomon::changePassword(
const QString& login,
const QString& oldpassword,
const QString& newpassword) {
85 Q_UNUSED(oldpassword);
86 Q_UNUSED(newpassword);
90QList<Dbt::Users> DatabasePluginFotomon::authenticate(
const QString& login,
const QString& password) {
91 QString md5 = QString::fromUtf8(QCryptographicHash::hash(password.toUtf8(), QCryptographicHash::Md5).toHex());
92 QList<Dbt::Users> list;
95 select "user", login, name, language
97 where password = :password
103 q.bindValue(":login", login);
104 q.bindValue(
":password", md5);
109 x.user = q.value(i++).toInt();
110 x.login = q.value(i++).toString();
111 x.name = q.value(i++).toString();
112 x.lang = q.value(i++).toString();
119QList<Dbt::Users> DatabasePluginFotomon::users(
int id) {
121 QList<Dbt::Users> list;
123 q.prepare(R
"X(select "user", login, name, language from users where is_active and not is_deleted;)X");
128 x.user = q.value(i++).toInt();
129 x.login = q.value(i++).toString();
130 x.name = q.value(i++).toString();
131 x.lang = q.value(i++).toString();
138void DatabasePluginFotomon::createTemporaryTableTickets(
int ticket,
bool all) {
140 if (m_temporaryTableTicketsCreated) {
return; }
141 m_temporaryTableTicketsCreated =
true;
144 create temporary table temporary_tickets (
149 date timestamp with time zone,
160 left join lateral (select tn.ticket, tn.status from tickets_notes tn where tn.ticket = t.ticket order by ticket, date desc limit 1) tl using (ticket)
161 left join tickets_status ts on (tl.status = ts.status)
162 where (:ticket1 <= 0 or :ticket2 = t.ticket)
163 and (ts.closed is null or not ts.closed)
167 from users_systems us, users u, systems s
168 where u."user" = :user
169 and u."user" = us."user"
170 and us.system = s.system
171 and s.show_on_web and s.show_on_panel
172 and u.is_active and not u.is_deleted
174 insert into temporary_tickets (ticket, type, system, category, date, "user", description)
175 select t.ticket, t.type, t.system, t.category, t.date, t."user",
176 case when description = '' then formal_description->0->'description'->>:lang else description end as description
177 from tickets t, users u
178 where u."user" = t."user"
179 and t.ticket in (select ticket from active_tickets)
180 and t.system in (select system from users_systems)
181 and (:ticket3 <= 0 or :ticket4 = t.ticket)
183 q.bindValue(":user", userId());
184 q.bindValue(
":lang", userLang());
185 q.bindValue(
":ticket1", ticket);
186 q.bindValue(
":ticket2", ticket);
187 q.bindValue(
":ticket3", ticket);
188 q.bindValue(
":ticket4", ticket);
193void DatabasePluginFotomon::createTemporaryTableCategories() {
196 q.exec(
"create temporary table timesheet_categories "
197 "(type int, system int, category int, description text, parent_type int)"
201 q.prepare(
"insert into timesheet_categories (type, system, category, description, parent_type) "
202 " select type, null, null, formal_description->>:lang, 1 "
203 " from tickets_types;");
204 q.bindValue(
":lang", userLang());
208 q.prepare(
"insert into timesheet_categories (type, system, category, description, parent_type) "
209 " select distinct on (tt.type, s.system) tt.type, s.system, null, s.description, 2 "
210 " from tickets_categories_types_systems tt, systems s "
211 " where s.show_on_panel and s.show_on_web "
212 " and s.system in (select system from users_systems where \"user\" = :user); "
214 q.bindValue(
":user", userId());
218 q.prepare(
"insert into timesheet_categories (type, system, category, description, parent_type) "
219 " select tt.type, s.system, tc.category, tc.formal_description->>:lang, 3 "
220 " from tickets_categories_types_systems tt, systems s, tickets_categories tc "
221 " where tt.system = s.system "
222 " and tc.category = tt.category "
223 " and s.show_on_panel and s.show_on_web "
224 " and s.system in (select system from users_systems where \"user\" = :user); "
226 q.bindValue(
":lang", userLang());
227 q.bindValue(
":user", userId());
231 q.prepare(
"insert into timesheet_categories (type, system, category, description, parent_type) "
232 " select tt.type, s.system, tc.category, tc.formal_description->>:lang, 4 "
233 " from systems s, tickets_types tt, tickets_categories tc "
234 " where s.show_on_panel and s.show_on_web "
235 " and s.system in (select system from users_systems where \"user\" = :user) "
236 " and not exists (select 1 "
237 " from tickets_categories_types_systems tcts "
238 " where tcts.type = tt.type "
239 " and tcts.system = s.system ); "
241 q.bindValue(
":user", userId());
242 q.bindValue(
":lang", userLang());
248QString DatabasePluginFotomon::categoryKey(
const QVariant& type,
const QVariant& system,
const QVariant& category,
int parent_type) {
249 if (parent_type == 1) {
250 return QString(R
"'({"type":%1})'")
255 if (parent_type == 2) {
256 return QString(R
"'({"type":%1,"system":%2})'")
262 if (parent_type == 3) {
263 return QString(R
"'({"type":%1,"system":%2,"category":%3})'")
266 .arg(category.toInt())
270 if (parent_type == 4) {
271 return QString(R
"'({"type":%1,"system":%2,"category":%3})'")
274 .arg(category.toInt())
282QString DatabasePluginFotomon::parentCategoryKey(
const QVariant& type,
const QVariant& system,
const QVariant& category,
int parent_type) {
284 if (parent_type == 1) {
288 if (parent_type == 2) {
289 return QString(R
"'({"type":%1})'")
294 if (parent_type == 3) {
295 return QString(R
"'({"type":%1,"system":%2})'")
301 if (parent_type == 4) {
302 return QString(R
"'({"type":%1,"system":%2})'")
312QList<Dbt::Categories> DatabasePluginFotomon::categoriesToRoot(
const QString&
id) {
314 QList<Dbt::Categories> list;
319QList<Dbt::Categories> DatabasePluginFotomon::categories(
const QString&
id) {
321 createTemporaryTableCategories();
323 QList<Dbt::Categories> list;
326 q.exec(
"select type, system, category, description, parent_type from timesheet_categories;");
329 QVariant type = q.value(0);
330 QVariant system = q.value(1);
331 QVariant category = q.value(2);
332 QVariant description = q.value(3);
333 int parent_type = q.value(4).toInt();
335 x.category = categoryKey(type, system, category, parent_type);
336 x.parent_category = parentCategoryKey(type, system, category, parent_type);
337 x.description = description.toString();
341 PDEBUG <<
"pocet kategorii" << list.size();
346QList<Dbt::Categories> DatabasePluginFotomon::subcategories(
const QString&
id) {
348 QList<Dbt::Categories> list;
353QList<Dbt::Categories> DatabasePluginFotomon::siblingcategories(
const QString&
id) {
355 QList<Dbt::Categories> list;
360QList<Dbt::StatusOrder> DatabasePluginFotomon::statusOrder(
const QString&
id) {
362 createTemporaryTableCategories();
364 QList<Dbt::StatusOrder> list;
367 q.exec(
"select c.type, c.system, c.category, c.description, c.parent_type, "
368 " s.status_from, s.status_to "
369 " from timesheet_categories c, tickets_types_status s"
370 " where c.type = s.type "
374 QVariant type = q.value(0);
375 QVariant system = q.value(1);
376 QVariant category = q.value(2);
377 QVariant description = q.value(3);
378 int parent_type = q.value(4).toInt();
380 x.previous_status = q.value(5);
381 x.next_status = q.value(6);
382 x.category = categoryKey(type, system, category, parent_type);
386 PDEBUG <<
"pocet prechodu" << list.size();
392QList<Dbt::Statuses> DatabasePluginFotomon::statuses(
const QString&
id) {
394 QList<Dbt::Statuses> list;
397 q.prepare(
"select ts.status, ts.formal_description->>:lang, ts.abbreviation, ts.color "
398 " from tickets_status ts "
400 q.bindValue(
":lang", userLang());
405 x.status = q.value(i++).toString();
406 x.description = q.value(i++).toString();
407 x.abbreviation = q.value(i++).toString();
408 x.color = q.value(i++).toString();
416QList<Dbt::Statuses> DatabasePluginFotomon::statuses(
const QString& category,
const QString& prevstatus) {
418 Q_UNUSED(prevstatus);
419 return statuses(QString());
423QList<Dbt::StatusTemplates> DatabasePluginFotomon::statusTemplates(
int id) {
425 QList<Dbt::StatusTemplates> list;
436 q.prepare(R
"X(select note_template, status, null, code, title->>:lang, description
437 from tickets_notes_templates
438 where note_template = :id1 or 0 > :id2;
442 q.bindValue(":id1",
id);
443 q.bindValue(
":id2",
id);
444 q.bindValue(
":lang", userLang());
449 x.id = q.value(i++).toInt();
450 x.status = q.value(i++).toString();
451 x.category = q.value(i++).toString();
452 x.code = q.value(i++).toString();
453 x.title = q.value(i++).toString();
454 x.description = q.value(i++).toString();
462QList<Dbt::Tickets> DatabasePluginFotomon::tickets(
bool all) {
463 return tickets(-1, all);
467QList<Dbt::Tickets> DatabasePluginFotomon::tickets(
int ticket,
bool all) {
469 createTemporaryTableTickets(ticket, all);
470 QList<Dbt::Tickets> list;
473 q.prepare(R
"X(select ticket, type, system, 1, date, description from temporary_tickets;)X");
478 x.ticket = q.value(i++);
479 QVariant type = q.value(i++);
480 QVariant system = q.value(i++);
481 QVariant category = q.value(i++);
482 x.category = categoryKey(type, system, category, 3);
483 x.date = q.value(i++).toDateTime();
484 x.description = q.value(i++).toString();
491QList<Dbt::Tickets> DatabasePluginFotomon::tickets(
const Dbt::Categories&,
bool all) {
492 return tickets(-1, all);
496QList<Dbt::TicketsVw> DatabasePluginFotomon::ticketsVw(
const Dbt::Categories&,
bool all) {
497 return ticketsVw(-1, all);
501QList<Dbt::TicketsVw> DatabasePluginFotomon::ticketsVw(
bool all) {
503 return ticketsVw(-1, all);
507QList<Dbt::TicketsVw> DatabasePluginFotomon::ticketsVw(
int ticket,
bool all) {
508 createTemporaryTableTickets(ticket, all);
509 QList<Dbt::Tickets> list1;
510 QList<Dbt::TicketsVw> list;
513 q.prepare(R
"X(select ticket, type, system, category, date, description, "user" from temporary_tickets;)X");
518 x.ticket = q.value(i++);
519 QVariant type = q.value(i++);
520 QVariant system = q.value(i++);
521 QVariant category = q.value(i++);
522 x.category = categoryKey(type, system, category, 3);
523 x.date = q.value(i++).toDateTime();
524 x.description = q.value(i++).toString();
525 x.user = q.value(i++).toInt();
528 for (
int i=0; i<list1.size(); i++) {
530 x.timesheets = ticketTimesheets(list1[i].ticket.toInt(), all);
531 x.statuses = ticketStatus(list1[i].ticket.toInt(), all);
532 x.values = ticketValues(list1[i].ticket.toInt(), all);
533 x.files = ticketFiles(list1[i].ticket.toInt(), all);
541QVariant DatabasePluginFotomon::save(
const Dbt::Tickets& data) {
544 QVariantMap x =
JSON::data(data.category.toByteArray()).toMap();
545 int type = x[
"type"].toInt();
546 int system = x[
"system"].toInt();
547 int category = x[
"category"].toInt();
551 q.prepare(R
"'(select 1 from tickets where ticket = :ticket;)'");
552 q.bindValue(":ticket", data.ticket);
557 if (!data.created && found) {
562 category = :category,
565 description = :description,
567 where ticket = :ticket
569 q.bindValue(":type", type);
570 q.bindValue(
":system", system);
571 q.bindValue(
":category", category);
572 q.bindValue(
":date", data.date);
573 q.bindValue(
":price", data.price);
574 q.bindValue(
":description", data.description);
575 q.bindValue(
":user", data.user);
576 q.bindValue(
":ticket", data.ticket);
578 return QVariant(data.ticket);
581 if (data.created || !found) {
583 insert into tickets (type, system, category, date, price, description, "user")
584 values (:type, :system, :category, :date, :price, :description, :user);
586 q.bindValue(":type", type);
587 q.bindValue(
":system", system);
588 q.bindValue(
":category", category);
589 q.bindValue(
":date", data.date);
590 q.bindValue(
":price", data.price);
591 q.bindValue(
":description", data.description);
592 q.bindValue(
":user", data.user);
594 return currval(
"tickets_ticket_seq");
598 qFatal(
"Should not happen");
604QList<T> remapTicket(
const QList<T>& input,
int ticket) {
606 QListIterator<T> iterator(input);
607 while (iterator.hasNext()) {
608 T x = iterator.next();
610 if (ticket <= 0) { x.id = 0; }
620 int ticket = save(
dynamic_cast<const Dbt::Tickets&
>(data)).toInt();
621 save(remapTicket(data.timesheets, ticket));
622 save(remapTicket(data.statuses, ticket));
623 save(remapTicket(data.values, ticket));
624 save(remapTicket(data.files, ticket));
631void DatabasePluginFotomon::remove(
const Dbt::Tickets&
id) {
633 q.prepare(R
"'(delete from tickets where ticket = :id;)'");
634 q.bindValue(":id",
id.ticket);
639QList<Dbt::TicketStatus> DatabasePluginFotomon::ticketStatus(
int ticket,
bool all) {
640 createTemporaryTableTickets(ticket, all);
641 QList<Dbt::TicketStatus> list;
645 select tn.note, tn.ticket, t."user", tn.date, tn.status,
646 case when tn.description != '' then tn.description else tn.formal_description->0->'description'->>'cs' end as description,
647 tn.formal_description,
648 ts.description, ts.color
649 from tickets_notes tn, temporary_tickets t, tickets_status ts
650 where tn.ticket = t.ticket
651 and ts.status = tn.status
652 and (:ticket1 <= 0 or :ticket2 = t.ticket)
655 q.bindValue(":user", userId());
656 q.bindValue(
":lang", userLang());
657 q.bindValue(
":ticket1", ticket);
658 q.bindValue(
":ticket2", ticket);
663 x.id = q.value(i++).toInt();
664 x.ticket = q.value(i++).toInt();
665 x.user = q.value(i++).toInt();
666 x.date = q.value(i++).toDateTime();
667 x.status = q.value(i++).toString();
668 x.description = q.value(i++).toString();
669 x.description2 =
JSON::data(q.value(i++).toString().toUtf8()).toMap();
670 x.status_description = q.value(i++).toString();
671 x.status_color = q.value(i++).toString();
681QList<Dbt::TicketStatus> DatabasePluginFotomon::ticketStatus(
bool all) {
683 return ticketStatus(-1, all);
687QList<Dbt::TicketStatus> DatabasePluginFotomon::ticketStatus(
int id) {
689 QList<Dbt::TicketStatus> list;
699 q.prepare(R
"'(select 1 from tickets_notes where note = :id;)'");
700 q.bindValue(":id", data.id);
705 if (!data.created && found) {
706 QByteArray description2 =
JSON::json(data.description2);
707 if (description2 ==
"{}") { description2 =
""; }
708 q.prepare(QString(R
"'(
709 update tickets_notes set
713 description = :description,
714 formal_description = %1,
717 )'").arg((description2=="") ?
"null" : QString(
"'%1'").arg(QString::fromUtf8(description2)) ) );
718 q.bindValue(
":id", data.id);
719 q.bindValue(
":user", data.user);
720 q.bindValue(
":ticket", data.ticket);
721 q.bindValue(
":date", data.date);
722 q.bindValue(
":description", data.description);
723 q.bindValue(
":status", data.status);
725 return QVariant(data.id);
728 if (data.created || !found) {
729 QByteArray description2 =
JSON::json(data.description2);
730 if (description2 ==
"{}") { description2 =
""; }
731 q.prepare(QString(R
"'(
732 insert into tickets_notes (ticket, "user", date, description, status, formal_description)
733 values (:ticket, :user, :date, :description, :status, %1)
734 )'").arg((description2=="") ?
"null" : QString(
"'%1'").arg(QString::fromUtf8(description2)) ) );
735 q.bindValue(
":user", data.user);
736 q.bindValue(
":ticket", data.ticket);
737 q.bindValue(
":date", data.date);
738 q.bindValue(
":description", data.description);
739 q.bindValue(
":status", data.status);
742 return currval(
"tickets_notes_note_seq");
750QList<Dbt::TicketTimesheets> DatabasePluginFotomon::ticketTimesheets(
int ticket,
bool all) {
751 createTemporaryTableTickets(ticket, all);
752 QList<Dbt::TicketTimesheets> list;
755 select tt.id, tt.ticket, tt."user", tt.date_from, tt.date_to
756 from temporary_tickets t, ticket_timesheets tt
757 where t.ticket = tt.ticket
758 and t.ticket = :ticket
761 q.bindValue(":user", userId());
762 q.bindValue(
":ticket", ticket);
767 x.id = q.value(i++).toInt();
768 x.ticket = q.value(i++).toInt();
769 x.user = q.value(i++).toInt();
770 x.date_from = q.value(i++).toDateTime();
771 x.date_to = q.value(i++).toDateTime();
778QList<Dbt::TicketTimesheets> DatabasePluginFotomon::ticketTimesheets(
int id) {
779 QList<Dbt::TicketTimesheets> list;
782 select tt.id, tt.ticket, tt."user", tt.date_from, tt.date_to
783 from ticket_timesheets tt, tickets t, users_categories uc
784 where t.ticket = tt.ticket
785 and t.category = uc.category
786 and uc."user" = :user
790 q.bindValue(":user", userId());
791 q.bindValue(
":id",
id);
796 x.id = q.value(i++).toInt();
797 x.ticket = q.value(i++).toInt();
798 x.user = q.value(i++).toInt();
799 x.date_from = q.value(i++).toDateTime();
800 x.date_to = q.value(i++).toDateTime();
807QList<Dbt::TicketTimesheets> DatabasePluginFotomon::ticketTimesheets(
bool all) {
808 return ticketTimesheets(-1, all);
812QList<Dbt::TicketTimesheets> DatabasePluginFotomon::runningTimesheets(
int ticket) {
814 return QList<Dbt::TicketTimesheets>();
818QList<Dbt::TicketTimesheets> DatabasePluginFotomon::startTimesheet(
int ticket) {
820 return QList<Dbt::TicketTimesheets>();
824QList<Dbt::TicketTimesheets> DatabasePluginFotomon::stopTimesheet(
int ticket) {
826 return QList<Dbt::TicketTimesheets>();
830QList<Dbt::TicketTimesheets> DatabasePluginFotomon::toggleTimesheet(
int ticket) {
832 return QList<Dbt::TicketTimesheets>();
841 q.prepare(R
"'(select 1 from ticket_timesheets where id = :id;)'");
842 q.bindValue(":id", data.id);
847 if (!data.created && found) {
849 update ticket_timesheets set
852 date_from = :date_from,
856 q.bindValue(":id", data.id);
857 q.bindValue(
":user", data.user);
858 q.bindValue(
":ticket", data.ticket);
859 q.bindValue(
":date_from", data.date_from);
860 q.bindValue(
":date_to", data.date_to);
862 return QVariant(data.id);
866 if (data.created || !found) {
868 insert into ticket_timesheets (ticket, "user", date_from, date_to)
869 values (:ticket, :user, :date_from, :date_to)
871 q.bindValue(":user", data.user);
872 q.bindValue(
":ticket", data.ticket);
873 q.bindValue(
":date_from", data.date_from);
874 q.bindValue(
":date_to", data.date_to);
877 return currval(
"ticket_timesheets_id_seq");
887 q.prepare(R
"'(delete from ticket_timesheets where id = :id;)'");
888 q.bindValue(":id",
id.
id);
893QByteArray DatabasePluginFotomon::fileContent(
const QString& filename) {
895 QDir dir(MSETTINGS->dbFilesDirectory());
896 QString fullfilename = dir.absoluteFilePath(filename);
897 QFile file(fullfilename);
898 if (file.open(QIODevice::ReadOnly)) {
899 content = file.readAll();
906QList<Dbt::TicketFiles> DatabasePluginFotomon::ticketFiles(
int ticket,
bool all) {
907 createTemporaryTableTickets(ticket, all);
908 QList<Dbt::TicketFiles> list;
912 select f.file, f.upload_date, tf.ticket, f.origname, f.filetype, f.filename
913 from temporary_tickets t, tickets_files tf, files f
914 where t.ticket = tf.ticket
915 and tf.file = f.file;
922 x.id = q.value(i++).toInt();
924 x.date = q.value(i++).toDateTime();
925 x.ticket = q.value(i++).toInt();
926 x.name = q.value(i++).toString();
927 x.type = q.value(i++).toString();
928 x.content = DatabasePluginFotomon::fileContent(q.value(i++).toString());
936QList<Dbt::TicketFiles> DatabasePluginFotomon::ticketFiles(
int id) {
937 QList<Dbt::TicketFiles> list;
941 select f.file, f.upload_date, tf.ticket, f.origname, f.filetype, f.filename
942 from tickets_files tf, files f, users u, tickets t, users_categories uc
945 and t.ticket = tf.ticket
946 and t.category = uc.category
950 q.bindValue(":id",
id);
951 q.bindValue(
":user", userId());
956 x.id = q.value(i++).toInt();
958 x.date = q.value(i++).toDateTime();
959 x.ticket = q.value(i++).toInt();
960 x.name = q.value(i++).toString();
961 x.type = q.value(i++).toString();
962 x.content = DatabasePluginFotomon::fileContent(q.value(i++).toString());
970QList<Dbt::TicketFiles> DatabasePluginFotomon::ticketFiles(
bool all) {
971 return ticketFiles(-1, all);
975QString DatabasePluginFotomon::suffixFromType(
const QString& type) {
976 if (type ==
"image/png") {
return ".png"; }
977 if (type ==
"image/jpeg") {
return ".jpeg"; }
978 if (type ==
"image/gif") {
return ".gif"; }
987 q.prepare(R
"'(select file from tickets_files where file = :file and ticket = :ticket;)'");
988 q.bindValue(":id", data.id);
989 q.bindValue(
":ticket", data.ticket);
994 QString suffix = suffixFromType(data.type);
995 QString webalizedName = QString(
"ta%1-%2%3")
996 .arg(data.ticket.toInt())
997 .arg(QUuid::createUuid().toString().remove(QChar(
'{')).remove(QChar(
'}')))
1000 QDir dir(MSETTINGS->dbFilesDirectory());
1001 QString filename = dir.absoluteFilePath(webalizedName);
1002 QFile file(filename);
1003 if (file.open(QIODevice::WriteOnly)) {
1004 file.write(data.content);
1007 QFileInfo info(filename);
1008 PDEBUG << webalizedName << filename << info.fileName();
1011 PDEBUG <<
"update files" << data.id << data.ticket;
1014 filename = :filename,
1015 upload_date = :date,
1019 where file = :fileid
1021 q.bindValue(":filename", info.fileName());
1022 q.bindValue(
":date", data.date);
1023 q.bindValue(
":name", data.name + suffix);
1024 q.bindValue(
":type", data.type);
1025 q.bindValue(
":size", info.size());
1026 q.bindValue(
":fileid", data.id);
1027 q.bindValue(
":ticket", data.ticket);
1029 return QVariant(data.id);
1034 insert into files (filename, upload_date, origname, filetype, filesize)
1035 values (:filename, :date, :name, :type, :sizeticket);
1037 q.bindValue(":filename", info.fileName());
1038 q.bindValue(
":date", data.date);
1039 q.bindValue(
":name", data.name + suffix);
1040 q.bindValue(
":type", data.type);
1041 q.bindValue(
":size", info.size());
1045 insert into tickets_files (ticket, file) select :ticket, currval('files_file_seq');
1047 q.bindValue(":ticket", data.ticket);
1050 QVariant rc = currval(
"files_file_seq");
1051 PDEBUG <<
"insert files" << rc.toInt() << data.ticket;
1062 q.prepare(R
"'(delete from ticket_images where id = :id;)'");
1063 q.bindValue(":id",
id.
id);
1068QList<Dbt::TicketValues> DatabasePluginFotomon::ticketValues(
int ticket,
bool all) {
1069 createTemporaryTableTickets(ticket, all);
1070 QList<Dbt::TicketValues> list;
1073 select tv.id, tt.ticket, tv.name, tv.value, tv."user", tv.date
1074 from temporary_tickets tt, ticket_values tv
1075 where tt.ticket = tv.ticket
1082 x.id = q.value(i++).toInt();
1083 x.ticket = q.value(i++).toInt();
1084 x.name = q.value(i++).toString();
1085 x.value =
JSON::data(q.value(i++).toByteArray());
1086 x.user = q.value(i++).toInt();
1087 x.date = q.value(i++).toDateTime();
1094QList<Dbt::TicketValues> DatabasePluginFotomon::ticketValues(
int id) {
1095 QList<Dbt::TicketValues> list;
1098 select tv.id, tv.ticket, tv.date, tv.name, tv.value, tv."user"
1099 from tickets tt, ticket_values tv, users_categories uc
1100 where tt.ticket = tv.ticket
1101 and tt.category = uc.category
1106 q.bindValue(":id",
id);
1107 q.bindValue(
":user", userId());
1112 x.id = q.value(i++).toInt();
1113 x.ticket = q.value(i++).toInt();
1114 x.date = q.value(i++).toDateTime();
1115 x.name = q.value(i++).toString();
1116 x.value =
JSON::data(q.value(i++).toByteArray());
1117 x.user = q.value(i++).toInt();
1124QList<Dbt::TicketValues> DatabasePluginFotomon::ticketValues(
bool all) {
1125 return ticketValues(-1, all);
1133 if (!data.created) {
1134 q.prepare(R
"'(select 1 from ticket_values where id = :id;)'");
1135 q.bindValue(":id", data.id);
1140 if (!data.created && found) {
1141 q.prepare(QString(R
"'(
1142 update ticket_values set
1149 )'").arg(QString::fromUtf8(JSON::json(data.value))));
1150 q.bindValue(":id", data.id);
1151 q.bindValue(
":ticket", data.ticket);
1152 q.bindValue(
":user", data.user);
1153 q.bindValue(
":date", data.date);
1154 q.bindValue(
":name", data.name);
1157 return QVariant(data.id);
1160 if (data.created || !found) {
1161 q.prepare(QString(R
"'(
1162 insert into ticket_values (ticket, "user", date, name, value)
1163 select :ticket, :user, :date, :name, '%1'
1164 where not exists (select 1 from ticket_values where id = :id);
1165 )'").arg(QString::fromUtf8(JSON::json(data.value))));
1166 q.bindValue(":id", data.id);
1167 q.bindValue(
":ticket", data.ticket);
1168 q.bindValue(
":user", data.user);
1169 q.bindValue(
":date", data.date);
1170 q.bindValue(
":name", data.name);
1174 return currval(
"ticket_values_id_seq");
1184 q.prepare(R
"'(delete from ticket_values where id = :id;)'");
1185 q.bindValue(":id",
id.
id);
1190QList<Dbt::UsersCategories> DatabasePluginFotomon::usersCategories(
int id,
int user,
const QString& category) {
1194 QList<Dbt::UsersCategories> list;
1199QList<Dbt::ClientSettings> DatabasePluginFotomon::clientSettings() {
1200 QList<Dbt::ClientSettings> list;
1204 select multiple_timesheets, show_price, can_change_category, edit_categories,
1205 show_multiple_timesheets, show_show_price, show_can_change_category, show_edit_categories
1206 from ticket_client_settings;
1212 x.multiple_timesheets = q.value(i++).toBool();
1213 x.show_price = q.value(i++).toBool();
1214 x.can_change_category = q.value(i++).toBool();
1215 x.edit_categories = q.value(i++).toBool();
1216 x.show_multiple_timesheets = q.value(i++).toBool();
1217 x.show_show_price = q.value(i++).toBool();
1218 x.show_can_change_category = q.value(i++).toBool();
1219 x.show_edit_categories = q.value(i++).toBool();
1226QList<Dbt::CategoriesOverview> DatabasePluginFotomon::categoriesOverview(
const QStringList& statuses) {
1228 QList<Dbt::CategoriesOverview> list;
1233QList<Dbt::Overview> DatabasePluginFotomon::overview(
const QString& category,
const QStringList& statuses) {
1235 QList<Dbt::Overview> list;
1240QList<Dbt::Overview> DatabasePluginFotomon::overview(
const QString& overviewId) {
1241 Q_UNUSED(overviewId);
1242 QList<Dbt::Overview> list;
1247QList<Dbt::OverviewList> DatabasePluginFotomon::overviewList() {
1248 QList<Dbt::OverviewList> list;
Vlastní rozšíření QSqlQuery o primitivní transakce a logování
static QVariant data(const QByteArray &json)
Converts json to data.
static QByteArray json(const QVariant &data)
Converts data to json.