|
|
@@ -4,6 +4,11 @@ Lib::loadClass('RouteBase');
|
|
|
|
|
|
class Route_Budget extends RouteBase {
|
|
|
|
|
|
+ private $_costs = array();
|
|
|
+ private $_plan = array();
|
|
|
+ private $_projectInfo = array();
|
|
|
+ private $_projectPathsOrder = array();
|
|
|
+
|
|
|
public function handleAuth() {
|
|
|
if (!User::logged()) {
|
|
|
throw new HttpException('Unauthorized', 401);
|
|
|
@@ -26,12 +31,20 @@ class Route_Budget extends RouteBase {
|
|
|
public function yearBudgetAction() {
|
|
|
$args = array();
|
|
|
$args['year'] = V::get('year', '', $_REQUEST, 'int');
|
|
|
+ $args['groups'] = V::get('fltrGroups', array(), $_REQUEST, 'array', array('V', 'filterPositiveInteger'));
|
|
|
$args['_print'] = V::get('_print', '', $_REQUEST, 'int');
|
|
|
|
|
|
+ $hasData = false;
|
|
|
+ $groups = null;
|
|
|
+ if ($args['year'] > 0) {
|
|
|
+ $hasData = $this->fetchDataByYear($args['year']);
|
|
|
+ $groups = $this->getUsedUserGroups();
|
|
|
+ }
|
|
|
+
|
|
|
SE_Layout::gora();
|
|
|
SE_Layout::menu();
|
|
|
if (!$args['_print']) {
|
|
|
- $this->menu($args['year']);
|
|
|
+ $this->menu($args['year'], $groups, $args['groups']);
|
|
|
}
|
|
|
|
|
|
if (empty($args['year'])) {
|
|
|
@@ -44,8 +57,7 @@ class Route_Budget extends RouteBase {
|
|
|
exit;
|
|
|
}
|
|
|
|
|
|
- $costs = $this->getCostsByYear($args['year']);
|
|
|
- if (empty($costs)) {
|
|
|
+ if (!$hasData) {
|
|
|
?>
|
|
|
<div class="alert alert-warning">
|
|
|
Brak danych na wybrany rok.
|
|
|
@@ -55,12 +67,12 @@ class Route_Budget extends RouteBase {
|
|
|
}
|
|
|
//echo'<pre style="border:1px solid red;overflow:auto;max-height:400px">$costs: ';print_r($costs);echo'</pre>';
|
|
|
|
|
|
- $this->printCostsForYear($args['year']);
|
|
|
+ $this->printCostsForYear($args['year'], $args['groups']);
|
|
|
|
|
|
SE_Layout::dol();
|
|
|
}
|
|
|
|
|
|
- private function menu($selectedYear) {
|
|
|
+ private function menu($selectedYear, $groups = array(), $selectedGroups = array()) {
|
|
|
//SE_Layout::menu();
|
|
|
$year = ($selectedYear)? $selectedYear : date("Y");
|
|
|
?>
|
|
|
@@ -68,11 +80,25 @@ class Route_Budget extends RouteBase {
|
|
|
<div class="container">
|
|
|
<form class="form-inline" method="POST">
|
|
|
<input type="hidden" name="_task" value="yearBudget" />
|
|
|
- <label for="year">Zestawienie kosztów projektów na podstawie korespondencji:</label>
|
|
|
+ <label for="year">Zestawienie kosztów projektów. Wybierz rok:</label>
|
|
|
<div class="input-group date" id="fldZestYear">
|
|
|
<input type="text" name="year" class="form-control" value="" />
|
|
|
<span class="input-group-addon"><span class="glyphicon glyphicon-time"></span></span>
|
|
|
</div>
|
|
|
+ <?php if (!empty($groups)) : ?>
|
|
|
+ <div style="margin:8px 0">
|
|
|
+ <label for="fltrGroups">Pokaż tylko projekty dostępne dla grup:</label>
|
|
|
+ <select multiple name="fltrGroups[]" size="<?php echo min(5, count($groups)); ?>" class="form-control">
|
|
|
+ <option value=""> [ Wszystkie ] </option>
|
|
|
+ <?php foreach ($groups as $idGroup => $groupLdapName) : ?>
|
|
|
+ <option
|
|
|
+ value="<?php echo $idGroup; ?>"
|
|
|
+ <?php if (in_array($idGroup, $selectedGroups)) { echo 'selected="selected"'; } ?>
|
|
|
+ ><?php echo $groupLdapName; ?></option>
|
|
|
+ <?php endforeach; ?>
|
|
|
+ </select>
|
|
|
+ </div>
|
|
|
+ <?php endif; ?>
|
|
|
<button type="submit" id="fldZestYearBtn" class="btn btn-primary" autocomplete="off">
|
|
|
Pokaż
|
|
|
</button>
|
|
|
@@ -103,20 +129,26 @@ jQuery(document).ready(function () {
|
|
|
.c { text-align:center; }
|
|
|
.r { text-align:right; }
|
|
|
|
|
|
- .zestawienie-kosztow-tbl { border-collapse:collapse; border:1px solid #7EC5FF; }
|
|
|
- .zestawienie-kosztow-tbl td { border:1px solid #7EC5FF; }
|
|
|
+ .zestawienie-kosztow-tbl { border-collapse:collapse; border:1px solid #aaa; }
|
|
|
+ .zestawienie-kosztow-tbl td { border:1px solid #aaa; }
|
|
|
.zestawienie-kosztow-tbl .p2 { padding:0 2px; }
|
|
|
.zestawienie-kosztow-tbl .nr { color:#7A7A7A; }
|
|
|
- .zestawienie-kosztow-tbl thead th { border:1px solid #7EC5FF; }
|
|
|
+ .zestawienie-kosztow-tbl thead th { border:1px solid #aaa; }
|
|
|
.zestawienie-kosztow-tbl tbody tr:hover td { background:#cafbfd; }
|
|
|
.row-selected td {background-color:#d8fded;}
|
|
|
.showOnlySelected tr { display:none; }
|
|
|
.showOnlySelected tr.row-selected { display:table-row; }
|
|
|
|
|
|
.cell-cost { padding:0 2px; min-width:30px; text-align:right; }
|
|
|
- .cell-cost-only_child { color:#777; }
|
|
|
- .cell-cost-only_self { color:red; }
|
|
|
- .cell-cost-self_and_child { color:orange; }
|
|
|
+ .cell-cost-only_self { color:#197fe6; }
|
|
|
+ .cell-cost-self_and_child { color:#33b2cc; }
|
|
|
+ .cell-cost-only_child { color:#59a680; }
|
|
|
+ .cell-plan { padding:0 2px; min-width:30px; text-align:right; color:#777; }
|
|
|
+ .cell-procent { padding:0 2px; min-width:20px; text-align:right; color:#777; }
|
|
|
+ .cell-procent-below100 { color:#777; }
|
|
|
+ .cell-procent-100 { color:#777; }
|
|
|
+ .cell-procent-over100 { color:#ff9b00; }
|
|
|
+ .cell-procent-over200 { color:#f00; }
|
|
|
|
|
|
/* print table background colors */
|
|
|
table td, table th { -webkit-print-color-adjust:exact; }
|
|
|
@@ -129,8 +161,7 @@ jQuery(document).ready(function () {
|
|
|
<?php
|
|
|
}
|
|
|
|
|
|
- function printCostsForYear($year) {
|
|
|
- $this->_costs = $this->_costs;
|
|
|
+ function printCostsForYear($year, $groups) {
|
|
|
$months = array();
|
|
|
for ($i = 0; $i < 12; $i++) {
|
|
|
$months[] = $i + 1;
|
|
|
@@ -141,72 +172,125 @@ jQuery(document).ready(function () {
|
|
|
<div class="container">
|
|
|
<div style="float:right;color:#aaa;"><?php echo date("Y-m-d"); ?></div>
|
|
|
<h1>Zestawienie kosztów projektów na rok <?php echo $year; ?></h1>
|
|
|
+</div>
|
|
|
<table cellspacing="0" cellpadding="0" border="0" id="zestawienie-kosztow-projektow" class="zestawienie-kosztow-tbl">
|
|
|
<thead>
|
|
|
+ <tr>
|
|
|
+ <td colspan="3" class="p2">
|
|
|
+ <span class="pull-right"><b>miesiąc</b></span>
|
|
|
+ </td>
|
|
|
+ <?php foreach ($months as $month) { ?>
|
|
|
+ <th class="c" colspan="3"><?php echo sprintf("%02d", $month); ?></th>
|
|
|
+ <?php } ?>
|
|
|
+ </tr>
|
|
|
<tr>
|
|
|
<td colspan="3" class="p2">
|
|
|
<span class="pull-left">
|
|
|
<input type="checkbox" onclick="return showHideAll(this);"/> pokaż tylko zaznaczone
|
|
|
</span>
|
|
|
- <span class="pull-right"><b>miesiąc</b></span>
|
|
|
</td>
|
|
|
<?php foreach ($months as $month) { ?>
|
|
|
- <th class="c"><?php echo sprintf("%02d", $month); ?></th>
|
|
|
+ <th class="c" title="Koszty wprowadzone do korespondencji">Koszty</th>
|
|
|
+ <th class="c" title="Plan budżetu">Plan</th>
|
|
|
+ <th class="c" title="Procent przekroczenia planu">%</th>
|
|
|
<?php } ?>
|
|
|
</tr>
|
|
|
</thead>
|
|
|
<tbody>
|
|
|
<?php $t = 1; ?>
|
|
|
<?php foreach ($this->_projectPathsOrder as $projPath => $projId) : ?>
|
|
|
- <?php $projectInfo = $this->_costs[$projId]; ?>
|
|
|
- <?php if (empty($projectInfo)) {
|
|
|
- //echo'<tr><td colspan="10"><pre>ERROR:EMPTY: Path('.$projPath.') id('.$projId.')</pre></td></tr>';
|
|
|
- continue;
|
|
|
- } ?>
|
|
|
+ <?php
|
|
|
+ $projectID = $projId;
|
|
|
+ $projectDesc = $this->_projectInfo[$projId]->M_DIST_DESC;
|
|
|
+ $projectPath = $this->_projectInfo[$projId]->path;
|
|
|
+ $projectAccess = $this->hasAccessToProject($projectID);
|
|
|
+ if (!empty($groups)) {
|
|
|
+ if (!$projectAccess) {
|
|
|
+ //echo '<pre>TODO: filtered by acl for project';print_r($this->_projectInfo[$projId]);echo'</pre>';
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (!$this->hasGroupsAccessToProjects($projectID, $groups)) {
|
|
|
+ //echo '<pre>TODO: filtered by acl and groups';print_r($this->_projectInfo[$projId]);echo'</pre>';
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ?>
|
|
|
<tr class="row-<?php echo ($t = 1 - $t); ?>"
|
|
|
- data-proj_id="<?php echo $projectInfo->ID_PROJECT; ?>"
|
|
|
- data-path="<?php echo $projectInfo->path; ?>">
|
|
|
+ data-proj_id="<?php echo $projectID; ?>"
|
|
|
+ data-path="<?php echo $projectPath; ?>">
|
|
|
<td class="p2 r nr">
|
|
|
- <input type="checkbox" name="selectedProject" onclick="return selectProject(this);" value="<?php echo $projectInfo->ID_PROJECT; ?>" />
|
|
|
+ <input type="checkbox" name="selectedProject" onclick="return selectProject(this);" value="<?php echo $projectID; ?>" />
|
|
|
</td>
|
|
|
- <td class="p2 l nr"><?php echo $projectInfo->path; ?></td>
|
|
|
- <td class="p2" style="max-width:300px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;" title="<?php echo $projectInfo->M_DIST_DESC; ?>"><?php echo $projectInfo->M_DIST_DESC; ?></td>
|
|
|
+ <td class="p2 l nr"><nobr><?php echo $projectPath; ?></nobr></td>
|
|
|
+ <?php if (!$projectAccess) : ?>
|
|
|
+ <td class="p2">***</td>
|
|
|
+ <?php else : ?>
|
|
|
+ <td class="p2" style="max-width:300px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;" title="<?php echo $projectDesc; ?>"><?php echo $projectDesc; ?></td>
|
|
|
+ <?php endif; ?>
|
|
|
<?php foreach ($months as $month) : ?>
|
|
|
- <?php if (array_key_exists($month, $projectInfo->costsByMonth)) : ?>
|
|
|
- <?php $vCost = V::get($month, '', $projectInfo->costsByMonth); ?>
|
|
|
- <?php $vCostChildOut = number_format($vCost->COST_CHILD, 2); ?>
|
|
|
- <?php $vCostSelfOut = number_format($vCost->COST_SELF, 2); ?>
|
|
|
- <?php $vCostTotalOut = number_format($vCost->COST_TOTAL, 2); ?>
|
|
|
- <?php if ($vCost->COST_CHILD > 0) : ?>
|
|
|
- <?php $title = "Koszt projektu {$vCostSelfOut} / koszt podprojektów $vCostChildOut"; ?>
|
|
|
- <?php if ($vCost->COST_SELF > 0) : ?>
|
|
|
- <td class="cell-cost cell-cost-self_and_child"
|
|
|
- data-month_num="<?php echo $month; ?>"
|
|
|
- data-cost="<?php echo $vCostTotalOut; ?>"
|
|
|
- data-proj_path="<?php echo $projectInfo->path; ?>"
|
|
|
- data-proj_id="<?php echo $projectInfo->ID_PROJECT; ?>">
|
|
|
- <span class="ttip" title="<?php echo $title; ?>"><?php echo $vCostTotalOut; ?></span>
|
|
|
- </td>
|
|
|
- <?php else : ?>
|
|
|
- <td class="cell-cost cell-cost-only_child"
|
|
|
+ <?php $vMonthCost = $this->getCost($projectID, $month); ?>
|
|
|
+ <?php $monthCostTotal = ($vMonthCost)? $vMonthCost->COST_TOTAL : 0; ?>
|
|
|
+ <?php if (!$projectAccess) : ?>
|
|
|
+ <td style="min-width:30px;text-align:right;">***</td>
|
|
|
+ <?php elseif (!$vMonthCost) : ?>
|
|
|
+ <td style="min-width:30px"> </td>
|
|
|
+ <?php else : ?>
|
|
|
+ <?php
|
|
|
+ $vCostChildOut = number_format($vMonthCost->COST_CHILD, 2);
|
|
|
+ $vCostSelfOut = number_format($vMonthCost->COST_SELF, 2);
|
|
|
+ $vCostTotalOut = number_format($vMonthCost->COST_TOTAL, 2);
|
|
|
+ $title = "Koszt projektu {$vCostSelfOut} / koszt podprojektów $vCostChildOut";
|
|
|
+ $cellCostCls = '';
|
|
|
+ if ($vMonthCost->COST_CHILD > 0) {
|
|
|
+ if ($vMonthCost->COST_SELF > 0) {
|
|
|
+ $cellCostCls = 'cell-cost-self_and_child';
|
|
|
+ } else {
|
|
|
+ $cellCostCls = 'cell-cost-only_child';
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ $cellCostCls = 'cell-cost-only_self';
|
|
|
+ }
|
|
|
+ ?>
|
|
|
+ <td class="cell-cost <?php echo $cellCostCls; ?>"
|
|
|
data-month_num="<?php echo $month; ?>"
|
|
|
data-cost="<?php echo $vCostTotalOut; ?>"
|
|
|
- data-proj_path="<?php echo $projectInfo->path; ?>"
|
|
|
- data-proj_id="<?php echo $projectInfo->ID_PROJECT; ?>">
|
|
|
+ data-proj_path="<?php echo $projectPath; ?>"
|
|
|
+ data-proj_id="<?php echo $projectID; ?>">
|
|
|
<span class="ttip" title="<?php echo $title; ?>"><?php echo $vCostTotalOut; ?></span>
|
|
|
</td>
|
|
|
- <?php endif; ?>
|
|
|
- <?php else : ?>
|
|
|
- <td class="cell-cost cell-cost-only_self"
|
|
|
- data-month_num="<?php echo $month; ?>"
|
|
|
- data-cost="<?php echo $vCostTotalOut; ?>"
|
|
|
- data-proj_path="<?php echo $projectInfo->path; ?>"
|
|
|
- data-proj_id="<?php echo $projectInfo->ID_PROJECT; ?>">
|
|
|
- <?php echo $vCostTotalOut; ?>
|
|
|
+ <?php endif; ?>
|
|
|
+ <td class="cell-plan">
|
|
|
+ <?php $monthPlan = $this->getPlan($projectID, $month); ?>
|
|
|
+ <?php $monthPlanOut = number_format($monthPlan, 2); ?>
|
|
|
+ <?php if (!$projectAccess) : ?>
|
|
|
+ ***
|
|
|
+ <?php elseif ($monthPlan > 0) : ?>
|
|
|
+ <?php echo $monthPlan; ?>
|
|
|
+ <?php else : ?>
|
|
|
+
|
|
|
+ <?php endif; ?>
|
|
|
</td>
|
|
|
- <?php endif; ?>
|
|
|
+ <?php
|
|
|
+ $cellProcentCls = '';
|
|
|
+ $procentOut = ' ';
|
|
|
+ $monthPlan = $this->getPlan($projectID, $month);
|
|
|
+ if ($monthPlan > 0) {
|
|
|
+ $procentOut = round(($monthCostTotal * 100) / $monthPlan);
|
|
|
+ if ($procentOut > 200) {
|
|
|
+ $cellProcentCls = 'cell-procent-over200';
|
|
|
+ } else if ($procentOut > 100) {
|
|
|
+ $cellProcentCls = 'cell-procent-over100';
|
|
|
+ } else if ($procentOut == 100) {
|
|
|
+ $cellProcentCls = 'cell-procent-100';
|
|
|
+ } else {
|
|
|
+ $cellProcentCls = 'cell-procent-below100';
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ?>
|
|
|
+ <?php if (!$projectAccess) : ?>
|
|
|
+ <td style="min-width:30px;text-align:right;">***</td>
|
|
|
<?php else : ?>
|
|
|
- <td style="min-width:30px"> </td>
|
|
|
+ <td class="cell-procent <?php echo $cellProcentCls; ?>"><?php echo $procentOut; ?></td>
|
|
|
<?php endif; ?>
|
|
|
<?php endforeach; ?>
|
|
|
</tr>
|
|
|
@@ -281,18 +365,28 @@ jQuery(document).ready(function() {
|
|
|
</div>
|
|
|
</div>
|
|
|
<table id="proj-koresp-info" style="display:none">
|
|
|
- <?php foreach ($this->_costs as $projId => $projectInfo) : ?>
|
|
|
+ <?php foreach ($this->_projectPathsOrder as $projPath => $projId) : ?>
|
|
|
+ <?php
|
|
|
+ $projectInfo = $this->_costs[$projId];
|
|
|
+ if (!$projectInfo) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ $projectID = $projId;
|
|
|
+ $projectDesc = $this->_projectInfo[$projId]->M_DIST_DESC;
|
|
|
+ $projectPath = $this->_projectInfo[$projId]->path;
|
|
|
+ ?>
|
|
|
<?php if (!empty($projectInfo->korespByMonth)) : ?>
|
|
|
<?php foreach ($projectInfo->korespByMonth as $kMonth => $vKorespMonthList) : ?>
|
|
|
- <tbody id="row-proj-<?php echo $projectInfo->ID_PROJECT; ?>-koresp-by-month-<?php echo $kMonth; ?>"
|
|
|
+ <tbody id="row-proj-<?php echo $projectID; ?>-koresp-by-month-<?php echo $kMonth; ?>"
|
|
|
data-month_num="<?php echo $kMonth; ?>"
|
|
|
- data-proj_path="<?php echo $projectInfo->path; ?>"
|
|
|
- data-proj_id="<?php echo $projectInfo->ID_PROJECT; ?>">
|
|
|
+ data-proj_path="<?php echo $projectPath; ?>"
|
|
|
+ data-proj_id="<?php echo $projectID; ?>">
|
|
|
<tr>
|
|
|
- <td style="padding:3px;font-size:1em;background:#eee;"><?php echo $projectInfo->path; ?></td>
|
|
|
- <td colspan="3" style="padding:3px;font-size:1.2em;background:#eee;">
|
|
|
- Koszty projektu nr <?php echo $projectInfo->ID_PROJECT; ?>
|
|
|
+ <td style="padding:3px;font-size:1em;background:#eee;"><nobr><?php echo $projectPath; ?></nobr></td>
|
|
|
+ <td colspan="3" style="padding:3px;font-size:1.1em;background:#eee;max-width:500px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;" title="<?php echo $projectDesc; ?>">
|
|
|
+ <!-- Koszty projektu nr <?php echo $projectID; ?> -->
|
|
|
<!-- - miesiąc <?php echo $year; ?>-<?php echo sprintf("%02d", $kMonth); ?> -->
|
|
|
+ <?php echo $projectDesc; ?>
|
|
|
</td>
|
|
|
</tr>
|
|
|
<?php foreach ($vKorespMonthList as $kKorespIdx => $vKorespInfo) : ?>
|
|
|
@@ -306,7 +400,7 @@ jQuery(document).ready(function() {
|
|
|
*/ ?>
|
|
|
<tr>
|
|
|
<td class="p2 r nr"><?php echo $vKorespInfo->ID; ?></td>
|
|
|
- <td class="p2" style="max-width:400px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;" title="<?php echo $projectInfo->M_DIST_DESC; ?>"><?php echo $vKorespInfo->K_ZAWARTOS; ?></td>
|
|
|
+ <td class="p2" style="max-width:400px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;" title="<?php echo $vKorespInfo->K_ZAWARTOS; ?>"><?php echo $vKorespInfo->K_ZAWARTOS; ?></td>
|
|
|
<?php $vKorespCostOut = number_format($vKorespInfo->COST, 2); ?>
|
|
|
<td class="cell-cost cell-cost-only_child"><?php echo $vKorespCostOut; ?></td>
|
|
|
<td>
|
|
|
@@ -322,7 +416,6 @@ jQuery(document).ready(function() {
|
|
|
<?php endif; ?>
|
|
|
<?php endforeach; ?>
|
|
|
</table>
|
|
|
-</div>
|
|
|
<script>
|
|
|
jQuery(document).ready(function(){
|
|
|
jQuery('.ttip').tooltip();
|
|
|
@@ -367,51 +460,70 @@ jQuery(document).ready(function() {
|
|
|
<?php
|
|
|
}
|
|
|
|
|
|
- public function getCostsByYear__OLD($year) {
|
|
|
+ public function getCost($idProject, $month) {
|
|
|
+ if (!array_key_exists($idProject, $this->_costs)) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ if (!array_key_exists($month, $this->_costs[$idProject]->costsByMonth)) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ return $this->_costs[$idProject]->costsByMonth[$month];
|
|
|
+ }
|
|
|
+
|
|
|
+ public function getPlan($idProject, $month) {
|
|
|
+ if (!array_key_exists($idProject, $this->_plan)) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ if (!array_key_exists($month, $this->_plan[$idProject])) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ return $this->_plan[$idProject][$month];
|
|
|
+ }
|
|
|
+
|
|
|
+ public function fetchDataByYear($year) {
|
|
|
+ $this->_fetchCostsByYear($year);
|
|
|
+ $this->_fetchPlanByYear($year);
|
|
|
+ $this->_fetchProjectInfo();
|
|
|
+ $this->_buildProjectTree();
|
|
|
+ $this->_reacountCostsFromKoresp();
|
|
|
+ return count($this->_projectInfo) > 1;// $this->_projectInfo[0] - Wszystkie projekty
|
|
|
+ }
|
|
|
+
|
|
|
+ public function _fetchPlanByYear($year) {
|
|
|
$db = DB::getDB();
|
|
|
- $costs = array();
|
|
|
+ $this->_plan = array();
|
|
|
$sql = "
|
|
|
- select
|
|
|
- t.`ID_PROJECT`
|
|
|
- , t.`M_DIST_DESC`
|
|
|
- , t.`P_ID`
|
|
|
- , t.`path`
|
|
|
- , t.`MONTH`
|
|
|
- , t.`COST_SELF`
|
|
|
- , t.`COST_CHILD`
|
|
|
- , t.`COST_TOTAL`
|
|
|
- , t.`INCOME_SELF`
|
|
|
- , t.`INCOME_CHILD`
|
|
|
- , t.`INCOME_TOTAL`
|
|
|
- from `test_budget_project_synthetics_view` as t
|
|
|
- where 1=1
|
|
|
- and t.`MONTH` like '{$year}-%'
|
|
|
+ select plan.`ID`
|
|
|
+ , plan.`ID_PROJECT` AS `ID_PROJECT`
|
|
|
+ , plan.`MONTH_1_VALUE`
|
|
|
+ , plan.`MONTH_2_VALUE`
|
|
|
+ , plan.`MONTH_3_VALUE`
|
|
|
+ , plan.`MONTH_4_VALUE`
|
|
|
+ , plan.`MONTH_5_VALUE`
|
|
|
+ , plan.`MONTH_6_VALUE`
|
|
|
+ , plan.`MONTH_7_VALUE`
|
|
|
+ , plan.`MONTH_8_VALUE`
|
|
|
+ , plan.`MONTH_9_VALUE`
|
|
|
+ , plan.`MONTH_10_VALUE`
|
|
|
+ , plan.`MONTH_11_VALUE`
|
|
|
+ , plan.`MONTH_12_VALUE`
|
|
|
+ from `projects_budget_year_month` plan
|
|
|
+ where plan.`year`='{$year}'
|
|
|
+ -- TODO: acl
|
|
|
";
|
|
|
+ //echo'<pre style="border:1px solid red;overflow:auto;max-height:400px">';print_r($sql);echo'</pre>';
|
|
|
$res = $db->query($sql);
|
|
|
while ($r = $db->fetch($res)) {
|
|
|
- if (!array_key_exists($r->ID_PROJECT, $costs)) {
|
|
|
- $projectInfo = new stdClass();
|
|
|
- $projectInfo->ID_PROJECT = $r->ID_PROJECT;
|
|
|
- $projectInfo->M_DIST_DESC = $r->M_DIST_DESC;
|
|
|
- $projectInfo->path = $r->path;
|
|
|
- $projectInfo->costsByMonth = array();
|
|
|
- $costs[$r->ID_PROJECT] = $projectInfo;
|
|
|
+ $plan = array();
|
|
|
+ for ($i = 1; $i <= 12; $i++) {
|
|
|
+ $plan[$i] = V::get("MONTH_{$i}_VALUE", 0, $r);
|
|
|
}
|
|
|
- $cost = new stdClass();
|
|
|
- $cost->MONTH = $r->MONTH;
|
|
|
- $cost->COST_SELF = $r->COST_SELF;
|
|
|
- $cost->COST_CHILD = $r->COST_CHILD;
|
|
|
- $cost->COST_TOTAL = $r->COST_TOTAL;
|
|
|
- $cost->INCOME_SELF = $r->INCOME_SELF;
|
|
|
- $cost->INCOME_CHILD = $r->INCOME_CHILD;
|
|
|
- $cost->INCOME_TOTAL = $r->INCOME_TOTAL;
|
|
|
- $monthNum = intval(substr($r->MONTH, 5, 2));
|
|
|
- $costs[$r->ID_PROJECT]->costsByMonth[$monthNum] = $cost;
|
|
|
+ $this->_plan[$r->ID_PROJECT] = $plan;
|
|
|
}
|
|
|
- return $costs;
|
|
|
+ return $this->_plan;
|
|
|
}
|
|
|
|
|
|
- public function getCostsByYear($year) {
|
|
|
+ public function _fetchCostsByYear($year) {
|
|
|
$db = DB::getDB();
|
|
|
$this->_costs = array();
|
|
|
$sql = "
|
|
|
@@ -434,6 +546,7 @@ jQuery(document).ready(function() {
|
|
|
from `IN7_DZIENNIK_KORESP` k
|
|
|
where ((k.`COST_VALUE` > 0) or (k.`INCOME_VALUE` > 0))
|
|
|
and k.`K_DATA_OTRZYMANEJ_KORESP` like '{$year}-%'
|
|
|
+ -- TODO: acl
|
|
|
";
|
|
|
//echo'<pre style="border:1px solid red;overflow:auto;max-height:400px">';print_r($sql);echo'</pre>';
|
|
|
$res = $db->query($sql);
|
|
|
@@ -465,8 +578,6 @@ jQuery(document).ready(function() {
|
|
|
{
|
|
|
$projectZeroInfo = new stdClass();
|
|
|
$projectZeroInfo->ID_PROJECT = 0;
|
|
|
- $projectZeroInfo->M_DIST_DESC = 'Wszystkie projekty';
|
|
|
- $projectZeroInfo->path = '0';
|
|
|
$projectZeroInfo->costsByMonth = array();
|
|
|
$projectZeroInfo->korespByMonth = array();
|
|
|
$this->_costs[0] = $projectZeroInfo;
|
|
|
@@ -475,8 +586,6 @@ jQuery(document).ready(function() {
|
|
|
if (!array_key_exists($vProjId, $this->_costs)) {
|
|
|
$projectInfo = new stdClass();
|
|
|
$projectInfo->ID_PROJECT = $vProjId;
|
|
|
- $projectInfo->M_DIST_DESC = '';
|
|
|
- $projectInfo->path = '';
|
|
|
$projectInfo->costsByMonth = array();
|
|
|
$projectInfo->korespByMonth = array();
|
|
|
$this->_costs[$vProjId] = $projectInfo;
|
|
|
@@ -502,37 +611,110 @@ jQuery(document).ready(function() {
|
|
|
$this->_costs[0]->korespByMonth[$monthNum][] = $korespInfo;
|
|
|
}
|
|
|
}
|
|
|
- $this->_fetchProjectInfo();
|
|
|
- $this->_buildProjectTree();
|
|
|
- $this->_reacountCostsFromKoresp();
|
|
|
return $this->_costs;
|
|
|
}
|
|
|
|
|
|
private function _fetchProjectInfo() {
|
|
|
$db = DB::getDB();
|
|
|
- $projectIds = array_keys($this->_costs);
|
|
|
+ $hasAccessForAllProjects = true;
|
|
|
+ $projectIds = array();
|
|
|
+ $projectsFromCostIds = array_keys($this->_costs);
|
|
|
+ foreach ($projectsFromCostIds as $idProject) $projectIds[$idProject] = true;
|
|
|
+ $projectsFromPlanIds = array_keys($this->_plan);
|
|
|
+ foreach ($projectsFromPlanIds as $idProject) $projectIds[$idProject] = true;
|
|
|
+ foreach ($projectIds as $idProject => $vBool) $this->_projectInfo[$idProject] = new stdClass();
|
|
|
+ $projectIds = array_keys($projectIds);
|
|
|
$sqlProjIds = "'" . implode("','", $projectIds) . "'";
|
|
|
- $sql = "select p.`ID`, p.`P_ID`, p.`path`, p.`M_DIST_DESC`
|
|
|
+ $sql = "
|
|
|
+ select p.`ID`
|
|
|
+ , p.`P_ID`
|
|
|
+ , p.`path`
|
|
|
+ , p.`M_DIST_DESC`
|
|
|
+ , p.`A_ADM_COMPANY` as aclGroupWrite
|
|
|
+ , p.`A_CLASSIFIED` as aclGroupRead
|
|
|
+ , p.`L_APPOITMENT_USER` as aclOwner
|
|
|
from `IN7_MK_BAZA_DYSTRYBUCJI` p
|
|
|
where p.`ID` in({$sqlProjIds})
|
|
|
";
|
|
|
$res = $db->query($sql);
|
|
|
while ($r = $db->fetch($res)) {
|
|
|
- $this->_costs[$r->ID]->path = $r->path;
|
|
|
- $this->_costs[$r->ID]->M_DIST_DESC = $r->M_DIST_DESC;
|
|
|
+ $this->_projectInfo[$r->ID]->path = $r->path;
|
|
|
+ $this->_projectInfo[$r->ID]->M_DIST_DESC = $r->M_DIST_DESC;
|
|
|
+ $this->_projectInfo[$r->ID]->aclGroupRead = $r->aclGroupRead;
|
|
|
+ $this->_projectInfo[$r->ID]->hasAccess = $this->_userHasAccessToProject($r);
|
|
|
+ if (!$this->_projectInfo[$r->ID]->hasAccess) $hasAccessForAllProjects = false;
|
|
|
+ }
|
|
|
+ $this->_projectInfo[0]->path = '0';
|
|
|
+ $this->_projectInfo[0]->M_DIST_DESC = "Wszystkie projekty";
|
|
|
+ $this->_projectInfo[0]->hasAccess = $hasAccessForAllProjects;
|
|
|
+ }
|
|
|
+
|
|
|
+ public function hasAccessToProject($idProject) {
|
|
|
+ if ($idProject >= 0) {
|
|
|
+ if (array_key_exists($idProject, $this->_projectInfo)) {
|
|
|
+ return V::get('hasAccess', false, $this->_projectInfo[$idProject]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ public function hasGroupsAccessToProjects($idProject, $groups) {
|
|
|
+ $selectedUserGroupNames = array();
|
|
|
+ $userGroups = User::getLdapGroupsNames();
|
|
|
+ foreach ($groups as $idGroup) {
|
|
|
+ $selectedUserGroupNames[$idGroup] = $userGroups[$idGroup];
|
|
|
+ }
|
|
|
+ if ($idProject >= 0) {
|
|
|
+ if (array_key_exists($idProject, $this->_projectInfo)) {
|
|
|
+ $alcGroupRead = V::get('aclGroupRead', null, $this->_projectInfo[$idProject]);
|
|
|
+ if (!$alcGroupRead) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (in_array($alcGroupRead, $selectedUserGroupNames)) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ private function _userHasAccessToProject($project) {
|
|
|
+ $groups = User::getLdapGroupsNames();
|
|
|
+ $userLogin = User::getLogin();
|
|
|
+ if ($project->aclOwner == $userLogin) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ else if (in_array($project->aclGroupRead, $groups)) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ public function getUsedUserGroups() {
|
|
|
+ $groups = array();
|
|
|
+ $userGroups = User::getLdapGroupsNames();
|
|
|
+ foreach ($this->_projectInfo as $projectInfo) {
|
|
|
+ if (!empty($projectInfo->aclGroupRead)) {
|
|
|
+ $groupKey = array_search($projectInfo->aclGroupRead, $userGroups);
|
|
|
+ if ($groupKey !== false) {
|
|
|
+ $groups[$groupKey] = $projectInfo->aclGroupRead;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return $groups;
|
|
|
}
|
|
|
|
|
|
private function _reacountCostsFromKoresp() {
|
|
|
$projMonthHasCostSelfIds = array();
|
|
|
foreach ($this->_costs as $kProjId => $vProjInfo) {
|
|
|
+ $projectPath = $this->_projectInfo[$kProjId]->path;
|
|
|
foreach ($vProjInfo->korespByMonth as $kMonthNum => $vKorespList) {
|
|
|
$this->_createCostIfNotDefined($kProjId, $kMonthNum);
|
|
|
foreach ($vKorespList as $vKoresp) {
|
|
|
$this->_costs[$kProjId]->costsByMonth[$kMonthNum]->COST_SELF += $vKoresp->COST;
|
|
|
$this->_costs[$kProjId]->costsByMonth[$kMonthNum]->INCOME_SELF += $vKoresp->INCOME;
|
|
|
}
|
|
|
- $projHasCostSelfIds[$kProjId][$kMonthNum] = $vProjInfo->path;
|
|
|
+ $projHasCostSelfIds[$kProjId][$kMonthNum] = $projectPath;
|
|
|
}
|
|
|
}
|
|
|
//echo'<pre style="width:600px;border:1px solid red;max-height:300px;overflow:auto;">$projHasCostSelfIds: ';print_r($projHasCostSelfIds);echo'</pre>';
|
|
|
@@ -576,8 +758,8 @@ jQuery(document).ready(function() {
|
|
|
|
|
|
public function _buildProjectTree() {
|
|
|
$this->_projectPathsOrder = array();
|
|
|
- foreach ($this->_costs as $idProject => $projectInfo) {
|
|
|
- $this->_projectPathsOrder[$projectInfo->path] = $projectInfo->ID_PROJECT;
|
|
|
+ foreach ($this->_projectInfo as $idProject => $projectInfo) {
|
|
|
+ $this->_projectPathsOrder[$projectInfo->path] = $idProject;
|
|
|
}
|
|
|
//echo'<pre style="width:600px;border:1px solid red;max-height:300px;overflow:auto;">projPaths: ';print_r($this->_projectPathsOrder);echo'</pre>';
|
|
|
uksort($this->_projectPathsOrder, array($this, 'sortPathsCallback'));
|
|
|
@@ -601,4 +783,71 @@ jQuery(document).ready(function() {
|
|
|
return $la - $lb;
|
|
|
}
|
|
|
|
|
|
+ public function updatePaths() {
|
|
|
+ $sqlList = array();
|
|
|
+ $sqlList['updateAllPaths'] = <<<SQL
|
|
|
+update `projects_budget_year_month` b
|
|
|
+set path = (select coalesce(
|
|
|
+ (select p.`path` from `IN7_MK_BAZA_DYSTRYBUCJI` p where p.`ID`=b.`ID_PROJECT` limit 1)
|
|
|
+ , '?'));
|
|
|
+SQL;
|
|
|
+ $db = DB::getDB();
|
|
|
+ if ($db->has_errors()) {
|
|
|
+ throw new Exception("DB Errors: " . implode("\n<br>", $db->get_errors()));
|
|
|
+ }
|
|
|
+ foreach ($sqlList as $sqlName => $sql) {
|
|
|
+ $res = $db->query($sql);
|
|
|
+ if ($db->has_errors()) {
|
|
|
+ throw new Exception("DB Errors at sql '{$sqlName}': " . implode("\n<br>", $db->get_errors()));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public function reinstall() {
|
|
|
+ $sqlList = array();
|
|
|
+ $sqlList['RemoveTrigger_BudgetPlan_BeforeInsert'] = "DROP TRIGGER IF EXISTS `projects_budget_year_month_BEFORE_INSERT`";
|
|
|
+ $sqlList['CreateTrigger_BudgetPlan_BeforeInsert'] = "
|
|
|
+CREATE DEFINER=`root`@`localhost` TRIGGER `projects_budget_year_month_BEFORE_INSERT` BEFORE INSERT ON `projects_budget_year_month`
|
|
|
+FOR EACH ROW BEGIN
|
|
|
+ IF NEW.ID_PROJECT IS NOT NULL and NEW.ID_PROJECT>0 THEN
|
|
|
+ SET NEW.path = (select coalesce(
|
|
|
+ (select p.`path` from `IN7_MK_BAZA_DYSTRYBUCJI` p where p.`ID`=NEW.`ID_PROJECT` limit 1)
|
|
|
+ , '?'
|
|
|
+ ));
|
|
|
+ END IF;
|
|
|
+END
|
|
|
+ ";
|
|
|
+ $sqlList['RemoveTrigger_BudgetPlan_BeforeUpdate'] = "DROP TRIGGER IF EXISTS `projects_budget_year_month_BEFORE_UPDATE `";
|
|
|
+ // throws errors:
|
|
|
+ // #1146 - Table '{DATABASE_NAME}.P5-MSG:Route_FixZasobPath:ERROR: Loop detected ID=PARENT_ID' doesn't exist
|
|
|
+ // #1146 - Table '{DATABASE_NAME}.P5-MSG:Route_FixZasobPath:ERROR: Parent item not exists' doesn't exist
|
|
|
+ // #1146 - Table '{DATABASE_NAME}.P5-MSG:Route_FixZasobPath:ERROR: Loop detected in path' doesn't exist
|
|
|
+ $sqlList['CreateTrigger_BudgetPlan_BeforeUpdate'] = "
|
|
|
+CREATE DEFINER=`root`@`localhost` TRIGGER `projects_budget_year_month_BEFORE_UPDATE` BEFORE UPDATE ON `projects_budget_year_month`
|
|
|
+FOR EACH ROW BEGIN
|
|
|
+ IF NEW.ID_PROJECT IS NULL THEN
|
|
|
+ SET NEW.path = '';
|
|
|
+ ELSEIF OLD.ID_PROJECT IS NULL or NEW.ID_PROJECT<>OLD.ID_PROJECT THEN
|
|
|
+ IF NEW.ID_PROJECT>0 THEN
|
|
|
+ SET NEW.path = (select coalesce(
|
|
|
+ (select p.`path` from `IN7_MK_BAZA_DYSTRYBUCJI` p where p.`ID`=NEW.`ID_PROJECT` limit 1)
|
|
|
+ , '?'));
|
|
|
+ ELSE
|
|
|
+ SET NEW.path = '';
|
|
|
+ END IF;
|
|
|
+ END IF;
|
|
|
+END
|
|
|
+ ";
|
|
|
+ $db = DB::getDB();
|
|
|
+ if ($db->has_errors()) {
|
|
|
+ throw new Exception("DB Errors: " . implode("\n<br>", $db->get_errors()));
|
|
|
+ }
|
|
|
+ foreach ($sqlList as $sqlName => $sql) {
|
|
|
+ $res = $db->query($sql);
|
|
|
+ if ($db->has_errors()) {
|
|
|
+ throw new Exception("DB Errors at sql '{$sqlName}': " . implode("\n<br>", $db->get_errors()));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
}
|