00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <qdom.h>
00021 #include <QString>
00022
00023 #include <klocale.h>
00024
00025 #include <kdebug.h>
00026
00027 #include "kptaccount.h"
00028 #include "kptduration.h"
00029 #include "kptproject.h"
00030
00031 namespace KPlato
00032 {
00033
00034 Account::Account()
00035 : m_name(),
00036 m_description(),
00037 m_list(0),
00038 m_parent(0),
00039 m_accountList(),
00040 m_costPlaces() {
00041
00042 }
00043
00044 Account::Account(QString name, QString description)
00045 : m_name(name),
00046 m_description(description),
00047 m_list(0),
00048 m_parent(0),
00049 m_accountList(),
00050 m_costPlaces() {
00051
00052 }
00053
00054 Account::~Account() {
00055
00056 if (findAccount() == this) {
00057 removeId();
00058 }
00059 if (m_list)
00060 m_list->accountDeleted(this);
00061
00062 while (!m_accountList.isEmpty())
00063 delete m_accountList.takeFirst();
00064
00065 while (!m_costPlaces.isEmpty())
00066 delete m_costPlaces.takeFirst();
00067 }
00068
00069
00070 void Account::setName(QString name) {
00071 if (findAccount() == this) {
00072 removeId();
00073 }
00074 m_name = name;
00075 insertId();
00076 }
00077
00078 void Account::append(Account *account){
00079 Q_ASSERT(account);
00080 m_accountList.append(account);
00081 account->setList(m_list);
00082 account->setParent(this);
00083 insertId(account);
00084 }
00085
00086 void Account::insertChildren() {
00087 foreach (Account *a, m_accountList) {
00088 a->setList(m_list);
00089 a->setParent(this);
00090 insertId(a);
00091 a->insertChildren();
00092 }
00093 }
00094
00095 void Account::take(Account *account) {
00096 if (account == 0) {
00097 return;
00098 }
00099 if (account->parent() == this) {
00100 int i = m_accountList.indexOf(account);
00101 if (i != -1)
00102 m_accountList.removeAt(i);
00103 } else if (account->parent()) {
00104 account->parent()->take(account);
00105 } else {
00106 m_list->take(account);
00107 }
00108
00109 }
00110
00111 bool Account::load(QDomElement &element, Project &project) {
00112 m_name = element.attribute("name");
00113 m_description = element.attribute("description");
00114 QDomNodeList list = element.childNodes();
00115 for (unsigned int i=0; i<list.count(); ++i) {
00116 if (list.item(i).isElement()) {
00117 QDomElement e = list.item(i).toElement();
00118 if (e.tagName() == "costplace") {
00119 Account::CostPlace *child = new Account::CostPlace(this);
00120 if (child->load(e, project)) {
00121 append(child);
00122 } else {
00123 delete child;
00124 }
00125 } else if (e.tagName() == "account") {
00126 Account *child = new Account();
00127 if (child->load(e, project)) {
00128 m_accountList.append(child);
00129 } else {
00130
00131 kWarning()<<k_funcinfo<<"Loading failed"<<endl;
00132 delete child;
00133 }
00134 }
00135 }
00136 }
00137 return true;
00138 }
00139
00140 void Account::save(QDomElement &element) const {
00141 QDomElement me = element.ownerDocument().createElement("account");
00142 element.appendChild(me);
00143 me.setAttribute("name", m_name);
00144 me.setAttribute("description", m_description);
00145 foreach (Account::CostPlace *cp, m_costPlaces) {
00146 cp->save(me);
00147 }
00148 foreach (Account *a, m_accountList) {
00149 a->save(me);
00150 }
00151 }
00152
00153 Account::CostPlace *Account::findCostPlace(const Node &node) const {
00154 foreach (Account::CostPlace *cp, m_costPlaces) {
00155 if (&node == cp->node()) {
00156 return cp;
00157 }
00158 }
00159 return 0;
00160 }
00161
00162 Account::CostPlace *Account::findRunning(const Node &node) const {
00163 Account::CostPlace *cp = findCostPlace(node);
00164 return cp && cp->running() ? cp : 0;
00165 }
00166
00167 void Account::removeRunning(const Node &node) {
00168 Account::CostPlace *cp = findRunning(node);
00169 if (cp) {
00170 cp->setRunning(false);
00171 if (cp->isEmpty()) {
00172 deleteCostPlace(cp);
00173 }
00174 }
00175 }
00176
00177 void Account::addRunning(Node &node) {
00178 Account::CostPlace *cp = findCostPlace(node);
00179 if (cp) {
00180 cp->setRunning(true);
00181 return;
00182 }
00183 append(new CostPlace(this, &node, true));
00184 }
00185
00186 Account::CostPlace *Account::findStartup(const Node &node) const {
00187 Account::CostPlace *cp = findCostPlace(node);
00188 return cp && cp->startup() ? cp : 0;
00189 }
00190
00191 void Account::removeStartup(const Node &node) {
00192 Account::CostPlace *cp = findStartup(node);
00193 if (cp) {
00194 cp->setStartup(false);
00195 if (cp->isEmpty()) {
00196 deleteCostPlace(cp);
00197 }
00198 }
00199 }
00200
00201 void Account::addStartup(Node &node) {
00202 Account::CostPlace *cp = findCostPlace(node);
00203 if (cp) {
00204 cp->setStartup(true);
00205 return;
00206 }
00207 append(new CostPlace(this, &node, false, true));
00208
00209 }
00210
00211 Account::CostPlace *Account::findShutdown(const Node &node) const {
00212 Account::CostPlace *cp = findCostPlace(node);
00213 return cp && cp->shutdown() ? cp : 0;
00214 }
00215
00216 void Account::removeShutdown(const Node &node) {
00217 Account::CostPlace *cp = findShutdown(node);
00218 if (cp) {
00219 cp->setShutdown(false);
00220 if (cp->isEmpty()) {
00221 deleteCostPlace(cp);
00222 }
00223 }
00224 }
00225
00226 void Account::addShutdown(Node &node) {
00227 Account::CostPlace *cp = findCostPlace(node);
00228 if (cp) {
00229 cp->setShutdown(true);
00230 return;
00231 }
00232 append(new CostPlace(this, &node, false, false, true));
00233 }
00234
00235 Account *Account::findAccount(const QString &id) const {
00236 if (m_list)
00237 return m_list->findAccount(id);
00238 return 0;
00239 }
00240
00241 bool Account::removeId(const QString &id) {
00242 return (m_list ? m_list->removeId(id) : false);
00243 }
00244
00245 bool Account::insertId() {
00246 return insertId(this);
00247 }
00248
00249 bool Account::insertId(Account *account) {
00250 return (m_list ? m_list->insertId(account) : false);
00251 }
00252
00253 void Account::deleteCostPlace(CostPlace *cp) {
00254
00255 int i = m_costPlaces.indexOf(cp);
00256 if (i != -1)
00257 m_costPlaces.removeAt(i);
00258 delete cp;
00259 }
00260
00261
00262
00263 Account::CostPlace::~CostPlace() {
00264 if (m_node) {
00265 if (m_running)
00266 m_node->setRunningAccount(0);
00267 if (m_startup)
00268 m_node->setStartupAccount(0);
00269 if (m_shutdown)
00270 m_node->setShutdownAccount(0);
00271 }
00272 }
00273
00274 void Account::CostPlace::setRunning(bool on ) {
00275 m_running = on;
00276 if (m_node)
00277 m_node->setRunningAccount(on ? m_account : 0);
00278 }
00279
00280 void Account::CostPlace::setStartup(bool on ) {
00281 m_startup = on;
00282 if (m_node)
00283 m_node->setStartupAccount(on ? m_account : 0);
00284 }
00285
00286 void Account::CostPlace::setShutdown(bool on ) {
00287 m_shutdown = on;
00288 if (m_node)
00289 m_node->setShutdownAccount(on ? m_account : 0);
00290 }
00291
00292 bool Account::CostPlace::load(QDomElement &element, Project &project) {
00293
00294 m_nodeId = element.attribute("node-id");
00295 if (m_nodeId.isEmpty()) {
00296 kError()<<k_funcinfo<<"No node id"<<endl;
00297 return false;
00298 }
00299 m_node = project.findNode(m_nodeId);
00300 if (m_node == 0) {
00301 kError()<<k_funcinfo<<"Cannot not find node with id: "<<m_nodeId<<endl;
00302 return false;
00303 }
00304 setRunning(element.attribute("running-cost").toInt());
00305 setStartup(element.attribute("startup-cost").toInt());
00306 setShutdown(element.attribute("shutdown-cost").toInt());
00307 return true;
00308 }
00309
00310 void Account::CostPlace::save(QDomElement &element) const {
00311
00312 QDomElement me = element.ownerDocument().createElement("costplace");
00313 element.appendChild(me);
00314 me.setAttribute("node-id", m_nodeId);
00315 me.setAttribute("running-cost", m_running);
00316 me.setAttribute("startup-cost", m_startup);
00317 me.setAttribute("shutdown-cost", m_shutdown);
00318
00319 }
00320
00321
00322 Accounts::Accounts(Project &project)
00323 : m_project(project),
00324 m_accountList(),
00325 m_idDict(),
00326 m_defaultAccount(0) {
00327
00328 }
00329
00330 Accounts::~Accounts() {
00331
00332 while (!m_accountList.isEmpty()) {
00333 delete m_accountList.takeFirst();
00334 }
00335 }
00336
00337 EffortCostMap Accounts::plannedCost(const Account &account, const QDate &start, const QDate &end) {
00338 EffortCostMap ec;
00339 foreach (Account::CostPlace *cp, account.costPlaces()) {
00340 Node *n = cp->node();
00341 if (n == 0) {
00342 continue;
00343 }
00344
00345 if (cp->running()) {
00346 ec += n->plannedEffortCostPrDay(start, end);
00347 }
00348 if (cp->startup()) {
00349 if (n->startTime().date() >= start &&
00350 n->startTime().date() <= end)
00351 ec.add(n->startTime().date(), EffortCost(Duration::zeroDuration, n->startupCost()));
00352 }
00353 if (cp->shutdown()) {
00354 if (n->endTime().date() >= start &&
00355 n->endTime().date() <= end)
00356 ec.add(n->endTime().date(), EffortCost(Duration::zeroDuration, n->shutdownCost()));
00357 }
00358 }
00359 if (&account == m_defaultAccount) {
00360 QHash<QString, Node*> hash = m_project.nodeDict();
00361 foreach (Node *n, hash) {
00362 if (n->runningAccount() == 0) {
00363 ec += n->plannedEffortCostPrDay(start, end);
00364 }
00365 if (n->startupAccount() == 0) {
00366 if (n->startTime().date() >= start &&
00367 n->startTime().date() <= end)
00368 ec.add(n->startTime().date(), EffortCost(Duration::zeroDuration, n->startupCost()));
00369 }
00370 if (n->shutdownAccount() == 0) {
00371 if (n->endTime().date() >= start &&
00372 n->endTime().date() <= end)
00373 ec.add(n->endTime().date(), EffortCost(Duration::zeroDuration, n->shutdownCost()));
00374 }
00375 }
00376 }
00377 return ec;
00378 }
00379
00380 void Accounts::append(Account *account) {
00381 Q_ASSERT(account);
00382 m_accountList.append(account);
00383 account->setList(this);
00384 account->setParent(0);
00385 insertId(account);
00386
00387 account->insertChildren();
00388 }
00389
00390 void Accounts::take(Account *account){
00391 if (account == 0) {
00392 return;
00393 }
00394 removeId(account->name());
00395 if (account->parent()) {
00396 account->parent()->take(account);
00397 return;
00398 }
00399 int i = m_accountList.indexOf(account);
00400 if (i != -1)
00401 m_accountList.removeAt(i);
00402
00403 }
00404
00405 bool Accounts::load(QDomElement &element, Project &project) {
00406 QDomNodeList list = element.childNodes();
00407 for (unsigned int i=0; i<list.count(); ++i) {
00408 if (list.item(i).isElement()) {
00409 QDomElement e = list.item(i).toElement();
00410 if (e.tagName() == "account") {
00411 Account *child = new Account();
00412 if (child->load(e, project)) {
00413 append(child);
00414 } else {
00415
00416 kWarning()<<k_funcinfo<<"Loading failed"<<endl;
00417 delete child;
00418 }
00419 }
00420 }
00421 }
00422 if (element.hasAttribute("default-account")) {
00423 m_defaultAccount = findAccount(element.attribute("default-account"));
00424 if (m_defaultAccount == 0) {
00425 kWarning()<<k_funcinfo<<"Could not find default account."<<endl;
00426 }
00427 }
00428 return true;
00429 }
00430
00431 void Accounts::save(QDomElement &element) const {
00432 QDomElement me = element.ownerDocument().createElement("accounts");
00433 element.appendChild(me);
00434 if (m_defaultAccount) {
00435 me.setAttribute("default-account", m_defaultAccount->name());
00436 }
00437 foreach (Account *a, m_accountList) {
00438 a->save(me);
00439 }
00440 }
00441
00442 QStringList Accounts::costElements() const {
00443 QStringList l;
00444 foreach (QString key, m_idDict.uniqueKeys()) {
00445 if (m_idDict[key]->isElement())
00446 l << key;
00447 }
00448 return l;
00449 }
00450
00451
00452 QStringList Accounts::nameList() const {
00453 return m_idDict.uniqueKeys();
00454 }
00455
00456 Account *Accounts::findRunningAccount(const Node &node) const {
00457 foreach (Account *a, m_idDict) {
00458 if (a->findRunning(node))
00459 return a;
00460 }
00461 return 0;
00462 }
00463
00464 Account *Accounts::findStartupAccount(const Node &node) const {
00465 foreach (Account *a, m_idDict) {
00466 if (a->findStartup(node))
00467 return a;
00468 }
00469 return 0;
00470 }
00471
00472 Account *Accounts::findShutdownAccount(const Node &node) const {
00473 foreach (Account *a, m_idDict) {
00474 if (a->findShutdown(node))
00475 return a;
00476 }
00477 return 0;
00478 }
00479
00480 Account *Accounts::findAccount(const QString &id) const {
00481 QHash<QString, Account*>::ConstIterator ai = m_idDict.find(id);
00482 if (ai == m_idDict.constEnd()) {
00483 return 0;
00484 }
00485 return ai.value();
00486 }
00487
00488 bool Accounts::insertId(Account *account) {
00489 Q_ASSERT(account);
00490 Account *a = findAccount(account->name());
00491 if (a == 0) {
00492
00493 m_idDict.insert(account->name(), account);
00494 return true;
00495 }
00496 if (a == account) {
00497 kDebug()<<k_funcinfo<<"'"<<a->name()<<"' already exists"<<endl;
00498 return true;
00499 }
00500
00501 kWarning()<<k_funcinfo<<"Insert failed"<<endl;
00502 return false;
00503 }
00504
00505 bool Accounts::removeId(const QString &id) {
00506 bool res = m_idDict.remove(id);
00507
00508 return res;
00509 }
00510
00511 #ifndef NDEBUG
00512 void Accounts::printDebug(QString ) {
00513 }
00514 void Account::printDebug(QString ) {
00515 }
00516 #endif
00517 }