ProjektyKosztyWstepnychRobot.php 61 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604
  1. <?php
  2. Lib::loadClass('RouteBase');
  3. class Route_UrlAction_ProjektyKosztyWstepnychRobot extends RouteBase {// TODO: UrlActionBase @see Route_UrlAction
  4. public function handleAuth() {
  5. if (!User::logged()) {
  6. User::authByRequest();
  7. }
  8. }
  9. public function defaultAction() {
  10. // TODO: check if user is allowed to run this action
  11. SE_Layout::gora();
  12. if (1 != V::get('_print', '', $_GET)) SE_Layout::menu();
  13. try {
  14. $idProject = V::get('ID_PROJECT', 0, $_REQUEST, 'int');
  15. $idCompany = V::get('ID_COMPANY', 0, $_REQUEST, 'int');
  16. if (!$idProject) throw new Exception("Wrong param in 'ID_PROJECT' - expected integer!");
  17. $this->panel($idProject, $idCompany);
  18. $this->kosztorys($idProject, $idCompany);
  19. } catch (Exception $e) {
  20. SE_Layout::alert('danger', "Error #" . $e->getCode() . "|" . $e->getLine() . ": " . $e->getMessage());
  21. }
  22. SE_Layout::dol();
  23. }
  24. public function ofertaAdminAction() {
  25. // TODO: check if user is allowed to run this action
  26. SE_Layout::gora();
  27. SE_Layout::menu();
  28. try {
  29. $idProject = V::get('ID_PROJECT', 0, $_REQUEST, 'int');
  30. $idCompany = V::get('ID_COMPANY', 0, $_REQUEST, 'int');
  31. $this->panel($idProject, $idCompany);
  32. if ($idProject > 0) {
  33. $this->oferta($idProject, $idCompany, $admin = true);
  34. } else {
  35. $this->defaultOferta();
  36. }
  37. } catch (Exception $e) {
  38. SE_Layout::alert('danger', "Error #" . $e->getCode() . "|" . $e->getLine() . ": " . $e->getMessage());
  39. }
  40. SE_Layout::dol();
  41. }
  42. public function ofertaDefaultAdminAction() {
  43. // TODO: check if user is allowed to run this action
  44. SE_Layout::gora();
  45. SE_Layout::menu();
  46. try {
  47. $idProject = 0;
  48. $idCompany = V::get('ID_COMPANY', 0, $_REQUEST, 'int');
  49. $this->panel($idProject, $idCompany);
  50. $this->defaultOferta();
  51. } catch (Exception $e) {
  52. SE_Layout::alert('danger', "Error #" . $e->getCode() . "|" . $e->getLine() . ": " . $e->getMessage());
  53. }
  54. SE_Layout::dol();
  55. }
  56. public function ofertaAction() {
  57. // TODO: check if user is allowed to run this action
  58. SE_Layout::gora();
  59. SE_Layout::menu();
  60. try {
  61. $idProject = V::get('ID_PROJECT', 0, $_REQUEST, 'int');
  62. $idCompany = V::get('ID_COMPANY', 0, $_REQUEST, 'int');
  63. if (!$idProject) throw new Exception("Wrong param in 'ID_PROJECT' - expected integer!");// TODO: show select box if not defined
  64. $this->panel($idProject, $idCompany);
  65. $this->oferta($idProject, $idCompany, $admin = false);
  66. } catch (Exception $e) {
  67. SE_Layout::alert('danger', "Error #" . $e->getCode() . "|" . $e->getLine() . ": " . $e->getMessage());
  68. }
  69. SE_Layout::dol();
  70. }
  71. public function getArgsList() {// TODO: override UrlActionBase::getArgsList action
  72. $args = array();
  73. $args[] = 'ID_PROJECT';
  74. return $args;
  75. }
  76. public function reinstallAction() {// TODO: mv to UrlActionBase
  77. $jsonData = new stdClass();
  78. $jsonData->type = 'success';
  79. $jsonData->msg = 'Gotowe';
  80. try {
  81. $this->reinstall();
  82. } catch (Exception $e) {
  83. $jsonData->type = 'danger';
  84. $jsonData->msg = $e->getMessage();
  85. }
  86. echo json_encode($jsonData);
  87. }
  88. public function reinstall() {// TODO: mv struct check to UrlActionBase
  89. $pdo = DB::getPDO();
  90. {
  91. $dropGDistanceFuncion = "DROP FUNCTION IF EXISTS `GDistance`";
  92. $pdo->exec($dropGDistanceFuncion);
  93. // Test for GDistance:
  94. // select '' as test, GDistance('') as GDistance, IF(GDistance('') = 0, 1, 0) as test_ok;
  95. // select 'NULL' as test, GDistance(NULL) as GDistance, IF(GDistance(NULL) = 0, 1, 0) as test_ok;
  96. // select 'GeomFromText(POLYGON((18.5573431614953 54.3472831082951,18.5612466579916 54.3460308284799,18.5617610722586 54.346524689865,18.5619728898979 54.3488528136092,18.5609743210268 54.3496376437764,18.5600057772984 54.3494578097971,18.559603951991 54.350742572617,18.5590637025025 54.3507194967965,18.5578575757622 54.349434823939,18.5573431614953 54.3472831082951)))' as test, GDistance(GeomFromText('POLYGON((18.5573431614953 54.3472831082951,18.5612466579916 54.3460308284799,18.5617610722586 54.346524689865,18.5619728898979 54.3488528136092,18.5609743210268 54.3496376437764,18.5600057772984 54.3494578097971,18.559603951991 54.350742572617,18.5590637025025 54.3507194967965,18.5578575757622 54.349434823939,18.5573431614953 54.3472831082951))')) as GDistance, IF(1 = GDistance(GeomFromText('POLYGON((18.5573431614953 54.3472831082951,18.5612466579916 54.3460308284799,18.5617610722586 54.346524689865,18.5619728898979 54.3488528136092,18.5609743210268 54.3496376437764,18.5600057772984 54.3494578097971,18.559603951991 54.350742572617,18.5590637025025 54.3507194967965,18.5578575757622 54.349434823939,18.5573431614953 54.3472831082951))')), 1, 0) as test_ok;
  97. // select 'GeomFromText(LINESTRING(18.5573431614953 54.3472831082951,18.5612466579916 54.3460308284799))' as test, GDistance(GeomFromText('LINESTRING(18.5573431614953 54.3472831082951,18.5612466579916 54.3460308284799)')) as GDistance, IF(GDistance(GeomFromText('LINESTRING(18.5573431614953 54.3472831082951,18.5612466579916 54.3460308284799)')) is not null, 1, 0) as test_ok;
  98. // select 'GeomFromText(POINT(18.5573431614953 54.3472831082951))' as test, GDistance(GeomFromText('POINT(18.5573431614953 54.3472831082951)')) as GDistance, IF(GDistance(GeomFromText('POINT(18.5573431614953 54.3472831082951)')) is not null, 1, 0) as test_ok;
  99. $gDistanceFuncion = <<<SQL_FUN
  100. CREATE DEFINER=`root`@`localhost` FUNCTION `GDistance`(`LS` LINESTRING) RETURNS double NO SQL
  101. BEGIN
  102. DECLARE LON_A, LAT_A, LON_B, LAT_B, R, RESULT DOUBLE;
  103. DECLARE A, B POINT;
  104. DECLARE I, N INT;
  105. -- if LS is not geometry type then return 0
  106. -- if GeometryType is not 'LINESTRING' then return 1
  107. -- if GeometryType is 'LINESTRING' then return length
  108. IF LS is null or GeometryType(LS) is null THEN
  109. RETURN 0;
  110. END IF;
  111. IF 'LINESTRING' != GeometryType(LS) THEN
  112. RETURN 1;
  113. END IF;
  114. SET R = 6372795.477598;
  115. SET N = NUMPOINTS(LS);
  116. IF N is null or N = 1 THEN
  117. RETURN 1;
  118. END IF;
  119. SET RESULT = 0;
  120. SET I = 1;
  121. WHILE I < N DO
  122. SET A = POINTN(LS, I);
  123. SET B = POINTN(LS, I + 1);
  124. SET LON_A = RADIANS(X(A));
  125. SET LAT_A = RADIANS(Y(A));
  126. SET LON_B = RADIANS(X(B));
  127. SET LAT_B = RADIANS(Y(B));
  128. SET RESULT = RESULT + ACOS(SIN(LAT_A) * SIN(LAT_B) + COS(LAT_A) * COS(LAT_B) * COS(LON_A - LON_B));
  129. SET I = I + 1;
  130. END WHILE;
  131. SET RESULT = RESULT * R;
  132. RETURN RESULT;
  133. END
  134. SQL_FUN;
  135. $pdo->exec($gDistanceFuncion);
  136. }
  137. /* required Zasoby tree structure - XML (parent rel in PARENT_ID field):
  138. <zasob:tree>
  139. <zasob:TYPESPECIALS>
  140. <zasob:URL_ACTION zasob:key=":action_id" zasob:desc=":url_action_name">
  141. <zasob:PARAM_IN zasob:key=":action_param_1_id" zasob:desc=":url_action_param_1_name"/>
  142. </zasob:URL_ACTION>
  143. </zasob:TYPESPECIALS>
  144. <zasob:BAZA_DANYCH zasob:key=":main_db_id" altername_types="DATABASE_MYSQL,DATABASE_POSTGRESQL">
  145. <zasob:TABELA zasob:key=":tbl_id" zasob:desc="IN7_MK_BAZA_DYSTRYBUCJI">
  146. <zasob:KOMORKA zasob:key=":cell_id" zasob:desc="ID"/>
  147. <zasob:URL_ACTION zasob:key=":link_action_id" zasob:desc=":url_action_name" zasob:alias_id=":action_id">
  148. <zasob:PARAM_IN zasob:key=":cell_id" zasob:desc="ID_PROJECT" zasob:alias_id=":cell_id"/>
  149. </zasob:URL_ACTION>
  150. </zasob:TABELA>
  151. </zasob:BAZA_DANYCH>
  152. </zasob:tree>
  153. */
  154. /* required Zasoby tree structure:
  155. - required base structure
  156. [:ts_main_id] TYPESPECIALS
  157. [:action_id] URL_ACTION :url_action_name
  158. [:action_param_1_id] PARAM_IN :url_action_param_1_name
  159. - current function from schema
  160. [:main_db_id] (DATABASE_MYSQL, BAZA_DANYCH, DATABASE_POSTGRESQL)
  161. [:tbl_id] TABELA 'IN7_MK_BAZA_DYSTRYBUCJI'
  162. [:cell_id] KOMORKA 'ID'
  163. [:link_action_id] (ALIAS DO :action_id) URL_ACTION :url_action_name
  164. [:link_param_id] (ALIAS DO :cell_id) PARAM_IN :url_action_param_1_name
  165. :url_action_name = 'ProjektyKosztyWstepnychRobot'
  166. :url_action_param_1_name = 'ID_PROJECT'
  167. */
  168. $flatConfig_main = array();
  169. {
  170. $flatConfig_main[] = (object)array(// Zasob::assert(TYPESPECIALS)
  171. 'query' => "
  172. select z.ID from CRM_LISTA_ZASOBOW z
  173. where z.TYPE='TYPESPECIALS'
  174. and z.A_STATUS not in('DELETED')
  175. ",
  176. 'createTable' => 'CRM_LISTA_ZASOBOW',
  177. 'createArgs' => array('TYPE' => 'TYPESPECIALS', 'DESC' => 'Typespecials'),
  178. 'out' => array(':ts_main_id' => 'ID')
  179. );
  180. $flatConfig_main[] = (object)array(// Zasob::assert(TYPESPECIALS/:url_action_name)
  181. 'query' => "
  182. select z.ID from CRM_LISTA_ZASOBOW z
  183. where z.PARENT_ID = :ts_main_id
  184. and z.TYPE = 'URL_ACTION'
  185. and z.DESC = :url_action_name
  186. and z.A_STATUS not in('DELETED')
  187. ",
  188. 'createTable' => 'CRM_LISTA_ZASOBOW',
  189. 'createArgs' => array('TYPE' => 'URL_ACTION', 'PARENT_ID' => ':ts_main_id', 'DESC' => ':url_action_name'),
  190. 'in' => array(':ts_main_id', ':url_action_name'),
  191. 'out' => array(':action_id' => 'ID')
  192. );
  193. $flatConfig_main[] = (object)array(// Zasob::assert(TYPESPECIALS/:url_action_name/:url_action_param_1_name)
  194. 'query' => "
  195. select z.ID from CRM_LISTA_ZASOBOW z
  196. where z.PARENT_ID = :action_id
  197. and z.TYPE = 'PARAM_IN'
  198. and z.DESC = :url_action_param_1_name
  199. and z.A_STATUS not in('DELETED')
  200. ",
  201. 'createTable' => 'CRM_LISTA_ZASOBOW',
  202. 'createArgs' => array('TYPE' => 'PARAM_IN', 'PARENT_ID' => ':action_id', 'DESC' => ':url_action_param_1_name'),
  203. 'in' => array(':action_id', ':url_action_param_1_name'),
  204. 'out' => array(':action_param_1_id' => 'ID')
  205. );
  206. }
  207. //DBG::_('DBG', '>1', "flatConfig_main", $flatConfig_main, __CLASS__, __FUNCTION__, __LINE__);
  208. $flatConfig_link_in_projekt = array();
  209. {
  210. $flatConfig_link_in_projekt[] = (object)array(// Zasob::assert(default_db)
  211. 'query' => "
  212. select z.ID from CRM_LISTA_ZASOBOW z
  213. where z.ID = :main_db_id
  214. and z.TYPE in('DATABASE_MYSQL', 'BAZA_DANYCH', 'DATABASE_POSTGRESQL')
  215. and z.A_STATUS not in('DELETED')
  216. ",
  217. 'createTable' => 'CRM_LISTA_ZASOBOW',
  218. 'createArgs' => array('TYPE' => 'BAZA_DANYCH', 'DESC' => 'Baza danych'),
  219. 'in' => array(':main_db_id'),
  220. 'out' => array(':main_db_id' => 'ID')
  221. );
  222. $flatConfig_link_in_projekt[] = (object)array(// Zasob::assert(default_db/IN7_MK_BAZA_DYSTRYBUCJI)
  223. 'query' => "
  224. select z.ID from CRM_LISTA_ZASOBOW z
  225. where z.PARENT_ID = :main_db_id
  226. and z.TYPE = 'TABELA'
  227. and z.DESC = 'IN7_MK_BAZA_DYSTRYBUCJI'
  228. and z.A_STATUS not in('DELETED')
  229. ",
  230. 'createTable' => 'CRM_LISTA_ZASOBOW',
  231. 'createArgs' => array('TYPE' => 'TABELA', 'PARENT_ID' => ':main_db_id', 'DESC' => 'IN7_MK_BAZA_DYSTRYBUCJI'),
  232. 'in' => array(':main_db_id'),
  233. 'out' => array(':tbl_id' => 'ID')
  234. );
  235. $flatConfig_link_in_projekt[] = (object)array(// Zasob::assert(default_db/IN7_MK_BAZA_DYSTRYBUCJI/ID)
  236. 'query' => "
  237. select z.ID from CRM_LISTA_ZASOBOW z
  238. where z.PARENT_ID = :tbl_id
  239. and z.TYPE = 'KOMORKA'
  240. and z.DESC = 'ID'
  241. and z.A_STATUS not in('DELETED')
  242. ",
  243. 'createTable' => 'CRM_LISTA_ZASOBOW',
  244. 'createArgs' => array('TYPE' => 'KOMORKA', 'PARENT_ID' => ':tbl_id', 'DESC' => 'ID'),
  245. 'in' => array(':tbl_id'),
  246. 'out' => array(':cell_id' => 'ID')
  247. );
  248. $flatConfig_link_in_projekt[] = (object)array(// Zasob::assert(default_db/IN7_MK_BAZA_DYSTRYBUCJI/:url_action_name)
  249. 'query' => "
  250. select z.ID from CRM_LISTA_ZASOBOW z
  251. where z.PARENT_ID = :tbl_id
  252. and z.ALIAS_ID = ':action_id'
  253. and z.TYPE = 'URL_ACTION'
  254. and z.DESC = ':url_action_name'
  255. and z.A_STATUS not in('DELETED')
  256. ",
  257. 'createTable' => 'CRM_LISTA_ZASOBOW',
  258. 'createArgs' => array('TYPE' => 'URL_ACTION', 'PARENT_ID' => ':tbl_id', 'ALIAS_ID' => ':action_id', 'DESC' => ':url_action_name'),
  259. 'in' => array(':tbl_id', ':action_id', ':url_action_name'),
  260. 'out' => array(':link_action_id' => 'ID')
  261. );
  262. // [:link_param_id] (ALIAS DO :cell_id) PARAM_IN :url_action_param_1_name
  263. $flatConfig_link_in_projekt[] = (object)array(// Zasob::assert(default_db/IN7_MK_BAZA_DYSTRYBUCJI/:url_action_name/:url_action_param_1_name)
  264. 'query' => "
  265. select z.ID from CRM_LISTA_ZASOBOW z
  266. where z.PARENT_ID = :link_action_id
  267. and z.ALIAS_ID = ':cell_id'
  268. and z.TYPE = 'PARAM_IN'
  269. and z.DESC = ':url_action_param_1_name'
  270. and z.A_STATUS not in('DELETED')
  271. ",
  272. 'createTable' => 'CRM_LISTA_ZASOBOW',
  273. 'createArgs' => array('TYPE' => 'PARAM_IN', 'PARENT_ID' => ':link_action_id', 'ALIAS_ID' => ':cell_id', 'DESC' => ':url_action_param_1_name'),
  274. 'in' => array(':cell_id', ':link_action_id', ':url_action_param_1_name'),
  275. 'out' => array(':link_action_id' => 'ID')
  276. );
  277. }
  278. //DBG::_('DBG', '>1', "flatConfig_link_in_projekt", $flatConfig_link_in_projekt, __CLASS__, __FUNCTION__, __LINE__);
  279. $flatConf = array_merge($flatConfig_main, $flatConfig_link_in_projekt);
  280. $knownArgs = array();
  281. $knownArgs[':url_action_name'] = 'Test';
  282. $knownArgs[':url_action_param_1_name'] = 'ID_PROJECT';
  283. $knownArgs[':main_db_id'] = '36';// from DB::getDB()->getZasobId(); or DB::getPDO()->getZasobId();
  284. $this->_debugFlatConfig($flatConf, $knownArgs);
  285. $args = $this->getArgsList();
  286. $clsName = __CLASS__;
  287. $urlActionName = str_replace('Route_UrlAction_', '', $clsName);
  288. DBG::_('DBG', '>1', "reinstall class", __CLASS__, __CLASS__, __FUNCTION__, __LINE__);
  289. DBG::_('DBG', '>1', "reinstall funName", $urlActionName, __CLASS__, __FUNCTION__, __LINE__);
  290. DBG::_('DBG', '>1', "reinstall test", $args, __CLASS__, __FUNCTION__, __LINE__);
  291. $dbFunction = $this->fetchZasobInfo();
  292. $usrLogin = User::getLogin();
  293. {// check if URL_ACTION already exists
  294. if (!$dbFunction) throw new Exception("Brak id zasobu typu TYPESPECIALS - TODO: CREATE");// $this->createZasobTypespecials();
  295. DBG::_('DBG', '>1', "dbFunction", $dbFunction, __CLASS__, __FUNCTION__, __LINE__);
  296. if ($dbFunction['action_id_is_null']) {
  297. $sth = $pdo->prepare("
  298. insert into CRM_LISTA_ZASOBOW (
  299. TYPE,
  300. PARENT_ID,
  301. `DESC`,
  302. A_RECORD_CREATE_AUTHOR,
  303. A_RECORD_CREATE_DATE
  304. )
  305. values (
  306. 'URL_ACTION',
  307. :ts_id,
  308. :url_action_name,
  309. 'system-by-{$usrLogin}',
  310. NOW()
  311. )
  312. ");
  313. //$sth->bindValue('ts_id', $dbFunction['ts_id'], PDO::PARAM_INT);
  314. //$sth->bindValue('url_action_name', $urlActionName, PDO::PARAM_STR);
  315. $bindValues = array();
  316. $bindValues['ts_id'] = array($dbFunction['ts_id'], PDO::PARAM_INT);
  317. $bindValues['url_action_name'] = $urlActionName;
  318. $pdo->bindValues($sth, $bindValues);
  319. DBG::_('DBG', '>1', "sql", $pdo->getRawSql($sth), __CLASS__, __FUNCTION__, __LINE__);
  320. $sth->execute();
  321. $dbFunction = $this->fetchZasobInfo();
  322. if (!$dbFunction || $dbFunction['action_id_is_null']) throw new Exception("Brak zasobu typu URL_ACTION, nie udało się go utworzyć!");
  323. }
  324. }
  325. {// check params
  326. if (!empty($args)) {
  327. $todoArgs = array();
  328. foreach ($args as $argName) {
  329. if (empty($dbFunction['url_params'])) {
  330. $todoArgs[$argName] = true;
  331. } else if (!array_key_exists($argName, $dbFunction['url_params'])) {
  332. $todoArgs[$argName] = true;
  333. }
  334. // OK PARAM_IN exists
  335. }
  336. $todoArgs = array_keys($todoArgs);
  337. DBG::_('DBG', '>1', "todoArgs", $todoArgs, __CLASS__, __FUNCTION__, __LINE__);
  338. if (!empty($todoArgs)) {
  339. $sqlValues = array();
  340. foreach ($todoArgs as $argName) {
  341. $sqlValues[] = "(
  342. 'PARAM_IN',
  343. {$dbFunction['action_id']},
  344. '{$argName}',
  345. 'system-by-{$usrLogin}',
  346. NOW()
  347. )
  348. ";
  349. }
  350. $sqlValues = implode(", ", $sqlValues);
  351. $sth = $pdo->prepare("
  352. insert into CRM_LISTA_ZASOBOW (
  353. TYPE,
  354. PARENT_ID,
  355. `DESC`,
  356. A_RECORD_CREATE_AUTHOR,
  357. A_RECORD_CREATE_DATE
  358. )
  359. values {$sqlValues}
  360. ");
  361. DBG::_('DBG', '>1', "sql", $pdo->getRawSql($sth), __CLASS__, __FUNCTION__, __LINE__);
  362. //$sth->execute();
  363. $dbFunction = $this->fetchZasobInfo();
  364. }
  365. if (empty($dbFunction['url_params'])) {
  366. throw new Exception("Brak zdefiniowanych parametrów, nie udało się ich utworzyć!");
  367. }
  368. }
  369. }
  370. {// check links in tables
  371. // $info['links']['IN7_MK_BAZA_DYSTRYBUCJI'] = $linkInfo;
  372. if (empty($dbFunction['links']['IN7_MK_BAZA_DYSTRYBUCJI'])) throw new Exception("Brak poprawne wprowadzonej tabeli 'IN7_MK_BAZA_DYSTRYBUCJI' w drzewie zasobów!");
  373. $projInfo = $dbFunction['links']['IN7_MK_BAZA_DYSTRYBUCJI'];
  374. /*
  375. [link_action_id] =>
  376. [db_id] => 36
  377. [tbl_id] => 636
  378. [cell_id] => 763
  379. [param1_id] =>
  380. */
  381. if (!$projInfo['link_action_id']) {
  382. $sth = $pdo->prepare("
  383. insert into CRM_LISTA_ZASOBOW (
  384. TYPE,
  385. PARENT_ID,
  386. ALIAS_ID,
  387. `DESC`,
  388. A_RECORD_CREATE_AUTHOR,
  389. A_RECORD_CREATE_DATE
  390. )
  391. values (
  392. 'URL_ACTION',
  393. {$projInfo['tbl_id']},
  394. {$dbFunction['action_id']},
  395. '{$urlActionName}',
  396. 'system-by-{$usrLogin}',
  397. NOW()
  398. )
  399. ");
  400. //DBG::_('DBG', '>1', "sql", $pdo->getRawSql($sth), __CLASS__, __FUNCTION__, __LINE__);
  401. $sth->execute();
  402. $dbFunction = $this->fetchZasobInfo();
  403. $projInfo = $dbFunction['links']['IN7_MK_BAZA_DYSTRYBUCJI'];
  404. if (!$projInfo['link_action_id']) throw new Exception("Brak zainstalowanej akcji dla tabeli 'IN7_MK_BAZA_DYSTRYBUCJI' - nie udało się zainstalować");
  405. }
  406. if (!$projInfo['param1_id']) {// TODO: get from params
  407. $sth = $pdo->prepare("
  408. insert into CRM_LISTA_ZASOBOW (
  409. TYPE,
  410. PARENT_ID,
  411. ALIAS_ID,
  412. `DESC`,
  413. A_RECORD_CREATE_AUTHOR,
  414. A_RECORD_CREATE_DATE
  415. )
  416. values (
  417. 'PARAM_IN',
  418. {$projInfo['link_action_id']},
  419. {$projInfo['cell_id']},
  420. 'ID_PROJECT',
  421. 'system-by-{$usrLogin}',
  422. NOW()
  423. )
  424. ");
  425. $sth->execute();
  426. $dbFunction = $this->fetchZasobInfo();
  427. $projInfo = $dbFunction['links']['IN7_MK_BAZA_DYSTRYBUCJI'];
  428. if (!$projInfo['param1_id']) throw new Exception("Brak zainstalowanego parametru 1 w akcji dla tabeli 'IN7_MK_BAZA_DYSTRYBUCJI' - nie udało się zainstalować");
  429. }
  430. }
  431. }
  432. public function _debugFlatConfig($flatConfig, $args = array()) {
  433. //DBG::_('DBG', '>1', "flatConfig", $flatConfig, __CLASS__, __FUNCTION__, __LINE__);
  434. echo '<pre style="border:1px solid green">';
  435. foreach ($flatConfig as $conf) {
  436. /*
  437. [query] => string
  438. [createTable] => srting - eg. CRM_LISTA_ZASOBOW
  439. [createArgs] => array - eg. [ TYPE: 'TYPESPECIALS', DESC: 'Typespecials' ]
  440. [in] => array - eg. [ ':ts_main_id', ':url_action_name' ]
  441. [out] => array - eg. [ ':ts_main_id': 'ID' ]
  442. */
  443. echo "Zasob::assert({$conf->createTable}): " . json_encode($conf->createArgs) . " returns: " . json_encode($conf->out) . "\n";
  444. }
  445. echo '</pre>';
  446. echo '<pre style="border:1px solid green">';
  447. echo "DBG: Simulate iter loop:\n";
  448. $simulateGeneratedId = 1000;
  449. $i = 0; $limit = 10; $todoIdx = array(); $knownArgsMap = array();
  450. foreach ($flatConfig as $idx => $conf) $todoIdx[] = $idx;
  451. foreach ($args as $arg => $val) $knownArgsMap[$arg] = $val;
  452. for ($i = 0; $i < $limit; $i++) {
  453. echo ">> DBG loop({$i}):\n";
  454. $isExecuted = false;
  455. foreach ($todoIdx as $idx) {
  456. $conf = $flatConfig[$idx];
  457. /*
  458. [query] => string
  459. [createTable] => srting - eg. CRM_LISTA_ZASOBOW
  460. [createArgs] => array - eg. [ TYPE: 'TYPESPECIALS', DESC: 'Typespecials' ]
  461. [in] => array - eg. [ ':ts_main_id', ':url_action_name' ]
  462. [out] => array - eg. [ ':ts_main_id': 'ID' ]
  463. */
  464. echo ">>>> Loop({$i}): idx({$idx}) Zasob::assert({$conf->createTable}): " . json_encode($conf->createArgs) . " returns: " . json_encode($conf->out) . "\n";
  465. $canExecute = true;
  466. if (!empty($conf->in)) foreach ($conf->in as $argName) {
  467. if (!array_key_exists($argName, $knownArgsMap)) {
  468. $canExecute = false;
  469. }
  470. }
  471. if ($canExecute) {
  472. // TODO: execute - $r = $this->_assertZasobConf($conf, $knownArgsMap);
  473. // fetch params out to $knownArgsMap
  474. foreach ($conf->out as $argName => $outFieldName) {
  475. $knownArgsMap[$argName] = $simulateGeneratedId++;// TODO: fetch from returned object ($r->{$outFieldName})
  476. }
  477. $todoIdx = array_diff($todoIdx, array($idx));// remove $idx from $todoIdx
  478. echo ">>>> Loop({$i}): knownArgsMap: " . json_encode($knownArgsMap) . " \n";
  479. $isExecuted = true;
  480. } else {
  481. echo ">>>> Loop({$i}): cannot execute conf [{$idx}] missing args: " . json_encode($conf->in) . " \n";
  482. }
  483. }
  484. if (!$isExecuted) {
  485. echo "DBG: Stop";
  486. if (empty($todoIdx)) {
  487. echo " - OK";
  488. } else {
  489. echo " - Error - TODO:\n";
  490. foreach ($todoIdx as $idx) {
  491. $conf = $flatConfig[$idx];
  492. echo "Zasob::assert({$conf->createTable}): " . json_encode($conf->createArgs) . " returns: " . json_encode($conf->out) . "\n";
  493. }
  494. }
  495. break;
  496. }
  497. }
  498. echo '</pre>';
  499. }
  500. public function fetchZasobInfo() {
  501. $pdo = DB::getPDO();
  502. $args = $this->getArgsList();
  503. $clsName = __CLASS__;
  504. $urlActionName = str_replace('Route_UrlAction_', '', $clsName);
  505. $sth = $pdo->prepare("
  506. select zp.ID as ts_id
  507. , IF(z.ID is null, 1, 0) as action_id_is_null
  508. , z.ID as action_id
  509. , z.DESC as action_desc
  510. from CRM_LISTA_ZASOBOW zp
  511. left join CRM_LISTA_ZASOBOW z on(z.PARENT_ID = zp.ID
  512. and z.TYPE = 'URL_ACTION'
  513. and z.DESC = :url_action_name
  514. and z.A_STATUS not in('DELETED')
  515. )
  516. where zp.TYPE = 'TYPESPECIALS'
  517. and zp.A_STATUS not in('DELETED')
  518. ");
  519. $sth->bindValue('url_action_name', $urlActionName);
  520. $sth->execute();
  521. $info = $sth->fetch();
  522. if (!$info) return $info;
  523. $info['url_params'] = array();
  524. $info['links'] = array();// where action is installed - expected `IN7_MK_BAZA_DYSTRYBUCJI`
  525. if ($info['action_id'] > 0) {
  526. $sthParams = $pdo->prepare("
  527. select z.ID as param_id
  528. , z.DESC as param_desc
  529. from CRM_LISTA_ZASOBOW z
  530. where z.TYPE = 'PARAM_IN'
  531. and z.A_STATUS not in('DELETED')
  532. and z.PARENT_ID = :url_action_id
  533. ");
  534. $sthParams->bindValue('url_action_id', $info['action_id']);
  535. $sthParams->execute();
  536. $urlParams = array();
  537. $rawUrlParams = $sthParams->fetchAll();
  538. foreach ($rawUrlParams as $urlParam) {
  539. $urlParams[$urlParam['param_desc']] = $urlParam;
  540. }
  541. $info['url_params'] = $urlParams;
  542. }
  543. {
  544. $main_db_id = $pdo->getZasobId();
  545. $sth_dbInfo = $pdo->prepare("
  546. select za.id as link_action_id
  547. , zd.id as db_id
  548. , zt.id as tbl_id
  549. , zi.id as cell_id
  550. , zp1.id as param1_id -- for every param
  551. from CRM_LISTA_ZASOBOW zt
  552. join CRM_LISTA_ZASOBOW zd on(zd.ID = zt.PARENT_ID
  553. and zd.TYPE in('DATABASE_MYSQL', 'BAZA_DANYCH', 'DATABASE_POSTGRESQL')
  554. and zd.ID = {$main_db_id}
  555. )
  556. join CRM_LISTA_ZASOBOW zi on(zi.PARENT_ID = zt.ID
  557. and zi.TYPE = 'KOMORKA'
  558. and zi.DESC = 'ID'
  559. )
  560. left join CRM_LISTA_ZASOBOW za on(za.PARENT_ID = zt.ID
  561. and za.TYPE = 'URL_ACTION'
  562. and za.ALIAS_ID = {$info['action_id']}
  563. )
  564. -- TODO: for every param:
  565. left join CRM_LISTA_ZASOBOW zp1 on(zp1.PARENT_ID = za.ID
  566. and zp1.TYPE = 'PARAM_IN'
  567. and zp1.ALIAS_ID = zi.id
  568. and zp1.DESC = 'ID_PROJECT'
  569. )
  570. where zt.TYPE = 'TABELA'
  571. and zt.A_STATUS not in('DELETED')
  572. and zt.DESC = 'IN7_MK_BAZA_DYSTRYBUCJI'
  573. ");
  574. DBG::_('DBG', '>1', "dbInfo query", $pdo->getRawSql($sth_dbInfo), __CLASS__, __FUNCTION__, __LINE__);
  575. $sth_dbInfo->execute();
  576. $linkInfo = $sth_dbInfo->fetch();
  577. if ($linkInfo) {
  578. $info['links']['IN7_MK_BAZA_DYSTRYBUCJI'] = $linkInfo;
  579. }
  580. }
  581. return $info;
  582. }
  583. public function kosztorysXmlAction() {
  584. $idProject = 1921;
  585. $schema = $this->getSchema();
  586. $data = $this->_fetchKosztorysData($idProject);
  587. //DBG::_('DBG', '>1', "XMLWriter", class_exists('XMLWriter'), __CLASS__, __FUNCTION__, __LINE__);
  588. //header('Content-type: application/xml; charset=utf-8');
  589. header('Content-type: text/plain; charset=utf-8');
  590. $xmlWriter = new XMLWriter();
  591. $xmlWriter->openUri('php://output');
  592. $xmlWriter->setIndent(true);
  593. if ($xmlWriter) {
  594. $xmlWriter->startDocument('1.0','UTF-8');
  595. //$xmlWriter->startElementNS(null, 'kosztorysy', 'https://biuro.biall-net.pl/wfs');// adds @xmlns=...
  596. $xmlWriter->startElement('kosztorysy');
  597. $xmlWriter->writeAttribute('targetNamespace', 'https://biuro.biall-net.pl/wfs');
  598. $xmlWriter->writeAttributeNS('xmlns', 'p5', 'http://www.w3.org/2000/xmlns/', 'https://biuro.biall-net.pl/wfs');
  599. for ($i = 1; $i <= 10; $i++) {
  600. $idProject += 1;
  601. $schema = $this->getSchema();
  602. $data = $this->_fetchKosztorysData($idProject);
  603. $xmlWriter->startElement('kosztorys');
  604. $xmlWriter->startElement('projekt');
  605. $xmlWriter->writeAttribute('id', $idProject);
  606. $xmlWriter->startElement('projekt');
  607. $xmlWriter->text("TODO L." . __LINE__);
  608. $xmlWriter->endElement();
  609. $xmlWriter->endElement();
  610. $xmlWriter->endElement();
  611. }
  612. /*
  613. $memXmlWriter = new XMLWriter();
  614. $memXmlWriter->openMemory();
  615. $memXmlWriter->setIndent(true);
  616. for ($i = 1; $i <= 10; $i++) {
  617. $idProject += 1;
  618. $schema = $this->getSchema();
  619. $data = $this->_fetchKosztorysData($idProject);
  620. $memXmlWriter->startElement('kosztorys');
  621. $memXmlWriter->writeAttribute('id', $idProject);
  622. $memXmlWriter->writeAttributeNS('p5', 'typeName', 'https://biuro.biall-net.pl/wfs', 'Kosztorys');
  623. $memXmlWriter->text('book_'.$i);
  624. $memXmlWriter->endElement();
  625. if ($i % 5 == 0) {
  626. $batchXmlString = $memXmlWriter->outputMemory(true);
  627. $xmlWriter->writeRaw($batchXmlString);
  628. }
  629. }
  630. $memXmlWriter->flush();
  631. unset($memXmlWriter);
  632. */
  633. $xmlWriter->endElement();
  634. $xmlWriter->endDocument();
  635. }
  636. }
  637. public function panel($idProject, $idCompany = 0) {
  638. if (User::get('ADM_ADMIN_LEVEL') > 6 || 'Pracownik' != User::getType()) return;// Only for workers with admin level < 6
  639. if (1 == V::get('_print', '', $_GET)) return;// print mode
  640. $task = V::get('_task', '', $_GET);
  641. ?>
  642. <div class="jumbotron">
  643. <div class="container">
  644. <?php
  645. $schema = $this->getSchema();
  646. ?>
  647. <div class="row">
  648. <div class="col-md-12">
  649. <?php if ($idProject > 0) : ?>
  650. <a class="btn btn-default" href="index.php?_route=UrlAction_ProjektyKosztyWstepnychRobot&ID_PROJECT=<?php echo $idProject; ?>">Kosztorys</a>
  651. <a class="btn btn-default" href="index.php?_route=UrlAction_ProjektyKosztyWstepnychRobot&ID_PROJECT=<?php echo $idProject; ?>&_print=1" target="_blank">Wydruk Kosztorysu</a>
  652. <a class="btn btn-default" href="index.php?_route=UrlAction_ProjektyKosztyWstepnychRobot&ID_PROJECT=<?php echo $idProject; ?>&_task=oferta">oferta</a>
  653. <a class="btn btn-default" href="index.php?_route=UrlAction_ProjektyKosztyWstepnychRobot&ID_PROJECT=<?php echo $idProject; ?>&_task=ofertaAdmin">oferta (Admin)</a>
  654. <?php endif; ?>
  655. <a class="btn btn-default" href="index.php?_route=UrlAction_ProjektyKosztyWstepnychRobot&_task=ofertaDefaultAdmin" target="_blank">oferta domyślna (Admin)</a>
  656. </div>
  657. </div>
  658. <br>
  659. <?php if ('ofertaAdmin' == $task) : ?>
  660. <form action="" method="get" class="form-inline">
  661. <input type="hidden" name="_route" value="UrlAction_ProjektyKosztyWstepnychRobot">
  662. <input type="hidden" name="_task" value="ofertaAdmin">
  663. <label for="ID_PROJECT">Nr projektu:</label>
  664. <input type="text" name="ID_PROJECT" value="<?php echo $idProject; ?>" class="form-control">
  665. <label for="ID_COMPANY">Nr kontrahenta (0 = oferta wewnętrzna/kosztorys)</label>
  666. <input type="text" name="ID_COMPANY" value="<?php echo $idCompany; ?>" class="form-control">
  667. <input type="submit" value="Wybierz" class="btn btn-primary">
  668. </form>
  669. <?php elseif ('oferta' == $task || 'ofertaDefaultAdmin' == $task) : ?>
  670. <form action="" method="get" class="form-inline">
  671. <input type="hidden" name="_route" value="UrlAction_ProjektyKosztyWstepnychRobot">
  672. <input type="hidden" name="_task" value="oferta">
  673. <input type="hidden" name="ID_PROJECT" value="<?php echo $idProject; ?>">
  674. <label for="ID_COMPANY">Nr kontrahenta</label>
  675. <input type="text" name="ID_COMPANY" value="<?php echo $idCompany; ?>" class="form-control">
  676. <input type="submit" value="Wybierz" class="btn btn-primary">
  677. </form>
  678. <?php endif; ?>
  679. </div>
  680. </div>
  681. <?php
  682. }
  683. public function saveOffer($idProject, $idCompany, $args, $admin = false) {
  684. DBG::_('DBG', '>1', "args", $args, __CLASS__, __FUNCTION__, __LINE__);
  685. if (!$admin) return;
  686. $cennik = $this->getCennik($idProject, $idCompany);
  687. DBG::_('DBG', '>1', "cennik", $cennik, __CLASS__, __FUNCTION__, __LINE__);
  688. $pdo = DB::getPDO();
  689. {
  690. $add_id_zasob = 0;
  691. $add_unit = '';
  692. $add_price = 0;
  693. $add_quantity = 0;
  694. $add__sth = $pdo->prepare("
  695. insert into CRM_LISTA_ZASOBOW_OFFERS (
  696. CRM_LISTA_ZASOBOW_ID
  697. , COMPANIES_ID
  698. , ID_PROJECT
  699. , OFFER_PRICE_PER_RESOURCE_UNIT
  700. , RESOURCE_UNIT_TYPE
  701. , OFFER_UNIT_TYPE
  702. , REQUIRED_RESOURCE_UNITS
  703. , A_RECORD_CREATE_AUTHOR
  704. , A_RECORD_CREATE_DATE
  705. ) values (
  706. :id_zasob
  707. , :id_company
  708. , :id_project
  709. , :price
  710. , :unit
  711. , :unit
  712. , :quantity
  713. , :author
  714. , NOW()
  715. )
  716. ");
  717. $add__sth->bindValue(':author', User::getLogin(), PDO::PARAM_STR);
  718. $add__sth->bindValue(':id_project', $idProject, PDO::PARAM_INT);
  719. $add__sth->bindValue(':id_company', $idCompany, PDO::PARAM_INT);
  720. $add__sth->bindValue(':quantity', $add_quantity, PDO::PARAM_STR);
  721. $add__sth->bindParam(':id_zasob', $add_id_zasob, PDO::PARAM_INT);
  722. $add__sth->bindParam(':price', $add_price, PDO::PARAM_STR);
  723. $add__sth->bindParam(':unit', $add_unit, PDO::PARAM_STR);
  724. }
  725. {
  726. $edit_id_company = $idCompany;
  727. $edit_id_zasob = 0;
  728. $edit_unit = '';
  729. $edit_price = 0;
  730. $edit_author = 0;
  731. $edit_quantity = 0;
  732. $edit__sth = $pdo->prepare("
  733. update CRM_LISTA_ZASOBOW_OFFERS
  734. set CRM_LISTA_ZASOBOW_ID = :id_zasob
  735. , COMPANIES_ID = :id_company
  736. , ID_PROJECT = :id_project
  737. , OFFER_PRICE_PER_RESOURCE_UNIT = :price
  738. , RESOURCE_UNIT_TYPE = :unit
  739. , OFFER_UNIT_TYPE = :unit
  740. , REQUIRED_RESOURCE_UNITS = :quantity
  741. , A_RECORD_UPDATE_AUTHOR = :author
  742. , A_RECORD_UPDATE_DATE = NOW()
  743. where ID = :id
  744. ");
  745. $edit__sth->bindParam(':id', $edit_id, PDO::PARAM_INT);
  746. $edit__sth->bindValue(':author', User::getLogin(), PDO::PARAM_STR);
  747. $edit__sth->bindValue(':id_project', $idProject, PDO::PARAM_INT);
  748. $edit__sth->bindValue(':id_company', $idCompany, PDO::PARAM_INT);
  749. $edit__sth->bindValue(':quantity', $edit_quantity, PDO::PARAM_STR);
  750. $edit__sth->bindParam(':id_zasob', $edit_id_zasob, PDO::PARAM_INT);
  751. $edit__sth->bindParam(':price', $edit_price, PDO::PARAM_STR);
  752. $edit__sth->bindParam(':unit', $edit_unit, PDO::PARAM_STR);
  753. }
  754. $schema = $this->getSchema();
  755. foreach ($schema['config']['layer'] as $idLayer => $layData) {
  756. DBG::_('DBG', '>1', "layData", $layData, __CLASS__, __FUNCTION__, __LINE__);
  757. foreach ($layData['type'] as $idType => $typeLabel) {
  758. $edit_id = V::get("edit_price_id_{$idType}", '', $args);
  759. $add_price = V::get("price_{$idType}", '', $args);
  760. DBG::_('DBG', '>1', "typeLabel (edit={$edit_id}, price={$add_price})", $typeLabel, __CLASS__, __FUNCTION__, __LINE__);
  761. if ($edit_id > 0) {
  762. $edit_price = V::get("price_{$idType}", '', $args);
  763. $edit_price = str_replace(',', '.', $edit_price);
  764. if ($edit_id > 0 && $edit_price > 0) {
  765. $edit_id_zasob = $idType;
  766. $edit_unit = $layData['jednostka'];
  767. // TODO: check if anything change
  768. $edit__sth->execute();
  769. // TODO: add to hist
  770. }
  771. } else {
  772. $add_price = V::get("price_{$idType}", '', $args);
  773. $add_price = str_replace(',', '.', $add_price);
  774. if ($add_price > 0) {
  775. $add_id_zasob = $idType;
  776. $add_unit = $layData['jednostka'];
  777. $add__sth->execute();
  778. }
  779. }
  780. }
  781. }
  782. }
  783. public function saveDefaultOffer($args) {
  784. DBG::_('DBG', '>1', "args", $args, __CLASS__, __FUNCTION__, __LINE__);
  785. $cennik = $this->getDefaultCennik();
  786. DBG::_('DBG', '>1', "cennik", $cennik, __CLASS__, __FUNCTION__, __LINE__);
  787. $idCompany = 0;
  788. $idProject = 0;
  789. $pdo = DB::getPDO();
  790. {
  791. $add_id_zasob = 0;
  792. $add_unit = '';
  793. $add_price = 0;
  794. $add_quantity = 0;
  795. $add__sth = $pdo->prepare("
  796. insert into CRM_LISTA_ZASOBOW_OFFERS (
  797. CRM_LISTA_ZASOBOW_ID
  798. , COMPANIES_ID
  799. , ID_PROJECT
  800. , OFFER_PRICE_PER_RESOURCE_UNIT
  801. , RESOURCE_UNIT_TYPE
  802. , OFFER_UNIT_TYPE
  803. , REQUIRED_RESOURCE_UNITS
  804. , A_RECORD_CREATE_AUTHOR
  805. , A_RECORD_CREATE_DATE
  806. ) values (
  807. :id_zasob
  808. , :id_company
  809. , :id_project
  810. , :price
  811. , :unit
  812. , :unit
  813. , :quantity
  814. , :author
  815. , NOW()
  816. )
  817. ");
  818. $add__sth->bindValue(':author', User::getLogin(), PDO::PARAM_STR);
  819. $add__sth->bindValue(':id_project', $idProject, PDO::PARAM_INT);
  820. $add__sth->bindValue(':id_company', $idCompany, PDO::PARAM_INT);
  821. $add__sth->bindValue(':quantity', $add_quantity, PDO::PARAM_STR);
  822. $add__sth->bindParam(':id_zasob', $add_id_zasob, PDO::PARAM_INT);
  823. $add__sth->bindParam(':price', $add_price, PDO::PARAM_STR);
  824. $add__sth->bindParam(':unit', $add_unit, PDO::PARAM_STR);
  825. }
  826. {
  827. $edit_id_zasob = 0;
  828. $edit_unit = '';
  829. $edit_price = 0;
  830. $edit_author = 0;
  831. $edit_quantity = 0;
  832. $edit__sth = $pdo->prepare("
  833. update CRM_LISTA_ZASOBOW_OFFERS
  834. set CRM_LISTA_ZASOBOW_ID = :id_zasob
  835. , COMPANIES_ID = :id_company
  836. , ID_PROJECT = :id_project
  837. , OFFER_PRICE_PER_RESOURCE_UNIT = :price
  838. , RESOURCE_UNIT_TYPE = :unit
  839. , OFFER_UNIT_TYPE = :unit
  840. , REQUIRED_RESOURCE_UNITS = :quantity
  841. , A_RECORD_UPDATE_AUTHOR = :author
  842. , A_RECORD_UPDATE_DATE = NOW()
  843. where ID = :id
  844. ");
  845. $edit__sth->bindParam(':id', $edit_id, PDO::PARAM_INT);
  846. $edit__sth->bindValue(':author', User::getLogin(), PDO::PARAM_STR);
  847. $edit__sth->bindValue(':id_project', $idProject, PDO::PARAM_INT);
  848. $edit__sth->bindValue(':id_company', $idCompany, PDO::PARAM_INT);
  849. $edit__sth->bindValue(':quantity', $edit_quantity, PDO::PARAM_STR);
  850. $edit__sth->bindParam(':id_zasob', $edit_id_zasob, PDO::PARAM_INT);
  851. $edit__sth->bindParam(':price', $edit_price, PDO::PARAM_STR);
  852. $edit__sth->bindParam(':unit', $edit_unit, PDO::PARAM_STR);
  853. }
  854. $schema = $this->getSchema();
  855. foreach ($schema['config']['layer'] as $idLayer => $layData) {
  856. DBG::_('DBG', '>1', "layData", $layData, __CLASS__, __FUNCTION__, __LINE__);
  857. foreach ($layData['type'] as $idType => $typeLabel) {
  858. DBG::_('DBG', '>1', "typeLabel", $typeLabel, __CLASS__, __FUNCTION__, __LINE__);
  859. $edit_id = V::get("edit_price_id_{$idType}", '', $args);
  860. if ($edit_id > 0) {
  861. $edit_price = V::get("price_{$idType}", '', $args);
  862. $edit_price = str_replace(',', '.', $edit_price);
  863. if ($edit_id > 0 && $edit_price > 0) {
  864. $edit_id_zasob = $idType;
  865. $edit_unit = $layData['jednostka'];
  866. // TODO: check if anything change
  867. $edit__sth->execute();
  868. // TODO: add to hist
  869. }
  870. } else {
  871. $add_price = V::get("price_{$idType}", '', $args);
  872. $add_price = str_replace(',', '.', $add_price);
  873. if ($add_price > 0) {
  874. $add_id_zasob = $idType;
  875. $add_unit = $layData['jednostka'];
  876. $add__sth->execute();
  877. }
  878. }
  879. }
  880. }
  881. }
  882. /**
  883. * @returns [ $id_zasob => [ 'price' => $price, 'ID', 'id_zasob', 'id_company', 'id_project', 'unit', 'quantity' ] ]
  884. */
  885. public function getDefaultCennik($idCompany = 0) {
  886. $schema = $this->getSchema();
  887. $typeIdList = array_keys($schema['config']['type']);
  888. $sqlTypeIdList = implode(',', $typeIdList);
  889. $pdo = DB::getPDO();
  890. $sth = $pdo->prepare("
  891. select o.ID
  892. , o.CRM_LISTA_ZASOBOW_ID as id_zasob
  893. , o.COMPANIES_ID as id_company
  894. , o.ID_PROJECT as id_project
  895. , o.OFFER_PRICE_PER_RESOURCE_UNIT as price
  896. , o.RESOURCE_UNIT_TYPE as unit
  897. -- , o.OFFER_UNIT_TYPE as unit
  898. , o.REQUIRED_RESOURCE_UNITS as quantity
  899. from CRM_LISTA_ZASOBOW_OFFERS o
  900. where o.CRM_LISTA_ZASOBOW_ID in({$sqlTypeIdList})
  901. -- and o.A_STATUS not in ('DELETED')
  902. and o.ID_PROJECT = 0
  903. and o.COMPANIES_ID = :id_company
  904. ");
  905. $sth->bindValue(':id_company', $idCompany, PDO::PARAM_INT);
  906. $sth->execute();
  907. $cennikRaw = $sth->fetchAll();
  908. $cennik = array();
  909. foreach ($cennikRaw as $itemRaw) {
  910. $item = $itemRaw;
  911. $item['price'] = round($item['price'], 2);
  912. if (!empty($cennik[$itemRaw['id_zasob']])) {
  913. if ($itemRaw['ID'] < $cennik[$itemRaw['id_zasob']]['ID']) continue;
  914. }
  915. $cennik[$item['id_zasob']] = $item;
  916. }
  917. return $cennik;
  918. }
  919. /**
  920. * @returns [ $id_zasob => [ 'price' => $price, 'ID', 'id_zasob', 'id_company', 'id_project', 'unit', 'quantity' ] ]
  921. */
  922. public function getCennik($idProject, $idCompany = 0) {
  923. $schema = $this->getSchema();
  924. $typeIdList = array_keys($schema['config']['type']);
  925. $sqlTypeIdList = implode(',', $typeIdList);
  926. $pdo = DB::getPDO();
  927. $sth = $pdo->prepare("
  928. select o.ID
  929. , o.CRM_LISTA_ZASOBOW_ID as id_zasob
  930. , o.COMPANIES_ID as id_company
  931. , o.ID_PROJECT as id_project
  932. , o.OFFER_PRICE_PER_RESOURCE_UNIT as price
  933. , o.RESOURCE_UNIT_TYPE as unit
  934. -- , o.OFFER_UNIT_TYPE as unit
  935. , o.REQUIRED_RESOURCE_UNITS as quantity
  936. from CRM_LISTA_ZASOBOW_OFFERS o
  937. where o.CRM_LISTA_ZASOBOW_ID in({$sqlTypeIdList})
  938. -- and o.A_STATUS not in ('DELETED')
  939. and o.ID_PROJECT = :id_project
  940. and o.COMPANIES_ID = :id_company
  941. ");
  942. $sth->bindValue(':id_project', $idProject, PDO::PARAM_INT);
  943. $sth->bindValue(':id_company', $idCompany, PDO::PARAM_INT);
  944. $sth->execute();
  945. $cennikRaw = $sth->fetchAll();
  946. $cennik = array();
  947. foreach ($cennikRaw as $itemRaw) {
  948. $item = $itemRaw;
  949. $item['price'] = round($item['price'], 2);
  950. $cennik[$itemRaw['id_zasob']] = $item;
  951. }
  952. return $cennik;
  953. }
  954. public function defaultOferta($idCompany = 0) {
  955. if ('1' == V::get('save_offer', '', $_POST)) {
  956. $this->saveDefaultOffer($_POST);
  957. }
  958. $schema = $this->getSchema();
  959. if (empty($schema['config']['type'])) throw new Exception("Schema error - brak zdefiniowanych typów");
  960. $cennik = $this->getDefaultCennik($idCompany);
  961. //DBG::_(true, true, "cennik", $cennik, __CLASS__, __FUNCTION__, __LINE__);
  962. ?>
  963. <div class="container">
  964. <form action="" method="post">
  965. <?php foreach ($schema['config']['layer'] as $idLayer => $layData) : ?>
  966. <h4 style="padding:0 6px"><?php echo $layData['label']; ?></h4>
  967. <table class="tabel table-bordered" style="width:100%">
  968. <tbody>
  969. <tr>
  970. <th style="padding:0 6px">id zasobu</th>
  971. <th style="padding:0 6px">typ</th>
  972. <th style="padding:0 6px">jednotka miary</th>
  973. <th style="padding:0 6px">cena jednostkowa</th>
  974. </tr>
  975. <?php foreach ($layData['type'] as $idType => $typeLabel) : ?>
  976. <tr>
  977. <td style="width:100px; padding:0 6px"><?php echo $idType; ?></td>
  978. <td style="padding:0 6px" title="[<?php echo $idType; ?>] <?php echo $typeLabel; ?>"><?php echo $typeLabel; ?></td>
  979. <td style="padding:0 6px"><?php echo $layData['jednostka']; ?></td>
  980. <td style="padding:3px 6px"><input type="text" class="form-control input-sm" name="price_<?php echo $idType; ?>" value="<?php echo $cennik[$idType]['price']; ?>"/></td>
  981. </tr>
  982. <?php endforeach; ?>
  983. </tbody>
  984. </table>
  985. <?php endforeach; ?>
  986. <br>
  987. <?php foreach ($cennik as $item) : ?>
  988. <input type="hidden" name="edit_price_id_<?php echo $item['id_zasob']; ?>" value="<?php echo $item['ID']; ?>">
  989. <?php endforeach; ?>
  990. <input type="hidden" name="save_offer" value="1">
  991. <input type="submit" value="Zapisz" class="btn btn-primary">
  992. </form>
  993. </div>
  994. <?php
  995. }
  996. /**
  997. * @returns [ 'cost_total' => :numeric, 'sub_costs' => [ $id_zasob => 'price' ] ]
  998. */
  999. public function getProjectCostForCennik($idProject, $idCompany = 0) {
  1000. $projCost = array();
  1001. $projCost['cost_total'] = 0;
  1002. $projCost['sub_costs'] = array();
  1003. $defCennik = $this->getDefaultCennik($idCompany);
  1004. // $defCennik = [ $id_zasob => [ 'price' => $price, 'ID', 'id_zasob', 'id_company', 'id_project', 'unit', 'quantity' ] ]
  1005. $cennik = $this->getCennik($idProject, $idCompany);
  1006. $data = $this->getData($idProject, $admin);
  1007. foreach ($data as $idLayer => $layData) {
  1008. foreach ($layData['data'] as $typeData) {
  1009. if (!$typeData['idType']) continue;
  1010. $price = (!empty($cennik[$typeData['idType']]['price']))? $cennik[$typeData['idType']]['price'] : 0;
  1011. $defPrice = (!empty($defCennik[$typeData['idType']]['price']))? $defCennik[$typeData['idType']]['price'] : 0;
  1012. $cost = ($price > 0)? $price : $defPrice;
  1013. $cost = $typeData['ilosc'] * $cost;
  1014. $projCost['sub_costs'][$typeData['idType']] = $cost;
  1015. $projCost['cost_total'] += $cost;
  1016. }
  1017. }
  1018. return $projCost;
  1019. }
  1020. public function kosztorys($idProject) {
  1021. $schema = $this->getSchema();
  1022. $data = $this->_fetchKosztorysData($idProject);
  1023. $projCost = $this->getProjectCostForCennik($idProject, $idCompany = 0);
  1024. ?>
  1025. <div class="container">
  1026. <h1>Kosztorys wstępny robót telekomunikacyjnych</h1>
  1027. <table class="table">
  1028. <tr>
  1029. <th><?php echo $schema['nr']; ?></th>
  1030. <th><?php echo $schema['title']; ?></th>
  1031. <th><?php echo $schema['owner_name']; ?></th>
  1032. <th style="text-align:right"><?php echo $schema['cost_total']; ?></th>
  1033. </tr>
  1034. <tr>
  1035. <td><?php echo $data['nr']; ?></td>
  1036. <td><?php echo $data['title']; ?></td>
  1037. <td><?php echo $data['owner_name']; ?></td>
  1038. <td style="text-align:right"><?php echo number_format($projCost['cost_total'], 2, ',', ' '); ?></td>
  1039. </tr>
  1040. </table>
  1041. <?php $this->viewLayersData($idProject, $idCompany = 0, $admin = false, $projCost['sub_costs']); ?>
  1042. </div>
  1043. <?php
  1044. DBG::_('DBG', '>0', "data", $data, __CLASS__, __FUNCTION__, __LINE__);
  1045. DBG::_('DBG', '>0', "schema", $schema, __CLASS__, __FUNCTION__, __LINE__);
  1046. DBG::_('DBG', '>0', "projCost", $projCost, __CLASS__, __FUNCTION__, __LINE__);
  1047. }
  1048. public function oferta($idProject, $idCompany = 0, $admin = false) {
  1049. if ($admin && '1' == V::get('save_offer', '', $_POST)) {
  1050. $this->saveOffer($idProject, $idCompany, $_POST, $admin);
  1051. }
  1052. ?>
  1053. <div class="container">
  1054. <?php if ($admin) : ?>
  1055. <form action="" method="post">
  1056. <?php endif; ?>
  1057. <?php $this->viewLayersData($idProject, $idCompany, $admin); ?>
  1058. <?php if ($admin) : ?>
  1059. <?php foreach ($cennik as $item) : ?>
  1060. <input type="hidden" name="edit_price_id_<?php echo $item['id_zasob']; ?>" value="<?php echo $item['ID']; ?>">
  1061. <?php endforeach; ?>
  1062. <input type="hidden" name="save_offer" value="1">
  1063. <hr><input class="btn btn-primary" type="submit" value="Zapisz ofertę">
  1064. </form>
  1065. <?php endif; ?>
  1066. </div>
  1067. <?php
  1068. }
  1069. public function viewLayersData($idProject, $idCompany = 0, $admin = false, $projSubCost = array()) {
  1070. $schema = $this->getSchema();
  1071. $conf = $schema['config'];
  1072. DBG::_('DBG', '>1', "conf", $conf, __CLASS__, __FUNCTION__, __LINE__);
  1073. $data = $this->getData($idProject, $admin);
  1074. DBG::_('DBG', '>1', "data", $data, __CLASS__, __FUNCTION__, __LINE__);
  1075. $defCennik = $this->getDefaultCennik($idCompany);
  1076. $cennik = $this->getCennik($idProject, $idCompany);
  1077. ?>
  1078. <?php foreach ($data as $idLayer => $layData) : ?>
  1079. <h4 style="padding:0 6px"><?php echo $layData['label']; ?></h4>
  1080. <table class="tabel table-bordered" style="width:100%">
  1081. <tbody>
  1082. <tr>
  1083. <th style="padding:0 6px">typ</th>
  1084. <th style="padding:0 6px; text-align:right">ilość</th>
  1085. <th style="padding:0 6px; text-align:right">jednotka miary</th>
  1086. <th style="padding:0 6px; text-align:right">cena jednostkowa</th>
  1087. <?php if ($admin) : ?>
  1088. <th style="padding:0 6px; text-align:right">cena jednostkowa (domyślna)</th>
  1089. <?php endif; ?>
  1090. <?php if (!empty($projSubCost)) : ?>
  1091. <th style="padding:0 6px; text-align:right">szacowany koszt [zł]</th>
  1092. <?php endif; ?>
  1093. </tr>
  1094. <?php foreach ($layData['data'] as $typeData) : ?>
  1095. <?php if (!$typeData['idType']) : ?>
  1096. <tr>
  1097. <td colspan="4">
  1098. <?php if ($admin) {
  1099. $fixLink = 'index.php?MENU_INIT=VIEWTABLE_AJAX&ZASOB_ID=' . $conf['layer'][$idLayer]['tabela_id'];
  1100. $fixLink .= '&f_' . $conf['layer'][$idLayer]['zasob_field'] . '=%3D' . $typeData['type'];
  1101. $fixLink .= '&_hash=' . uniqid();
  1102. $fixProjectLink = '<a target="_blank" href="' . $fixLink . "&f_ID_PROJECT={$idProject}" . '">' . "Popraw" . '</a>' . " (dane dla projektu [{$idProject}])";
  1103. $fixAllLink = '<a target="_blank" href="' . $fixLink . '">' . "Popraw wszystkie" . '</a>';
  1104. SE_Layout::alert('danger', "Niezdefiniowany typ: <code>{$typeData['type']}</code> - {$fixProjectLink}, {$fixAllLink}");
  1105. } ?>
  1106. <?php DBG::_('DBG', '>1', "Error conf", $conf, __CLASS__, __FUNCTION__, __LINE__); ?>
  1107. <?php DBG::_('DBG', '>1', "Error", $typeData, __CLASS__, __FUNCTION__, __LINE__); ?>
  1108. </td>
  1109. </tr>
  1110. <?php else : ?>
  1111. <?php $defPrice = (!empty($defCennik[$typeData['idType']]['price']))? $defCennik[$typeData['idType']]['price'] : 0; ?>
  1112. <?php $price = (!empty($cennik[$typeData['idType']]['price']))? $cennik[$typeData['idType']]['price'] : $defPrice; ?>
  1113. <tr>
  1114. <td style="padding:0 6px" title="[<?php echo $typeData['idType']; ?>] <?php echo $typeData['type']; ?>"><?php echo $typeData['type']; ?></td>
  1115. <td style="padding:0 6px; text-align:right"><?php echo $typeData['ilosc']; ?></td>
  1116. <td style="padding:0 6px; text-align:right"><?php echo $typeData['jednostka']; ?></td>
  1117. <td style="padding:3px 6px; text-align:right">
  1118. <?php if ($admin) : ?>
  1119. <input type="text" style="text-align:right" class="form-control input-sm" name="price_<?php echo $typeData['idType']; ?>" value="<?php echo $price; ?>"/>
  1120. <?php else : ?>
  1121. <?php echo $price; ?>
  1122. <?php endif; ?>
  1123. </td>
  1124. <?php if ($admin) : ?>
  1125. <td style="padding:3px 6px; text-align:right"><?php echo $defPrice; ?></td>
  1126. <?php endif; ?>
  1127. <?php if (!empty($projSubCost)) : ?>
  1128. <td style="padding:3px 6px; text-align:right"><?php echo number_format(V::get($typeData['idType'], 0, $projSubCost), 2, ',', ' '); ?></td>
  1129. <?php endif; ?>
  1130. </tr>
  1131. <?php endif; ?>
  1132. <?php endforeach; ?>
  1133. </tbody>
  1134. </table>
  1135. <?php endforeach; ?>
  1136. <?php
  1137. }
  1138. public function checkGeomDuplicate() {
  1139. // TODO: for every schema.layer
  1140. $sqlTblName = 'Rozdzielcza_Kabel_Swiatlowodowy_wsg84';
  1141. $sql = "select a.ID, b.ID, aswkt(a.the_geom)
  1142. from `{$sqlTblName}` a
  1143. join `$sqlTblName` b on(b.the_geom = a.the_geom and a.ID != b.ID)
  1144. ";
  1145. }
  1146. public function getSchema() {
  1147. static $_schema = null;
  1148. if (null !== $_schema) return $_schema;
  1149. $_schema = array();
  1150. /*
  1151. 22444 INNE Kosztorys - zasoby
  1152. 22445 INNE Kabel 2J do wdmuchiwania w mikrorurce 7/4 mm z wdmuchiwaniem
  1153. 22446 INNE Kabel 4J do wdmuchiwania w mikrorurce 7/4 mm z wdmuchiwaniem
  1154. ... Labels for order form
  1155. 22460 TABELA Światłowód (Alias do [20225] TABELA default_db/Rozdzielcza_Kabel_Swiatlowodowy_wsg84)
  1156. 22461 20299 KOMORKA ZASOB (Alias do [20299] KOMORKA OznKabla)
  1157. 22462 20292 KOMORKA JEDNOSTKA_METR ilość [m] (Alias do [20292] KOMORKA Dlugosc)
  1158. ... where to search for data
  1159. */
  1160. {
  1161. $pdo = DB::getPDO();
  1162. $sth = $pdo->prepare("
  1163. select z.ID, z.TYPE, z.DESC, z.ALIAS_ID
  1164. , c.ID as c_ID, c.TYPE as c_TYPE, c.DESC as c_DESC, c.ALIAS_ID as c_ALIAS_ID
  1165. , a.ID as a_ID, a.TYPE as a_TYPE, a.DESC as a_DESC, a.ALIAS_ID as a_ALIAS_ID
  1166. , za.ID as za_ID, za.TYPE as za_TYPE, za.DESC as za_DESC, za.ALIAS_ID as za_ALIAS_ID
  1167. from CRM_LISTA_ZASOBOW z
  1168. left join CRM_LISTA_ZASOBOW c on(c.PARENT_ID = z.ID)
  1169. left join CRM_LISTA_ZASOBOW a on(a.ID = z.ALIAS_ID and z.ALIAS_ID > 0)
  1170. left join CRM_LISTA_ZASOBOW za on(za.ID = c.ALIAS_ID and c.ALIAS_ID > 0)
  1171. where z.PARENT_ID = 22444 -- TODO how to find ID, Typespecial with link
  1172. ");
  1173. $sth->execute();
  1174. $rawConf = $sth->fetchAll();
  1175. $conf = array();
  1176. $conf['type'] = array();
  1177. $conf['layer'] = array();
  1178. foreach ($rawConf as $z) {
  1179. if ('INNE' == $z['TYPE']) {
  1180. if (!array_key_exists($z['ID'], $conf['type'])) {
  1181. $conf['type'][$z['ID']] = $z['DESC'];
  1182. }
  1183. }
  1184. }
  1185. foreach ($rawConf as $z) {
  1186. if ('TABELA' == $z['TYPE']) {
  1187. if (!array_key_exists($z['ID'], $conf['layer'])) {
  1188. $layer = array();
  1189. $layer['label'] = $z['DESC'];
  1190. $layer['tabela_id'] = $z['a_ID'];
  1191. $layer['tabela_name'] = $z['a_DESC'];
  1192. $layer['jednostka'] = '';
  1193. $layer['zasob_type'] = '';
  1194. $layer['zasob_field'] = '';
  1195. $layer['zasob_id'] = '';
  1196. $layer['ilosc_field'] = '';
  1197. $layer['type'] = array();
  1198. $conf['layer'][$z['ID']] = $layer;
  1199. }
  1200. if ($z['c_ID'] > 0) {
  1201. if ('JEDNOSTKA_' == substr($z['c_DESC'], 0, 10)) {
  1202. $layer = $conf['layer'][$z['ID']];
  1203. $layer['jednostka'] = substr($z['c_DESC'], 10);
  1204. $layer['ilosc_field'] = $z['za_DESC'];
  1205. $layer['zasob_id'] = $z['za_ID'];
  1206. $conf['layer'][$z['ID']] = $layer;
  1207. }
  1208. /*
  1209. [za_ID] => 20299
  1210. [za_TYPE] => KOMORKA
  1211. [za_DESC] => OznKabla
  1212. [za_ALIAS_ID] => 0
  1213. */
  1214. switch ($z['c_DESC']) {
  1215. case 'ZASOB': {
  1216. if ($z['za_ID'] > 0) {
  1217. $layer = $conf['layer'][$z['ID']];
  1218. $layer['zasob_type'] = $z['c_DESC'];
  1219. $layer['zasob_field'] = $z['za_DESC'];
  1220. $layer['zasob_id'] = $z['za_ID'];
  1221. $conf['layer'][$z['ID']] = $layer;
  1222. }
  1223. } break;
  1224. case 'ZASOB_ID': {
  1225. if ($z['za_ID'] > 0) {
  1226. $layer = $conf['layer'][$z['ID']];
  1227. $layer['zasob_type'] = $z['c_DESC'];
  1228. $layer['zasob_id'] = $z['za_ID'];
  1229. $layer['zasob_label'] = $z['za_DESC'];
  1230. $conf['layer'][$z['ID']] = $layer;
  1231. $conf['layer'][$z['ID']]['type'][$z['za_ID']] = $z['za_DESC'];
  1232. }
  1233. } break;
  1234. case 'TYPE': {
  1235. //DBG::_(true, true, "z", $z, __CLASS__, __FUNCTION__, __LINE__);
  1236. if (empty($z['c_ALIAS_ID'])) throw new Exception("Schema error - brak ALIAS_ID dla typu");
  1237. if (empty($conf['type'][$z['za_ID']])) ;// TODO: throw exception
  1238. $conf['layer'][$z['ID']]['type'][$z['za_ID']] = $z['za_DESC'];
  1239. } break;
  1240. }
  1241. }
  1242. }
  1243. }
  1244. foreach ($rawConf as $z) {
  1245. if ('INNE' == $z['TYPE']) {
  1246. } else if ('TABELA' == $z['TYPE']) {
  1247. } else {
  1248. SE_Layout::alert('warnig', "BUG: unimplemented type '{$z['TYPE']}' for zasob nr: {$z['ID']}");
  1249. }
  1250. }
  1251. DBG::_('DBG', '>1', "config", $conf, __CLASS__, __FUNCTION__, __LINE__);
  1252. {// validate schema - show warnings
  1253. foreach ($conf['layer'] as $layer) {
  1254. try {
  1255. if (empty($layer['tabela_id'])) throw new Exception("brak zdefiniowanego aliasa do tabeli dla warstwy {$layer['label']}");
  1256. if (empty($layer['jednostka'])) throw new Exception("brak jednostki dla warstwy [{$layer['tabela_id']}] {$layer['label']}");
  1257. switch ($layer['jednostka']) {
  1258. case 'METR': break;
  1259. case 'SZTUKA': break;
  1260. default: throw new Exception("Nieznana jednostka '{$layer['jednostka']}' dla warstwy [{$layer['tabela_id']}] {$layer['label']}");
  1261. }
  1262. } catch (Exception $e) {
  1263. SE_Layout::alert('warning', $e->getMessage());
  1264. }
  1265. }
  1266. }
  1267. DBG::_('DBG', '>2', "rawConf", $rawConf, __CLASS__, __FUNCTION__, __LINE__);
  1268. $_schema['config'] = $conf;
  1269. }
  1270. $_schema['nr'] = "Nr projektu";
  1271. $_schema['title'] = "Tytuł projektu";
  1272. $_schema['owner_name'] = "Osoba prowadząca";
  1273. $_schema['cost_total'] = "Szacowany koszt projektu [zł]";
  1274. $_schema['sub_costs'] = array();
  1275. {
  1276. $layerConf = array();
  1277. $layerConf['label'] = "Wykop";
  1278. $layerConf['_agr_fields_to_cols'] = array();
  1279. $layerConf['_agr_fields_to_cols']['ilosc'] = "ilość [m]";
  1280. $layerConf['_agr_fields_to_cols']['cena'] = "podstawowa cena [zł/m]";
  1281. $layerConf['_agr_fields_to_cols']['koszt'] = "koszt [zł]";
  1282. $_schema['sub_costs']['Rozdzielcza_Wykop_przedmiar_na_mikrorurki'] = $layerConf;
  1283. }
  1284. {
  1285. $layerConf = array();
  1286. $layerConf['label'] = "Mikrokanalizacja do klienta";
  1287. $layerConf['_agr_fields_to_cols'] = array();
  1288. $layerConf['_agr_fields_to_cols']['ilosc'] = "ilość [m]";
  1289. $layerConf['_agr_fields_to_cols']['cena'] = "podstawowa cena [zł/m]";
  1290. $layerConf['_agr_fields_to_cols']['koszt'] = "koszt [zł]";
  1291. $_schema['sub_costs']['Rozdzielcza_Mikrokanalizacja_do_klienta'] = $layerConf;
  1292. }
  1293. {
  1294. $layerConf = array();
  1295. $layerConf['label'] = "Przeciski";
  1296. $layerConf['_agr_fields_to_cols'] = array();
  1297. $layerConf['_agr_fields_to_cols']['ilosc'] = "ilość [m]";
  1298. $layerConf['_agr_fields_to_cols']['cena'] = "podstawowa cena [zł/m]";
  1299. $layerConf['_agr_fields_to_cols']['koszt'] = "koszt [zł]";
  1300. $_schema['sub_costs']['Rozdzielcza_Przeciski_110mm'] = $layerConf;
  1301. }
  1302. {
  1303. $layerConf = array();
  1304. $layerConf['label'] = "Zabruki";
  1305. $layerConf['_agr_fields_to_cols'] = array();
  1306. $layerConf['_agr_fields_to_cols']['ilosc'] = "ilość [m]";
  1307. $layerConf['_agr_fields_to_cols']['cena'] = "podstawowa cena [zł/m]";
  1308. $layerConf['_agr_fields_to_cols']['koszt'] = "koszt [zł]";
  1309. $_schema['sub_costs']['Rozdzielcza_Zabruki'] = $layerConf;
  1310. }
  1311. {
  1312. $layerConf = array();
  1313. $layerConf['label'] = "Światłowód";
  1314. $layerConf['_agr_fields_to_cols'] = array();
  1315. $layerConf['_agr_fields_to_cols']['ilosc'] = "ilość [m]";
  1316. $layerConf['_agr_fields_to_cols']['cena'] = "podstawowa cena [zł/m]";
  1317. $layerConf['_agr_fields_to_cols']['koszt'] = "koszt [zł]";
  1318. {
  1319. $layerSubCostsConf = array();
  1320. $layerSubCostsConf['group_by_field'] = 'wlokien_j';
  1321. $layerSubCostsConf['sql_agr_func'] = array();
  1322. $layerSubCostsConf['sql_agr_func']['sum_dlugosc'] = array();//sum(Dlugosc) as sum_dlugosc
  1323. $layerSubCostsConf['sql_agr_func']['sum_dlugosc']['func'] = 'sum';
  1324. $layerSubCostsConf['sql_agr_func']['sum_dlugosc']['field'] = 'Dlugosc';
  1325. $layerSubCostsConf['labels'] = array();
  1326. $layerSubCostsConf['labels']['cost_type'] = "rodzaj kosztu";
  1327. $layerSubCostsConf['labels']['sum_dlugosc'] = "suma długości";
  1328. $layerConf['sub_costs'] = $layerSubCostsConf;
  1329. }
  1330. $_schema['sub_costs']['Rozdzielcza_Kabel_Swiatlowodowy_wsg84'] = $layerConf;
  1331. }
  1332. {
  1333. $layerConf = array();
  1334. $layerConf['label'] = "Studnie - TODO (Lokalizacje)";
  1335. $layerConf['_agr_fields_to_cols'] = array();
  1336. $_schema['sub_costs']['__STUDNIE__'] = $layerConf;
  1337. }
  1338. {
  1339. $layerConf = array();
  1340. $layerConf['label'] = "Rury osłonowe - TODO";
  1341. $layerConf['_agr_fields_to_cols'] = array();
  1342. $_schema['sub_costs']['Rura_oslonowa_rozdzielcza_magistralna'] = $layerConf;
  1343. }
  1344. {
  1345. $layerConf = array();
  1346. $layerConf['label'] = "Pakiet mikrorurek - TODO";
  1347. $layerConf['_agr_fields_to_cols'] = array();
  1348. $_schema['sub_costs']['__PAKIET_MIKRORUREK__'] = $layerConf;
  1349. }
  1350. {
  1351. $layerConf = array();
  1352. $layerConf['label'] = "Koszty dodatkowe - TODO";
  1353. $layerConf['_agr_fields_to_cols'] = array();
  1354. $_schema['sub_costs']['__KOSZTY_DODATKOWE__'] = $layerConf;
  1355. }
  1356. return $_schema;
  1357. }
  1358. public function getData($idProject, $admin = 0) {
  1359. static $_data = null;
  1360. if (!is_array($_data)) $_data = array();
  1361. if (!array_key_exists($idProject, $_data)) $_data[$idProject] = $this->fetchData($idProject, $admin);
  1362. return $_data[$idProject];
  1363. }
  1364. public function fetchData($idProject, $admin = 0) {
  1365. $data = array();
  1366. $schema = $this->getSchema();
  1367. $conf = $schema['config'];
  1368. $pdo = DB::getPDO();
  1369. foreach ($conf['layer'] as $idLayer => $layer) {
  1370. $layData = array();
  1371. $layData['label'] = $layer['label'];
  1372. {
  1373. if (!$layer['tabela_name']) continue;// TODO: throw error in validate
  1374. $tblName = $layer['tabela_name'];
  1375. $sqlIloscField = (!empty($layer['ilosc_field']))? $layer['ilosc_field'] : 'ID';
  1376. $sqlIlosc = ('SZTUKA' == $layer['jednostka'])? "count(1)" : "sum(t.{$sqlIloscField})";
  1377. $sqlZasobField = (!empty($layer['zasob_field']))? $layer['zasob_field'] : 'ID';
  1378. $sqlGroupBy = (!empty($layer['zasob_field']))? "group by t.{$sqlZasobField}" : '';
  1379. $sth = $pdo->prepare("
  1380. select t.{$sqlZasobField}
  1381. , {$sqlIlosc} as ilosc
  1382. from {$tblName} t
  1383. where t.ID_PROJECT = :id_project
  1384. {$sqlGroupBy}
  1385. ");
  1386. $sth->bindValue(':id_project', $idProject, PDO::PARAM_INT);
  1387. $sth->execute();
  1388. $rawLayData = $sth->fetchAll();
  1389. $layData['_raw'] = $rawLayData;
  1390. $layData['_rawSql'] = "
  1391. select t.{$sqlZasobField}
  1392. , sum(t.{$sqlIloscField}) as ilosc
  1393. from {$tblName} t
  1394. where t.ID_PROJECT = {$idProject}
  1395. {$sqlGroupBy}
  1396. ";
  1397. $iloscByType = array();
  1398. $hasIlosc = false;
  1399. foreach ($rawLayData as $d) {
  1400. if ($d['ilosc'] <= 0) continue;
  1401. $hasIlosc = true;
  1402. $idType = 0;
  1403. $iloscType = null;
  1404. DBG::_('DBG', '>1', "layer", $layer, __CLASS__, __FUNCTION__, __LINE__);
  1405. DBG::_('DBG', '>1', "conf", $conf, __CLASS__, __FUNCTION__, __LINE__);
  1406. if ('ZASOB' == $layer['zasob_type']) {
  1407. $iloscType = array();
  1408. $iloscType['type'] = trim($d[$sqlZasobField]);
  1409. $idType = array_search($iloscType['type'], $conf['type']);
  1410. $iloscType['idType'] = $idType;
  1411. $iloscType['jednostka'] = $layer['jednostka'];
  1412. $iloscType['ilosc'] = $d['ilosc'];
  1413. } else if ('ZASOB_ID' == $layer['zasob_type']) {
  1414. $iloscType = array();
  1415. $iloscType['type'] = $layer['zasob_label'];
  1416. $idType = (array_key_exists($layer['zasob_id'], $conf['type']))? $layer['zasob_id'] : null;
  1417. $iloscType['idType'] = $idType;
  1418. $iloscType['jednostka'] = $layer['jednostka'];
  1419. $iloscType['ilosc'] = $d['ilosc'];
  1420. } else {
  1421. // TODO: BUG
  1422. }
  1423. if (!empty($iloscType) && $idType) {
  1424. if (!array_key_exists($idType, $iloscByType)) {
  1425. $iloscByType[$idType] = $iloscType;
  1426. } else {
  1427. DBG::_('DBG', '>1', "merge stats {$idType}", array($iloscByType[$idType], $iloscType), __CLASS__, __FUNCTION__, __LINE__);
  1428. $iloscByType[$idType]['ilosc'] += $iloscType['ilosc'];
  1429. }
  1430. } else {
  1431. DBG::_('DBG', '>1', "skip stats", $d, __CLASS__, __FUNCTION__, __LINE__);
  1432. if ($admin) SE_Layout::alert('warning', "Pomijanie nieznanego oznaczenia '{$iloscType['type']}' w ilości {$iloscType['ilosc']} - warstwa '{$layer['label']}' ({$layer['tabela_name']})");
  1433. }
  1434. }
  1435. if ($hasIlosc) $layData['data'] = $iloscByType;
  1436. }
  1437. if (!empty($layData['data'])) $data[$idLayer] = $layData;
  1438. }
  1439. return $data;
  1440. }
  1441. public function _fetchKosztorysData($idProject) {
  1442. $project = array();
  1443. $schema = $this->getSchema();
  1444. if(0){// TEST join by ogc
  1445. $exampleOgcJoin = <<<OGC_JOIN
  1446. <wfs:Query typeNames="p5_default_db:IN7_MK_BAZA_DYSTRYBUCJI p5_default_db:ADMIN_USERS" aliases="p u">
  1447. <fes:Filter>
  1448. <fes:And>
  1449. <fes:PropertyIsEqualTo>
  1450. <fes:ValueReference>p/ID</fes:ValueReference>
  1451. <fes:Literal>{$idProject}</fes:Literal>
  1452. </fes:PropertyIsEqualTo>
  1453. <fes:PropertyIsEqualTo>
  1454. <fes:ValueReference>u/ADM_ACCOUNT<fes:ValueReference>
  1455. <fes:ValueReference>p/L_APPOITMENT_USER</fes:ValueReference>
  1456. </fes:PropertyIsEqualTo>
  1457. </fes:And>
  1458. </fes:Filter>
  1459. </wfs:Query>
  1460. OGC_JOIN;
  1461. }
  1462. $pdo = DB::getPDO();
  1463. {
  1464. $sth = $pdo->prepare("
  1465. select p.ID, p.M_DIST_DESC, p.L_APPOITMENT_USER
  1466. , p.koszt_wspolny
  1467. , p.koszt_na_budynek
  1468. , p.koszt_na_mieszkanie
  1469. , p.Agr_Rozdzielcza_Wykop_przedmiar_na_mikrorurki_ilosc
  1470. , p.Agr_Rozdzielcza_Wykop_przedmiar_na_mikrorurki_cena
  1471. , p.Agr_Rozdzielcza_Wykop_przedmiar_na_mikrorurki_koszt
  1472. , p.Agr_Rozdzielcza_Mikrokanalizacja_do_klienta_ilosc
  1473. , p.Agr_Rozdzielcza_Mikrokanalizacja_do_klienta_cena
  1474. , p.Agr_Rozdzielcza_Mikrokanalizacja_do_klienta_koszt
  1475. , p.Agr_metrow_mikrorurek_5szt
  1476. , p.Agr_metrow_mikrorurek_5szt_cena
  1477. , p.Agr_Rozdzielcza_Przeciski_110mm_ilosc
  1478. , p.Agr_Rozdzielcza_Przeciski_110mm_cena
  1479. , p.Agr_Rozdzielcza_Przeciski_110mm_koszt
  1480. , p.Agr_Rozdzielcza_Zabruki_ilosc
  1481. , p.Agr_Rozdzielcza_Zabruki_cena
  1482. , p.Agr_Rozdzielcza_Zabruki_koszt
  1483. , p.Agr_Rozdzielcza_wezly_ilosc
  1484. , p.Agr_Rozdzielcza_wezly_cena
  1485. , p.Agr_Rozdzielcza_wezly_koszt
  1486. , p.Agr_Rozdzielcza_koszty_dodatkowe_wsg84
  1487. , p.Agr_Rozdzielcza_rurociag_wsg84_ilosc
  1488. , p.Agr_Rozdzielcza_rurociag_wsg84_cena
  1489. , p.Agr_Rozdzielcza_rurociag_wsg84_koszt
  1490. , p.Agr_Rozdzielcza_Kabel_Swiatlowodowy_wsg84_ilosc
  1491. , p.Agr_Rozdzielcza_Kabel_Swiatlowodowy_wsg84_cena
  1492. , p.Agr_Rozdzielcza_Kabel_Swiatlowodowy_wsg84_koszt
  1493. , p.Agr_USERS2_MARKETING_ilosc
  1494. , p.Agr_USERS2_MARKETING_cena
  1495. , p.Agr_USERS2_MARKETING_koszt
  1496. , p.Agr_BUILDINGS_ilosc
  1497. from IN7_MK_BAZA_DYSTRYBUCJI p
  1498. where p.ID = :ID_PROJECT
  1499. -- TODO: check perms!
  1500. ");
  1501. $sth->bindValue('ID_PROJECT', $idProject, PDO::PARAM_INT);
  1502. $sth->execute();
  1503. $projectList = $sth->fetchAll();
  1504. if (empty($projectList)) throw new Exception("404 - Project Not Found");
  1505. $projectRaw = reset($projectList);
  1506. }
  1507. {
  1508. $project['nr'] = $projectRaw['ID'];
  1509. $project['title'] = $projectRaw['M_DIST_DESC'];
  1510. $project['owner_name'] = $this->fetchUserName($projectRaw['L_APPOITMENT_USER']);
  1511. $project['cost_total'] = $projectRaw['koszt_wspolny'];
  1512. foreach ($schema['sub_costs'] as $layerName => $layerConf) {
  1513. $values = array();
  1514. foreach ($layerConf['_agr_fields_to_cols'] as $fldName => $label) {
  1515. $values[$fldName] = V::get("Agr_{$layerName}_{$fldName}", '', $projectRaw);
  1516. }
  1517. $project['sub_costs'][$layerName] = $values;
  1518. if (!empty($layerConf['sub_costs'])) {
  1519. $sub_costs = array();
  1520. {
  1521. $groupByField = $layerConf['sub_costs']['group_by_field'];
  1522. $sqlFields = array();
  1523. foreach ($layerConf['sub_costs']['sql_agr_func'] as $fldName => $funcConf) {
  1524. $sqlFuncName = $funcConf['func'];
  1525. $sqlFuncField = $funcConf['field'];
  1526. $sqlFields[] = "{$sqlFuncName}(l.{$sqlFuncField}) as {$fldName}";
  1527. }
  1528. $sqlFields = implode(", ", $sqlFields);
  1529. $sth = $pdo->prepare("
  1530. select l.{$groupByField} as cost_type
  1531. , $sqlFields
  1532. from Rozdzielcza_Kabel_Swiatlowodowy_wsg84 l
  1533. where l.ID_PROJECT = :ID_PROJECT
  1534. group by l.{$groupByField}
  1535. ");
  1536. $sth->bindValue('ID_PROJECT', $idProject, PDO::PARAM_INT);
  1537. $sth->execute();
  1538. $sub_costs = $sth->fetchAll();
  1539. }
  1540. $project['sub_costs'][$layerName]['sub_costs'] = $sub_costs;
  1541. }
  1542. }
  1543. }
  1544. $project['_raw'] = $projectRaw;
  1545. return $project;
  1546. }
  1547. public function fetchUserName($userLogin) {
  1548. $userName = $userLogin;
  1549. // TODO: sql from ADMIN_USERS
  1550. return $userName;
  1551. }
  1552. }