File indexing completed on 2024-05-12 16:45:25

0001 /***************************************************************************
0002  * SPDX-FileCopyrightText: 2022 S. MANKOWSKI stephane@mankowski.fr
0003  * SPDX-FileCopyrightText: 2022 G. DE BURE support@mankowski.fr
0004  * SPDX-License-Identifier: GPL-3.0-or-later
0005  ***************************************************************************/
0006 /** @file
0007  * This file is a test script.
0008  *
0009  * @author Stephane MANKOWSKI / Guillaume DE BURE
0010  */
0011 #include "skgtestmacro.h"
0012 #include "skgbankincludes.h"
0013 #include "skgservices.h"
0014 
0015 /**
0016  * The main function of the unit test
0017  * @param argc the number of arguments
0018  * @param argv the list of arguments
0019  */
0020 int main(int argc, char** argv)
0021 {
0022     Q_UNUSED(argc)
0023     Q_UNUSED(argv)
0024 
0025     // Init test
0026     SKGINITTEST(true)
0027 
0028     struct TestData {
0029         bool sourceOperationIsTemplate;
0030         bool recurrentOperationIsTemplate;
0031     };
0032 
0033     std::vector<TestData> testDataSet {
0034         { false, false },
0035         { false, true },
0036         { true, true },
0037     };
0038 
0039     // ============================================================================
0040     for (const auto& testData : testDataSet) {
0041         const auto sourceOperationIsTemplate = testData.sourceOperationIsTemplate;
0042         const auto recurrentOperationIsTemplate = testData.recurrentOperationIsTemplate;
0043         const bool createTemplateForRecurrent = !sourceOperationIsTemplate && recurrentOperationIsTemplate;
0044         SKGTRACE << "####### Test data set:" << SKGENDL;
0045         SKGTRACE << "####### sourceOperationIsTemplate=" << sourceOperationIsTemplate << SKGENDL;
0046         SKGTRACE << "####### recurrentOperationIsTemplate=" << recurrentOperationIsTemplate << SKGENDL;
0047         SKGTRACE << "####### createTemplateForRecurrent=" << createTemplateForRecurrent << SKGENDL;
0048 
0049         // Test bank document
0050         SKGDocumentBank document1;
0051         SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
0052         SKGBankObject bank(&document1);
0053         SKGAccountObject account;
0054         SKGUnitObject unit_euro(&document1);
0055         SKGUnitValueObject unit_euro_val1;
0056         QDate d1 = QDate::currentDate().addMonths(-6);
0057         QDate d2 = QDate::currentDate().addMonths(-4);
0058         SKGError err;
0059         {
0060             // Scope of the transaction
0061             SKGBEGINTRANSACTION(document1, QStringLiteral("BANK_T1"), err)
0062 
0063             // Creation bank
0064             SKGTESTERROR(QStringLiteral("BANK:setName"), bank.setName(QStringLiteral("CREDIT COOP")), true)
0065             SKGTESTERROR(QStringLiteral("BANK:save"), bank.save(), true)
0066 
0067             // Creation account
0068             SKGTESTERROR(QStringLiteral("BANK:addAccount"), bank.addAccount(account), true)
0069             SKGTESTERROR(QStringLiteral("ACCOUNT:setName"), account.setName(QStringLiteral("Courant steph")), true)
0070             SKGTESTERROR(QStringLiteral("ACCOUNT:save"), account.save(), true)
0071 
0072             // Creation unit
0073             SKGTESTERROR(QStringLiteral("UNIT:setName"), unit_euro.setName(QStringLiteral("euro")), true)
0074             SKGTESTERROR(QStringLiteral("UNIT:save"), unit_euro.save(), true)
0075 
0076             // Creation unitvalue
0077             SKGTESTERROR(QStringLiteral("UNIT:addUnitValue"), unit_euro.addUnitValue(unit_euro_val1), true)
0078             SKGTESTERROR(QStringLiteral("UNITVALUE:setQuantity"), unit_euro_val1.setQuantity(1), true)
0079             SKGTESTERROR(QStringLiteral("UNITVALUE:setDate"), unit_euro_val1.setDate(d1), true)
0080             SKGTESTERROR(QStringLiteral("UNITVALUE:save"), unit_euro_val1.save(), true)
0081 
0082             const auto createOperation = [&](SKGOperationObject & op, const QDate & operationDate, const QString & comment, bool isTemplate) {
0083                 SKGTESTERROR(QStringLiteral("ACCOUNT:addOperation"), account.addOperation(op), true)
0084 
0085                 SKGTESTERROR(QStringLiteral("OP:setTemplate"), op.setTemplate(isTemplate), true)
0086                 SKGTESTERROR(QStringLiteral("OP:setMode"), op.setMode(QStringLiteral("cheque")), true)
0087                 SKGTESTERROR(QStringLiteral("OP:setComment"), op.setComment(comment), true)
0088                 SKGTESTERROR(QStringLiteral("OP:setDate"), op.setDate(operationDate), true)
0089                 SKGTESTERROR(QStringLiteral("OP:setUnit"), op.setUnit(unit_euro), true)
0090                 SKGTESTERROR(QStringLiteral("OP:save"), op.save(), true)
0091             };
0092 
0093             const auto addSuboperations = [&](SKGOperationObject & op) {
0094                 {
0095                     SKGSubOperationObject subop;
0096                     SKGTESTERROR(QStringLiteral("OP:addSubOperation"), op.addSubOperation(subop), true)
0097                     SKGTESTERROR(QStringLiteral("SUBOP:setQuantity"), subop.setQuantity(8.5), true)
0098                     SKGTESTERROR(QStringLiteral("SUBOP:save"), subop.save(), true)
0099                 }
0100                 {
0101                     SKGSubOperationObject subop;
0102                     SKGTESTERROR(QStringLiteral("OP:addSubOperation"), op.addSubOperation(subop), true)
0103                     SKGTESTERROR(QStringLiteral("SUBOP:setQuantity"), subop.setQuantity(10), true)
0104                     SKGTESTERROR(QStringLiteral("SUBOP:save"), subop.save(), true)
0105                 }
0106             };
0107 
0108             SKGOperationObject op1;
0109             SKGOperationObject templateOp1;
0110 
0111             SKGTRACE << "####### Test recurrent with an unsaved operation" << SKGENDL;
0112             SKGTESTERROR(QStringLiteral("ACCOUNT:addOperation"), account.addOperation(op1), true)
0113 
0114             SKGObjectBase::SKGListSKGObjectBase recups;
0115             SKGTESTERROR(QStringLiteral("OP:getRecurrentOperations"), op1.getRecurrentOperations(recups), false)
0116             SKGTEST(QStringLiteral("RECOP:recops.count"), recups.count(), 0)
0117             SKGTEST(QStringLiteral("OP:getRecurrentOperation"), op1.getRecurrentOperation(), 0)
0118 
0119             SKGRecurrentOperationObject recuope1;
0120             SKGTESTERROR(QStringLiteral("OP:addRecurrentOperation"), op1.addRecurrentOperation(recuope1), false)
0121             SKGTEST(QStringLiteral("OP:getRecurrentOperation"), op1.getRecurrentOperation(), 0)
0122 
0123             const auto addGroupedOperation = [&](SKGOperationObject & op, const QDate & operationDate, const QString & comment) {
0124                 SKGTESTERROR(QStringLiteral("OP:load"), op.load(), true) {
0125                     SKGOperationObject op2;
0126                     SKGTESTERROR(QStringLiteral("ACCOUNT:addOperation"), account.addOperation(op2), true)
0127                     SKGTESTERROR(QStringLiteral("OP:setMode"), op2.setMode(QStringLiteral("cheque")), true)
0128                     SKGTESTERROR(QStringLiteral("OP:setComment"), op2.setComment(comment), true)
0129                     SKGTESTERROR(QStringLiteral("OP:setDate"), op2.setDate(operationDate), true)
0130                     SKGTESTERROR(QStringLiteral("OP:setUnit"), op2.setUnit(unit_euro), true)
0131                     SKGTESTERROR(QStringLiteral("OP:save"), op2.save(), true)
0132 
0133                     SKGSubOperationObject subop;
0134                     SKGTESTERROR(QStringLiteral("OP:addSubOperation"), op2.addSubOperation(subop), true)
0135                     SKGTESTERROR(QStringLiteral("SUBOP:setQuantity"), subop.setQuantity(8.5), true)
0136                     SKGTESTERROR(QStringLiteral("SUBOP:save"), subop.save(), true)
0137 
0138                     SKGTESTERROR(QStringLiteral("OP:save"), op.setGroupOperation(op2), true)
0139                     SKGTESTERROR(QStringLiteral("OP:save"), op.save(), true)
0140                 }
0141             };
0142 
0143             const auto createRecurrentOperation = [&](SKGRecurrentOperationObject & recuope, SKGOperationObject & sourceOp, SKGOperationObject & templateOp) {
0144                 SKGOperationObject op = sourceOp;
0145                 if (createTemplateForRecurrent) {
0146                     IFOKDO(err, op.duplicate(templateOp, op.getDate(), true))
0147                     op = templateOp;
0148                 }
0149 
0150                 SKGTESTERROR(QStringLiteral("OP:addRecurrentOperation"), op.addRecurrentOperation(recuope), true)
0151                 SKGTESTERROR(QStringLiteral("RECOP:setPeriodIncrement"), recuope.setPeriodIncrement(2), true)
0152                 SKGTESTERROR(QStringLiteral("RECOP:setPeriodUnit"), recuope.setPeriodUnit(SKGRecurrentOperationObject::MONTH), true)
0153                 SKGTESTERROR(QStringLiteral("RECOP:setAutoWriteDays"), recuope.setAutoWriteDays(6), true)
0154                 SKGTESTERROR(QStringLiteral("RECOP:autoWriteEnabled"), recuope.autoWriteEnabled(true), true)
0155                 SKGTESTERROR(QStringLiteral("RECOP:setWarnDays"), recuope.setWarnDays(10), true)
0156                 SKGTESTERROR(QStringLiteral("RECOP:warnEnabled"), recuope.warnEnabled(true), true)
0157                 SKGTESTERROR(QStringLiteral("RECOP:setTimeLimit"), recuope.setTimeLimit(d2), true)
0158                 SKGTESTERROR(QStringLiteral("RECOP:timeLimit"), recuope.timeLimit(true), true)
0159                 SKGTEST(QStringLiteral("OP:getRecurrentOperation"), op.getRecurrentOperation(), 0)
0160                 SKGTESTERROR(QStringLiteral("RECOP:save"), recuope.save(), true)
0161 
0162                 if (createTemplateForRecurrent) {
0163                     SKGTESTERROR(QStringLiteral("RECOP:save"), sourceOp.setAttribute(QStringLiteral("r_recurrentoperation_id"), SKGServices::intToString(recuope.getID())), true)
0164                     SKGTESTERROR(QStringLiteral("OP:save"), sourceOp.save(), true)
0165                 }
0166 
0167                 SKGTESTBOOL(QStringLiteral("RECOP:isTemplate"), recuope.isTemplate(), recurrentOperationIsTemplate)
0168             };
0169 
0170             SKGTRACE << "####### Test recurrent with a saved operation" << SKGENDL;
0171             createOperation(op1, d1, QStringLiteral("10 tickets"), sourceOperationIsTemplate);
0172             addSuboperations(op1);
0173             addGroupedOperation(op1, d1, QStringLiteral("10 tickets"));
0174 
0175             createRecurrentOperation(recuope1, op1, templateOp1);
0176             SKGTEST(QStringLiteral("OP:getRecurrentOperation"), op1.getRecurrentOperation(), recuope1.getID())
0177             SKGTESTBOOL(QStringLiteral("OP:exist"), templateOp1.exist(), createTemplateForRecurrent)
0178 
0179             SKGRecurrentOperationObject recuope2(recuope1);
0180             SKGRecurrentOperationObject recuope3(SKGObjectBase(recuope1.getDocument(), QStringLiteral("xxx"), recuope1.getID()));
0181             SKGRecurrentOperationObject recuope4(SKGNamedObject(recuope1.getDocument(), QStringLiteral("xxx"), recuope1.getID()));
0182 
0183             SKGObjectBase::SKGListSKGObjectBase recops;
0184             SKGTESTERROR(QStringLiteral("OP:getRecurrentOperations"), op1.getRecurrentOperations(recops), true)
0185             SKGTEST(QStringLiteral("RECOP:recops.count"), recops.count(), createTemplateForRecurrent ? 0 : 1)
0186             if (createTemplateForRecurrent) {
0187                 SKGTESTERROR(QStringLiteral("OP:getRecurrentOperations"), templateOp1.getRecurrentOperations(recops), true)
0188                 SKGTEST(QStringLiteral("RECOP:recops.count"), recops.count(), 1)
0189             }
0190 
0191             SKGTEST(QStringLiteral("RECOP:getPeriodIncrement"), recuope1.getPeriodIncrement(), 2)
0192             SKGTEST(QStringLiteral("RECOP:getPeriodUnit"), static_cast<unsigned int>(recuope1.getPeriodUnit()), static_cast<unsigned int>(SKGRecurrentOperationObject::MONTH))
0193             SKGTEST(QStringLiteral("RECOP:getAutoWriteDays"), recuope1.getAutoWriteDays(), 6)
0194             SKGTESTBOOL("RECOP:isAutoWriteEnabled", recuope1.isAutoWriteEnabled(), true)
0195             SKGTEST(QStringLiteral("RECOP:getWarnDays"), recuope1.getWarnDays(), 10)
0196             SKGTESTBOOL("RECOP:isWarnEnabled", recuope1.isWarnEnabled(), true)
0197             SKGTEST(QStringLiteral("RECOP:getTimeLimit"), recuope1.getTimeLimit(), 3)
0198             SKGTESTBOOL("RECOP:hasTimeLimit", recuope1.hasTimeLimit(), true)
0199             SKGTEST(QStringLiteral("RECOP:getDate"), recuope1.getDate().toString(), d1.toString())
0200 
0201             SKGOperationObject ope2;
0202             SKGTESTERROR(QStringLiteral("RECOP:getParentOperation"), recuope1.getParentOperation(ope2), true)
0203             SKGTESTBOOL("RECOP:op1==ope2", (op1 == ope2), !createTemplateForRecurrent)
0204             SKGTESTBOOL("RECOP:templateOp1==ope2", (templateOp1 == ope2), createTemplateForRecurrent)
0205             SKGTEST(QStringLiteral("OP:getRecurrentOperation"), ope2.getRecurrentOperation(), recuope1.getID())
0206 
0207             document1.dump(DUMPOPERATION);
0208 
0209             const auto testProcess = [&](SKGRecurrentOperationObject & recuope, int resultingOperationsCount) {
0210                 int nbi = 0;
0211                 SKGTESTERROR(QStringLiteral("RECOP:process"), recuope.process(nbi), true)
0212                 SKGTEST(QStringLiteral("RECOP:nbi"), nbi, resultingOperationsCount)
0213                 SKGOperationObject opeP;
0214                 SKGTESTERROR(QStringLiteral("RECOP:getParentOperation"), recuope.getParentOperation(opeP), true)
0215                 SKGTESTBOOL("RECOP:op1!=opeP", (op1 != opeP), !sourceOperationIsTemplate)
0216                 SKGTEST(QStringLiteral("OP:getRecurrentOperation"), opeP.getRecurrentOperation(), recuope.getID())
0217 
0218                 SKGObjectBase::SKGListSKGObjectBase recopsP;
0219                 SKGTESTERROR(QStringLiteral("RECOP:getRecurredOperations"), recuope.getRecurredOperations(recopsP), true)
0220                 SKGTEST(QStringLiteral("RECOP:recops.count"), recopsP.count(), resultingOperationsCount + (createTemplateForRecurrent ? 1 : 0))
0221                 for (const auto& opr : qAsConst(recopsP)) {
0222                     SKGTEST(QStringLiteral("OP:getAttribute"), opr.getAttribute(QStringLiteral("r_recurrentoperation_id")), SKGServices::intToString(recuope.getID()))
0223                 }
0224 
0225                 SKGTESTERROR(QStringLiteral("RECOP:SKGRecurrentOperationObject::process"), SKGRecurrentOperationObject::process(&document1, nbi), true)
0226             };
0227 
0228             SKGTRACE << "####### Process a schedule" << SKGENDL;
0229             testProcess(recuope1, 3);
0230             document1.dump(DUMPOPERATION);
0231 
0232             SKGTESTERROR(QStringLiteral("RECOP:setPeriodIncrement"), recuope1.setPeriodIncrement(2), true)
0233             SKGTESTERROR(QStringLiteral("RECOP:setPeriodUnit"), recuope1.setPeriodUnit(SKGRecurrentOperationObject::DAY), true)
0234             recuope1.getNextDate();
0235             SKGTESTERROR(QStringLiteral("RECOP:setPeriodUnit"), recuope1.setPeriodUnit(SKGRecurrentOperationObject::WEEK), true)
0236             recuope1.getNextDate();
0237             SKGTESTERROR(QStringLiteral("RECOP:setPeriodUnit"), recuope1.setPeriodUnit(SKGRecurrentOperationObject::MONTH), true)
0238             recuope1.getNextDate();
0239             SKGTESTERROR(QStringLiteral("RECOP:setPeriodUnit"), recuope1.setPeriodUnit(SKGRecurrentOperationObject::YEAR), true)
0240             recuope1.getNextDate();
0241 
0242             const auto testAssign = [&](SKGRecurrentOperationObject & recuope, const QDate & operationDate, const QString & comment, int resultingOperationsCount) {
0243                 SKGOperationObject opA;
0244                 SKGTESTERROR(QStringLiteral("OP:duplicate"), op1.duplicate(opA, operationDate, false), true)
0245                 SKGTESTERROR(QStringLiteral("OP:setComment"), opA.setComment(comment), true)
0246                 SKGTESTERROR(QStringLiteral("OP:duplicate"), opA.setAttribute(QStringLiteral("r_recurrentoperation_id"), QString("0")), true)
0247                 SKGTESTERROR(QStringLiteral("OP:save"), opA.save(), true)
0248 
0249                 // Update comment for all grouped transactions
0250                 SKGObjectBase::SKGListSKGObjectBase goupops;
0251                 SKGTESTERROR(QStringLiteral("OP:getGroupedOperations"), opA.getGroupedOperations(goupops), true)
0252                 for (int i = 0; !err && i < goupops.count(); ++i) {
0253                     SKGOperationObject groupop(goupops.at(i));
0254                     SKGTESTERROR(QStringLiteral("OP:setComment"), groupop.setComment(comment), true)
0255                     SKGTESTERROR(QStringLiteral("OP:save"), groupop.save(), true)
0256                 }
0257 
0258                 auto expectedRecurrentId = recuope.getID();
0259                 if (!recurrentOperationIsTemplate) {
0260                     SKGOperationObject parentOp;
0261                     SKGTESTERROR(QStringLiteral("RECOP:getParentOperation"), recuope.getParentOperation(parentOp), true)
0262                     if (operationDate >= parentOp.getDate()) {
0263                         // This transaction should become a parent for a non-template schedule
0264                         expectedRecurrentId = 0;
0265                     }
0266                 }
0267                 SKGTESTERROR(QStringLiteral("OP:setRecurrentOperation"), opA.setRecurrentOperation(recuope.getID()), true)
0268                 SKGTEST(QStringLiteral("OP:getAttribute"), opA.getAttribute(QStringLiteral("r_recurrentoperation_id")), SKGServices::intToString(expectedRecurrentId))
0269 
0270                 SKGObjectBase::SKGListSKGObjectBase recopsP;
0271                 SKGTESTERROR(QStringLiteral("RECOP:getRecurredOperations"), recuope.getRecurredOperations(recopsP), true)
0272                 SKGTEST(QStringLiteral("RECOP:recops.count"), recopsP.count(), resultingOperationsCount + (createTemplateForRecurrent ? 1 : 0))
0273                 for (const auto& opr : qAsConst(recopsP)) {
0274                     SKGTEST(QStringLiteral("OP:getAttribute"), opr.getAttribute(QStringLiteral("r_recurrentoperation_id")), SKGServices::intToString(recuope.getID()))
0275                 }
0276             };
0277 
0278             const auto removeOperation = [&](SKGOperationObject & op) {
0279                 const auto removeSubOp = [&](SKGSubOperationObject & subop) {
0280                     SKGTESTERROR(QStringLiteral("SUBOP:remove"), subop.remove(false), true)
0281                 };
0282                 const auto removeOpAndSubops = [&](SKGOperationObject & op) {
0283                     SKGObjectBase::SKGListSKGObjectBase subops;
0284                     SKGTESTERROR(QStringLiteral("OP:getSubOperations"), op.getSubOperations(subops), true)
0285                     for (int i = 0; !err && i < subops.count(); ++i) {
0286                         SKGSubOperationObject subop(subops.at(i));
0287                         removeSubOp(subop);
0288                     }
0289                     SKGTESTERROR(QStringLiteral("OP:remove"), op.remove(false), true)
0290                 };
0291                 const auto removeOp = [&](SKGOperationObject & op) {
0292                     if (op.isInGroup()) {
0293                         SKGObjectBase::SKGListSKGObjectBase groupops;
0294                         SKGTESTERROR(QStringLiteral("OP:getGroupedOperations"), op.getGroupedOperations(groupops), true)
0295                         for (int i = 0; !err && i < groupops.count(); ++i) {
0296                             SKGOperationObject groupop(groupops.at(i));
0297                             removeOpAndSubops(groupop);
0298                         }
0299                     } else {
0300                         removeOpAndSubops(op);
0301                     }
0302                 };
0303 
0304                 removeOp(op);
0305             };
0306 
0307             const auto removeAllScheduled = [&](SKGRecurrentOperationObject & recuope) {
0308                 SKGObjectBase::SKGListSKGObjectBase recops;
0309                 SKGTESTERROR(QStringLiteral("RECOP:getRecurredOperations"), recuope.getRecurredOperations(recops), true)
0310                 for (int i = 0; !err && i < recops.count(); ++i) {
0311                     SKGOperationObject op(recops.at(i));
0312                     removeOperation(op);
0313                 }
0314 
0315                 recuope.load();
0316                 SKGOperationObject parentOp;
0317                 SKGTESTERROR(QStringLiteral("RECOP:getParentOperation"), recuope.getParentOperation(parentOp), true)
0318 
0319                 SKGTESTERROR(QStringLiteral("RECOP:remove"), recuope.remove(false), true)
0320 
0321                 removeOperation(parentOp);
0322             };
0323 
0324             const auto testDocumentIsEmpty = [&]() {
0325                 bool exists = false;
0326                 SKGTESTERROR(QStringLiteral("DOC:existObjects"), document1.existObjects("operation", "", exists), true)
0327                 SKGTESTBOOL(QStringLiteral("DOC:operation.exists"), exists, false)
0328                 SKGTESTERROR(QStringLiteral("DOC:existObjects"), document1.existObjects("recurrentoperation", "", exists), true)
0329                 SKGTESTBOOL(QStringLiteral("DOC:recurrentoperation.exists"), exists, false)
0330                 SKGTESTERROR(QStringLiteral("DOC:existObjects"), document1.existObjects("suboperation", "", exists), true)
0331                 SKGTESTBOOL(QStringLiteral("DOC:recurrentoperation.suboperation"), exists, false)
0332             };
0333 
0334             QDate start_date, end_date;
0335 
0336             SKGTRACE << "####### Assign a schedule to a preceeding operation" << SKGENDL;
0337             start_date = d1.addMonths(-3);
0338             testAssign(recuope1, start_date, "10 tickets (old)", 4);
0339             document1.dump(DUMPOPERATION);
0340 
0341             SKGTRACE << "####### Assign a schedule to a succeeding operation" << SKGENDL;
0342             end_date = d2.addMonths(2);
0343             testAssign(recuope1, end_date, "10 tickets (new)", 5);
0344             document1.dump(DUMPOPERATION);
0345 
0346             SKGTRACE << "####### Remove all scheduled transactions" << SKGENDL;
0347             removeAllScheduled(recuope1);
0348             testDocumentIsEmpty();
0349             document1.dump(DUMPOPERATION);
0350 
0351             SKGTRACE << "####### Unassign last transaction from a schedule" << SKGENDL;
0352             {
0353                 SKGOperationObject op;
0354                 createOperation(op, d1, QStringLiteral("20 tickets"), sourceOperationIsTemplate);
0355 
0356                 SKGRecurrentOperationObject recuope;
0357                 SKGOperationObject templateOp;
0358                 createRecurrentOperation(recuope, op, templateOp);
0359 
0360                 const bool shouldFail = sourceOperationIsTemplate && recurrentOperationIsTemplate;
0361                 SKGTESTERROR(QStringLiteral("OP:setRecurrentOperation"), op.setRecurrentOperation(0), !shouldFail)
0362                 if (!shouldFail) {
0363                     SKGTEST(QStringLiteral("OP:getAttribute"), op.getAttribute(QStringLiteral("r_recurrentoperation_id")), QString("0"))
0364                 }
0365 
0366                 document1.dump(DUMPOPERATION);
0367 
0368                 recuope.load();
0369                 SKGTESTBOOL(QStringLiteral("RECOP:exist"), recuope.exist(), recurrentOperationIsTemplate)
0370 
0371                 if (createTemplateForRecurrent) {
0372                     SKGOperationObject parentOp;
0373                     SKGTESTERROR(QStringLiteral("RECOP:getParentOperation"), recuope.getParentOperation(parentOp), true)
0374                     SKGTESTBOOL(QStringLiteral("RECOP:exist"), parentOp.exist(), true)
0375                     SKGTESTBOOL("RECOP:templateOp==parentOp", (templateOp == parentOp), true)
0376                 }
0377 
0378                 removeAllScheduled(recuope);
0379                 removeOperation(op);
0380 
0381                 testDocumentIsEmpty();
0382             }
0383 
0384             SKGTRACE << "####### Remove last transaction from a schedule" << SKGENDL;
0385             {
0386                 SKGOperationObject op;
0387                 createOperation(op, d1, QStringLiteral("20 tickets"), sourceOperationIsTemplate);
0388 
0389                 SKGRecurrentOperationObject recuope;
0390                 SKGOperationObject templateOp;
0391                 createRecurrentOperation(recuope, op, templateOp);
0392 
0393                 removeOperation(op);
0394 
0395                 document1.dump(DUMPOPERATION);
0396 
0397                 recuope.load();
0398                 SKGTESTBOOL(QStringLiteral("RECOP:exist"), recuope.exist(), createTemplateForRecurrent)
0399 
0400                 if (createTemplateForRecurrent) {
0401                     SKGOperationObject parentOp;
0402                     SKGTESTERROR(QStringLiteral("RECOP:getParentOperation"), recuope.getParentOperation(parentOp), true)
0403                     SKGTESTBOOL(QStringLiteral("RECOP:exist"), parentOp.exist(), createTemplateForRecurrent)
0404                     SKGTESTBOOL("RECOP:templateOp==parentOp", (templateOp == parentOp), true)
0405                     removeAllScheduled(recuope);
0406                 }
0407 
0408                 testDocumentIsEmpty();
0409             }
0410 
0411             SKGTRACE << "####### Unassign non-last transaction from a schedule" << SKGENDL;
0412             {
0413                 SKGOperationObject op1;
0414                 createOperation(op1, d1, QStringLiteral("20 tickets"), sourceOperationIsTemplate);
0415 
0416                 SKGRecurrentOperationObject recuope;
0417                 SKGOperationObject templateOp;
0418                 createRecurrentOperation(recuope, op1, templateOp);
0419 
0420                 SKGOperationObject op2;
0421                 createOperation(op2, d2, QStringLiteral("15 tickets"), false);
0422                 SKGTESTERROR(QStringLiteral("OP:setRecurrentOperation"), op2.setRecurrentOperation(recuope.getID()), true)
0423 
0424                 SKGObjectBase::SKGListSKGObjectBase recopsP;
0425                 SKGTESTERROR(QStringLiteral("RECOP:getRecurredOperations"), recuope.getRecurredOperations(recopsP), true)
0426                 SKGTEST(QStringLiteral("RECOP:recopsP.count"), recopsP.count(), createTemplateForRecurrent ? 2 : 1)
0427                 SKGOperationObject firstOp(recopsP.first());
0428                 SKGTESTERROR(QStringLiteral("OP:setRecurrentOperation"), firstOp.setRecurrentOperation(0), true)
0429                 SKGTEST(QStringLiteral("OP:getAttribute"), firstOp.getAttribute(QStringLiteral("r_recurrentoperation_id")), QString("0"))
0430 
0431                 document1.dump(DUMPOPERATION);
0432 
0433                 recuope.load();
0434                 SKGTEST(QStringLiteral("RECOP:exist"), recuope.exist(), true)
0435 
0436                 SKGTESTERROR(QStringLiteral("RECOP:getRecurredOperations"), recuope.getRecurredOperations(recopsP), true)
0437                 SKGTEST(QStringLiteral("RECOP:recops.count"), recopsP.count(), createTemplateForRecurrent ? 1 : 0)
0438                 for (const auto& opr : qAsConst(recopsP)) {
0439                     SKGTEST(QStringLiteral("OP:getAttribute"), opr.getAttribute(QStringLiteral("r_recurrentoperation_id")), SKGServices::intToString(recuope.getID()))
0440                 }
0441 
0442                 SKGOperationObject parentOp;
0443                 SKGTESTERROR(QStringLiteral("RECOP:getParentOperation"), recuope.getParentOperation(parentOp), true)
0444                 SKGTEST(QStringLiteral("RECOP:exist"), parentOp.exist(), true)
0445                 SKGTESTBOOL("RECOP:templateOp==parentOp", (templateOp == parentOp), createTemplateForRecurrent)
0446                 SKGTEST(QStringLiteral("OP:getRecurrentOperation"), parentOp.getRecurrentOperation(), recuope.getID())
0447 
0448                 removeAllScheduled(recuope);
0449                 removeOperation(firstOp);
0450                 testDocumentIsEmpty();
0451             }
0452 
0453             SKGTRACE << "####### Remove non-last transaction from a schedule" << SKGENDL;
0454             {
0455                 SKGOperationObject op1;
0456                 createOperation(op1, d1, QStringLiteral("20 tickets"), sourceOperationIsTemplate);
0457 
0458                 SKGRecurrentOperationObject recuope;
0459                 SKGOperationObject templateOp;
0460                 createRecurrentOperation(recuope, op1, templateOp);
0461 
0462                 SKGOperationObject op2;
0463                 createOperation(op2, d2, QStringLiteral("15 tickets"), false);
0464                 SKGTESTERROR(QStringLiteral("OP:setRecurrentOperation"), op2.setRecurrentOperation(recuope.getID()), true)
0465 
0466                 SKGObjectBase::SKGListSKGObjectBase recopsP;
0467                 SKGTESTERROR(QStringLiteral("RECOP:getRecurredOperations"), recuope.getRecurredOperations(recopsP), true)
0468                 SKGTEST(QStringLiteral("RECOP:recopsP.count"), recopsP.count(), createTemplateForRecurrent ? 2 : 1)
0469                 SKGOperationObject firstOp(recopsP.first());
0470                 removeOperation(firstOp);
0471 
0472                 document1.dump(DUMPOPERATION);
0473 
0474                 recuope.load();
0475                 SKGTEST(QStringLiteral("RECOP:exist"), recuope.exist(), true)
0476 
0477                 SKGTESTERROR(QStringLiteral("RECOP:getRecurredOperations"), recuope.getRecurredOperations(recopsP), true)
0478                 SKGTEST(QStringLiteral("RECOP:recops.count"), recopsP.count(), createTemplateForRecurrent ? 1 : 0)
0479                 for (const auto& opr : qAsConst(recopsP)) {
0480                     SKGTEST(QStringLiteral("OP:getAttribute"), opr.getAttribute(QStringLiteral("r_recurrentoperation_id")), SKGServices::intToString(recuope.getID()))
0481                 }
0482 
0483                 SKGOperationObject parentOp;
0484                 SKGTESTERROR(QStringLiteral("RECOP:getParentOperation"), recuope.getParentOperation(parentOp), true)
0485                 SKGTEST(QStringLiteral("RECOP:exist"), parentOp.exist(), true)
0486                 SKGTESTBOOL("RECOP:templateOp==parentOp", (templateOp == parentOp), createTemplateForRecurrent)
0487                 SKGTEST(QStringLiteral("OP:getRecurrentOperation"), parentOp.getRecurrentOperation(), recuope.getID())
0488 
0489                 removeAllScheduled(recuope);
0490                 testDocumentIsEmpty();
0491             }
0492 
0493             SKGTRACE << "####### Toggle template mode for a schedule with a single operation" << SKGENDL;
0494             {
0495                 SKGOperationObject op;
0496                 createOperation(op, d1, QStringLiteral("20 tickets"), sourceOperationIsTemplate);
0497 
0498                 SKGRecurrentOperationObject recuope;
0499                 SKGOperationObject templateOp;
0500                 createRecurrentOperation(recuope, op, templateOp);
0501 
0502                 const bool newTemplateState = !recurrentOperationIsTemplate;
0503                 const bool shouldFail = sourceOperationIsTemplate && recurrentOperationIsTemplate;
0504                 SKGTESTERROR(QStringLiteral("RECOP:setTemplate"), recuope.setTemplate(newTemplateState), !shouldFail)
0505                 if (!shouldFail) {
0506                     SKGOperationObject parentOp;
0507                     SKGTESTERROR(QStringLiteral("RECOP:getParentOperation"), recuope.getParentOperation(parentOp), true)
0508                     SKGTEST(QStringLiteral("RECOP:exist"), parentOp.exist(), true)
0509                     SKGTESTBOOL("RECOP:parentOp.idTemplate", parentOp.isTemplate(), newTemplateState)
0510                 }
0511 
0512                 SKGObjectBase::SKGListSKGObjectBase recopsP;
0513                 SKGTESTERROR(QStringLiteral("RECOP:getRecurredOperations"), recuope.getRecurredOperations(recopsP), true)
0514                 SKGTEST(QStringLiteral("RECOP:recopsP.count"), recopsP.count(), !!newTemplateState && !sourceOperationIsTemplate ? 1 : 0)
0515 
0516                 document1.dump(DUMPOPERATION);
0517 
0518                 removeAllScheduled(recuope);
0519                 testDocumentIsEmpty();
0520             }
0521 
0522             SKGTRACE << "####### Toggle template mode for a schedule with several transactions" << SKGENDL;
0523             {
0524                 SKGOperationObject op1;
0525                 createOperation(op1, d1, QStringLiteral("20 tickets"), sourceOperationIsTemplate);
0526 
0527                 SKGRecurrentOperationObject recuope;
0528                 SKGOperationObject templateOp;
0529                 createRecurrentOperation(recuope, op1, templateOp);
0530 
0531                 SKGOperationObject op2;
0532                 createOperation(op2, d2, QStringLiteral("15 tickets"), false);
0533                 SKGTESTERROR(QStringLiteral("OP:setRecurrentOperation"), op2.setRecurrentOperation(recuope.getID()), true)
0534 
0535                 const bool newTemplateState = !recurrentOperationIsTemplate;
0536                 recuope.load();
0537                 SKGTESTERROR(QStringLiteral("RECOP:setTemplate"), recuope.setTemplate(newTemplateState), true)
0538                 SKGOperationObject parentOp;
0539                 SKGTESTERROR(QStringLiteral("RECOP:getParentOperation"), recuope.getParentOperation(parentOp), true)
0540                 SKGTEST(QStringLiteral("RECOP:exist"), parentOp.exist(), true)
0541                 SKGTESTBOOL("RECOP:parentOp.idTemplate", parentOp.isTemplate(), newTemplateState)
0542 
0543                 SKGObjectBase::SKGListSKGObjectBase recopsP;
0544                 SKGTESTERROR(QStringLiteral("RECOP:getRecurredOperations"), recuope.getRecurredOperations(recopsP), true)
0545                 SKGTEST(QStringLiteral("RECOP:recopsP.count"), recopsP.count(), !sourceOperationIsTemplate ? (!!newTemplateState ? 2 : 1) : 0)
0546 
0547                 document1.dump(DUMPOPERATION);
0548 
0549                 removeAllScheduled(recuope);
0550                 testDocumentIsEmpty();
0551             }
0552         }
0553     }
0554 
0555     // End test
0556     SKGENDTEST()
0557 }