00001 #include "addcostpositionmodel.h"
00002 #include <QDebug>
00003
00004 AddCostPositionModel::AddCostPositionModel(CostTypeModel *type, CostCentreModel *centre, int rowid, double sum, QObject *parent) : QAbstractTableModel(parent), costtypemodel(type), costcentremodel(centre), currentSelectedRowId(rowid), p_completeSum(sum)
00005 {
00006 setHeaders();
00007 setDefaultFields();
00008 setCostCentres();
00009 refreshSums(QModelIndex(), QModelIndex());
00010
00011 connect(this, SIGNAL(dataChanged(const QModelIndex, const QModelIndex)), this, SLOT(refreshSums(const QModelIndex, const QModelIndex)));
00012 }
00013
00014 void AddCostPositionModel::setHeaders()
00015 {
00016 p_headers << "";
00017
00018 QStringList costcentreheaders = costcentremodel->headers();
00019 for(int i = 0; i < costcentreheaders.count(); i++)
00020 {
00021 if(costcentremodel->isCostCentreColumn(i))
00022 {
00023
00024 p_headers << costcentreheaders.value(i);
00025 }
00026 }
00027 p_headers << tr("Summe");
00028
00029 p_vert_headers << "Kostenstellenart";
00030 p_vert_headers << "Prozent";
00031 p_vert_headers << "Stunden";
00032 p_vert_headers << "Wert";
00033 p_vert_headers << "Gemeinkosten";
00034 }
00035
00036 void AddCostPositionModel::setDefaultFields()
00037 {
00038 for(int row = 0; row < p_vert_headers.count(); row++)
00039 {
00040 if(!insertRows(row, 1, QModelIndex()))
00041 {
00042 return;
00043 }
00044 QModelIndex i = index(row, 0, QModelIndex());
00045
00046
00047 if(row != 0 && row != rowCount(i) - 1)
00048 {
00049 setData(i, Qt::Unchecked, Qt::CheckStateRole);
00050 }
00051 }
00052
00053 for(int column = 1; column < p_headers.count() - 1; column++)
00054 {
00055 QModelIndex i = index(4, column, QModelIndex());
00056 setData(i, Qt::Unchecked, Qt::CheckStateRole);
00057 }
00058 }
00059
00060 void AddCostPositionModel::setCostCentres()
00061 {
00062 QModelIndex i;
00063 for(int column = 1; column < columnCount(QModelIndex()) - 1; column++)
00064 {
00065 i = index(0, column, QModelIndex());
00066
00067 QStringList row = costcentremodel->data(0);
00068 int costCentreColumn = costcentremodel->columnIdIndex(p_headers.value(column));
00069 QString name = row.value(costCentreColumn);
00070 setData(i, name, Qt::EditRole);
00071 }
00072 }
00073
00074 QStringList AddCostPositionModel::currentRow() const
00075 {
00076 return costtypemodel->data(currentSelectedRowId);
00077 }
00078
00079 int AddCostPositionModel::rowCount(const QModelIndex &parent) const
00080 {
00081
00082
00083
00084
00085
00086 return 5;
00087 }
00088
00089 int AddCostPositionModel::columnCount(const QModelIndex &parent) const
00090 {
00091 Q_UNUSED(parent);
00092
00093 int costcentres = costcentremodel->costCentreCount();
00094 return (1 + costcentres + 1);
00095 }
00096
00097 QVariant AddCostPositionModel::data(const QModelIndex &index, int role) const
00098 {
00099 if(!index.isValid())
00100 {
00101 return QVariant();
00102 }
00103
00104 if(index.row() >= p_entries.size() || index.row() < 0)
00105 {
00106 return QVariant();
00107 }
00108
00109 if(role == Qt::BackgroundRole)
00110 {
00111 if(index.column() == 0)
00112 {
00113 QColor c;
00114 c.setNamedColor("#eaeaea");
00115 return c;
00116 }
00117 if(index.column() == columnCount(index) - 1)
00118 {
00119 QColor c;
00120 c.setNamedColor("#f3f3f3");
00121 return c;
00122 }
00123 if(index.row() == rowCount(index) - 1)
00124 {
00125 QColor c;
00126 c.setNamedColor("#AAAAAA");
00127 return c;
00128 }
00129 }
00130 if(role == Qt::DisplayRole || role == Qt::EditRole)
00131 {
00132 QVariantList pair = p_entries.value(index.row());
00133 if(pair.size() > index.column() && index.column() != 0 && (index.row() != (rowCount(index) - 1)))
00134 {
00135 return pair.value(index.column());
00136 }
00137 }
00138 else if(role == Qt::CheckStateRole)
00139 {
00140 if(index.column() == 0)
00141 {
00142 if(index.row() != 0 && index.row() != rowCount(index) - 1)
00143 {
00144 QVariantList pair = p_entries.value(index.row());
00145 bool firstColumnChecked = pair.value(0).toBool();
00146
00147 if(firstColumnChecked)
00148 {
00149 return Qt::Checked;
00150 }
00151 else
00152 {
00153 return Qt::Unchecked;
00154 }
00155 }
00156 }
00157 else if(index.row() == 4)
00158 {
00159 if(index.column() >= 1 && index.column() < columnCount(index) - 1)
00160 {
00161 QVariantList pair = p_entries.value(index.row());
00162 bool firstColumnChecked = pair.value(index.column()).toBool();
00163
00164 if(firstColumnChecked)
00165 {
00166 return Qt::Checked;
00167 }
00168 else
00169 {
00170 return Qt::Unchecked;
00171 }
00172 }
00173 }
00174 }
00175 return QVariant();
00176 }
00177
00178 QVariant AddCostPositionModel::headerData(int section, Qt::Orientation orientation, int role) const
00179 {
00180 if(role != Qt::DisplayRole)
00181 {
00182 return QVariant();
00183 }
00184
00185 if(orientation == Qt::Horizontal)
00186 {
00187 return p_headers.value(section);
00188 }
00189 else if(orientation == Qt::Vertical)
00190 {
00191 return p_vert_headers.value(section);
00192 }
00193 return QVariant();
00194 }
00195
00196 Qt::ItemFlags AddCostPositionModel::flags(const QModelIndex &index) const
00197 {
00198 if(!index.isValid())
00199 {
00200 return Qt::NoItemFlags;
00201 }
00202
00203 if(index.column() == 0)
00204 {
00205 if(index.row() == 0)
00206 {
00207 return Qt::NoItemFlags;
00208 }
00209 if(index.row() == rowCount(index) - 1)
00210 {
00211 return Qt::NoItemFlags;
00212 }
00213 return Qt::ItemIsEnabled | Qt::ItemIsUserCheckable;
00214 }
00215 if(index.column() >= 1 && index.column() < columnCount(index) -1)
00216 {
00217 if(index.row() == 0)
00218 {
00219 return Qt::NoItemFlags;
00220 }
00221 if(index.row() == rowCount(index) - 1)
00222 {
00223 return Qt::ItemIsEnabled | Qt::ItemIsUserCheckable;
00224 }
00225 return Qt::ItemIsEnabled | Qt::ItemIsEditable;
00226 }
00227 if(index.column() == columnCount(index) - 1)
00228 {
00229 return Qt::NoItemFlags;
00230 }
00231 return Qt::ItemIsEnabled | Qt::ItemIsEditable;
00232 }
00233
00234 bool AddCostPositionModel::setData(const QModelIndex &index, const QVariant &value, int role)
00235 {
00236 if(index.isValid())
00237 {
00238 if(role == Qt::EditRole || role == Qt::CheckStateRole)
00239 {
00240 int row = index.row();
00241 QVariantList p = p_entries.value(row);
00242 for(int i = 0; i < p_headers.size(); i++)
00243 {
00244 if(index.column() == i)
00245 {
00246 p.replace(i, value.toString());
00247 }
00248 }
00249 p_entries.replace(row, p);
00250 }
00251 emit dataChanged(index, index);
00252 return true;
00253 }
00254 return false;
00255 }
00256
00257 bool AddCostPositionModel::insertRows(int position, int rows, const QModelIndex &index)
00258 {
00259 beginInsertRows(QModelIndex(), position, position + rows - 1);
00260
00261 int columncount = columnCount(index);
00262 for (int row = 0; row < rows; row++)
00263 {
00264 QVariantList pair;
00265 for(int i = 0; i < columncount; i++)
00266 {
00267 if(row >= 1 && i >=1 && row <= rowCount(index) - 1 && i <= columnCount(index) -1)
00268 {
00269
00270 pair << "0";
00271 }
00272 else
00273 {
00274 pair << "";
00275 }
00276 }
00277 p_entries.insert(position, pair);
00278 }
00279
00280 endInsertRows();
00281 return true;
00282 }
00283
00284 bool AddCostPositionModel::removeRows(int position, int rows, const QModelIndex &index)
00285 {
00286 Q_UNUSED(index);
00287 beginRemoveRows(QModelIndex(), position, position+rows-1);
00288
00289 for (int row = 0; row < rows; ++row)
00290 {
00291 p_entries.removeAt(position);
00292 }
00293
00294 endRemoveRows();
00295 return true;
00296 }
00297
00298 void AddCostPositionModel::refreshSums(const QModelIndex left, const QModelIndex right)
00299 {
00300 p_currentSum = 0;
00301
00302
00303 if(left == right)
00304 {
00305 qDebug()<<"left equals right";
00306 qDebug()<<"index: " << left;
00307 int row = left.row();
00308 qDebug()<<"row: " << row;
00309 switch(row)
00310 {
00311 case 1:
00312 {
00313
00314 if(p_entries.value(row).value(0) == Qt::Checked)
00315 {
00316
00317 QVariantList secondrow = p_entries.value(2);
00318 secondrow.replace(0, Qt::Unchecked);
00319 p_entries.replace(2, secondrow);
00320 }
00321 break;
00322 }
00323 case 2:
00324 {
00325
00326 if(p_entries.value(row).value(0) == Qt::Checked)
00327 {
00328
00329 QVariantList firstrow = p_entries.value(1);
00330 firstrow.replace(0, Qt::Unchecked);
00331 p_entries.replace(1, firstrow);
00332
00333 QVariantList thirdrow = p_entries.value(3);
00334 thirdrow.replace(0, Qt::Unchecked);
00335 p_entries.replace(3, thirdrow);
00336 }
00337 break;
00338 }
00339 case 3:
00340 {
00341 if(p_entries.value(row).value(0) == Qt::Checked)
00342 {
00343
00344 QVariantList secondrow = p_entries.value(2);
00345 secondrow.replace(0, Qt::Unchecked);
00346 p_entries.replace(2, secondrow);
00347 break;
00348 }
00349 }
00350 }
00351 }
00352 else
00353 {
00354 qDebug()<<"left doesn't match right";
00355 }
00356
00357 for(int row = 1; row < rowCount(QModelIndex()) - 1; row++)
00358 {
00359 double sum = 0;
00360
00361 if(p_entries.value(row).value(0) == Qt::Checked)
00362 {
00363 sum = 0;
00364 bool rowOk = true;
00365 switch(row)
00366 {
00367 case 1:
00368 {
00369 rowOk = checkPercentageOfRow(p_entries.value(row));
00370 if(rowOk)
00371 {
00372 sum += calculatedRowValuePercentage(p_entries.value(row));
00373 }
00374 else
00375 {
00376 qDebug()<<"checkPercentageOfRow returned false";
00377 sum = -1;
00378 }
00379 break;
00380 }
00381 case 2:
00382 {
00383 rowOk = checkWorkTimeOfRow(p_entries.value(row));
00384 if(rowOk)
00385 {
00386 sum += calculatedRowValueHours(p_entries.value(row));
00387 }
00388 else
00389 {
00390 qDebug()<<"checkWorkTimeOfRow returned false";
00391 sum = -1;
00392 }
00393 break;
00394 }
00395 case 3:
00396 {
00397 rowOk = checkValuesOfRow(p_entries.value(row));
00398 if(rowOk)
00399 {
00400 sum += calculatedRowValueBased(p_entries.value(row));
00401 }
00402 else
00403 {
00404 qDebug()<<"checkValuesOfRow returned false";
00405 sum = -1;
00406 }
00407 break;
00408 }
00409 }
00410 }
00411
00412 QModelIndex i = index(row, columnCount(QModelIndex()) - 1, QModelIndex());
00413
00414 if(i.isValid())
00415 {
00416 QVariantList p = p_entries.value(row);
00417 for(int header = 0; header < p_headers.size(); header++)
00418 {
00419 if(i.column() == header)
00420 {
00421 if(sum == -1)
00422 {
00423 p.replace(header, "Fehler");
00424 }
00425 else
00426 {
00427 p.replace(header, QString::number(sum));
00428 }
00429 }
00430 }
00431 p_entries.replace(row, p);
00432 }
00433
00434 if(sum != -1)
00435 {
00436 p_currentSum += sum;
00437 }
00438 }
00439 emit updateView();
00440 emit currentSumChanged(p_currentSum);
00441 }
00442
00443 bool AddCostPositionModel::checkPercentageOfRow(QVariantList row)
00444 {
00445 double percentage = 0;
00446 for(int column = 1; column < row.count() - 1; column++)
00447 {
00448 bool ok = true;
00449 double value = 0;
00450 if(row.value(column) != "")
00451 {
00452 value = row.value(column).toDouble(&ok);
00453 }
00454 if(!ok)
00455 {
00456 qDebug()<<"there's an error in the percentage field: " << row.value(column);
00457 return false;
00458 }
00459 percentage += value;
00460 }
00461 return (percentage >= 0 && percentage <= 100);
00462 }
00463
00464 double AddCostPositionModel::calculatedRowValuePercentage(QVariantList row)
00465 {
00466 double wholeCosts = 0;
00467 for(int column = 1; column < row.count() - 1; column++)
00468 {
00469 double value = 0;
00470 if(row.value(column) != "")
00471 {
00472 value = row.value(column).toDouble();
00473 }
00474 double newvalue = (p_completeSum / 100) * value;
00475 qDebug()<<"p_completeSum: " << p_completeSum;
00476 qDebug()<<"value: " << value;
00477 qDebug()<<"p_completeSum / 100) * value: " << (p_completeSum / 100) * value;
00478 wholeCosts += newvalue;
00479 }
00480 qDebug()<<"wholecosts of percentage: " << wholeCosts;
00481 return wholeCosts;
00482 }
00483
00484 double AddCostPositionModel::calculateCostCentreSum(int column)
00485 {
00486 double costs = 0;
00487
00488 double percentage = p_entries.value(1).value(column).toDouble();
00489 costs += (p_completeSum / 100 * percentage);
00490
00491 costs += workTimePerCostCentre(p_entries.value(2), column);
00492
00493 costs += p_entries.value(3).value(column).toDouble();
00494
00495 return costs;
00496 }
00497
00498 double AddCostPositionModel::workTimePerCostCentre(QVariantList row, int columnWanted)
00499 {
00500 double worktime = 0;
00501 for(int column = 1; column < columnCount(QModelIndex()) - 1; column++)
00502 {
00503 bool ok = true;
00504 double value = 0;
00505 if(row.value(column) != QVariant())
00506 {
00507 value = row.value(column).toDouble(&ok);
00508 }
00509 if(!ok)
00510 {
00511 return 0;
00512 }
00513 qDebug()<<"worktime value costcentre: " << column << " " << value;
00514 worktime += value;
00515 }
00516 qDebug() << "worktime: " << worktime;
00517
00518 double hourlyRate = (p_completeSum / worktime);
00519 qDebug()<<"hourlyRate: " << hourlyRate;
00520
00521 double value = 0;
00522 if(row.value(columnWanted) != QVariant())
00523 {
00524 value = row.value(columnWanted).toDouble();
00525 }
00526 return hourlyRate * value;
00527 }
00528
00529 bool AddCostPositionModel::checkWorkTimeOfRow(QVariantList row)
00530 {
00531 double worktime = 0;
00532 for(int column = 1; column < row.count() - 1; column++)
00533 {
00534 bool ok = true;
00535 double value = 0;
00536 if(row.value(column) != "")
00537 {
00538 value = row.value(column).toDouble(&ok);
00539 }
00540 if(!ok)
00541 {
00542 return false;
00543 }
00544 worktime += value;
00545 }
00546
00547 double hourlyRate = (p_completeSum / worktime);
00548 double wholePrice = 0;
00549 for(int column = 1; column < row.count() - 1; column++)
00550 {
00551 double value = 0;
00552 if(row.value(column) != "")
00553 {
00554 value = row.value(column).toDouble();
00555 }
00556 double valuePerCostCentre = hourlyRate * value;
00557 wholePrice += valuePerCostCentre;
00558 }
00559 return (wholePrice >= 0 || wholePrice <= p_completeSum);
00560 }
00561
00562 double AddCostPositionModel::calculatedRowValueHours(QVariantList row)
00563 {
00564 double worktime = 0;
00565 for(int column = 1; column < row.count() - 1; column++)
00566 {
00567 double value = 0;
00568 if(row.value(column) != "")
00569 {
00570 value = row.value(column).toDouble();
00571 }
00572 worktime += value;
00573 }
00574
00575 double hourlyRate = (p_completeSum / worktime);
00576 double wholePrice = 0;
00577 for(int column = 1; column < row.count() - 1; column++)
00578 {
00579 double value = 0;
00580 if(row.value(column) != "")
00581 {
00582 value = row.value(column).toDouble();
00583 }
00584 double valuePerCostCentre = hourlyRate * value;
00585 wholePrice += valuePerCostCentre;
00586 }
00587 return wholePrice;
00588 }
00589
00590 bool AddCostPositionModel::checkValuesOfRow(QVariantList row)
00591 {
00592 double rowCosts = 0;
00593 for(int column = 1; column < row.count() - 1; column++)
00594 {
00595 bool ok = true;
00596 double value = 0;
00597 if(row.value(column) != "")
00598 {
00599 value = row.value(column).toDouble(&ok);
00600 }
00601 if(!ok)
00602 {
00603 return false;
00604 }
00605 rowCosts += value;
00606 }
00607 qDebug()<<"checkValuesOfRow rowCosts: " << rowCosts;
00608 qDebug()<<"checkValuesOfRow completeCosts: " << p_completeSum;
00609 qDebug()<<"checkValuesOfRow expression: " << (rowCosts <= p_completeSum && rowCosts >= 0);
00610 return (rowCosts <= p_completeSum || rowCosts >= 0);
00611 }
00612
00613 double AddCostPositionModel::calculatedRowValueBased(QVariantList row)
00614 {
00615 double rowCosts = 0;
00616 for(int column = 1; column < row.count() - 1; column++)
00617 {
00618 double value = 0;
00619 if(row.value(column) != "")
00620 {
00621 value = row.value(column).toDouble();
00622 }
00623 rowCosts += value;
00624 }
00625 return rowCosts;
00626 }
00627
00628 void AddCostPositionModel::clear()
00629 {
00630 qDebug() << "TODO: clear everything after last row has been added";
00631 }
00632
00633 bool AddCostPositionModel::isCorrectSpreaded()
00634 {
00635 return p_currentSum == p_completeSum;
00636 }
00637
00638 QString AddCostPositionModel::costTypesRow()
00639 {
00640 QString types;
00641 for(int column = 1; column < columnCount(QModelIndex()) - 1; column++)
00642 {
00643 bool fixedCosts = p_entries.value(4).value(column).toBool();
00644 if(!fixedCosts)
00645 {
00646 types += "E";
00647 }
00648 else
00649 {
00650 types += "G";
00651 }
00652
00653 if(column <= columnCount(QModelIndex()) - 3)
00654 {
00655 types += "/";
00656 }
00657 }
00658 return types;
00659 }
00660
00661 QString AddCostPositionModel::costSpreadingRow()
00662 {
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674 QString spreading;
00675 for(int column = 1; column < columnCount(QModelIndex()) - 1; column++)
00676 {
00677 for(int row = 1; row < rowCount(QModelIndex()); row++)
00678 {
00679 if(p_entries.value(row).value(0) == Qt::Checked)
00680 {
00681 switch(row)
00682 {
00683 case 1:
00684 {
00685 if(p_entries.value(row).value(column) != "" && p_entries.value(row).value(column) != 0)
00686 {
00687 spreading += "p:";
00688 spreading += p_entries.value(row).value(column).toString();
00689 }
00690 break;
00691 }
00692 case 2:
00693 {
00694 if(p_entries.value(row).value(column) != "" && p_entries.value(row).value(column) != 0)
00695 {
00696 spreading += "h:";
00697 spreading += p_entries.value(row).value(column).toString();
00698 }
00699 break;
00700 }
00701 case 3:
00702 {
00703 if(p_entries.value(row).value(column) != "" && p_entries.value(row).value(column) != 0)
00704 {
00705 spreading += "v:";
00706 spreading += p_entries.value(row).value(column).toString();
00707 }
00708 break;
00709 }
00710 }
00711 }
00712 if(row < rowCount(QModelIndex()) - 2)
00713 {
00714 spreading += ";";
00715 }
00716 }
00717 if(column < columnCount(QModelIndex()) - 2)
00718 {
00719 spreading += "/";
00720 }
00721 }
00722 return spreading;
00723 }