StatsHelper.php 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068
  1. <?php
  2. Lib::loadClass('Windykacja_StatsModel');
  3. Lib::loadClass('Windykacja_FunkcjeL1');
  4. class Windykacja_StatsHelper {
  5. // TODO: `A_RECORD_UPDATE_DATE` aktualizowane tylko wraz ze statusem
  6. // TODO: statusy:
  7. // 1. Automatyczne wysłanie powiadomień do Abonentów o niezapłaconych fakturach drogą e-mailową
  8. // 5 dni roboczych po 10-go na okolo 5 dni przed blokadami
  9. // - blokada: ??? dni po ostatniej dacie platnosci - odczytac czy zablokowany z l2?
  10. // - 1 list - wezwanie - jesli min. 2 faktury - czyli 2 m-ce od 1 daty platnosci
  11. // - 2 list - wezwanie ostateczne - min. 300 zł
  12. public static function get_filter_selected() {
  13. $filter_selected = V::get('_f', '', $_GET);
  14. $filter_arr = self::get_filters();
  15. $filter_selected = (array_key_exists($filter_selected, $filter_arr))? $filter_selected : '';
  16. return $filter_selected;
  17. }
  18. public static function get_filter_selected_label() {
  19. $fltrLabel = '';
  20. $fltrSelected = self::get_filter_selected();
  21. if (!empty($fltrSelected)) {
  22. $fltrs = self::get_filters();
  23. $fltrLabel = V::get($fltrSelected, '', $fltrs);
  24. $fltrLabel = V::get(0, '', $fltrLabel);
  25. }
  26. return $fltrLabel;
  27. }
  28. public static function get_filters() {
  29. $filter_arr['stan_zero'] = array("stan zerowy");
  30. $filter_arr['10-ego'] = array("termin płatności faktur, saldo na -", 'desc'=>array("10-ego", "10-ego każdego miesiąca - termin płatnosci faktur oraz saldo na minusie"));
  31. $filter_arr['WAITING'] = array("termin płatności faktur", 'desc'=>array("10-ego", "10-ego każdego miesiąca - termin płatnosci faktur"));// z regulaminu
  32. $filter_arr['15'] = array("mail ponaglenie", 'desc'=>array("10-ego + 5", "10-ego + 5 dni roboczych"));
  33. $filter_arr['blokada'] = array("blokada", 'desc'=>array("pn, wt, śr około 25", "najbliższy pn, wt, śr do 25"));// najbliższy pn, wt, śr do 25-ego danego miesiąca
  34. $filter_arr['tel1'] = array("kontakt tel.", 'desc'=>array("", "Ostatni kontakt tel. ponad 3 m-ce temu"));
  35. $filter_arr['bad_address'] = array("błędny adres");
  36. $filter_arr['wezwanie1'] = array("wezwanie do zapłaty", 'desc'=>array("2 x FVat", "2 faktury"));
  37. $filter_arr['waiting-wezwanie2'] = array("oczekiwanie 7 dni od terminu płatności");
  38. $filter_arr['wezwanie2'] = array("ostateczne wezwanie do zapłaty, rozwiązanie umowy", 'desc'=>array("wezwanie + 14", "wezwanie + 14 dni"));
  39. $filter_arr['waiting-krd'] = array("min. 30 dni od ostatecznego wezwania");
  40. $filter_arr['krd'] = array("do przekazania do KRD", 'desc'=>array("wezwanie ost. + 60", "wezwanie ost. + 60 dni"));
  41. $filter_arr['waiting-sad'] = array("przekazano do KRD");
  42. $filter_arr['docs-in-sad'] = array("przekazać sprawę do sądu");// waiting-sad = 30 dni
  43. $filter_arr['sad'] = array("przekazano sprawę do sądu");
  44. $filter_arr['3 m-ce przed'] = array("3 m-ce przed przedawnieniem");// 3 m-ce przed przedawnieniem
  45. $filter_arr['po-terminie'] = array("po terminie");// 3 lata po dacie platnosci faktur
  46. $filter_arr['has_nr_sad'] = array("nr sprawy sąd");
  47. $filter_arr['has_nr_komornik'] = array("nr sprawy komornik");
  48. $filter_arr['has_ustalenia'] = array("ustalenia z klientem");
  49. $filter_arr['sad_and_komornik'] = array("sąd z komornik");
  50. $filter_arr['sad_bez_komornik'] = array("sąd bez komornik");
  51. $filter_arr['isMovedToVectra'] = array("przeniesieni do Vectra");
  52. return $filter_arr;
  53. }
  54. public static function get_by_user(&$user) {
  55. return DB::getPDO()->fetchFirstAsObject("
  56. select *
  57. from `USERS2_WINDYKACJA_STATUS` as w
  58. where w.`ID_BILLING_USERS` = :id_user
  59. ", [ ':id_user' => $user->ID ]);
  60. }
  61. /**
  62. * Auto update user stats.
  63. *
  64. * @returns boolean - status changed or not
  65. * @param $user - object return from function Windykacja_StatsModel::get_user_by_id
  66. * @param $billing_docs - user billing docs
  67. *
  68. * @used in task_update_stats - for all users
  69. * @used in Windykacja_View::user_historia_platnosci after view billing docs
  70. *
  71. * save HIST at status change to WAITING
  72. */
  73. public static function update_stats(&$user, &$billing_docs, $force = false) {
  74. $data_arr = array();
  75. if (!V::get('DBG_LAST_FVAT_PAY_TERM', '', $_GET)) {
  76. if ($user->A_STATUS_UPDATE_DATE >= date("Y-m-d") && !$force) {
  77. return;
  78. }
  79. }
  80. self::updateUserKoresp($user);
  81. $saldo = $billing_docs->get_saldo();
  82. $data_arr["A_STATUS_UPDATE_DATE"] = date("Y-m-d");
  83. $data_arr["A_RECORD_UPDATE_DATE"] = date("Y-m-d-H:i");
  84. $data_arr["A_RECORD_UPDATE_AUTHOR"] = "stat-update";
  85. $company = Windykacja_StatsModel::getOwnerCompany($user->ID_BILLING_USERS);
  86. $data_arr["ACCOUNT_NUMBER"] = Windykacja_FunkcjeL1::bankowy_make_nrach($company['NR_RACH_MASS_PAY'], $user->ID_BILLING_USERS, 0);
  87. $windykPerms = DB::getPDO()->fetchFirst(" select w.ID, w.A_ADM_COMPANY, w.A_CLASSIFIED from USERS2_WINDYKACJA_STATUS w where w.ID_BILLING_USERS = :id ", [ ':id' => $user->ID_BILLING_USERS ]);
  88. $companyPerms = DB::getPDO()->fetchFirst(" select c.ID, c.A_ADM_COMPANY, c.A_CLASSIFIED from COMPANIES c where c.ID = :id ", [ ':id' => $user->ID_BILLING_USERS ]);
  89. DBG::log([ 'windykPerms' => $windykPerms, 'companyPerms' => $companyPerms ], 'array', 'TODO:DBG:user perm from COMPANIES table');
  90. if ($windykPerms && $companyPerms) {
  91. if ($companyPerms['A_ADM_COMPANY'] != $windykPerms['A_ADM_COMPANY']) $data_arr['A_ADM_COMPANY'] = $companyPerms['A_ADM_COMPANY'];
  92. if ($companyPerms['A_CLASSIFIED'] != $windykPerms['A_CLASSIFIED']) $data_arr['A_CLASSIFIED'] = $companyPerms['A_CLASSIFIED'];
  93. }
  94. $data_arr["SERVICES_STREETS"] = Windykacja_StatsModel::getAllServicesStreetsCSV($user);
  95. $data_arr["BILLING_USER_NAME"] = DB::getPDO()->fetchValue("
  96. select concat(bua.`P_NAME`, ' ', bua.`P_NAME_SECOND`) as P_NAME
  97. from `BILLING_USERS_ADD` as bua
  98. left join `BILLING_USERS` as bu on ( bu.`ID` = bua.`id_users` )
  99. where bua.`id_users` = :id_user
  100. ", [ ':id_user' => $user->ID_BILLING_USERS ]);
  101. $data_arr["BILLING_USER_TEL"] = DB::getPDO()->fetchValue("
  102. select c.P_PHONE
  103. from `COMPANIES` as c
  104. where c.ID = :id_user
  105. ", [ ':id_user' => $user->ID_BILLING_USERS ]);
  106. $data_arr["BILLING_USER_TEL"] = self::fixPhoneNumberFieldFormat($data_arr["BILLING_USER_TEL"]);
  107. $data_arr["BILLING_USER_ADRES"] = DB::getPDO()->fetchValue("
  108. select concat(bua.P_ADDRESS_POST_CODE, ' ', bua.P_ADDRESS_CITY, ' ', bua.P_ADDRESS_STREET, ' ', bua.P_ADDRESS_HOME, '/', bua.P_ADDRESS_HOUSE) as P_NAME
  109. from `BILLING_USERS_ADD` as bua
  110. left join `BILLING_USERS` as bu on ( bu.`ID` = bua.`id_users` )
  111. where bua.`id_users` = :id_user
  112. ", [ ':id_user' => $user->ID_BILLING_USERS ]);
  113. $data_arr["BILLING_OWNER_NAME"] = DB::getPDO()->fetchValue("
  114. select ( select bo.name1 from BILLING_OWNER bo where bo.ID = bu.BILLING_OWNER ) as BILLING_OWNER_NAME
  115. from `BILLING_USERS` as bu
  116. where bu.ID = :id_user
  117. ", [ ':id_user' => $user->ID_BILLING_USERS ]);
  118. // set default values
  119. //$data_arr["A_STATUS"] = "WAITING";
  120. //$data_arr["PAY_FVAT"] = 0;
  121. //$data_arr["PAY_DATE"] = "0000-00-00";
  122. // update values
  123. {// LAST_PAY_DATE
  124. $lastPayDoc = $billing_docs->get_last_pay_doc();
  125. if ($lastPayDoc) {
  126. $data_arr["LAST_PAY_DATE"] = $lastPayDoc->get('BILL_DATE');
  127. $data_arr["LAST_PAY_VALUE"] = $lastPayDoc->get('MA');
  128. if(V::get('DBG_LAST_FVAT_PAY_TERM', '', $_GET)){echo'<pre>lastPayDoc: ';print_r($lastPayDoc);echo'</pre>';}
  129. }
  130. }
  131. $data_arr["PAY_SALDO"] = $saldo;
  132. $data_arr["PAY_SALDO_30_DNI"] = $billing_docs->get_saldo_30_dni();
  133. $data_arr["PAY_SALDO_ISSUED"] = $billing_docs->get_saldo_issued();
  134. $data_arr["PAY_FVAT"] = 0;
  135. $data_arr["PAY_DATE_FIRST_FVAT"] = '0000-00-00';
  136. $lastFvatDoc = $billing_docs->get_last_fvat_doc();
  137. if(V::get('DBG_LAST_FVAT_PAY_TERM', '', $_GET)){echo'<pre>lastFvatDoc: ';print_r($lastFvatDoc);echo'</pre>';}
  138. if ($lastFvatDoc) {
  139. $data_arr["LAST_FVAT_PAY_TERM"] = $lastFvatDoc->get('PAYMENT_TERM');
  140. $data_arr["LAST_FVAT_SELL_DATE"] = $lastFvatDoc->get('SELL_DATE');
  141. $data_arr["LAST_FVAT_VALUE"] = $lastFvatDoc->get('WINIEN');
  142. }
  143. if ($saldo <= -0.05) {
  144. $fvat_arr = $billing_docs->get_unpaid_fvat();
  145. $data_arr["PAY_FVAT"] = count($fvat_arr);
  146. if (count($fvat_arr) > 0) {
  147. foreach ($fvat_arr as $v_fvat) {
  148. if (!isset($data_arr["PAY_DATE"]) || $v_fvat['PAYMENT_TERM'] > $data_arr["PAY_DATE"]) {
  149. $data_arr["PAY_DATE"] = $v_fvat['PAYMENT_TERM'];
  150. }
  151. if ('0000-00-00' == $data_arr["PAY_DATE_FIRST_FVAT"] || $v_fvat['PAYMENT_TERM'] < $data_arr["PAY_DATE_FIRST_FVAT"]) {
  152. $data_arr["PAY_DATE_FIRST_FVAT"] = $v_fvat['PAYMENT_TERM'];
  153. }
  154. }
  155. }
  156. }
  157. // zmiana statusu na kolejny wg. salda
  158. switch ($user->A_STATUS) {
  159. case 'WAITING':// auto
  160. if ($user->wezwanie1_DATE == '0000-00-00') {
  161. if ($saldo <= -0.05) {
  162. $fvat_arr = $billing_docs->get_unpaid_fvat();
  163. if (count($fvat_arr) > 1) {
  164. $data_arr["A_STATUS"] = "wezwanie1";
  165. }
  166. }
  167. }
  168. else if ($user->wezwanie2_DATE == '0000-00-00') {
  169. $data_arr["A_STATUS"] = "waiting-wezwanie2";
  170. }
  171. else {
  172. $data_arr["A_STATUS"] = "wezwanie2";
  173. }
  174. break;
  175. case 'wezwanie1':// wymaga `PAY_TERM`, `wezwanie1_DATE`, `ID_KORESP`
  176. break;
  177. case 'waiting-wezwanie2':// auto -> wezwanie2
  178. if ($user->wezwanie2_DATE == '0000-00-00') {
  179. $payTermArr = explode('-', $user->PAY_TERM);// Y-m-d
  180. $payTermPlus7dni = date("Y-m-d", mktime(0,0,0, intval($payTermArr[1]), intval($payTermArr[2]) + 7, intval($payTermArr[0])));
  181. // TODO: data +7 dni od terminu płatności (PAY_TERM) / mktime ($user->PAY_TERM + 7 dni)
  182. if ($user->PAY_TERM != '0000-00-00' && $payTermPlus7dni < date('Y-m-d')) {
  183. $data_arr["A_STATUS"] = "wezwanie2";
  184. }
  185. }
  186. break;
  187. case 'wezwanie2':// wymaga `PAY_TERM`, `wezwanie2_DATE`, `ID_KORESP`
  188. break;
  189. case 'waiting-krd':// auto -> krd jesli minelo 30 dni od wystawienia wezwanie2
  190. if ($user->wezwanie2_DATE != '0000-00-00') {
  191. $wzw2 = new stdClass();
  192. $wzw2->Y = intval(substr($user->wezwanie2_DATE, 0, 4));
  193. $wzw2->m = intval(substr($user->wezwanie2_DATE, 5, 2));
  194. $wzw2->d = intval(substr($user->wezwanie2_DATE, 8, 2));
  195. $wzw2->plus_30 = date("Y-m-d", mktime(0,0,0, $wzw2->m, $wzw2->d + 30, $wzw2->Y));
  196. if ($wzw2->plus_30 < date("Y-m-d")) {
  197. $data_arr["A_STATUS"] = "krd";
  198. }
  199. }
  200. break;
  201. case 'waiting-sad':// auto -> sad jesli minelo 30 dni od wpisania do krd (wpis_w_krd_DATE)
  202. if ($user->wpis_w_krd_DATE != '0000-00-00') {
  203. $krdDate = new stdClass();
  204. $krdDate->Y = intval(substr($user->wpis_w_krd_DATE, 0, 4));
  205. $krdDate->m = intval(substr($user->wpis_w_krd_DATE, 5, 2));
  206. $krdDate->d = intval(substr($user->wpis_w_krd_DATE, 8, 2));
  207. $krdDate->plus_30 = date("Y-m-d", mktime(0,0,0, $krdDate->m, $krdDate->d + 30, $krdDate->Y));
  208. if ($krdDate->plus_30 < date("Y-m-d")) {
  209. $data_arr["A_STATUS"] = "docs-in-sad";
  210. }
  211. }
  212. break;
  213. default:
  214. }
  215. // zmiana statusu na czysty - WAITING
  216. if ($saldo > -0.05 || $data_arr["PAY_FVAT"] < 2) {
  217. if (!in_array($user->A_STATUS, array('waiting-sad', 'docs-in-sad', 'sad'))) {
  218. $data_arr["A_STATUS"] = "WAITING";
  219. $data_arr["wezwanie2_DATE"] = '0000-00-00';
  220. $data_arr["wezwanie1_DATE"] = '0000-00-00';
  221. //$data_arr["PAY_DATE"] = '0000-00-00';// TODO: ?
  222. }
  223. }
  224. {
  225. $hasActiveNET = 0;
  226. $hasActiveTV = 0;
  227. $isMovedToVectra = 0;
  228. $statsActiveVectra = DB::getPDO()->fetchFirst("
  229. select
  230. IF(1 = (
  231. select 1 as hasActiveNET
  232. from `SERVICES` srv
  233. where srv.`ID_BILLING_USERS` = :id_user
  234. and srv.`NAME_LIST_SERVICES`='USERS2'
  235. and 'NORMAL'=A_STATUS_L2_SQL_L1(srv.`ID`)
  236. limit 1
  237. ), 1, 0) as hasActiveNET
  238. ,
  239. IF(1 = (
  240. select 1 as hasActiveTV
  241. from `SERVICES` srv
  242. where srv.`ID_BILLING_USERS` = :id_user
  243. and srv.`NAME_LIST_SERVICES`='TV'
  244. and 'NORMAL'=A_STATUS_L2_SQL_L1(srv.`ID`)
  245. limit 1
  246. ), 1, 0) as hasActiveTV
  247. ,
  248. IF(1 = ('REZYGNACJA_Z_PRZEJSCIEM_DO_VECTRA'=(select `RODZAJ_DZIALANIA_HANDLOWEGO`
  249. from `DEALS_TABLE`
  250. where `A_STATUS`='NORMAL'
  251. and `ID_BILLING_USERS` = :id_user
  252. order by `ID` DESC
  253. limit 1)
  254. ), 1, 0) as IS_MOVED_TO_VECTRA
  255. ", [ ':id_user' => $user->ID ]);
  256. DBG::_('DBG_ACTIVE_SRV', '>2', "DBG_ACTIVE_SRV sql", $sql, __CLASS__, __FUNCTION__, __LINE__);
  257. if ($statsActiveVectra) {
  258. $hasActiveNET = V::get('hasActiveNET', '', $statsActiveVectra);
  259. $hasActiveTV = V::get('hasActiveTV', '', $statsActiveVectra);
  260. $isMovedToVectra = V::get('IS_MOVED_TO_VECTRA', '', $statsActiveVectra);
  261. }
  262. $data_arr['HAS_ACTIVE_NET'] = $hasActiveNET;
  263. $data_arr['HAS_ACTIVE_TV'] = $hasActiveTV;
  264. $data_arr['IS_MOVED_TO_VECTRA'] = $isMovedToVectra;
  265. }
  266. if(V::get('DBG_LAST_FVAT_PAY_TERM', '', $_GET)){echo'<pre>data_arr #' . __LINE__ . ': ';print_r($data_arr);echo'</pre>';}
  267. DB::getPDO()->update('USERS2_WINDYKACJA_STATUS', 'ID', $user->WINDYKACJA_ID, $data_arr);
  268. // update HIST - tylko zmiana na WAITING - powrót do oczekujących
  269. if (isset($data_arr["A_STATUS"]) && $data_arr["A_STATUS"] == "WAITING" && $user->A_STATUS != "WAITING") {
  270. DB::getPDO()->insert('USERS2_WINDYKACJA_STATUS_HIST', array_merge($data_arr, [
  271. 'ID_USERS2' => $user->WINDYKACJA_ID,
  272. ]));
  273. }
  274. }
  275. static function fixPhoneNumberFieldFormat($tel) {
  276. // @see https://pl.wikipedia.org/wiki/Numer_telefonu
  277. $tel = trim(str_replace(["/"], " ", $tel));
  278. $tel = str_replace([ "-" ], "", $tel);
  279. $tel = str_replace(" ", " ", $tel);
  280. if (preg_match_all("/^\d{3} \d{3} \d{3}\$/", $tel, $matches) > 0) {
  281. return str_replace([ " " ], "", $tel);
  282. }
  283. if (preg_match_all("/^\+48 \d{3} \d{2} \d{2}\$/", $tel, $matches) > 0) {
  284. return "+48 " . str_replace(" ", "", substr($tel, strlen("+48")));
  285. }
  286. if (preg_match_all("/^\+48 \d{2} \d{3} \d{2} \d{2}\$/", $tel, $matches) > 0) {
  287. return "+48 " . str_replace(" ", "", substr($tel, strlen("+48")));
  288. }
  289. if (preg_match_all("/^\+48 \(\d{2}\) \d{3} \d{2} \d{2}\$/", $tel, $matches) > 0) {
  290. return "+48 " . str_replace([" ", "(", ")"], "", substr($tel, strlen("+48")));
  291. }
  292. if (preg_match_all("/^\(\+48\) \(?\d{2}\)? \d{3} \d{2} \d{2}\$/", $tel, $matches) > 0) {
  293. return "+48 " . str_replace([" ", "(", ")"], "", substr($tel, strlen("(+48)")));
  294. }
  295. if (preg_match_all("/^48 \(\d{2}\) \d{3} \d{2} \d{2}\$/", $tel, $matches) > 0) {
  296. return "+48 " . str_replace([" ", "(", ")"], "", substr($tel, strlen("48")));
  297. }
  298. if (preg_match_all("/^\d{2} \d{7}\$/", $tel, $matches) > 0) {
  299. return "+48 " . str_replace(" ", "", $tel);
  300. }
  301. if (preg_match_all("/^\+48\d{9}\$/", $tel, $matches) > 0) {
  302. return "+48 " . substr($tel, strlen("+48"));
  303. }
  304. // if (preg_match_all("/^(58)?[ ]?\d{3}[ ]?\d{2}[ ]?\d{2}\$/", $tel, $matches) > 0) {
  305. // $tel = str_replace(" ", " ", $tel);
  306. // return str_replace([ " " ], "", $tel);
  307. // }
  308. if (preg_match_all("/^\d{9} \d{9}\$/", $tel, $matches) > 0) {
  309. return str_replace(" ", ", ", $tel);
  310. }
  311. return $tel;
  312. }
  313. static function test__fixPhoneNumberFieldFormat() {
  314. $examples = [];
  315. $examples[] = [ "+48 58 325 42 74", "+48 583254274" ];
  316. $examples[] = [ "+48607451902", "+48 607451902" ];
  317. $examples[] = [ "502 757 004", "502757004" ];
  318. $examples[] = [ "695250652, 223803000", "695250652, 223803000" ];
  319. $examples[] = [ "660747288 586825221", "660747288, 586825221" ];
  320. $examples[] = [ "694-110-000", "694110000" ];
  321. $examples[] = [ "+420 603158417", "+420 603158417" ]; // +420 Czechy
  322. $examples[] = [ "58/ 30-40-050", "+48 583040050" ];
  323. $examples[] = [ "58/326-01-00", "+48 583260100" ];
  324. $examples[] = [ "48 (22) 555 56 01", "+48 225555601" ];
  325. $examples[] = [ "(+48) 58 341 40 11", "+48 583414011" ];
  326. $examples[] = [ "(22) 782 35 20 (30)", "+48 227823520 (30)" ]; // ??
  327. $examples[] = [ "95 7336200", "+48 957336200" ];
  328. UI::table([
  329. 'rows' => array_map(function ($test) {
  330. $tel = $test[0];
  331. $expected = $test[1];
  332. $result = self::fixPhoneNumberFieldFormat($tel);
  333. return [
  334. 'in' => $tel,
  335. 'out' => $result,
  336. 'passed' => ($result === $expected) ? "OK" : "ERR",
  337. 'expected' => $expected,
  338. ];
  339. }, $examples),
  340. ]);
  341. }
  342. public static function updateUserKoresp($user) {
  343. DB::getPDO()->execSql("
  344. insert into `USERS2_WINDYKACJA_STATUS_HIST` (
  345. `A_RECORD_UPDATE_DATE`
  346. , `A_RECORD_UPDATE_AUTHOR`
  347. , `ID_USERS2`
  348. , `ID_KORESP`
  349. , `A_STATUS_UPDATE_DATE`
  350. )
  351. select
  352. NOW() as `A_RECORD_UPDATE_DATE`
  353. , 'auto-update-koresp-hist' as `A_RECORD_UPDATE_AUTHOR`
  354. , w.`ID` as `ID_USERS2`
  355. , k.`ID` as `ID_KORESP`
  356. , k.`K_DATA_OTRZYM_KORESP` as `A_STATUS_UPDATE_DATE`
  357. from `USERS2_WINDYKACJA_STATUS` w
  358. join `IN7_DZIENNIK_KORESP` k on (k.`ID_BILLING_USERS`=w.`ID_BILLING_USERS`)
  359. left join `USERS2_WINDYKACJA_STATUS_HIST` h on (h.`ID_USERS2`=w.`ID` and h.`ID_KORESP`=k.`ID`)
  360. where 1=1
  361. and h.ID is null
  362. and w.`ID_BILLING_USERS` = :id_user
  363. ", [ ':id_user' => $user->ID_BILLING_USERS ]);
  364. }
  365. public static function &get_phone_status_array(&$user) {
  366. $ret = array();
  367. $status_info = self::get_phone_status_info($user);
  368. foreach ($status_info as $k => $v) {
  369. $ret[$k] = $v['label'];
  370. }
  371. return $ret;
  372. }
  373. /**
  374. * @param $user
  375. *
  376. * @returns array of 'label', 'date' -> nowy PAY_TERM ustalony wg. aktualnego stanu
  377. */
  378. public static function get_phone_status_info($user) {
  379. $ret = array();
  380. $ret['nie_zaplaci'] = array('label'=>"nie zapłaci", 'date'=>'');
  381. $today = date("Y-m-d");
  382. $date = date("Y-m-d");
  383. {// PAY_TERM jesli jest ustalony np. z wewaznie1 lub wezwanie2
  384. if ($user->PAY_TERM != '0000-00-00') {
  385. if ($user->PAY_TERM > $today) {
  386. // jest już ustalona data platnosci na przyszłość
  387. $date = $user->PAY_TERM;
  388. }
  389. }
  390. }
  391. if ($date > $today) {// data platnosci w przyszlosci -> ok
  392. {// zapłaci w terminie today +14 dni lub PAY_TERM jesli jest ustalony np. z wewaznie1 lub wezwanie2
  393. $ret['zaplaci_w_terminie'] = array('label'=>"zapłaci w terminie", 'date'=>$date);
  394. }
  395. }
  396. else {// data platnosci w przeszlosci - przeterminowana -> ustalic nowa (+14,+1mc,+2mc,+3mc)
  397. {// zapłaci w terminie today +14 dni lub PAY_TERM jesli jest ustalony np. z wewaznie1 lub wezwanie2
  398. $date = date("Y-m-d", mktime(0,0,0,date('m'), date('d') + 14, date('Y')));
  399. $ret['zaplaci_w_terminie'] = array('label'=>"zapłaci w terminie", 'date'=>$date);
  400. }
  401. {// zaplaci za 1-mc pozniej
  402. $date = date("Y-m-d", mktime(0,0,0,date('m') + 1, date('d'), date('Y')));
  403. $ret['zaplaci_za_1mc'] = array('label'=>"zapłaci miesiąc później", 'date'=>$date);
  404. }
  405. {// zaplaci za 2-mce pozniej
  406. $date = date("Y-m-d", mktime(0,0,0,date('m') + 2, date('d'), date('Y')));
  407. $ret['zaplaci_za_2mc'] = array('label'=>"zapłaci 2 miesiące później", 'date'=>$date);
  408. }
  409. {// zaplaci za 3-mce pozniej
  410. $date = date("Y-m-d", mktime(0,0,0,date('m') + 3, date('d'), date('Y')));
  411. $ret['zaplaci_za_3mc'] = array('label'=>"zapłaci 3 miesiące później", 'date'=>$date);
  412. }
  413. }
  414. $ret['nie_odbiera'] = array('label'=>"nie obiera lub wyłączony telefon", 'date'=>'');
  415. $ret['zly_numer'] = array('label'=>"zły numer telefonu", 'date'=>'');
  416. return $ret;
  417. }
  418. public static function get_sms_status_info($user, $terminPlatnosci = '') {
  419. $ret = array();
  420. $today = date("Y-m-d");
  421. $due_date = $user->PAY_TERM;// ustalowny pay term
  422. $zaleglosc = number_format($user->PAY_SALDO, 2, ',', '');
  423. if ($user->PAY_SALDO <= -0.05) {
  424. $msg = "Twoje saldo na dzien {$today} wynosi {$zaleglosc} zl.\n";
  425. if (strlen($terminPlatnosci) == 10 && $terminPlatnosci > date("Y-m-d")) {
  426. $msg .= "Prosimy o uregulowanie w/w zaleglosci w terminie do {$terminPlatnosci}.";
  427. } else {
  428. $msg .= "Prosimy o niezwloczne uregulowanie zaleglosci.";
  429. }
  430. if ($due_date > $today) {
  431. // $msg .= "Prosimy o uregulowanie zaleglosci do dnia {$due_date} r.";
  432. } else {
  433. }
  434. $ret['Powiadomienie SMS o zaleglosciach'] = array('label'=>"Windykacja: Powiadomienie SMS o zaleglosciach", 'msg'=>$msg);
  435. // Z powodu niedotrzymania terminu płatności nastąpi blokada usług. Dowód wpłaty w kwocie #Saldo# zł prosimy przesłać na bok@biall.net.pl. Szczegóły 587277777.
  436. $doZaplaty = number_format(-1 * $user->PAY_SALDO, 2, ',', '');
  437. $msgBlokada = "Z powodu niedotrzymania terminu platnosci nastapi blokada uslug. Dowod wplaty w kwocie {$doZaplaty} zl prosimy przeslac na bok@biall.net.pl. Szczegoly 587277777.";
  438. $ret['Powiadomienie SMS o blokadzie'] = array('label'=>"Windykacja: Powiadomienie SMS o blokadzie", 'msg'=>$msgBlokada);
  439. }
  440. return $ret;
  441. }
  442. /*
  443. <html><body>Informujemy Pana/Pania o zalegosci w platnosciach w wysokosci 109.16 zl. Prosimy o uregulowanie w/w zaleglosci w terminie do 31.03.2015 r.<br>W przypadku watpliwosci prosimy o kontakt z Biurem Obslugi Klienta. <p>BIALL-NET Sp. z o.o. <br><br>Biuro Obslugi Klienta:<br>tel. 58 741 84 10<br>fax 58 741 84 30</body></html>
  444. */
  445. public static function get_mail_status_info($user, $terminPlatnosci = '') {
  446. $ret = array();
  447. $today = date("Y-m-d");
  448. $due_date = $user->PAY_TERM;// ustalowny pay term
  449. $zaleglosc = number_format(abs($user->PAY_SALDO), 2, ',', '');
  450. if ($user->PAY_SALDO <= -0.05) {
  451. $msg = "Informujemy Pana/Pania o zalegosci w platnosciach w wysokosci {$zaleglosc} zl.\n";
  452. if (strlen($terminPlatnosci) == 10 && $terminPlatnosci > date("Y-m-d")) {
  453. $msg .= "Prosimy o uregulowanie w/w zaleglosci w terminie do {$terminPlatnosci}.";
  454. } else {
  455. $msg .= "Prosimy o niezwloczne uregulowanie zaleglosci.";
  456. }
  457. $msg .= "<br>W przypadku watpliwosci prosimy o kontakt z Biurem Obslugi Klienta.";
  458. $msg .= "<p>BIALL-NET Sp. z o.o.</p>";
  459. if ($due_date > $today) {
  460. // $msg .= "Prosimy o uregulowanie zaleglosci do dnia {$due_date} r.";
  461. } else {
  462. }
  463. $ret['Powiadomienie o zaleglosciach'] = array('label'=>"Windykacja: Powiadomienie o zaleglosciach", 'msg'=>$msg);
  464. }
  465. return $ret;
  466. }
  467. /**
  468. * Update user phone status.
  469. *
  470. * @returns boolean - status changed or not
  471. * @param $user - object return from function Windykacja_StatsModel::get_user_by_id
  472. * @param $phone_status - phone status
  473. *
  474. */
  475. public static function update_phone_status($user, $phone_status) {
  476. $data_arr = array();
  477. $data_arr["A_RECORD_UPDATE_DATE"] = date("Y-m-d-H:i");
  478. $data_arr["A_RECORD_UPDATE_AUTHOR"] = $_SESSION['ADM_ACCOUNT'];
  479. $data_arr["LAST_PHONE_STATUS"] = $phone_status;
  480. $data_arr["LAST_PHONE_STATUS_DATE"] = date("Y-m-d");
  481. $status_info = self::get_phone_status_info($user);
  482. if (array_key_exists($phone_status, $status_info)) {
  483. $date = V::get('date', '', $status_info[$phone_status]);
  484. if ($date != '' && $date != '0000-00-00') {
  485. $data_arr["PAY_TERM"] = $date;
  486. }
  487. }
  488. DB::getPDO()->update('USERS2_WINDYKACJA_STATUS', 'ID', $user->WINDYKACJA_ID, $data_arr);
  489. DB::getPDO()->insert('USERS2_WINDYKACJA_STATUS_HIST', array_merge($data_arr, [
  490. 'ID_USERS2' => $user->WINDYKACJA_ID,
  491. ]));
  492. return true;
  493. }
  494. public static function update_sms_status($user, $sms_status) {
  495. $data_arr = array();
  496. $status_info = self::get_sms_status_info($user);
  497. //echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;">$sms_status ';print_r($sms_status);echo'</pre>';
  498. //echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;">$status_info ';print_r($status_info);echo'</pre>';
  499. if (!array_key_exists($sms_status, $status_info)) {
  500. echo '<div class="alert alert-danger">Nieznany status!</div>';
  501. return false;
  502. }
  503. $db_webone = DB::getPDO('931');
  504. if (!$db_webone) {
  505. echo '<div class="alert alert-danger">Brak połączenia do bazy billing!</div>';
  506. return false;
  507. }
  508. $msgId = $db_webone->insert('HIST_CONTACTS', [
  509. 'ID_BILLING_USERS' => $user->ID,
  510. 'SUBJECT' => $status_info[$sms_status]['label'],
  511. 'BODY_HTML' => $status_info[$sms_status]['msg'],
  512. 'REQUEST_STATUS_SMS' => "SENT_SMS",
  513. ]);
  514. //echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;">$msgId ';print_r($msgId);echo'</pre>';
  515. $data_arr["A_RECORD_UPDATE_DATE"] = date("Y-m-d-H:i");
  516. $data_arr["A_RECORD_UPDATE_AUTHOR"] = $_SESSION['ADM_ACCOUNT'];
  517. $data_arr["LAST_SMS_MSG_ID"] = $msgId;
  518. $data_arr["LAST_SMS_STATUS"] = $sms_status;
  519. $data_arr["LAST_PHONE_STATUS_DATE"] = date("Y-m-d");
  520. if (array_key_exists($sms_status, $status_info)) {
  521. $date = V::get('date', '', $status_info[$sms_status]);
  522. if ($date != '' && $date != '0000-00-00') {
  523. $data_arr["PAY_TERM"] = $date;
  524. }
  525. }
  526. DB::getPDO()->update('USERS2_WINDYKACJA_STATUS', 'ID', $user->WINDYKACJA_ID, $data_arr);
  527. DB::getPDO()->insert('USERS2_WINDYKACJA_STATUS_HIST', array_merge($data_arr, [
  528. 'ID_USERS2' => $user->WINDYKACJA_ID,
  529. ]));
  530. return true;
  531. }
  532. public static function update_mail_status($user, $mail_status) {
  533. $data_arr = array();
  534. $status_info = self::get_mail_status_info($user);
  535. //echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;">$mail_status ';print_r($mail_status);echo'</pre>';
  536. //echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;">$status_info ';print_r($status_info);echo'</pre>';
  537. if (!array_key_exists($mail_status, $status_info)) {
  538. echo '<div class="alert alert-danger">Nieznany status!</div>';
  539. return false;
  540. }
  541. $db_webone = DB::getPDO('931');
  542. if (!$db_webone) {
  543. echo '<div class="alert alert-danger">Brak połączenia do bazy billing!</div>';
  544. return false;
  545. }
  546. $msgId = $db_webone->insert('HIST_CONTACTS', [
  547. 'ID_BILLING_USERS' => $user->ID,
  548. 'SUBJECT' => $status_info[$mail_status]['label'],
  549. 'BODY_HTML' => "<html><body>{$status_info[$mail_status]['msg']}</body></html>",
  550. 'REQUEST_STATUS_MAIL' => "CONFIRM_SENT_MAIL",
  551. ]);
  552. echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;">$msgId ';print_r($msgId);echo'</pre>';
  553. $data_arr["A_RECORD_UPDATE_DATE"] = date("Y-m-d-H:i");
  554. $data_arr["A_RECORD_UPDATE_AUTHOR"] = $_SESSION['ADM_ACCOUNT'];
  555. $data_arr["LAST_MAIL_MSG_ID"] = $msgId;
  556. $data_arr["LAST_MAIL_STATUS"] = $mail_status;
  557. $data_arr["LAST_PHONE_STATUS_DATE"] = date("Y-m-d");
  558. if (array_key_exists($mail_status, $status_info)) {
  559. $date = V::get('date', '', $status_info[$mail_status]);
  560. if ($date != '' && $date != '0000-00-00') {
  561. $data_arr["PAY_TERM"] = $date;
  562. }
  563. }
  564. DB::getPDO()->update('USERS2_WINDYKACJA_STATUS', 'ID', $user->WINDYKACJA_ID, $data_arr);
  565. DB::getPDO()->insert('USERS2_WINDYKACJA_STATUS_HIST', array_merge($data_arr, [
  566. 'ID_USERS2' => $user->WINDYKACJA_ID,
  567. ]));
  568. return true;
  569. }
  570. public static function update_old_id_koresp(&$user, $id_koresp, $koresp_type) {
  571. $koresp = DB::getPDO()->fetchFirst("
  572. select *
  573. from IN7_DZIENNIK_KORESP
  574. where ID = :id
  575. ", [ ':id' => $id_koresp ]);
  576. if (!$koresp) {
  577. return false;
  578. }
  579. // check if ID koresp already exists in HIST table!
  580. // $sql = "select wh.`ID`,wh.``,wh.`` from `USERS2_WINDYKACJA_STATUS_HIST` as wh where ";
  581. DB::getPDO()->insert('USERS2_WINDYKACJA_STATUS_HIST', [
  582. 'ID_USERS2' => $user->WINDYKACJA_ID,
  583. 'A_RECORD_UPDATE_DATE' => date("Y-m-d-H:i"),
  584. 'A_RECORD_UPDATE_AUTHOR' => $_SESSION['ADM_ACCOUNT'],
  585. 'ID_KORESP' => $id_koresp,
  586. //'A_STATUS_UPDATE_DATE' => $koresp['K_DATA_OTRZYMANEJ_KORESP'], // data utworzenia
  587. 'A_STATUS_UPDATE_DATE' => $koresp['K_DATA_OTRZYM_KORESP'], // data wyslania
  588. // $koresp_type ?
  589. ]);
  590. return true;
  591. }
  592. /**
  593. * @returns int - ID Koresp or null if error
  594. */
  595. public static function update_bok_rozwiazanie_umowy(&$user, $id_proj, $nr_umowy, $powod, $powod_desc, $termin_odlaczenia, &$msg_log) {
  596. $data_arr = array();
  597. if ($id_proj <= 0 || $nr_umowy <= 0 || $powod = '') {
  598. return null;
  599. }
  600. $new_id_deals = Windykacja_StatsModel::create_deals_rozwiazanie($user->ID, $nr_umowy, $termin_odlaczenia, $powod_desc);
  601. if (!$new_id_deals) {
  602. $msg_log[] = "Nie udało się utworzyć rekordu w DEALS_TABLE";
  603. return null;
  604. }
  605. $msg_log[] = "Utworzonno rekord w DEALS_TABLE ID={$new_id_deals}";
  606. $new_id_koresp = Windykacja_StatsModel::create_koresp($user, 'rozwiazanie umowy', $id_proj, array('nr_umowy'=>$nr_umowy, 'powod'=>$powod, 'powod_desc'=>$powod_desc));
  607. if (!$new_id_koresp) {
  608. $msg_log[] = "Nie udało się utworzyć rekordu KORESP";
  609. return null;
  610. }
  611. $msg_log[] = "Utworzonno rekord KORESP ID={$new_id_koresp}";
  612. $data_arr["ID_KORESP"] = $new_id_koresp;
  613. $data_arr["params"] = "rozwiazanie umowy,{$nr_umowy},{$powod},{$termin_odlaczenia},{$new_id_deals}";
  614. $data_arr["A_STATUS_UPDATE_DATE"] = date("Y-m-d");// zawsze podana jesli jest zmiana A_STATUS
  615. $data_arr["A_RECORD_UPDATE_DATE"] = date("Y-m-d-H:i");
  616. $data_arr["A_RECORD_UPDATE_AUTHOR"] = $_SESSION['ADM_ACCOUNT'];
  617. DB::getPDO()->update('USERS2_WINDYKACJA_STATUS', 'ID', $user->WINDYKACJA_ID, $data_arr);
  618. // update $user data
  619. foreach ($data_arr as $k => $v) {
  620. $user->$k = $v;
  621. }
  622. DB::getPDO()->insert('USERS2_WINDYKACJA_STATUS_HIST', array_merge($data_arr, [ 'ID_USERS2' => $user->WINDYKACJA_ID ]));
  623. return $new_id_koresp;
  624. }
  625. public static function update_users_table() {
  626. if (!isset($_SESSION['USERS2_WINDYKACJA_PANEL'])) $_SESSION['USERS2_WINDYKACJA_PANEL'] = array();
  627. $_SESSION['USERS2_WINDYKACJA_PANEL']['_initialized'] = 0;// always actualize
  628. if (0 == V::get('_initialized', 0, $_SESSION['USERS2_WINDYKACJA_PANEL'], 'int')) {
  629. DB::getPDO()->execSql("
  630. insert ignore into `USERS2_WINDYKACJA_STATUS` (`ID_BILLING_USERS`, `A_RECORD_CREATE_DATE`, `A_RECORD_CREATE_AUTHOR`)
  631. select `id_users`, :today , 'sync-users' from `BILLING_USERS_ADD`
  632. ", [ ':today' => date("Y-m-d-H:i") ]);
  633. $_SESSION['USERS2_WINDYKACJA_PANEL']['_initialized'] = 1;
  634. }
  635. }
  636. public static function _to_update_where() {
  637. $sql_where = "";
  638. $sql_where_and_arr = array();
  639. //$sql_where_and_arr[] = "w.`A_STATUS`='WAITING'";
  640. $sql_where_and_arr[] = "w.`A_STATUS_UPDATE_DATE`<CURDATE()";
  641. $sql_where = implode(" and ", $sql_where_and_arr);
  642. return $sql_where;
  643. }
  644. public static function get_to_update_total() {
  645. $sql_where = self::_to_update_where();
  646. return DB::getPDO()->fetchValue("
  647. select count(1) as cnt
  648. from `USERS2_WINDYKACJA_STATUS` as w
  649. where {$sql_where}
  650. ");
  651. }
  652. public static function get_to_update_list($limit) {
  653. $sql_where = self::_to_update_where();
  654. $sql_limit = ($limit > 0)? "limit {$limit}" : "";
  655. return array_map(function ($item) { return (object)$item; }, DB::getPDO()->fetchAll("
  656. select w.*
  657. from `USERS2_WINDYKACJA_STATUS` as w
  658. where {$sql_where}
  659. order by ID desc
  660. {$sql_limit}
  661. ", [ ':id' => $user->WINDYKACJA_ID ]));
  662. }
  663. /**
  664. * @returns boolean - status changed or not
  665. * @param $user - object return from function Windykacja_StatsModel::get_user_by_id
  666. * @param $data - array of new user data
  667. * 1. wysłanie 1 wezwania do zapłaty ($user->A_STATUS='wezwanie1'; `PAY_TERM`, `wezwanie1_DATE`, `ID_PROJ`)
  668. * 2. wysłanie 2 wezwania do zapłaty ($user->A_STATUS='wezwanie2'; `PAY_TERM`, `wezwanie2_DATE`, `ID_KORESP`)
  669. * 3. klient spłacił wszystkie zobowiązania (`PAY_SALDO` >= -0.05)
  670. * TODO: 4. bledny adres klienta - ponowne wyslanie wezwania - niezaleznie od statusu?
  671. *
  672. * if $user->A_STATUS == 'wezwanie1' @param $data:
  673. * $data['wezwanie1_DATE'] - user data
  674. * $data['PAY_TERM'] - user data
  675. * $data['ID_PROJ'] - do Windykacja_StatsModel::create_koresp
  676. */
  677. public static function update_user($user, $data) {
  678. if (empty($data)) {
  679. return $user;
  680. }
  681. $data_arr = array();
  682. // set up status by current status and $data
  683. switch ($user->A_STATUS) {
  684. case 'WAITING':// auto
  685. break;
  686. case 'wezwanie1':// wymaga `PAY_TERM`, `wezwanie1_DATE`, `ID_KORESP` - wysłanie wezwanie1 (z podaniem ID_KORESP, i PAY_TERM=NOW()+14dni)
  687. // TODO: ID_KORESP z utworzonego rekordu KORESP (wymaga ID_PROJ)
  688. if ("" != V::get('wezwanie1_DATE' ,'', $data) && "" != V::get('PAY_TERM' ,'', $data) && V::get('ID_PROJ' ,'', $data, 'int') > 0) {
  689. $new_id_koresp = Windykacja_StatsModel::create_koresp($user, 'wezwanie1', V::get('ID_PROJ' ,'', $data, 'int'));
  690. if (!$new_id_koresp) {
  691. // TODO: revert changes - DB error
  692. return $user;
  693. }
  694. $data_arr["ID_KORESP"] = $new_id_koresp;
  695. $data_arr["LAST_ID_KORESP_WEZWANIE1"] = $new_id_koresp;
  696. $data_arr["A_STATUS"] = "waiting-wezwanie2";
  697. $data_arr["wezwanie1_DATE"] = V::get('wezwanie1_DATE' ,'', $data);
  698. $data_arr["PAY_TERM"] = V::get('PAY_TERM' ,'', $data);
  699. unset($data['ID_PROJ']);// TODO: RM after mv $data to $data_arr
  700. }
  701. break;
  702. case 'waiting-wezwanie2':// auto
  703. break;
  704. case 'wezwanie2':// wymaga `PAY_TERM`, `wezwanie2_DATE`, `ID_KORESP` - wysłanie wezwanie2 (z podaniem ID_KORESP, i PAY_TERM=NOW()+14dni)
  705. if ("" != V::get('wezwanie2_DATE' ,'', $data) && "" != V::get('PAY_TERM' ,'', $data) && V::get('ID_PROJ' ,'', $data, 'int') > 0) {
  706. $new_id_koresp = Windykacja_StatsModel::create_koresp($user, 'wezwanie2', V::get('ID_PROJ' ,'', $data, 'int'));
  707. if (!$new_id_koresp) {
  708. // TODO: revert changes - DB error
  709. return $user;
  710. }
  711. $data_arr["ID_KORESP"] = $new_id_koresp;
  712. $data_arr["LAST_ID_KORESP_WEZWANIE2"] = $new_id_koresp;
  713. $data_arr["A_STATUS"] = "waiting-krd";
  714. $data_arr["wezwanie2_DATE"] = V::get('wezwanie2_DATE' ,'', $data);
  715. $data_arr["PAY_TERM"] = V::get('PAY_TERM' ,'', $data);
  716. }
  717. break;
  718. default:
  719. }
  720. // if status not set, check id user saldo is ok
  721. if (!isset($data_arr["A_STATUS"])) {
  722. if (isset($data['PAY_SALDO']) && $data['PAY_SALDO'] >= -0.05) {
  723. $data_arr["A_STATUS"] = "WAITING";
  724. }
  725. }
  726. // error jesli nie ustalono statusu
  727. if (!isset($data_arr["A_STATUS"])) {
  728. return false;
  729. }
  730. $data_arr["A_STATUS_UPDATE_DATE"] = date("Y-m-d");// zawsze podana jesli jest zmiana A_STATUS
  731. $data_arr["A_RECORD_UPDATE_DATE"] = date("Y-m-d-H:i");
  732. $data_arr["A_RECORD_UPDATE_AUTHOR"] = $_SESSION['ADM_ACCOUNT'];
  733. DB::getPDO()->update('USERS2_WINDYKACJA_STATUS', 'ID', $user->WINDYKACJA_ID, $data_arr);
  734. // update $user data
  735. foreach ($data_arr as $k => $v) {
  736. $user->$k = $v;
  737. }
  738. DB::getPDO()->insert('USERS2_WINDYKACJA_STATUS_HIST', array_merge($data_arr, [ 'ID_USERS2' => $user->WINDYKACJA_ID ]));
  739. return true;
  740. }
  741. public static function bad_address_save($user, $id_koresp) {
  742. $data_arr = array();
  743. $data_arr["A_RECORD_UPDATE_DATE"] = date("Y-m-d-H:i");
  744. $data_arr["A_RECORD_UPDATE_AUTHOR"] = $_SESSION['ADM_ACCOUNT'];
  745. $data_arr["BAD_ADDRESS"] = 1;
  746. $data_arr["ID_KORESP"] = $id_koresp;
  747. return self::_sql_update($user, $data_arr);
  748. }
  749. public static function bad_address_confirm($user, $id_koresp) {
  750. $data_arr = array();
  751. $data_arr["A_RECORD_UPDATE_DATE"] = date("Y-m-d-H:i");
  752. $data_arr["A_RECORD_UPDATE_AUTHOR"] = $_SESSION['ADM_ACCOUNT'];
  753. $data_arr["BAD_ADDRESS"] = 0;
  754. $data_arr["ID_KORESP"] = $id_koresp;
  755. return self::_sql_update($user, $data_arr);
  756. }
  757. public static function _sql_update($user, $data_arr) {
  758. DB::getPDO()->update('USERS2_WINDYKACJA_STATUS', 'ID', $user->WINDYKACJA_ID, $data_arr);
  759. // update $user data
  760. foreach ($data_arr as $k => $v) {
  761. $user->$k = $v;
  762. }
  763. DB::getPDO()->insert('USERS2_WINDYKACJA_STATUS_HIST', array_merge($data_arr, [ 'ID_USERS2' => $user->WINDYKACJA_ID ]));
  764. return true;
  765. }
  766. public static function change_status_save($user, $new_status) {
  767. $data_arr = array();
  768. $data_arr["A_RECORD_UPDATE_DATE"] = date("Y-m-d-H:i");
  769. $data_arr["A_RECORD_UPDATE_AUTHOR"] = $_SESSION['ADM_ACCOUNT'];
  770. $data_arr["A_STATUS_UPDATE_DATE"] = date("Y-m-d");
  771. $data_arr["A_STATUS"] = $new_status;
  772. if ($user->A_STATUS == 'krd' && $new_status == 'waiting-sad') {
  773. $data_arr["wpis_w_krd_DATE"] = date('Y-m-d');
  774. }
  775. return self::_sql_update($user, $data_arr);
  776. }
  777. public static function nr_sprawy_krd_save($user, $nr_sprawy_krd) {
  778. $data_arr = array();
  779. $data_arr["A_RECORD_UPDATE_DATE"] = date("Y-m-d-H:i");
  780. $data_arr["A_RECORD_UPDATE_AUTHOR"] = $_SESSION['ADM_ACCOUNT'];
  781. $data_arr["NR_SPRAWY_KRD"] = $nr_sprawy_krd;
  782. return self::_sql_update($user, $data_arr);
  783. }
  784. public static function nr_sprawy_sad_save($user, $nr_sprawy_sad) {
  785. $data_arr = array();
  786. $data_arr["A_RECORD_UPDATE_DATE"] = date("Y-m-d-H:i");
  787. $data_arr["A_RECORD_UPDATE_AUTHOR"] = $_SESSION['ADM_ACCOUNT'];
  788. $data_arr["NR_SPRAWY_SAD"] = $nr_sprawy_sad;
  789. return self::_sql_update($user, $data_arr);
  790. }
  791. public static function nr_sprawy_komornik_save($user, $nr_sprawy_komornik) {
  792. $data_arr = array();
  793. $data_arr["A_RECORD_UPDATE_DATE"] = date("Y-m-d-H:i");
  794. $data_arr["A_RECORD_UPDATE_AUTHOR"] = $_SESSION['ADM_ACCOUNT'];
  795. $data_arr["NR_SPRAWY_KOMORNIK"] = $nr_sprawy_komornik;
  796. return self::_sql_update($user, $data_arr);
  797. }
  798. public static function ustalenia_info_save($user, $ustalenia_date, $ustalenia_info) {
  799. $data_arr = array();
  800. $data_arr["A_RECORD_UPDATE_DATE"] = date("Y-m-d-H:i");
  801. $data_arr["A_RECORD_UPDATE_AUTHOR"] = $_SESSION['ADM_ACCOUNT'];
  802. $data_arr["L_APPOITMENT_DATE"] = $ustalenia_date;
  803. $data_arr["L_APPOITMENT_INFO"] = $ustalenia_info;
  804. $data_arr["L_APPOITMENT_USER"] = $_SESSION['ADM_ACCOUNT'];
  805. if (empty($ustalenia_info) && (empty($ustalenia_date) || $ustalenia_date == '0000-00-00')) {
  806. $data_arr["L_APPOITMENT_USER"] = '';
  807. }
  808. return self::_sql_update($user, $data_arr);
  809. }
  810. public static function getUserHistStatusEvents($idUser) { // TODO: convert to idUser. Sql join USERS2_WINDYKACJA_STATUS w where w.ID_BILLING_USERS = :id_user
  811. return DB::getPDO()->fetchAll("
  812. select wh.*, kor.`K_ZAWARTOS`
  813. from `USERS2_WINDYKACJA_STATUS` as w
  814. join `USERS2_WINDYKACJA_STATUS_HIST` as wh on ( wh.`ID_USERS2` = w.ID )
  815. left join `IN7_DZIENNIK_KORESP` as kor on ( wh.`ID_KORESP` != 'N/S;' and kor.`ID` = wh.`ID_KORESP` )
  816. where w.`ID_BILLING_USERS` = :id
  817. and wh.`A_STATUS_UPDATE_DATE` != 'N/S;'
  818. ", [ ':id' => $idUser ]);
  819. }
  820. public static function getUserHistPhoneEvents($idUser) {
  821. return DB::getPDO()->fetchAll("
  822. select wh.*
  823. from `USERS2_WINDYKACJA_STATUS` as w
  824. join `USERS2_WINDYKACJA_STATUS_HIST` as wh on ( wh.`ID_USERS2` = w.ID )
  825. where w.`ID_BILLING_USERS` = :id
  826. and wh.`LAST_PHONE_STATUS_DATE` != 'N/S;'
  827. ", [ ':id' => $idUser ]);
  828. }
  829. public static function getUserBadAddressEvents($idUser) {
  830. return DB::getPDO()->fetchAll("
  831. select wh.*
  832. from `USERS2_WINDYKACJA_STATUS` as w
  833. join `USERS2_WINDYKACJA_STATUS_HIST` as wh on ( wh.`ID_USERS2` = w.ID )
  834. where w.`ID_BILLING_USERS` = :id
  835. and wh.`BAD_ADDRESS` != 'N/S;'
  836. order by wh.`ID` ASC
  837. ", [ ':id' => $idUser ]);
  838. }
  839. public static function get_status_count() {
  840. $sql_where_and_arr = array();
  841. $usrAclGroups = User::getLdapGroupsNames();
  842. $usrAclGroups[] = '';
  843. $sqlUsrAclGroups = "'" . implode("','", $usrAclGroups) . "'";
  844. $sql_where_and_arr[] = "a.`A_ADM_COMPANY` in({$sqlUsrAclGroups})";
  845. $sql_where_and_arr[] = "a.`A_CLASSIFIED` in({$sqlUsrAclGroups})";
  846. $sqlWhereAdd = " and " . implode(" and ", $sql_where_and_arr);
  847. $ret = array();
  848. $ret = array_map(function ($item) {
  849. return (object)$item;
  850. }, DB::getPDO()->fetchAllByKey("
  851. select w.`A_STATUS`, count(1) as cnt
  852. , sum(IF(w.`PAY_SALDO`<=-0.05, w.`PAY_SALDO`, 0)) as suma_zaleglosci
  853. from `USERS2_WINDYKACJA_STATUS` as w
  854. left join `BILLING_USERS_ADD` as a on(a.`id_users`=w.`ID_BILLING_USERS`)
  855. where 1=1 {$sqlWhereAdd}
  856. group by w.`A_STATUS`
  857. ", $key = 'A_STATUS'));
  858. $ret['po-terminie'] = DB::getPDO()->fetchFirstAsObject("
  859. select w.`A_STATUS`
  860. , count(1) as cnt
  861. , sum(IF(w.`PAY_SALDO`<=-0.05, w.`PAY_SALDO`, 0)) as suma_zaleglosci
  862. from `USERS2_WINDYKACJA_STATUS` as w
  863. left join `BILLING_USERS_ADD` as a on(a.`id_users`=w.`ID_BILLING_USERS`)
  864. where
  865. w.`PAY_SALDO`<=-0.05
  866. and w.`PAY_DATE`!='0000-00-00'
  867. and w.`PAY_DATE`<DATE_SUB(NOW(), INTERVAL 36 MONTH)
  868. {$sqlWhereAdd}
  869. ");
  870. $ret['3 m-ce przed'] = DB::getPDO()->fetchFirstAsObject("
  871. select w.`A_STATUS`
  872. , count(1) as cnt
  873. , sum(IF(w.`PAY_SALDO`<=-0.05, w.`PAY_SALDO`, 0)) as suma_zaleglosci
  874. from `USERS2_WINDYKACJA_STATUS` as w
  875. left join `BILLING_USERS_ADD` as a on(a.`id_users`=w.`ID_BILLING_USERS`)
  876. where
  877. w.`PAY_SALDO`<=-0.05
  878. and w.`PAY_DATE`!='0000-00-00'
  879. and w.`PAY_DATE`<DATE_SUB(NOW(), INTERVAL 33 MONTH)
  880. and w.`PAY_DATE`>DATE_SUB(NOW(), INTERVAL 36 MONTH)
  881. {$sqlWhereAdd}
  882. ");
  883. $ret['tel1'] = DB::getPDO()->fetchFirstAsObject("
  884. select w.`A_STATUS`
  885. , count(1) as cnt
  886. , sum(IF(w.`PAY_SALDO`<=-0.05, w.`PAY_SALDO`, 0)) as suma_zaleglosci
  887. from `USERS2_WINDYKACJA_STATUS` as w
  888. left join `BILLING_USERS_ADD` as a on(a.`id_users`=w.`ID_BILLING_USERS`)
  889. where
  890. w.`PAY_SALDO`<=-0.05
  891. and w.`A_STATUS` in('wezwanie1', 'waiting-wezwanie2', 'wezwanie2', 'waiting-krd')
  892. and ( w.`LAST_PHONE_STATUS_DATE`='0000-00-00'
  893. or w.`LAST_PHONE_STATUS_DATE`<DATE_SUB(NOW(), INTERVAL 14 DAY) )
  894. {$sqlWhereAdd}
  895. ");
  896. $ret['bad_address'] = DB::getPDO()->fetchFirstAsObject("
  897. select w.`A_STATUS`
  898. , count(1) as cnt
  899. , sum(IF(w.`PAY_SALDO`<=-0.05, w.`PAY_SALDO`, 0)) as suma_zaleglosci
  900. from `USERS2_WINDYKACJA_STATUS` as w
  901. left join `BILLING_USERS_ADD` as a on(a.`id_users`=w.`ID_BILLING_USERS`)
  902. where
  903. w.`PAY_SALDO`<=-0.05
  904. -- and w.`A_STATUS` in('wezwanie1', 'waiting-wezwanie2', 'wezwanie2', 'waiting-krd')
  905. and w.`BAD_ADDRESS`>0
  906. {$sqlWhereAdd}
  907. ");
  908. $stanZeroLimit = -0.05;
  909. $statsZero10ego = DB::getPDO()->fetchFirstAsObject("
  910. select w.`A_STATUS`
  911. , count(1) as cnt
  912. , sum(IF(w.`PAY_SALDO`>{$stanZeroLimit}, 1, 0)) as cnt_stan_zero
  913. , sum(IF(w.`PAY_SALDO`<={$stanZeroLimit}, 1, 0)) as cnt_stan_minus
  914. , sum(IF(w.`PAY_SALDO`<={$stanZeroLimit}, w.`PAY_SALDO`, 0)) as suma_zaleglosci
  915. from `USERS2_WINDYKACJA_STATUS` as w
  916. left join `BILLING_USERS_ADD` as a on(a.`id_users`=w.`ID_BILLING_USERS`)
  917. where
  918. w.`A_STATUS`='WAITING'
  919. {$sqlWhereAdd}
  920. ");
  921. if ($statsZero10ego) {
  922. $ret['stan_zero'] = (object)[ 'A_STATUS' => 'stan_zero', 'cnt' => $statsZero10ego->cnt_stan_zero, 'suma_zaleglosci' => 0 ];
  923. $ret['10-ego'] = (object)[ 'A_STATUS' => '10-ego', 'cnt' => $statsZero10ego->cnt_stan_minus, 'suma_zaleglosci' => $statsZero10ego->suma_zaleglosci ];
  924. }
  925. // filter: 'has_nr_sad', 'has_nr_komornik', 'has_ustalenia'
  926. $statsSad = DB::getPDO()->fetchFirstAsObject("
  927. select w.`A_STATUS`
  928. , count(1) as cnt
  929. , sum(IF(w.`NR_SPRAWY_SAD`!='', 1, 0)) as cnt_sad
  930. , sum(IF(w.`NR_SPRAWY_KOMORNIK`!='', 1, 0)) as cnt_komornik
  931. , sum(IF(w.`L_APPOITMENT_INFO`!='', 1, 0)) as cnt_ustalenia
  932. from `USERS2_WINDYKACJA_STATUS` as w
  933. left join `BILLING_USERS_ADD` as a on(a.`id_users`=w.`ID_BILLING_USERS`)
  934. where
  935. (w.`NR_SPRAWY_SAD`!=''
  936. or w.`NR_SPRAWY_KOMORNIK`!=''
  937. or w.`L_APPOITMENT_INFO`!=''
  938. )
  939. {$sqlWhereAdd}
  940. ");
  941. if ($statsSad) {
  942. $ret['has_nr_sad'] = (object)[ 'A_STATUS' => 'has_nr_sad', 'cnt' => $statsSad->cnt_sad, 'suma_zaleglosci' => null ];
  943. $ret['has_nr_komornik'] = (object)[ 'A_STATUS' => 'has_nr_komornik', 'cnt' => $statsSad->cnt_komornik, 'suma_zaleglosci' => null ];
  944. $ret['has_ustalenia'] = (object)[ 'A_STATUS' => 'has_ustalenia', 'cnt' => $statsSad->cnt_ustalenia, 'suma_zaleglosci' => null ];
  945. }
  946. // filter: 'sad_and_komornik', 'sad_bez_komornik'
  947. $statsKom = DB::getPDO()->fetchFirstAsObject("
  948. select w.`A_STATUS`
  949. , count(1) as cnt
  950. , sum(IF(w.`NR_SPRAWY_KOMORNIK`!='', 1, 0)) as cnt_komornik
  951. from `USERS2_WINDYKACJA_STATUS` as w
  952. left join `BILLING_USERS_ADD` as a on(a.`id_users`=w.`ID_BILLING_USERS`)
  953. where
  954. w.`A_STATUS`='sad'
  955. {$sqlWhereAdd}
  956. ");
  957. if ($statsKom) {
  958. $ret['sad_and_komornik'] = (object)[ 'A_STATUS' => 'sad_and_komornik', 'cnt' => $statsKom->cnt_komornik, 'suma_zaleglosci' => null ];
  959. $ret['sad_bez_komornik'] = (object)[ 'A_STATUS' => 'sad_bez_komornik', 'cnt' => ($statsKom->cnt - $statsKom->cnt_komornik), 'suma_zaleglosci' => null ];
  960. }
  961. // filter: 'isMovedToVectra'
  962. $statsVectra = DB::getPDO()->fetchFirstAsObject("
  963. select w.`A_STATUS`
  964. , count(1) as cnt
  965. , sum(IF(w.`PAY_SALDO`<={$stanZeroLimit}, w.`PAY_SALDO`, 0)) as suma_zaleglosci
  966. from `USERS2_WINDYKACJA_STATUS` as w
  967. left join `BILLING_USERS_ADD` as a on(a.`id_users`=w.`ID_BILLING_USERS`)
  968. where
  969. w.`IS_MOVED_TO_VECTRA`=1
  970. {$sqlWhereAdd}
  971. ");
  972. if ($statsVectra) {
  973. $ret['isMovedToVectra'] = (object)[ 'cnt' => $statsVectra->cnt, 'suma_zaleglosci' => $statsVectra->suma_zaleglosci ];
  974. }
  975. return $ret;
  976. }
  977. }