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.h>
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 m_accountList.setAutoDelete(true);
00043 m_costPlaces.setAutoDelete(true);
00044 }
00045
00046 Account::Account(QString name, QString description)
00047 : m_name(name),
00048 m_description(description),
00049 m_list(0),
00050 m_parent(0),
00051 m_accountList(),
00052 m_costPlaces() {
00053
00054 m_accountList.setAutoDelete(true);
00055 m_costPlaces.setAutoDelete(true);
00056 }
00057
00058 Account::~Account() {
00059 m_accountList.clear();
00060 if (findAccount() == this) {
00061 removeId();
00062 }
00063 if (m_list)
00064 m_list->accountDeleted(this);
00065 }
00066
00067
00068 void Account::setName(QString name) {
00069 if (findAccount() == this) {
00070 removeId();
00071 }
00072 m_name = name;
00073 insertId();
00074 }
00075
00076 void Account::append(Account *account){
00077 Q_ASSERT(account);
00078 m_accountList.append(account);
00079 account->setList(m_list);
00080 account->setParent(this);
00081 insertId(account);
00082 }
00083
00084 void Account::insertChildren() {
00085 AccountListIterator it = m_accountList;
00086 for (; it.current(); ++it) {
00087 it.current()->setList(m_list);
00088 it.current()->setParent(this);
00089 insertId(it.current());
00090 it.current()->insertChildren();
00091 }
00092 }
00093
00094 void Account::take(Account *account) {
00095 if (account == 0) {
00096 return;
00097 }
00098 if (account->parent() == this) {
00099 m_accountList.take(m_accountList.findRef(account));
00100 } else if (account->parent()) {
00101 account->parent()->take(account);
00102 } else {
00103 m_list->take(account);
00104 }
00105
00106 }
00107
00108 bool Account::load(QDomElement &element, const Project &project) {
00109 m_name = element.attribute("name");
00110 m_description = element.attribute("description");
00111 QDomNodeList list = element.childNodes();
00112 for (unsigned int i=0; i<list.count(); ++i) {
00113 if (list.item(i).isElement()) {
00114 QDomElement e = list.item(i).toElement();
00115 if (e.tagName() == "costplace") {
00116 Account::CostPlace *child = new Account::CostPlace(this);
00117 if (child->load(e, project)) {
00118 append(child);
00119 } else {
00120 delete child;
00121 }
00122 } else if (e.tagName() == "account") {
00123 Account *child = new Account();
00124 if (child->load(e, project)) {
00125 m_accountList.append(child);
00126 } else {
00127
00128 kdWarning()<<k_funcinfo<<"Loading failed"<<endl;
00129 delete child;
00130 }
00131 }
00132 }
00133 }
00134 return true;
00135 }
00136
00137 void Account::save(QDomElement &element) const {
00138 QDomElement me = element.ownerDocument().createElement("account");
00139 element.appendChild(me);
00140 me.setAttribute("name", m_name);
00141 me.setAttribute("description", m_description);
00142 QPtrListIterator<Account::CostPlace> cit = m_costPlaces;
00143 for (; cit.current(); ++cit) {
00144 cit.current()->save(me);
00145 }
00146 AccountListIterator it = m_accountList;
00147 for (; it.current(); ++it) {
00148 it.current()->save(me);
00149 }
00150 }
00151
00152 Account::CostPlace *Account::findCostPlace(const Node &node) const {
00153 QPtrListIterator<CostPlace> it = m_costPlaces;
00154 for (; it.current(); ++it) {
00155 if (&node == it.current()->node()) {
00156 return it.current();
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 m_costPlaces.removeRef(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 m_costPlaces.removeRef(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 m_costPlaces.removeRef(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(const Account *account) {
00250 return (m_list ? m_list->insertId(account) : false);
00251 }
00252
00253
00254 Account::CostPlace::~CostPlace() {
00255 if (m_node) {
00256 if (m_running)
00257 m_node->setRunningAccount(0);
00258 if (m_startup)
00259 m_node->setStartupAccount(0);
00260 if (m_shutdown)
00261 m_node->setShutdownAccount(0);
00262 }
00263 }
00264
00265 void Account::CostPlace::setRunning(bool on ) {
00266 m_running = on;
00267 if (m_node)
00268 m_node->setRunningAccount(on ? m_account : 0);
00269 }
00270
00271 void Account::CostPlace::setStartup(bool on ) {
00272 m_startup = on;
00273 if (m_node)
00274 m_node->setStartupAccount(on ? m_account : 0);
00275 }
00276
00277 void Account::CostPlace::setShutdown(bool on ) {
00278 m_shutdown = on;
00279 if (m_node)
00280 m_node->setShutdownAccount(on ? m_account : 0);
00281 }
00282
00283 bool Account::CostPlace::load(QDomElement &element, const Project &project) {
00284
00285 m_nodeId = element.attribute("node-id");
00286 if (m_nodeId.isEmpty()) {
00287 kdError()<<k_funcinfo<<"No node id"<<endl;
00288 return false;
00289 }
00290 m_node = project.findNode(m_nodeId);
00291 if (m_node == 0) {
00292 kdError()<<k_funcinfo<<"Cannot not find node with id: "<<m_nodeId<<endl;
00293 return false;
00294 }
00295 setRunning(element.attribute("running-cost").toInt());
00296 setStartup(element.attribute("startup-cost").toInt());
00297 setShutdown(element.attribute("shutdown-cost").toInt());
00298 return true;
00299 }
00300
00301 void Account::CostPlace::save(QDomElement &element) const {
00302
00303 QDomElement me = element.ownerDocument().createElement("costplace");
00304 element.appendChild(me);
00305 me.setAttribute("node-id", m_nodeId);
00306 me.setAttribute("running-cost", m_running);
00307 me.setAttribute("startup-cost", m_startup);
00308 me.setAttribute("shutdown-cost", m_shutdown);
00309
00310 }
00311
00312
00313 Accounts::Accounts(Project &project)
00314 : m_project(project),
00315 m_accountList(),
00316 m_idDict(),
00317 m_defaultAccount(0) {
00318
00319 m_accountList.setAutoDelete(true);
00320 }
00321
00322 Accounts::~Accounts() {
00323 m_accountList.clear();
00324 }
00325
00326 EffortCostMap Accounts::plannedCost(const Account &account, const QDate &start, const QDate &end) {
00327 EffortCostMap ec;
00328 QPtrListIterator<Account::CostPlace> it = account.costPlaces();
00329 for (; it.current(); ++it) {
00330 Node *n = it.current()->node();
00331 if (n == 0) {
00332 continue;
00333 }
00334
00335 if (it.current()->running()) {
00336 ec += n->plannedEffortCostPrDay(start, end);
00337 }
00338 if (it.current()->startup()) {
00339 if (n->startTime().date() >= start &&
00340 n->startTime().date() <= end)
00341 ec.add(n->startTime().date(), EffortCost(Duration::zeroDuration, n->startupCost()));
00342 }
00343 if (it.current()->shutdown()) {
00344 if (n->endTime().date() >= start &&
00345 n->endTime().date() <= end)
00346 ec.add(n->endTime().date(), EffortCost(Duration::zeroDuration, n->shutdownCost()));
00347 }
00348 }
00349 if (&account == m_defaultAccount) {
00350 QDictIterator<Node> nit = m_project.nodeDict();
00351 for (; nit.current(); ++nit) {
00352 Node *n = nit.current();
00353 if (n->runningAccount() == 0) {
00354 ec += n->plannedEffortCostPrDay(start, end);
00355 }
00356 if (n->startupAccount() == 0) {
00357 if (n->startTime().date() >= start &&
00358 n->startTime().date() <= end)
00359 ec.add(n->startTime().date(), EffortCost(Duration::zeroDuration, n->startupCost()));
00360 }
00361 if (n->shutdownAccount() == 0) {
00362 if (n->endTime().date() >= start &&
00363 n->endTime().date() <= end)
00364 ec.add(n->endTime().date(), EffortCost(Duration::zeroDuration, n->shutdownCost()));
00365 }
00366 }
00367 }
00368 return ec;
00369 }
00370
00371 void Accounts::append(Account *account) {
00372 Q_ASSERT(account);
00373 m_accountList.append(account);
00374 account->setList(this);
00375 account->setParent(0);
00376 insertId(account);
00377
00378 account->insertChildren();
00379 }
00380
00381 void Accounts::take(Account *account){
00382 if (account == 0) {
00383 return;
00384 }
00385 removeId(account->name());
00386 if (account->parent()) {
00387 account->parent()->take(account);
00388 return;
00389 }
00390 m_accountList.take(m_accountList.findRef(account));
00391
00392 }
00393
00394 bool Accounts::load(QDomElement &element, const Project &project) {
00395 QDomNodeList list = element.childNodes();
00396 for (unsigned int i=0; i<list.count(); ++i) {
00397 if (list.item(i).isElement()) {
00398 QDomElement e = list.item(i).toElement();
00399 if (e.tagName() == "account") {
00400 Account *child = new Account();
00401 if (child->load(e, project)) {
00402 append(child);
00403 } else {
00404
00405 kdWarning()<<k_funcinfo<<"Loading failed"<<endl;
00406 delete child;
00407 }
00408 }
00409 }
00410 }
00411 if (element.hasAttribute("default-account")) {
00412 m_defaultAccount = findAccount(element.attribute("default-account"));
00413 if (m_defaultAccount == 0) {
00414 kdWarning()<<k_funcinfo<<"Could not find default account."<<endl;
00415 }
00416 }
00417 return true;
00418 }
00419
00420 void Accounts::save(QDomElement &element) const {
00421 QDomElement me = element.ownerDocument().createElement("accounts");
00422 element.appendChild(me);
00423 if (m_defaultAccount) {
00424 me.setAttribute("default-account", m_defaultAccount->name());
00425 }
00426 AccountListIterator it = m_accountList;
00427 for (; it.current(); ++it) {
00428 it.current()->save(me);
00429 }
00430 }
00431
00432 QStringList Accounts::costElements() const {
00433 QDictIterator<Account> it(m_idDict);
00434 QStringList l;
00435 for(; it.current(); ++it) {
00436 if (it.current()->isElement())
00437 l << it.currentKey();
00438 }
00439 return l;
00440 }
00441
00442
00443 QStringList Accounts::nameList() const {
00444 QDictIterator<Account> it(m_idDict);
00445 QStringList l;
00446 for(; it.current(); ++it) {
00447 l << it.currentKey();
00448 }
00449 return l;
00450 }
00451
00452 Account *Accounts::findRunningAccount(const Node &node) const {
00453 QDictIterator<Account> it = m_idDict;
00454 for (; it.current(); ++it) {
00455 if (it.current()->findRunning(node))
00456 return it.current();
00457 }
00458 return 0;
00459 }
00460
00461 Account *Accounts::findStartupAccount(const Node &node) const {
00462 QDictIterator<Account> it = m_idDict;
00463 for (; it.current(); ++it) {
00464 if (it.current()->findStartup(node))
00465 return it.current();
00466 }
00467 return 0;
00468 }
00469
00470 Account *Accounts::findShutdownAccount(const Node &node) const {
00471 QDictIterator<Account> it = m_idDict;
00472 for (; it.current(); ++it) {
00473 if (it.current()->findShutdown(node))
00474 return it.current();
00475 }
00476 return 0;
00477 }
00478
00479 Account *Accounts::findAccount(const QString &id) const {
00480 return m_idDict.find(id);
00481 }
00482
00483 bool Accounts::insertId(const Account *account) {
00484 Q_ASSERT(account);
00485 Account *a = m_idDict.find(account->name());
00486 if (a == 0) {
00487
00488 m_idDict.insert(account->name(), account);
00489 return true;
00490 }
00491 if (a == account) {
00492 kdDebug()<<k_funcinfo<<"'"<<a->name()<<"' allready exists"<<endl;
00493 return true;
00494 }
00495
00496 kdWarning()<<k_funcinfo<<"Insert failed"<<endl;
00497 return false;
00498 }
00499
00500 bool Accounts::removeId(const QString &id) {
00501 bool res = m_idDict.remove(id);
00502
00503 return res;
00504 }
00505
00506 #ifndef NDEBUG
00507 void Accounts::printDebug(QString ) {
00508 }
00509 void Account::printDebug(QString ) {
00510 }
00511 #endif
00512 }