DECLARE_EXPORT void ItemSupplier::validate(Action action) { // Catch null supplier and item pointers Supplier *sup = getSupplier(); Item *it = getItem(); Location *loc = getLocation(); if (!sup || !it) { // Invalid ItemSupplier model if (!sup && !it) throw DataException("Missing supplier and item on a itemsupplier"); else if (!sup) throw DataException("Missing supplier on a itemsupplier on item '" + it->getName() + "'"); else if (!it) throw DataException("Missing item on a itemsupplier on supplier '" + sup->getName() + "'"); } // Check if a ItemSupplier with 1) identical supplier, 2) identical item // 3) identical location, and 4) overlapping effectivity dates already exists Supplier::itemlist::const_iterator i = sup->getItems().begin(); for (; i != sup->getItems().end(); ++i) if (i->getItem() == it && i->getEffective().overlap(getEffective()) && i->getLocation() == loc && &*i != this) break; // Apply the appropriate action switch (action) { case ADD: if (i != sup->getItems().end()) { throw DataException("ItemSupplier of '" + sup->getName() + "' and '" + it->getName() + "' already exists"); } break; case CHANGE: throw DataException("Can't update a itemsupplier"); case ADD_CHANGE: // ADD is handled in the code after the switch statement if (i == sup->getItems().end()) break; throw DataException("Can't update a itemsupplier"); case REMOVE: // This ItemSupplier was only used temporarily during the reading process delete this; if (i == sup->getItems().end()) // Nothing to delete throw DataException("Can't remove nonexistent itemsupplier of '" + sup->getName() + "' and '" + it->getName() + "'"); delete &*i; return; } }
Location::~Location() { // Remove all references from buffers to this location for (Buffer::iterator buf = Buffer::begin(); buf != Buffer::end(); ++buf) if (buf->getLocation() == this) buf->setLocation(nullptr); // Remove all references from resources to this location for (Resource::iterator res = Resource::begin(); res != Resource::end(); ++res) if (res->getLocation() == this) res->setLocation(nullptr); // Remove all references from operations to this location for (Operation::iterator oper = Operation::begin(); oper != Operation::end(); ++oper) if (oper->getLocation() == this) oper->setLocation(nullptr); // Remove all references from demands to this location for (Demand::iterator dmd = Demand::begin(); dmd != Demand::end(); ++dmd) if (dmd->getLocation() == this) dmd->setLocation(nullptr); // Remove all item suppliers referencing this location for (Supplier::iterator sup = Supplier::begin(); sup != Supplier::end(); ++sup) { for (Supplier::itemlist::const_iterator it = sup->getItems().begin(); it != sup->getItems().end(); ) { if (it->getLocation() == this) { const ItemSupplier *itemsup = &*it; ++it; // Advance iterator before the delete delete itemsup; } else ++it; } } // The ItemDistribution objects are automatically deleted by the // destructor of the Association list class. }