C++: Fix component replace in PriceListSpecification
authorjani <jani@asema.com>
Tue, 7 Jan 2020 22:14:52 +0000 (00:14 +0200)
committerjani <jani@asema.com>
Tue, 7 Jan 2020 22:14:52 +0000 (00:14 +0200)
Common/C++/SmartAPI/smartapi/common/ClassMapper.h
Common/C++/SmartAPI/smartapi/model/.gitignore [new file with mode: 0644]
Common/C++/SmartAPI/smartapi/model/PriceListSpecification.cpp
Common/C++/SmartAPI/smartapi/model/PriceSpecification.cpp
Common/C++/SmartAPI/tests/TestSequences.cpp

index 9939d4fd5175644692482bffb749d806c8276087..5419343136e3860cdc4030cefc2e1dfb51aac489 100644 (file)
@@ -104,20 +104,20 @@ public:
                return NULL;
        }
        
-       Obj* getClass(QList<QString> typelist)
+       static Obj* getClass(QList<QString> typelist)
        {
                for (int i = 0; i < typelist.length(); i++) {
-                       Obj* o = getClass(typelist.at(i));
+                       Obj* o =  ClassMapper::getClass(typelist.at(i));
                        if (o != NULL) return o;
                }
                return NULL;
        }
        
-       Obj* getClass(QList<QString> typelist, Obj* oo)
+       static Obj* getClass(QList<QString> typelist, Obj* oo)
        {
                if (typelist.length() == 0) return new Obj(oo); // qDebug() << "WARNING, cannot copy an object with no type information";
                for (int i = 0; i < typelist.length(); i++) {
-                       Obj* o = getClass(typelist.at(i), oo);
+                       Obj* o = ClassMapper::getClass(typelist.at(i), oo);
                        if (o != NULL) return o;
                }
                return NULL;
@@ -207,7 +207,7 @@ public:
                return NULL;
        }
        
-       Obj* getClass(QString type, Obj* o)
+       static Obj* getClass(QString type, Obj* o)
        {
                if (type == RESOURCE__ABILITY) return new Ability((Ability*)o);
                if (type == RESOURCE__ABSTRACTENTITY) return new AbstractEntity((AbstractEntity*)o);
@@ -345,16 +345,15 @@ public:
                if (Address* oo                         = dynamic_cast<Address*>(o)) return oo;
                if (Coordinates* oo             = dynamic_cast<Coordinates*>(o)) { return oo; }
                if (Offering* oo                                                                                        = dynamic_cast<Offering*>(o)) { return oo; }
-               if (PriceSpecification* oo                                                                      = dynamic_cast<PriceSpecification*>(o)) { return oo; }
                if (UnitPriceSpecification* oo                                                          = dynamic_cast<UnitPriceSpecification*>(o)) { return oo; }
                if (SubscriptionPriceSpecification* oo                                          = dynamic_cast<SubscriptionPriceSpecification*>(o)) { return oo; }
                if (Transaction* oo                                                                             = dynamic_cast<Transaction*>(o)) { return oo; }
+               if (LinearCalculation* oo                                                                       = dynamic_cast<LinearCalculation*>(o)) { return oo; }
 
                if (PriceListSpecification* oo                                                          = dynamic_cast<PriceListSpecification*>(o)) { return oo; }
                if (TimeDependentPriceSpecification* oo                                         = dynamic_cast<TimeDependentPriceSpecification*>(o)) { return oo; }
                if (PropertyDependentPriceSpecification* oo                                     = dynamic_cast<PropertyDependentPriceSpecification*>(o)) { return oo; }
                if (DurationDependentPriceSpecification* oo                                     = dynamic_cast<DurationDependentPriceSpecification*>(o)) { return oo; }
-               if (LinearCalculation* oo                                                                       = dynamic_cast<LinearCalculation*>(o)) { return oo; }
                if (TravelDistanceDependentPriceSpecification* oo                       = dynamic_cast<TravelDistanceDependentPriceSpecification*>(o)) { return oo; }
                if (DistanceDependentPriceSpecification* oo                                     = dynamic_cast<DistanceDependentPriceSpecification*>(o)) { return oo; }
                if (ScriptDependentPriceSpecification* oo                                       = dynamic_cast<ScriptDependentPriceSpecification*>(o)) { return oo; }
@@ -364,6 +363,7 @@ public:
                if (ZoneTravelDurationDependentPriceSpecification* oo           = dynamic_cast<ZoneTravelDurationDependentPriceSpecification*>(o)) { return oo; }
                if (DurationAtDistanceDependentPriceSpecification* oo           = dynamic_cast<DurationAtDistanceDependentPriceSpecification*>(o)) { return oo; }
                if (DurationAtZoneDependentPriceSpecification* oo                       = dynamic_cast<DurationAtZoneDependentPriceSpecification*>(o)) { return oo; }
+               if (PriceSpecification* oo                                                                      = dynamic_cast<PriceSpecification*>(o)) { return oo; }
 
                return o;
        }
diff --git a/Common/C++/SmartAPI/smartapi/model/.gitignore b/Common/C++/SmartAPI/smartapi/model/.gitignore
new file mode 100644 (file)
index 0000000..e69de29
index bb9de966d288b4c1685dc9b967b62a920fbbb84c..0bf2d3b538034d18ea6a7dfe55d1da3ca5ec5c1f 100644 (file)
@@ -88,7 +88,6 @@ PriceSpecification* PriceListSpecification::replacePriceSpecification(PriceSpeci
                        // of some other list so only the caller can know whether it should actually be destroyed.
                        if (removedFromThisList) {
                                removed = i->getItem();
-                               delete i;
                        }
 
                        // Put the new one as last item
index 2617afc0b4b75e7a6ab3ddf74269562ecfddedeb..a7ba318c12592e76e0559f934c05d167ef24fc01 100755 (executable)
@@ -71,7 +71,7 @@ PriceSpecification::PriceSpecification(PriceSpecification* o) : GrObj(o)
        SET_PROPERTY_REFERENCE(PROPERTY__SECONDARYUNIT, mSecondaryUnit, Variant);
        SET_PROPERTY_REFERENCE(PROPERTY__VOUCHER, mVoucher, Voucher);
        SET_PROPERTY_REFERENCE(PROPERTY__CONDITION, mCondition, Condition);
-       setType(RESOURCE__PRICESPECIFICATION);
+       setTypes(o->getTypes());
 }
 
 PriceSpecification::~PriceSpecification()
index 9f0572c8aacf8ff7306d6a9e9825ed871d6d21c7..21ac45fab0d768cc78ed8b62722842d0a44b10f5 100644 (file)
@@ -25,6 +25,7 @@
 #include "smartapi/common/Tools.h"
 #include "smartapi/common/SmartAPICrypto.h"
 #include "smartapi/common/UnitConverter.h"
+#include "smartapi/common/ClassMapper.h"
 #include "smartapi/agents/OAuthAgent.h"
 #include "smartapi/agents/RegistrationAgent.h"
 #include "smartapi/agents/SearchAgent.h"
@@ -3101,6 +3102,137 @@ bool priceSpecificationCopyTest()
        }
 }
 
+bool priceListCombineTest()
+{
+       bool ret = true;
+
+       PriceListSpecification* destinationPriceList;
+       PriceListSpecification* sourcePriceList1;
+       PriceListSpecification* sourcePriceList2;
+
+       destinationPriceList = new PriceListSpecification();
+       sourcePriceList1 = new PriceListSpecification("http://sourcespec");
+       sourcePriceList2 = new PriceListSpecification("http://sourcespec");
+
+       PropertyDependentPriceSpecification* ps11 = new PropertyDependentPriceSpecification("http://prop1");
+       ps11->setUnit(RESOURCE__EURO);
+       ps11->setReferenceObject("http://someobject1.com");
+       ps11->setProperty("http://proper.1.ty");
+
+       PropertyDependentPriceSpecification* ps12 = new PropertyDependentPriceSpecification("http://prop2");
+       ps12->setUnit(RESOURCE__EURO);
+       ps12->setReferenceObject("http://someobject2.com");
+       ps12->setProperty("http://proper.2.ty");
+
+       PropertyDependentPriceSpecification* ps21 = new PropertyDependentPriceSpecification("http://prop1");
+       ps21->setUnit(RESOURCE__EURO);
+       ps21->setReferenceObject("http://someobject1.com");
+       ps21->setProperty("http://proper.1.ty");
+
+       PropertyDependentPriceSpecification* ps22 = new PropertyDependentPriceSpecification("http://prop2");
+       ps22->setUnit(RESOURCE__EURO);
+       ps22->setReferenceObject("http://someobject2.replaced.com");
+       ps22->setProperty("http://proper.2.replaced.ty");
+
+       PropertyDependentPriceSpecification* ps23 = new PropertyDependentPriceSpecification("http://prop3");
+       ps23->setUnit(RESOURCE__EURO);
+       ps23->setReferenceObject("http://someobject3.com");
+       ps23->setProperty("http://proper.3.ty");
+
+       sourcePriceList1->addPriceSpecification(ps11);
+       sourcePriceList1->addPriceSpecification(ps12);
+       sourcePriceList2->addPriceSpecification(ps21);
+       sourcePriceList2->addPriceSpecification(ps22);
+       sourcePriceList2->addPriceSpecification(ps23);
+
+       if (destinationPriceList->getIdentifierUri().length() == 0) {
+               destinationPriceList->setIdentifierUri(sourcePriceList1->getIdentifierUri());
+       }
+
+       qDebug() << "Add, round 1";
+       PropertyList<PriceSpecification*> specs = sourcePriceList1->getPriceSpecifications();
+       for (PropertyListItem<PriceSpecification*>* i = specs.firstItem(); i != nullptr; i = i->next()) {
+               if (i->getItem()) {
+                       PriceSpecification* compo = i->getItem();
+                       qDebug() << "Adding" << compo->getIdentifierUri();
+
+                       // Only add the component directly if it is not there yet
+                       if (!destinationPriceList->hasPriceSpecification(compo->getIdentifierUri())) {
+                               destinationPriceList->addPriceSpecification(dynamic_cast<PriceSpecification*>(ClassMapper::getClass(compo->getTypes(), compo)));
+                       } else {
+                               qDebug() << "** Replace on round 1, should not happen.";
+                               PriceSpecification* replaced = destinationPriceList->replacePriceSpecification(dynamic_cast<PriceSpecification*>(ClassMapper::getClass(compo->getTypes(), compo)));
+                               Q_UNUSED(replaced);
+                       }
+               }
+       }
+
+       // We also want conditions and vouchers, if those do not exist yet
+       if (sourcePriceList1->hasVoucher() && !destinationPriceList->hasVoucher()) {
+               destinationPriceList->setVoucher(new Voucher(sourcePriceList1->getVoucher()));
+       }
+
+       if (sourcePriceList1->hasCondition() && !destinationPriceList->hasCondition()) {
+               destinationPriceList->setCondition(new Condition(sourcePriceList1->getCondition()));
+       }
+
+       // We've taken all the components, get rid of the list
+       sourcePriceList1->destroyCascade();
+
+
+       qDebug() << "Add, round 1 done";
+       destinationPriceList->turtlePrint();
+
+       qDebug() << "Add, round <2>";
+       PropertyList<PriceSpecification*> specs2 = sourcePriceList2->getPriceSpecifications();
+       for (PropertyListItem<PriceSpecification*>* i = specs2.firstItem(); i != nullptr; i = i->next()) {
+               if (i->getItem()) {
+                       PriceSpecification* compo = i->getItem();
+                       qDebug() << "Adding" << compo->getIdentifierUri();
+                       // Only add the component directly if it is not there yet
+                       if (!destinationPriceList->hasPriceSpecification(compo->getIdentifierUri())) {
+                               destinationPriceList->addPriceSpecification(dynamic_cast<PriceSpecification*>(ClassMapper::getClass(compo->getTypes(), compo)));
+                       } else {
+                               PriceSpecification* replaced = destinationPriceList->replacePriceSpecification(dynamic_cast<PriceSpecification*>(ClassMapper::getClass(compo->getTypes(), compo)));
+                               replaced->destroyCascade();
+                       }
+               }
+       }
+
+       // We also want conditions and vouchers, if those do not exist yet
+       if (sourcePriceList2->hasVoucher() && !destinationPriceList->hasVoucher()) {
+               destinationPriceList->setVoucher(new Voucher(sourcePriceList2->getVoucher()));
+       }
+
+       if (sourcePriceList2->hasCondition() && !destinationPriceList->hasCondition()) {
+               destinationPriceList->setCondition(new Condition(sourcePriceList2->getCondition()));
+       }
+
+       // We've taken all the components, get rid of the list
+       sourcePriceList2->destroyCascade();
+
+       qDebug() << "Add, round 2 done.";
+       qDebug() << "\nFinal result:\n";
+       destinationPriceList->turtlePrint();
+
+       qDebug() << "\n\nIndividual components:\n";
+       int index = 1;
+       PropertyList<PriceSpecification*> specs3 = destinationPriceList->getPriceSpecifications();
+       for (PropertyListItem<PriceSpecification*>* i = specs3.firstItem(); i != nullptr; i = i->next()) {
+               if (i->getItem()) {
+                       if (PropertyDependentPriceSpecification* psn = dynamic_cast<PropertyDependentPriceSpecification*>(i->getItem())) {
+                               qDebug() << psn->getReferenceObject();
+                               if (index == 1) ret = ret && psn->getReferenceObject() == "http://someobject1.com";
+                               if (index == 2) ret = ret && psn->getReferenceObject() == "http://someobject2.replaced.com";
+                               if (index == 3) ret = ret && psn->getReferenceObject() == "http://someobject3.com";
+                               index++;
+                       }
+               }
+       }
+       destinationPriceList->destroyCascade();
+       return ret;
+}
+
 bool priceSpecificationTimeDependentSerializeParseTest()
 {
        TimeDependentPriceListSpecification* tdps = new TimeDependentPriceListSpecification();
@@ -3297,7 +3429,7 @@ int main(int argc, char *argv[])
        QCoreApplication app(argc, argv);
 
        durationTest();
-       durationInTemporalContextTest();
+       // durationInTemporalContextTest();
 
        //modelReadTest();
 
@@ -3635,11 +3767,15 @@ int main(int argc, char *argv[])
                qDebug() << "\nPRICELIST COPY CONSTRUCTOR TEST FAILED!";
                return -1;
        }
+       */
+       qDebug() << "\n\nPRICELIST COMBINE TEST";
+       if (!priceListCombineTest()) {
+               qDebug() << "\nPRICELIST COMBINE TEST FAILED!";
+               return -1;
+       }
 
        //currencyConversionTest();
 
-       */
-
        /*qDebug() << "\n\nTIME DEPENDENT PRICELIST TEST";
        if (!priceSpecificationTimeDependentSerializeParseTest()) {
                qDebug() << "\nTIME DEPENDENT PRICELIST TEST!";