ProjektyKosztyWstepnychRobot.php 61 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608
  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. DBG::_('DBG', '>1', "EDIT price for idZasob({$idType}) {price:{$edit_price}, id_offer:{$edit_id}}", $typeLabel, __CLASS__, __FUNCTION__, __LINE__);
  769. $edit__sth->execute();
  770. // TODO: add to hist
  771. }
  772. } else {
  773. $add_price = V::get("price_{$idType}", '', $args);
  774. $add_price = str_replace(',', '.', $add_price);
  775. if ($add_price > 0) {
  776. $add_id_zasob = $idType;
  777. $add_unit = $layData['jednostka'];
  778. DBG::_('DBG', '>1', "ADD price for idZasob({$idType}) {price:{$add_price}}", $typeLabel, __CLASS__, __FUNCTION__, __LINE__);
  779. $add__sth->execute();
  780. }
  781. }
  782. }
  783. }
  784. }
  785. public function saveDefaultOffer($args) {
  786. DBG::_('DBG', '>1', "args", $args, __CLASS__, __FUNCTION__, __LINE__);
  787. $cennik = $this->getDefaultCennik();
  788. DBG::_('DBG', '>1', "cennik", $cennik, __CLASS__, __FUNCTION__, __LINE__);
  789. $idCompany = 0;
  790. $idProject = 0;
  791. $pdo = DB::getPDO();
  792. {
  793. $add_id_zasob = 0;
  794. $add_unit = '';
  795. $add_price = 0;
  796. $add_quantity = 0;
  797. $add__sth = $pdo->prepare("
  798. insert into CRM_LISTA_ZASOBOW_OFFERS (
  799. CRM_LISTA_ZASOBOW_ID
  800. , COMPANIES_ID
  801. , ID_PROJECT
  802. , OFFER_PRICE_PER_RESOURCE_UNIT
  803. , RESOURCE_UNIT_TYPE
  804. , OFFER_UNIT_TYPE
  805. , REQUIRED_RESOURCE_UNITS
  806. , A_RECORD_CREATE_AUTHOR
  807. , A_RECORD_CREATE_DATE
  808. ) values (
  809. :id_zasob
  810. , :id_company
  811. , :id_project
  812. , :price
  813. , :unit
  814. , :unit
  815. , :quantity
  816. , :author
  817. , NOW()
  818. )
  819. ");
  820. $add__sth->bindValue(':author', User::getLogin(), PDO::PARAM_STR);
  821. $add__sth->bindValue(':id_project', $idProject, PDO::PARAM_INT);
  822. $add__sth->bindValue(':id_company', $idCompany, PDO::PARAM_INT);
  823. $add__sth->bindValue(':quantity', $add_quantity, PDO::PARAM_STR);
  824. $add__sth->bindParam(':id_zasob', $add_id_zasob, PDO::PARAM_INT);
  825. $add__sth->bindParam(':price', $add_price, PDO::PARAM_STR);
  826. $add__sth->bindParam(':unit', $add_unit, PDO::PARAM_STR);
  827. }
  828. {
  829. $edit_id_zasob = 0;
  830. $edit_unit = '';
  831. $edit_price = 0;
  832. $edit_author = 0;
  833. $edit_quantity = 0;
  834. $edit__sth = $pdo->prepare("
  835. update CRM_LISTA_ZASOBOW_OFFERS
  836. set CRM_LISTA_ZASOBOW_ID = :id_zasob
  837. , COMPANIES_ID = :id_company
  838. , ID_PROJECT = :id_project
  839. , OFFER_PRICE_PER_RESOURCE_UNIT = :price
  840. , RESOURCE_UNIT_TYPE = :unit
  841. , OFFER_UNIT_TYPE = :unit
  842. , REQUIRED_RESOURCE_UNITS = :quantity
  843. , A_RECORD_UPDATE_AUTHOR = :author
  844. , A_RECORD_UPDATE_DATE = NOW()
  845. where ID = :id
  846. ");
  847. $edit__sth->bindParam(':id', $edit_id, PDO::PARAM_INT);
  848. $edit__sth->bindValue(':author', User::getLogin(), PDO::PARAM_STR);
  849. $edit__sth->bindValue(':id_project', $idProject, PDO::PARAM_INT);
  850. $edit__sth->bindValue(':id_company', $idCompany, PDO::PARAM_INT);
  851. $edit__sth->bindValue(':quantity', $edit_quantity, PDO::PARAM_STR);
  852. $edit__sth->bindParam(':id_zasob', $edit_id_zasob, PDO::PARAM_INT);
  853. $edit__sth->bindParam(':price', $edit_price, PDO::PARAM_STR);
  854. $edit__sth->bindParam(':unit', $edit_unit, PDO::PARAM_STR);
  855. }
  856. $schema = $this->getSchema();
  857. foreach ($schema['config']['layer'] as $idLayer => $layData) {
  858. DBG::_('DBG', '>1', "layData", $layData, __CLASS__, __FUNCTION__, __LINE__);
  859. foreach ($layData['type'] as $idType => $typeLabel) {
  860. DBG::_('DBG', '>1', "typeLabel", $typeLabel, __CLASS__, __FUNCTION__, __LINE__);
  861. $edit_id = V::get("edit_price_id_{$idType}", '', $args);
  862. if ($edit_id > 0) {
  863. $edit_price = V::get("price_{$idType}", '', $args);
  864. $edit_price = str_replace(',', '.', $edit_price);
  865. if ($edit_id > 0 && $edit_price > 0) {
  866. $edit_id_zasob = $idType;
  867. $edit_unit = $layData['jednostka'];
  868. // TODO: check if anything change
  869. $edit__sth->execute();
  870. // TODO: add to hist
  871. }
  872. } else {
  873. $add_price = V::get("price_{$idType}", '', $args);
  874. $add_price = str_replace(',', '.', $add_price);
  875. if ($add_price > 0) {
  876. $add_id_zasob = $idType;
  877. $add_unit = $layData['jednostka'];
  878. $add__sth->execute();
  879. }
  880. }
  881. }
  882. }
  883. }
  884. /**
  885. * @returns [ $id_zasob => [ 'price' => $price, 'ID', 'id_zasob', 'id_company', 'id_project', 'unit', 'quantity' ] ]
  886. */
  887. public function getDefaultCennik($idCompany = 0) {
  888. $schema = $this->getSchema();
  889. $typeIdList = array_keys($schema['config']['type']);
  890. $sqlTypeIdList = implode(',', $typeIdList);
  891. $pdo = DB::getPDO();
  892. $sth = $pdo->prepare("
  893. select o.ID
  894. , o.CRM_LISTA_ZASOBOW_ID as id_zasob
  895. , o.COMPANIES_ID as id_company
  896. , o.ID_PROJECT as id_project
  897. , o.OFFER_PRICE_PER_RESOURCE_UNIT as price
  898. , o.RESOURCE_UNIT_TYPE as unit
  899. -- , o.OFFER_UNIT_TYPE as unit
  900. , o.REQUIRED_RESOURCE_UNITS as quantity
  901. from CRM_LISTA_ZASOBOW_OFFERS o
  902. where o.CRM_LISTA_ZASOBOW_ID in({$sqlTypeIdList})
  903. -- and o.A_STATUS not in ('DELETED')
  904. and o.ID_PROJECT = 0
  905. and o.COMPANIES_ID = :id_company
  906. ");
  907. $sth->bindValue(':id_company', $idCompany, PDO::PARAM_INT);
  908. $sth->execute();
  909. $cennikRaw = $sth->fetchAll();
  910. $cennik = array();
  911. foreach ($cennikRaw as $itemRaw) {
  912. $item = $itemRaw;
  913. $item['price'] = round($item['price'], 2);
  914. if (!empty($cennik[$itemRaw['id_zasob']])) {
  915. if ($itemRaw['ID'] < $cennik[$itemRaw['id_zasob']]['ID']) continue;
  916. }
  917. $cennik[$item['id_zasob']] = $item;
  918. }
  919. return $cennik;
  920. }
  921. /**
  922. * @returns [ $id_zasob => [ 'price' => $price, 'ID', 'id_zasob', 'id_company', 'id_project', 'unit', 'quantity' ] ]
  923. */
  924. public function getCennik($idProject, $idCompany = 0) {
  925. $schema = $this->getSchema();
  926. $typeIdList = array_keys($schema['config']['type']);
  927. $sqlTypeIdList = implode(',', $typeIdList);
  928. $pdo = DB::getPDO();
  929. $sth = $pdo->prepare("
  930. select o.ID
  931. , o.CRM_LISTA_ZASOBOW_ID as id_zasob
  932. , o.COMPANIES_ID as id_company
  933. , o.ID_PROJECT as id_project
  934. , o.OFFER_PRICE_PER_RESOURCE_UNIT as price
  935. , o.RESOURCE_UNIT_TYPE as unit
  936. -- , o.OFFER_UNIT_TYPE as unit
  937. , o.REQUIRED_RESOURCE_UNITS as quantity
  938. from CRM_LISTA_ZASOBOW_OFFERS o
  939. where o.CRM_LISTA_ZASOBOW_ID in({$sqlTypeIdList})
  940. -- and o.A_STATUS not in ('DELETED')
  941. and o.ID_PROJECT = :id_project
  942. and o.COMPANIES_ID = :id_company
  943. ");
  944. $sth->bindValue(':id_project', $idProject, PDO::PARAM_INT);
  945. $sth->bindValue(':id_company', $idCompany, PDO::PARAM_INT);
  946. $sth->execute();
  947. $cennikRaw = $sth->fetchAll();
  948. $cennik = array();
  949. foreach ($cennikRaw as $itemRaw) {
  950. $item = $itemRaw;
  951. $item['price'] = round($item['price'], 2);
  952. $cennik[$itemRaw['id_zasob']] = $item;
  953. }
  954. return $cennik;
  955. }
  956. public function defaultOferta($idCompany = 0) {
  957. if ('1' == V::get('save_offer', '', $_POST)) {
  958. $this->saveDefaultOffer($_POST);
  959. }
  960. $schema = $this->getSchema();
  961. if (empty($schema['config']['type'])) throw new Exception("Schema error - brak zdefiniowanych typów");
  962. $cennik = $this->getDefaultCennik($idCompany);
  963. //DBG::_(true, true, "cennik", $cennik, __CLASS__, __FUNCTION__, __LINE__);
  964. ?>
  965. <div class="container">
  966. <form action="" method="post">
  967. <?php foreach ($schema['config']['layer'] as $idLayer => $layData) : ?>
  968. <h4 style="padding:0 6px"><?php echo $layData['label']; ?></h4>
  969. <table class="tabel table-bordered" style="width:100%">
  970. <tbody>
  971. <tr>
  972. <th style="padding:0 6px">id zasobu</th>
  973. <th style="padding:0 6px">typ</th>
  974. <th style="padding:0 6px">jednotka miary</th>
  975. <th style="padding:0 6px">cena jednostkowa</th>
  976. </tr>
  977. <?php foreach ($layData['type'] as $idType => $typeLabel) : ?>
  978. <tr>
  979. <td style="width:100px; padding:0 6px"><?php echo $idType; ?></td>
  980. <td style="padding:0 6px" title="[<?php echo $idType; ?>] <?php echo $typeLabel; ?>"><?php echo $typeLabel; ?></td>
  981. <td style="padding:0 6px"><?php echo $layData['jednostka']; ?></td>
  982. <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>
  983. </tr>
  984. <?php endforeach; ?>
  985. </tbody>
  986. </table>
  987. <?php endforeach; ?>
  988. <br>
  989. <?php foreach ($cennik as $item) : ?>
  990. <input type="hidden" name="edit_price_id_<?php echo $item['id_zasob']; ?>" value="<?php echo $item['ID']; ?>">
  991. <?php endforeach; ?>
  992. <input type="hidden" name="save_offer" value="1">
  993. <input type="submit" value="Zapisz" class="btn btn-primary">
  994. </form>
  995. </div>
  996. <?php
  997. }
  998. /**
  999. * @returns [ 'cost_total' => :numeric, 'sub_costs' => [ $id_zasob => 'price' ] ]
  1000. */
  1001. public function getProjectCostForCennik($idProject, $idCompany = 0) {
  1002. $projCost = array();
  1003. $projCost['cost_total'] = 0;
  1004. $projCost['sub_costs'] = array();
  1005. $defCennik = $this->getDefaultCennik($idCompany);
  1006. // $defCennik = [ $id_zasob => [ 'price' => $price, 'ID', 'id_zasob', 'id_company', 'id_project', 'unit', 'quantity' ] ]
  1007. $cennik = $this->getCennik($idProject, $idCompany);
  1008. $data = $this->getData($idProject, $admin);
  1009. foreach ($data as $idLayer => $layData) {
  1010. foreach ($layData['data'] as $typeData) {
  1011. if (!$typeData['idType']) continue;
  1012. $price = (!empty($cennik[$typeData['idType']]['price']))? $cennik[$typeData['idType']]['price'] : 0;
  1013. $defPrice = (!empty($defCennik[$typeData['idType']]['price']))? $defCennik[$typeData['idType']]['price'] : 0;
  1014. $cost = ($price > 0)? $price : $defPrice;
  1015. $cost = $typeData['ilosc'] * $cost;
  1016. $projCost['sub_costs'][$typeData['idType']] = $cost;
  1017. $projCost['cost_total'] += $cost;
  1018. }
  1019. }
  1020. return $projCost;
  1021. }
  1022. public function kosztorys($idProject) {
  1023. $schema = $this->getSchema();
  1024. $data = $this->_fetchKosztorysData($idProject);
  1025. $projCost = $this->getProjectCostForCennik($idProject, $idCompany = 0);
  1026. ?>
  1027. <div class="container">
  1028. <h1>Kosztorys wstępny robót telekomunikacyjnych</h1>
  1029. <table class="table">
  1030. <tr>
  1031. <th><?php echo $schema['nr']; ?></th>
  1032. <th><?php echo $schema['title']; ?></th>
  1033. <th><?php echo $schema['owner_name']; ?></th>
  1034. <th style="text-align:right"><?php echo $schema['cost_total']; ?></th>
  1035. </tr>
  1036. <tr>
  1037. <td><?php echo $data['nr']; ?></td>
  1038. <td><?php echo $data['title']; ?></td>
  1039. <td><?php echo $data['owner_name']; ?></td>
  1040. <td style="text-align:right"><?php echo number_format($projCost['cost_total'], 2, ',', ' '); ?></td>
  1041. </tr>
  1042. </table>
  1043. <?php $this->viewLayersData($idProject, $idCompany = 0, $admin = false, $projCost['sub_costs']); ?>
  1044. </div>
  1045. <?php
  1046. DBG::_('DBG', '>0', "data", $data, __CLASS__, __FUNCTION__, __LINE__);
  1047. DBG::_('DBG', '>0', "schema", $schema, __CLASS__, __FUNCTION__, __LINE__);
  1048. DBG::_('DBG', '>0', "projCost", $projCost, __CLASS__, __FUNCTION__, __LINE__);
  1049. }
  1050. public function oferta($idProject, $idCompany = 0, $admin = false) {
  1051. if ($admin && '1' == V::get('save_offer', '', $_POST)) {
  1052. $this->saveOffer($idProject, $idCompany, $_POST, $admin);
  1053. }
  1054. $defCennik = $this->getDefaultCennik($idCompany);
  1055. $cennik = $this->getCennik($idProject, $idCompany);
  1056. ?>
  1057. <div class="container">
  1058. <?php if ($admin) : ?>
  1059. <form action="" method="post">
  1060. <?php endif; ?>
  1061. <?php $this->viewLayersData($idProject, $idCompany, $admin); ?>
  1062. <?php if ($admin) : ?>
  1063. <?php foreach ($cennik as $item) : ?>
  1064. <input type="hidden" name="edit_price_id_<?php echo $item['id_zasob']; ?>" value="<?php echo $item['ID']; ?>">
  1065. <?php endforeach; ?>
  1066. <input type="hidden" name="save_offer" value="1">
  1067. <hr><input class="btn btn-primary" type="submit" value="Zapisz ofertę">
  1068. </form>
  1069. <?php endif; ?>
  1070. </div>
  1071. <?php
  1072. }
  1073. public function viewLayersData($idProject, $idCompany = 0, $admin = false, $projSubCost = array()) {
  1074. $schema = $this->getSchema();
  1075. $conf = $schema['config'];
  1076. DBG::_('DBG', '>1', "conf", $conf, __CLASS__, __FUNCTION__, __LINE__);
  1077. $data = $this->getData($idProject, $admin);
  1078. DBG::_('DBG', '>1', "data", $data, __CLASS__, __FUNCTION__, __LINE__);
  1079. $defCennik = $this->getDefaultCennik($idCompany);
  1080. $cennik = $this->getCennik($idProject, $idCompany);
  1081. ?>
  1082. <?php foreach ($data as $idLayer => $layData) : ?>
  1083. <h4 style="padding:0 6px"><?php echo $layData['label']; ?></h4>
  1084. <table class="tabel table-bordered" style="width:100%">
  1085. <tbody>
  1086. <tr>
  1087. <th style="padding:0 6px">typ</th>
  1088. <th style="padding:0 6px; text-align:right">ilość</th>
  1089. <th style="padding:0 6px; text-align:right">jednotka miary</th>
  1090. <th style="padding:0 6px; text-align:right">cena jednostkowa</th>
  1091. <?php if ($admin) : ?>
  1092. <th style="padding:0 6px; text-align:right">cena jednostkowa (domyślna)</th>
  1093. <?php endif; ?>
  1094. <?php if (!empty($projSubCost)) : ?>
  1095. <th style="padding:0 6px; text-align:right">szacowany koszt [zł]</th>
  1096. <?php endif; ?>
  1097. </tr>
  1098. <?php foreach ($layData['data'] as $typeData) : ?>
  1099. <?php if (!$typeData['idType']) : ?>
  1100. <tr>
  1101. <td colspan="4">
  1102. <?php if ($admin) {
  1103. $fixLink = 'index.php?MENU_INIT=VIEWTABLE_AJAX&ZASOB_ID=' . $conf['layer'][$idLayer]['tabela_id'];
  1104. $fixLink .= '&f_' . $conf['layer'][$idLayer]['zasob_field'] . '=%3D' . $typeData['type'];
  1105. $fixLink .= '&_hash=' . uniqid();
  1106. $fixProjectLink = '<a target="_blank" href="' . $fixLink . "&f_ID_PROJECT={$idProject}" . '">' . "Popraw" . '</a>' . " (dane dla projektu [{$idProject}])";
  1107. $fixAllLink = '<a target="_blank" href="' . $fixLink . '">' . "Popraw wszystkie" . '</a>';
  1108. SE_Layout::alert('danger', "Niezdefiniowany typ: <code>{$typeData['type']}</code> - {$fixProjectLink}, {$fixAllLink}");
  1109. } ?>
  1110. <?php DBG::_('DBG', '>1', "Error conf", $conf, __CLASS__, __FUNCTION__, __LINE__); ?>
  1111. <?php DBG::_('DBG', '>1', "Error", $typeData, __CLASS__, __FUNCTION__, __LINE__); ?>
  1112. </td>
  1113. </tr>
  1114. <?php else : ?>
  1115. <?php $defPrice = (!empty($defCennik[$typeData['idType']]['price']))? $defCennik[$typeData['idType']]['price'] : 0; ?>
  1116. <?php $price = (!empty($cennik[$typeData['idType']]['price']))? $cennik[$typeData['idType']]['price'] : $defPrice; ?>
  1117. <tr>
  1118. <td style="padding:0 6px" title="[<?php echo $typeData['idType']; ?>] <?php echo $typeData['type']; ?>"><?php echo $typeData['type']; ?></td>
  1119. <td style="padding:0 6px; text-align:right"><?php echo $typeData['ilosc']; ?></td>
  1120. <td style="padding:0 6px; text-align:right"><?php echo $typeData['jednostka']; ?></td>
  1121. <td style="padding:3px 6px; text-align:right">
  1122. <?php if ($admin) : ?>
  1123. <input type="text" style="text-align:right" class="form-control input-sm" name="price_<?php echo $typeData['idType']; ?>" value="<?php echo $price; ?>"/>
  1124. <?php else : ?>
  1125. <?php echo $price; ?>
  1126. <?php endif; ?>
  1127. </td>
  1128. <?php if ($admin) : ?>
  1129. <td style="padding:3px 6px; text-align:right"><?php echo $defPrice; ?></td>
  1130. <?php endif; ?>
  1131. <?php if (!empty($projSubCost)) : ?>
  1132. <td style="padding:3px 6px; text-align:right"><?php echo number_format(V::get($typeData['idType'], 0, $projSubCost), 2, ',', ' '); ?></td>
  1133. <?php endif; ?>
  1134. </tr>
  1135. <?php endif; ?>
  1136. <?php endforeach; ?>
  1137. </tbody>
  1138. </table>
  1139. <?php endforeach; ?>
  1140. <?php
  1141. }
  1142. public function checkGeomDuplicate() {
  1143. // TODO: for every schema.layer
  1144. $sqlTblName = 'Rozdzielcza_Kabel_Swiatlowodowy_wsg84';
  1145. $sql = "select a.ID, b.ID, aswkt(a.the_geom)
  1146. from `{$sqlTblName}` a
  1147. join `$sqlTblName` b on(b.the_geom = a.the_geom and a.ID != b.ID)
  1148. ";
  1149. }
  1150. public function getSchema() {
  1151. static $_schema = null;
  1152. if (null !== $_schema) return $_schema;
  1153. $_schema = array();
  1154. /*
  1155. 22444 INNE Kosztorys - zasoby
  1156. 22445 INNE Kabel 2J do wdmuchiwania w mikrorurce 7/4 mm z wdmuchiwaniem
  1157. 22446 INNE Kabel 4J do wdmuchiwania w mikrorurce 7/4 mm z wdmuchiwaniem
  1158. ... Labels for order form
  1159. 22460 TABELA Światłowód (Alias do [20225] TABELA default_db/Rozdzielcza_Kabel_Swiatlowodowy_wsg84)
  1160. 22461 20299 KOMORKA ZASOB (Alias do [20299] KOMORKA OznKabla)
  1161. 22462 20292 KOMORKA JEDNOSTKA_METR ilość [m] (Alias do [20292] KOMORKA Dlugosc)
  1162. ... where to search for data
  1163. */
  1164. {
  1165. $pdo = DB::getPDO();
  1166. $sth = $pdo->prepare("
  1167. select z.ID, z.TYPE, z.DESC, z.ALIAS_ID
  1168. , c.ID as c_ID, c.TYPE as c_TYPE, c.DESC as c_DESC, c.ALIAS_ID as c_ALIAS_ID
  1169. , a.ID as a_ID, a.TYPE as a_TYPE, a.DESC as a_DESC, a.ALIAS_ID as a_ALIAS_ID
  1170. , za.ID as za_ID, za.TYPE as za_TYPE, za.DESC as za_DESC, za.ALIAS_ID as za_ALIAS_ID
  1171. from CRM_LISTA_ZASOBOW z
  1172. left join CRM_LISTA_ZASOBOW c on(c.PARENT_ID = z.ID)
  1173. left join CRM_LISTA_ZASOBOW a on(a.ID = z.ALIAS_ID and z.ALIAS_ID > 0)
  1174. left join CRM_LISTA_ZASOBOW za on(za.ID = c.ALIAS_ID and c.ALIAS_ID > 0)
  1175. where z.PARENT_ID = 22444 -- TODO how to find ID, Typespecial with link
  1176. ");
  1177. $sth->execute();
  1178. $rawConf = $sth->fetchAll();
  1179. $conf = array();
  1180. $conf['type'] = array();
  1181. $conf['layer'] = array();
  1182. foreach ($rawConf as $z) {
  1183. if ('INNE' == $z['TYPE']) {
  1184. if (!array_key_exists($z['ID'], $conf['type'])) {
  1185. $conf['type'][$z['ID']] = $z['DESC'];
  1186. }
  1187. }
  1188. }
  1189. foreach ($rawConf as $z) {
  1190. if ('TABELA' == $z['TYPE']) {
  1191. if (!array_key_exists($z['ID'], $conf['layer'])) {
  1192. $layer = array();
  1193. $layer['label'] = $z['DESC'];
  1194. $layer['tabela_id'] = $z['a_ID'];
  1195. $layer['tabela_name'] = $z['a_DESC'];
  1196. $layer['jednostka'] = '';
  1197. $layer['zasob_type'] = '';
  1198. $layer['zasob_field'] = '';
  1199. $layer['zasob_id'] = '';
  1200. $layer['ilosc_field'] = '';
  1201. $layer['type'] = array();
  1202. $conf['layer'][$z['ID']] = $layer;
  1203. }
  1204. if ($z['c_ID'] > 0) {
  1205. if ('JEDNOSTKA_' == substr($z['c_DESC'], 0, 10)) {
  1206. $layer = $conf['layer'][$z['ID']];
  1207. $layer['jednostka'] = substr($z['c_DESC'], 10);
  1208. $layer['ilosc_field'] = $z['za_DESC'];
  1209. $layer['zasob_id'] = $z['za_ID'];
  1210. $conf['layer'][$z['ID']] = $layer;
  1211. }
  1212. /*
  1213. [za_ID] => 20299
  1214. [za_TYPE] => KOMORKA
  1215. [za_DESC] => OznKabla
  1216. [za_ALIAS_ID] => 0
  1217. */
  1218. switch ($z['c_DESC']) {
  1219. case 'ZASOB': {
  1220. if ($z['za_ID'] > 0) {
  1221. $layer = $conf['layer'][$z['ID']];
  1222. $layer['zasob_type'] = $z['c_DESC'];
  1223. $layer['zasob_field'] = $z['za_DESC'];
  1224. $layer['zasob_id'] = $z['za_ID'];
  1225. $conf['layer'][$z['ID']] = $layer;
  1226. }
  1227. } break;
  1228. case 'ZASOB_ID': {
  1229. if ($z['za_ID'] > 0) {
  1230. $layer = $conf['layer'][$z['ID']];
  1231. $layer['zasob_type'] = $z['c_DESC'];
  1232. $layer['zasob_id'] = $z['za_ID'];
  1233. $layer['zasob_label'] = $z['za_DESC'];
  1234. $conf['layer'][$z['ID']] = $layer;
  1235. $conf['layer'][$z['ID']]['type'][$z['za_ID']] = $z['za_DESC'];
  1236. }
  1237. } break;
  1238. case 'TYPE': {
  1239. //DBG::_(true, true, "z", $z, __CLASS__, __FUNCTION__, __LINE__);
  1240. if (empty($z['c_ALIAS_ID'])) throw new Exception("Schema error - brak ALIAS_ID dla typu");
  1241. if (empty($conf['type'][$z['za_ID']])) ;// TODO: throw exception
  1242. $conf['layer'][$z['ID']]['type'][$z['za_ID']] = $z['za_DESC'];
  1243. } break;
  1244. }
  1245. }
  1246. }
  1247. }
  1248. foreach ($rawConf as $z) {
  1249. if ('INNE' == $z['TYPE']) {
  1250. } else if ('TABELA' == $z['TYPE']) {
  1251. } else {
  1252. SE_Layout::alert('warnig', "BUG: unimplemented type '{$z['TYPE']}' for zasob nr: {$z['ID']}");
  1253. }
  1254. }
  1255. DBG::_('DBG', '>1', "config", $conf, __CLASS__, __FUNCTION__, __LINE__);
  1256. {// validate schema - show warnings
  1257. foreach ($conf['layer'] as $layer) {
  1258. try {
  1259. if (empty($layer['tabela_id'])) throw new Exception("brak zdefiniowanego aliasa do tabeli dla warstwy {$layer['label']}");
  1260. if (empty($layer['jednostka'])) throw new Exception("brak jednostki dla warstwy [{$layer['tabela_id']}] {$layer['label']}");
  1261. switch ($layer['jednostka']) {
  1262. case 'METR': break;
  1263. case 'SZTUKA': break;
  1264. default: throw new Exception("Nieznana jednostka '{$layer['jednostka']}' dla warstwy [{$layer['tabela_id']}] {$layer['label']}");
  1265. }
  1266. } catch (Exception $e) {
  1267. SE_Layout::alert('warning', $e->getMessage());
  1268. }
  1269. }
  1270. }
  1271. DBG::_('DBG', '>2', "rawConf", $rawConf, __CLASS__, __FUNCTION__, __LINE__);
  1272. $_schema['config'] = $conf;
  1273. }
  1274. $_schema['nr'] = "Nr projektu";
  1275. $_schema['title'] = "Tytuł projektu";
  1276. $_schema['owner_name'] = "Osoba prowadząca";
  1277. $_schema['cost_total'] = "Szacowany koszt projektu [zł]";
  1278. $_schema['sub_costs'] = array();
  1279. {
  1280. $layerConf = array();
  1281. $layerConf['label'] = "Wykop";
  1282. $layerConf['_agr_fields_to_cols'] = array();
  1283. $layerConf['_agr_fields_to_cols']['ilosc'] = "ilość [m]";
  1284. $layerConf['_agr_fields_to_cols']['cena'] = "podstawowa cena [zł/m]";
  1285. $layerConf['_agr_fields_to_cols']['koszt'] = "koszt [zł]";
  1286. $_schema['sub_costs']['Rozdzielcza_Wykop_przedmiar_na_mikrorurki'] = $layerConf;
  1287. }
  1288. {
  1289. $layerConf = array();
  1290. $layerConf['label'] = "Mikrokanalizacja do klienta";
  1291. $layerConf['_agr_fields_to_cols'] = array();
  1292. $layerConf['_agr_fields_to_cols']['ilosc'] = "ilość [m]";
  1293. $layerConf['_agr_fields_to_cols']['cena'] = "podstawowa cena [zł/m]";
  1294. $layerConf['_agr_fields_to_cols']['koszt'] = "koszt [zł]";
  1295. $_schema['sub_costs']['Rozdzielcza_Mikrokanalizacja_do_klienta'] = $layerConf;
  1296. }
  1297. {
  1298. $layerConf = array();
  1299. $layerConf['label'] = "Przeciski";
  1300. $layerConf['_agr_fields_to_cols'] = array();
  1301. $layerConf['_agr_fields_to_cols']['ilosc'] = "ilość [m]";
  1302. $layerConf['_agr_fields_to_cols']['cena'] = "podstawowa cena [zł/m]";
  1303. $layerConf['_agr_fields_to_cols']['koszt'] = "koszt [zł]";
  1304. $_schema['sub_costs']['Rozdzielcza_Przeciski_110mm'] = $layerConf;
  1305. }
  1306. {
  1307. $layerConf = array();
  1308. $layerConf['label'] = "Zabruki";
  1309. $layerConf['_agr_fields_to_cols'] = array();
  1310. $layerConf['_agr_fields_to_cols']['ilosc'] = "ilość [m]";
  1311. $layerConf['_agr_fields_to_cols']['cena'] = "podstawowa cena [zł/m]";
  1312. $layerConf['_agr_fields_to_cols']['koszt'] = "koszt [zł]";
  1313. $_schema['sub_costs']['Rozdzielcza_Zabruki'] = $layerConf;
  1314. }
  1315. {
  1316. $layerConf = array();
  1317. $layerConf['label'] = "Światłowód";
  1318. $layerConf['_agr_fields_to_cols'] = array();
  1319. $layerConf['_agr_fields_to_cols']['ilosc'] = "ilość [m]";
  1320. $layerConf['_agr_fields_to_cols']['cena'] = "podstawowa cena [zł/m]";
  1321. $layerConf['_agr_fields_to_cols']['koszt'] = "koszt [zł]";
  1322. {
  1323. $layerSubCostsConf = array();
  1324. $layerSubCostsConf['group_by_field'] = 'wlokien_j';
  1325. $layerSubCostsConf['sql_agr_func'] = array();
  1326. $layerSubCostsConf['sql_agr_func']['sum_dlugosc'] = array();//sum(Dlugosc) as sum_dlugosc
  1327. $layerSubCostsConf['sql_agr_func']['sum_dlugosc']['func'] = 'sum';
  1328. $layerSubCostsConf['sql_agr_func']['sum_dlugosc']['field'] = 'Dlugosc';
  1329. $layerSubCostsConf['labels'] = array();
  1330. $layerSubCostsConf['labels']['cost_type'] = "rodzaj kosztu";
  1331. $layerSubCostsConf['labels']['sum_dlugosc'] = "suma długości";
  1332. $layerConf['sub_costs'] = $layerSubCostsConf;
  1333. }
  1334. $_schema['sub_costs']['Rozdzielcza_Kabel_Swiatlowodowy_wsg84'] = $layerConf;
  1335. }
  1336. {
  1337. $layerConf = array();
  1338. $layerConf['label'] = "Studnie - TODO (Lokalizacje)";
  1339. $layerConf['_agr_fields_to_cols'] = array();
  1340. $_schema['sub_costs']['__STUDNIE__'] = $layerConf;
  1341. }
  1342. {
  1343. $layerConf = array();
  1344. $layerConf['label'] = "Rury osłonowe - TODO";
  1345. $layerConf['_agr_fields_to_cols'] = array();
  1346. $_schema['sub_costs']['Rura_oslonowa_rozdzielcza_magistralna'] = $layerConf;
  1347. }
  1348. {
  1349. $layerConf = array();
  1350. $layerConf['label'] = "Pakiet mikrorurek - TODO";
  1351. $layerConf['_agr_fields_to_cols'] = array();
  1352. $_schema['sub_costs']['__PAKIET_MIKRORUREK__'] = $layerConf;
  1353. }
  1354. {
  1355. $layerConf = array();
  1356. $layerConf['label'] = "Koszty dodatkowe - TODO";
  1357. $layerConf['_agr_fields_to_cols'] = array();
  1358. $_schema['sub_costs']['__KOSZTY_DODATKOWE__'] = $layerConf;
  1359. }
  1360. return $_schema;
  1361. }
  1362. public function getData($idProject, $admin = 0) {
  1363. static $_data = null;
  1364. if (!is_array($_data)) $_data = array();
  1365. if (!array_key_exists($idProject, $_data)) $_data[$idProject] = $this->fetchData($idProject, $admin);
  1366. return $_data[$idProject];
  1367. }
  1368. public function fetchData($idProject, $admin = 0) {
  1369. $data = array();
  1370. $schema = $this->getSchema();
  1371. $conf = $schema['config'];
  1372. $pdo = DB::getPDO();
  1373. foreach ($conf['layer'] as $idLayer => $layer) {
  1374. $layData = array();
  1375. $layData['label'] = $layer['label'];
  1376. {
  1377. if (!$layer['tabela_name']) continue;// TODO: throw error in validate
  1378. $tblName = $layer['tabela_name'];
  1379. $sqlIloscField = (!empty($layer['ilosc_field']))? $layer['ilosc_field'] : 'ID';
  1380. $sqlIlosc = ('SZTUKA' == $layer['jednostka'])? "count(1)" : "sum(t.{$sqlIloscField})";
  1381. $sqlZasobField = (!empty($layer['zasob_field']))? $layer['zasob_field'] : 'ID';
  1382. $sqlGroupBy = (!empty($layer['zasob_field']))? "group by t.{$sqlZasobField}" : '';
  1383. $sth = $pdo->prepare("
  1384. select t.{$sqlZasobField}
  1385. , {$sqlIlosc} as ilosc
  1386. from {$tblName} t
  1387. where t.ID_PROJECT = :id_project
  1388. {$sqlGroupBy}
  1389. ");
  1390. $sth->bindValue(':id_project', $idProject, PDO::PARAM_INT);
  1391. $sth->execute();
  1392. $rawLayData = $sth->fetchAll();
  1393. $layData['_raw'] = $rawLayData;
  1394. $layData['_rawSql'] = "
  1395. select t.{$sqlZasobField}
  1396. , sum(t.{$sqlIloscField}) as ilosc
  1397. from {$tblName} t
  1398. where t.ID_PROJECT = {$idProject}
  1399. {$sqlGroupBy}
  1400. ";
  1401. $iloscByType = array();
  1402. $hasIlosc = false;
  1403. foreach ($rawLayData as $d) {
  1404. if ($d['ilosc'] <= 0) continue;
  1405. $hasIlosc = true;
  1406. $idType = 0;
  1407. $iloscType = null;
  1408. DBG::_('DBG', '>1', "layer", $layer, __CLASS__, __FUNCTION__, __LINE__);
  1409. DBG::_('DBG', '>1', "conf", $conf, __CLASS__, __FUNCTION__, __LINE__);
  1410. if ('ZASOB' == $layer['zasob_type']) {
  1411. $iloscType = array();
  1412. $iloscType['type'] = trim($d[$sqlZasobField]);
  1413. $idType = array_search($iloscType['type'], $conf['type']);
  1414. $iloscType['idType'] = $idType;
  1415. $iloscType['jednostka'] = $layer['jednostka'];
  1416. $iloscType['ilosc'] = $d['ilosc'];
  1417. } else if ('ZASOB_ID' == $layer['zasob_type']) {
  1418. $iloscType = array();
  1419. $iloscType['type'] = $layer['zasob_label'];
  1420. $idType = (array_key_exists($layer['zasob_id'], $conf['type']))? $layer['zasob_id'] : null;
  1421. $iloscType['idType'] = $idType;
  1422. $iloscType['jednostka'] = $layer['jednostka'];
  1423. $iloscType['ilosc'] = $d['ilosc'];
  1424. } else {
  1425. // TODO: BUG
  1426. }
  1427. if (!empty($iloscType) && $idType) {
  1428. if (!array_key_exists($idType, $iloscByType)) {
  1429. $iloscByType[$idType] = $iloscType;
  1430. } else {
  1431. DBG::_('DBG', '>1', "merge stats {$idType}", array($iloscByType[$idType], $iloscType), __CLASS__, __FUNCTION__, __LINE__);
  1432. $iloscByType[$idType]['ilosc'] += $iloscType['ilosc'];
  1433. }
  1434. } else {
  1435. DBG::_('DBG', '>1', "skip stats", $d, __CLASS__, __FUNCTION__, __LINE__);
  1436. if ($admin) SE_Layout::alert('warning', "Pomijanie nieznanego oznaczenia '{$iloscType['type']}' w ilości {$iloscType['ilosc']} - warstwa '{$layer['label']}' ({$layer['tabela_name']})");
  1437. }
  1438. }
  1439. if ($hasIlosc) $layData['data'] = $iloscByType;
  1440. }
  1441. if (!empty($layData['data'])) $data[$idLayer] = $layData;
  1442. }
  1443. return $data;
  1444. }
  1445. public function _fetchKosztorysData($idProject) {
  1446. $project = array();
  1447. $schema = $this->getSchema();
  1448. if(0){// TEST join by ogc
  1449. $exampleOgcJoin = <<<OGC_JOIN
  1450. <wfs:Query typeNames="p5_default_db:IN7_MK_BAZA_DYSTRYBUCJI p5_default_db:ADMIN_USERS" aliases="p u">
  1451. <fes:Filter>
  1452. <fes:And>
  1453. <fes:PropertyIsEqualTo>
  1454. <fes:ValueReference>p/ID</fes:ValueReference>
  1455. <fes:Literal>{$idProject}</fes:Literal>
  1456. </fes:PropertyIsEqualTo>
  1457. <fes:PropertyIsEqualTo>
  1458. <fes:ValueReference>u/ADM_ACCOUNT<fes:ValueReference>
  1459. <fes:ValueReference>p/L_APPOITMENT_USER</fes:ValueReference>
  1460. </fes:PropertyIsEqualTo>
  1461. </fes:And>
  1462. </fes:Filter>
  1463. </wfs:Query>
  1464. OGC_JOIN;
  1465. }
  1466. $pdo = DB::getPDO();
  1467. {
  1468. $sth = $pdo->prepare("
  1469. select p.ID, p.M_DIST_DESC, p.L_APPOITMENT_USER
  1470. , p.koszt_wspolny
  1471. , p.koszt_na_budynek
  1472. , p.koszt_na_mieszkanie
  1473. , p.Agr_Rozdzielcza_Wykop_przedmiar_na_mikrorurki_ilosc
  1474. , p.Agr_Rozdzielcza_Wykop_przedmiar_na_mikrorurki_cena
  1475. , p.Agr_Rozdzielcza_Wykop_przedmiar_na_mikrorurki_koszt
  1476. , p.Agr_Rozdzielcza_Mikrokanalizacja_do_klienta_ilosc
  1477. , p.Agr_Rozdzielcza_Mikrokanalizacja_do_klienta_cena
  1478. , p.Agr_Rozdzielcza_Mikrokanalizacja_do_klienta_koszt
  1479. , p.Agr_metrow_mikrorurek_5szt
  1480. , p.Agr_metrow_mikrorurek_5szt_cena
  1481. , p.Agr_Rozdzielcza_Przeciski_110mm_ilosc
  1482. , p.Agr_Rozdzielcza_Przeciski_110mm_cena
  1483. , p.Agr_Rozdzielcza_Przeciski_110mm_koszt
  1484. , p.Agr_Rozdzielcza_Zabruki_ilosc
  1485. , p.Agr_Rozdzielcza_Zabruki_cena
  1486. , p.Agr_Rozdzielcza_Zabruki_koszt
  1487. , p.Agr_Rozdzielcza_wezly_ilosc
  1488. , p.Agr_Rozdzielcza_wezly_cena
  1489. , p.Agr_Rozdzielcza_wezly_koszt
  1490. , p.Agr_Rozdzielcza_koszty_dodatkowe_wsg84
  1491. , p.Agr_Rozdzielcza_rurociag_wsg84_ilosc
  1492. , p.Agr_Rozdzielcza_rurociag_wsg84_cena
  1493. , p.Agr_Rozdzielcza_rurociag_wsg84_koszt
  1494. , p.Agr_Rozdzielcza_Kabel_Swiatlowodowy_wsg84_ilosc
  1495. , p.Agr_Rozdzielcza_Kabel_Swiatlowodowy_wsg84_cena
  1496. , p.Agr_Rozdzielcza_Kabel_Swiatlowodowy_wsg84_koszt
  1497. , p.Agr_USERS2_MARKETING_ilosc
  1498. , p.Agr_USERS2_MARKETING_cena
  1499. , p.Agr_USERS2_MARKETING_koszt
  1500. , p.Agr_BUILDINGS_ilosc
  1501. from IN7_MK_BAZA_DYSTRYBUCJI p
  1502. where p.ID = :ID_PROJECT
  1503. -- TODO: check perms!
  1504. ");
  1505. $sth->bindValue('ID_PROJECT', $idProject, PDO::PARAM_INT);
  1506. $sth->execute();
  1507. $projectList = $sth->fetchAll();
  1508. if (empty($projectList)) throw new Exception("404 - Project Not Found");
  1509. $projectRaw = reset($projectList);
  1510. }
  1511. {
  1512. $project['nr'] = $projectRaw['ID'];
  1513. $project['title'] = $projectRaw['M_DIST_DESC'];
  1514. $project['owner_name'] = $this->fetchUserName($projectRaw['L_APPOITMENT_USER']);
  1515. $project['cost_total'] = $projectRaw['koszt_wspolny'];
  1516. foreach ($schema['sub_costs'] as $layerName => $layerConf) {
  1517. $values = array();
  1518. foreach ($layerConf['_agr_fields_to_cols'] as $fldName => $label) {
  1519. $values[$fldName] = V::get("Agr_{$layerName}_{$fldName}", '', $projectRaw);
  1520. }
  1521. $project['sub_costs'][$layerName] = $values;
  1522. if (!empty($layerConf['sub_costs'])) {
  1523. $sub_costs = array();
  1524. {
  1525. $groupByField = $layerConf['sub_costs']['group_by_field'];
  1526. $sqlFields = array();
  1527. foreach ($layerConf['sub_costs']['sql_agr_func'] as $fldName => $funcConf) {
  1528. $sqlFuncName = $funcConf['func'];
  1529. $sqlFuncField = $funcConf['field'];
  1530. $sqlFields[] = "{$sqlFuncName}(l.{$sqlFuncField}) as {$fldName}";
  1531. }
  1532. $sqlFields = implode(", ", $sqlFields);
  1533. $sth = $pdo->prepare("
  1534. select l.{$groupByField} as cost_type
  1535. , $sqlFields
  1536. from Rozdzielcza_Kabel_Swiatlowodowy_wsg84 l
  1537. where l.ID_PROJECT = :ID_PROJECT
  1538. group by l.{$groupByField}
  1539. ");
  1540. $sth->bindValue('ID_PROJECT', $idProject, PDO::PARAM_INT);
  1541. $sth->execute();
  1542. $sub_costs = $sth->fetchAll();
  1543. }
  1544. $project['sub_costs'][$layerName]['sub_costs'] = $sub_costs;
  1545. }
  1546. }
  1547. }
  1548. $project['_raw'] = $projectRaw;
  1549. return $project;
  1550. }
  1551. public function fetchUserName($userLogin) {
  1552. $userName = $userLogin;
  1553. // TODO: sql from ADMIN_USERS
  1554. return $userName;
  1555. }
  1556. }