ProjektyZamowieniaKosztorys.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. <?php
  2. Lib::loadClass('RouteBase');
  3. Lib::loadClass('ProjectKosztorysSchema');
  4. Lib::loadClass('ProjectKosztorysModel');
  5. Lib::loadClass('ProjectKosztorysCennik');
  6. Lib::loadClass('UI');
  7. Lib::loadClass('Response');
  8. Lib::loadClass('Route_ProjektyKosztorysBase');
  9. class Route_UrlAction_ProjektyZamowieniaKosztorys extends Route_ProjektyKosztorysBase {
  10. public $_model = array();
  11. public $_ID_ZASOB_ZAMOWIENIE = 24121;
  12. public function defaultAction() {
  13. // TODO: check if user is allowed to run this action
  14. UI::gora();
  15. if (1 != V::get('_print', '', $_GET)) UI::menu();
  16. try {
  17. $idProject = V::get('ID_PROJECT', 0, $_REQUEST, 'int');
  18. if (!$idProject) throw new Exception("Wrong param in 'ID_PROJECT' - expected integer!");
  19. $this->panel($idProject);
  20. $this->zamowienia($idProject);
  21. } catch (Exception $e) {
  22. UI::alert('danger', "Error #" . $e->getCode() . "|" . $e->getLine() . ": " . $e->getMessage());
  23. }
  24. UI::dol();
  25. }
  26. public function zamowienia($idProject) {
  27. $idProject = (int)$idProject;
  28. if ($idProject <= 0) throw new Exception("Error Processing Request - wrong param id project");
  29. $idOrder = V::get('ID_ORDER', 0, $_REQUEST, 'int');
  30. $ordersRaw = DB::getPDO()->fetchAllByKey("
  31. select k.ID
  32. , k.A_STATUS
  33. , k.K_DATA_OTRZYM_KORESP
  34. , k.K_DATA_OTRZYMANEJ_KORESP
  35. , k.K_OD_KOGO
  36. , k.OD_KOGO_ADRES
  37. , k.K_ZAWARTOS
  38. from IN7_DZIENNIK_KORESP k
  39. where k.CRM_LISTA_ZASOBOW_ID = {$this->_ID_ZASOB_ZAMOWIENIE}
  40. and k.ID_PROJECT = {$idProject}
  41. and k.K_TYP_KORESP = 'OUT'
  42. ", $key = 'ID');
  43. $orders = array();
  44. foreach ($ordersRaw as $r) {
  45. $item = array();
  46. $chkd = ($r['ID'] == $idOrder) ? ' checked="checked"' : '';
  47. $item['ID'] = '<label><input type="radio" onClick="this.form.submit()" name="ID_ORDER" value="'.$r['ID'].'" '.$chkd.'> '.$r['ID'].'</label>';
  48. $item['A_STATUS'] = $r['A_STATUS'];
  49. $item['K_DATA_OTRZYM_KORESP'] = $r['K_DATA_OTRZYM_KORESP'];
  50. $item['K_DATA_OTRZYMANEJ_KORESP'] = $r['K_DATA_OTRZYMANEJ_KORESP'];
  51. $item['K_OD_KOGO'] = $r['K_OD_KOGO'];
  52. $item['OD_KOGO_ADRES'] = $r['OD_KOGO_ADRES'];
  53. $item['K_ZAWARTOS'] = $r['K_ZAWARTOS'];
  54. $orders[] = $item;
  55. }
  56. $order = ($idOrder > 0 && array_key_exists($idOrder, $ordersRaw)) ? $ordersRaw[$idOrder] : null;
  57. UI::startContainer();
  58. if (1 != V::get('_print', '', $_GET)) {
  59. UI::startTag('form', ['action'=>'', 'method'=>'get']);
  60. UI::tag('input', ['type'=>'hidden', 'name'=>'_route', 'value'=>'UrlAction_ProjektyZamowieniaKosztorys']);
  61. UI::tag('input', ['type'=>'hidden', 'name'=>'ID_PROJECT', 'value'=>$idProject]);
  62. if (empty($orders)) UI::alert('info', "Brak zamówień w korespondencji dotyczących projektu {$idProject}");
  63. else UI::table(['caption'=>"Wybierz zamówienie", 'rows'=>$orders]);
  64. UI::endTag('form');
  65. UI::tag('hr');
  66. if (null != $order) {
  67. $printLink = Request::getPathUri() . "index.php?_route=UrlAction_ProjektyZamowieniaKosztorys";
  68. $printLink .= "&ID_PROJECT={$idProject}";
  69. $printLink .= "&ID_ORDER={$order['ID']}";
  70. $printLink .= "&_print=1";
  71. UI::startTag('div', ['style'=>'text-align:right']);
  72. UI::tag('a', ['_target'=>'blank', 'href'=>$printLink], '<i class="glyphicon glyphicon-print"></i>'. "Drukuj zamówienie");
  73. UI::endTag('div');
  74. }
  75. }
  76. if (null !== $order) {
  77. $schema = ProjectKosztorysSchema::getSchema();// OK only 'config'
  78. $model = $this->getModel($idProject);
  79. $data = $this->getKosztorysData($idProject, $order['ID']);
  80. {
  81. $idCompany = null;
  82. $admin = false;
  83. $companyAdmin = null;
  84. $projCosts = null;
  85. $hidePrices = true;
  86. $model = $this->getModel($idProject);
  87. //DBG::table("subProjectList", $model->subProjectList, __CLASS__, __FUNCTION__, __LINE__);
  88. $schema = ProjectKosztorysSchema::getSchema();
  89. $projCosts = $this->getProjectCostByCennik($idProject, $idCompany);
  90. //DBG::_(true, true, "projCosts", $projCosts, __CLASS__, __FUNCTION__, __LINE__);
  91. $viewLayerDataArgs = compact('idProject', 'idCompany', 'admin', 'companyAdmin', 'projCosts', 'hidePrices');
  92. UI::startTag('h1', ['style'=>'margin-bottom:1em']);
  93. echo "Zamówienie nr {$order['ID']}";
  94. UI::tag('small', ['style'=>"display:block"], $order['K_ZAWARTOS']);
  95. UI::endTag('h1');
  96. UI::setTitleJsTag("Zamówienie nr {$order['ID']} (Kosztorys projektu [{$idProject}])");
  97. UI::startTag('table', ['class'=>'table']);
  98. UI::startTag('tr');
  99. UI::tag('th', null, "Nr zamówienia");
  100. UI::tag('th', null, $schema['nr']);
  101. UI::tag('th', null, $schema['title']);
  102. UI::tag('th', null, $schema['ownerName']);
  103. // UI::tag('th', ['style'=>'text-align:right'], $schema['cost_total']);
  104. UI::endTag('tr');
  105. UI::startTag('tr');
  106. UI::tag('td', null, $order['ID']);
  107. UI::tag('td', null, $model->idProject);
  108. UI::tag('td', null, $model->title);
  109. UI::tag('td', null, $model->ownerName);
  110. // UI::tag('td', ['style'=>'text-align:right'], number_format($projCosts['cost_total'], 2, ',', ' '));
  111. UI::endTag('tr');
  112. UI::endTag('table');
  113. $this->viewLayersData($viewLayerDataArgs);
  114. }
  115. if (DBG::isActive()) DBG::nicePrint($data, '$data');
  116. // if (DBG::isActive()) DBG::nicePrint($schema, '$schema');
  117. // if (DBG::isActive()) DBG::nicePrint($model, '$model');
  118. }
  119. if (DBG::isActive()) UI::tag('hr');
  120. if (DBG::isActive()) $this->checkDBData();
  121. UI::endContainer();
  122. }
  123. public function checkDBData() {
  124. $schema = ProjectKosztorysSchema::getSchema();// OK only 'config'
  125. foreach ($schema['config']['layer'] as $idLayer => $layer) {
  126. // <div class="panel panel-default">
  127. // <div class="panel-heading">Panel heading without title</div>
  128. // <div class="panel-body">
  129. // Panel content
  130. // </div>
  131. // </div>
  132. UI::startTag('div', ['class'=>'panel panel-default']);
  133. UI::startTag('div', ['class'=>'panel-heading']);
  134. echo "Warstwa: {$layer['label']}";
  135. UI::endTag('div');// .panel-heading
  136. UI::startTag('div', ['class'=>'panel-body']);
  137. try {
  138. $rowsByIdOrder = DB::getPDO()->fetchAllByKey("
  139. select g.ID_KORESP_ZLECENIE, g.cnt
  140. -- , k.ID
  141. , k.A_STATUS
  142. , k.K_DATA_OTRZYM_KORESP
  143. , k.K_DATA_OTRZYMANEJ_KORESP
  144. , k.K_OD_KOGO
  145. , k.OD_KOGO_ADRES
  146. , k.K_ZAWARTOS
  147. , k.CRM_LISTA_ZASOBOW_ID
  148. , k.ID_PROJECT
  149. , k.K_TYP_KORESP
  150. from (
  151. select t.ID_KORESP_ZLECENIE, count(1) as cnt
  152. from {$layer['tabela_name']} t
  153. where t.ID_KORESP_ZLECENIE is not null and t.ID_KORESP_ZLECENIE > 0
  154. group by t.ID_KORESP_ZLECENIE
  155. ) g
  156. left join IN7_DZIENNIK_KORESP k on(k.ID = g.ID_KORESP_ZLECENIE)
  157. ", $key = 'ID_KORESP_ZLECENIE');
  158. } catch (Exception $e) {
  159. if ("SQLSTATE[42S22]: Column not found: 1054 Unknown column 't.ID_KORESP_ZLECENIE' in 'field list'" == $e->getMessage()) {
  160. UI::alert('danger', "Brak komórki `ID_KORESP_ZLECENIE` w tabeli `{$layer['tabela_name']}`");
  161. } else UI::alert('danger', $e->getMessage());
  162. }
  163. if (empty($rowsByIdOrder)) UI::tag('span', ['class'=>'text-warning'], "Brak wypełnionego pola ID_KORESP_ZLECENIE w tej warstwie");
  164. else {
  165. $rowsByIdOrder = array_map(function($r) {
  166. $item = [];
  167. $item['id'] = $r['ID_KORESP_ZLECENIE'];
  168. $item['ile'] = $r['cnt'];
  169. $item['K_OD_KOGO'] = $r['K_OD_KOGO'];
  170. $item['OD_KOGO_ADRES'] = $r['OD_KOGO_ADRES'];
  171. $item['K_ZAWARTOS'] = $r['K_ZAWARTOS'];
  172. $item['Zasób?'] = (int)$r['CRM_LISTA_ZASOBOW_ID'];
  173. $item['id Proj.'] = (int)$r['ID_PROJECT'];
  174. $item['typ'] = $r['K_TYP_KORESP'];
  175. $item['daty'] = "{$r['K_DATA_OTRZYM_KORESP']}<br>{$r['K_DATA_OTRZYMANEJ_KORESP']}";
  176. if ($item['Zasób?'] <= 0) $item['Zasób?'] .= '<br><span class="label label-danger" title="Brak numeru zasobu - powinien być 24121">Brak</span>';
  177. else if (24121 != $item['Zasób?']) $item['Zasób?'] .= '<br><span class="label label-danger" title="Błędny numer zasobu - powinien być 24121">Błąd</span>';
  178. if ($item['id Proj.'] <= 0) $item['id Proj.'] .= '<br><span class="label label-danger" title="Brak id projektu">Brak</span>';
  179. if ('OUT' != $item['typ']) $item['typ'] .= '<br><span class="label label-danger" title="Błędny typ korespondencji - powinien być OUT">Błąd</span>';
  180. return $item;
  181. }, $rowsByIdOrder);
  182. UI::table(['caption'=>"Pole ID_KORESP_ZLECENIE", 'rows'=>$rowsByIdOrder]);
  183. }
  184. UI::endTag('div');// .panel-body
  185. UI::endTag('div');
  186. }
  187. }
  188. public function getKosztorysData($idProject, $idOrder = 0, $admin = 0) {
  189. static $_data = null;
  190. if (null === $_data) {
  191. $idSubProject = $this->getModel($idProject)->getSubProjectIds();
  192. $idSubProject[] = $idProject;
  193. $_data = $this->fetchData($idSubProject, $idOrder, $admin);
  194. }
  195. return $_data;
  196. }
  197. public function fetchData($idProject, $idOrder = 0, $admin = 0) {
  198. $data = array();
  199. $data['summary'] = array();// [ $idType ] = ['type', 'jednostka', 'ilosc']
  200. $data['rawDataByType'] = array();
  201. if (empty($idProject)) return $data;
  202. $schema = ProjectKosztorysSchema::getSchema();// OK only 'config'
  203. $conf = $schema['config'];
  204. foreach ($conf['layer'] as $idLayer => $layer) {
  205. if (!$layer['tabela_name']) continue;// TODO: throw error in validate
  206. if ('ZASOB' == $layer['zasob_type']) {
  207. } else if ('ZASOB_ID' == $layer['zasob_type']) {
  208. } else {
  209. continue;// TODO: validate config error
  210. }
  211. $tblName = $layer['tabela_name'];
  212. $sqlIloscField = (!empty($layer['ilosc_field']))? $layer['ilosc_field'] : 'ID';
  213. $sqlIlosc = ('SZTUKA' == $layer['jednostka'])? "count(1)" : "sum(t.{$sqlIloscField})";
  214. $sqlZasobField = (!empty($layer['zasob_field']))? $layer['zasob_field'] : 'ID';
  215. $sqlGroupBy = "group by t.ID_PROJECT" . ((!empty($layer['zasob_field']))? ", t.{$sqlZasobField}" : '');
  216. $sqlIdProject = (is_array($idProject))? implode(",", $idProject) : (int)$idProject;
  217. $sql = "
  218. select t.{$sqlZasobField}
  219. , t.ID_PROJECT
  220. , {$sqlIlosc} as ilosc
  221. from {$tblName} t
  222. where t.ID_PROJECT in({$sqlIdProject})
  223. and t.the_geom is not null
  224. -- WHERE
  225. {$sqlGroupBy}
  226. ";
  227. $data['_DBG_sql'][$idLayer] = $sql;
  228. try {
  229. $sqlWithOrder = str_replace("-- WHERE", "and t.ID_KORESP_ZLECENIE = {$idOrder}", $sql);
  230. $rawLayData = DB::getPDO()->fetchAll($sqlWithOrder);
  231. } catch (Exception $e) {
  232. if (1 != V::get('_print', '', $_GET)) UI::alert('danger', "Brak pola `ID_KORESP_ZLECENIE` w tabeli `$tblName`");
  233. $rawLayData = DB::getPDO()->fetchAll($sql);
  234. }
  235. $rawLayData = array_filter($rawLayData, function($row) {
  236. return ($row['ilosc'] > 0);
  237. });
  238. foreach ($rawLayData as $idx => &$row) {
  239. if ('ZASOB' == $layer['zasob_type']) {
  240. $row['type'] = trim($row[$sqlZasobField]);
  241. $row['idType'] = array_search($row['type'], $conf['type']);
  242. } else if ('ZASOB_ID' == $layer['zasob_type']) {
  243. $row['type'] = $layer['zasob_label'];
  244. $row['idType'] = (array_key_exists($layer['zasob_id'], $conf['type']))? $layer['zasob_id'] : null;
  245. }
  246. $row['idLayer'] = $idLayer;
  247. unset($row[$sqlZasobField]);
  248. $data['rawDataByType'][] = $row;
  249. }
  250. }
  251. //DBG::_(true, true, "data", $data, __CLASS__, __FUNCTION__, __LINE__);
  252. //DBG::table("data['rawDataByType']", $data['rawDataByType'], __CLASS__, __FUNCTION__, __LINE__);
  253. if ($admin) {
  254. foreach ($data['rawDataByType'] as $row) {
  255. $layer = $conf['layer'][$row['idLayer']];
  256. if ($row['idType'] <= 0) {
  257. UI::alert('warning', "Pomijanie nieznanego oznaczenia '{$row['type']}' w ilości {$row['ilosc']} - warstwa '{$layer['label']}' ({$layer['tabela_name']}), projekt nr {$row['ID_PROJECT']}");
  258. }
  259. }
  260. }
  261. $data['rawDataByType'] = array_filter($data['rawDataByType'], function($row) {
  262. return ($row['idType'] > 0);
  263. });
  264. //DBG::table("data['rawDataByType'] - clean", $data['rawDataByType'], __CLASS__, __FUNCTION__, __LINE__);
  265. $data['by_layer'] = array_reduce($data['rawDataByType'], function($result, $row) {
  266. $idLayer = $row['idLayer'];
  267. $idType = $row['idType'];
  268. if (!array_key_exists($idLayer, $result)) $result[$idLayer] = array();
  269. if (!array_key_exists($idType, $result[$idLayer])) {
  270. $result[$idLayer][$idType] = $row;
  271. } else {
  272. $result[$idLayer][$idType]['ilosc'] += $row['ilosc'];
  273. }
  274. return $result;
  275. }, array());
  276. //DBG::_(true, true, "data['by_layer']", $data['by_layer'], __CLASS__, __FUNCTION__, __LINE__);
  277. $data['summary'] = array();
  278. foreach ($data['by_layer'] as $idLayer => $iloscByType) {
  279. $layData = array();
  280. $layData['label'] = $conf['layer'][$idLayer]['label'];
  281. $layData['data'] = $iloscByType;
  282. foreach ($layData['data'] as &$iloscData) {
  283. $iloscData['jednostka'] = $conf['layer'][$idLayer]['jednostka'];
  284. }
  285. $data['summary'][$idLayer] = $layData;
  286. }
  287. //DBG::_(true, true, "data['summary']", $data['summary'], __CLASS__, __FUNCTION__, __LINE__);
  288. $data['by_project'] = array_reduce($data['rawDataByType'], function($result, $row) {
  289. $idProj = $row['ID_PROJECT'];
  290. $idLayer = $row['idLayer'];
  291. $idType = $row['idType'];
  292. if (!array_key_exists($idProj, $result)) $result[$idProj] = array();
  293. if (!array_key_exists($idLayer, $result[$idProj])) $result[$idProj][$idLayer] = array();
  294. if (!array_key_exists($idType, $result[$idProj][$idLayer])) {
  295. $result[$idProj][$idLayer][$idType] = $row;
  296. } else {
  297. $result[$idProj][$idLayer][$idType]['ilosc'] += $row['ilosc'];
  298. }
  299. return $result;
  300. }, array());
  301. //DBG::_(true, true, "data['by_project']", $data['by_project'], __CLASS__, __FUNCTION__, __LINE__);
  302. return $data;
  303. }
  304. }