utils.class.php 74 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523
  1. <?php
  2. if (!defined('IN_ONLINE')) {
  3. exit('Access Denied');
  4. }
  5. /**
  6. * Description of utilsclass
  7. *
  8. * @author Administrator
  9. */
  10. class utils {
  11. public static function checkPassword($password,$rule="",$user_login="") {
  12. $str ="";
  13. if (!empty($rule)) {
  14. //是否校验大小写
  15. if (!empty($rule["hasOneUpperChar"])&&$rule["hasOneUpperChar"]) {
  16. if (!preg_match('/[A-Z]/',$password)) {
  17. $str ="Password must contain uppercase letters";
  18. }
  19. }
  20. //是否校验小写
  21. if (!empty($rule["hasOneLowerChar"])&&$rule["hasOneLowerChar"]) {
  22. if (!preg_match('/[a-z]/',$password)) {
  23. $str ="Password must contain lowercase letters";
  24. }
  25. }
  26. //是否存在数字
  27. if (!empty($rule["hasOneNumberChar"])&&$rule["hasOneNumberChar"]) {
  28. if (!preg_match('/[0-9]/',$password)) {
  29. $str ="Password must contain numbers";
  30. }
  31. }
  32. $sql = "select user_type from ra_online_user_roles_rel where upper(user_login)=upper('".$user_login."') and exists(select count(0) from ra_online_user where upper(user_login)=upper('".$user_login."') and is_desktop=true) order by id desc limit 1;";
  33. $user_type = common::excuteOneSql($sql);
  34. if (!empty($user_type)&&$user_type=="Super User") {
  35. if (strlen($password)<$rule["SuperMinLen"]||strlen($password)>$rule["SuperMaxLen"]) {
  36. $str ="Super user password length between ".$rule["SuperMinLen"]." and ".$rule["SuperMaxLen"];
  37. }
  38. }else{
  39. //校验密码长度
  40. if (strlen($password)<$rule["MinLen"]||strlen($password)>$rule["MaxLen"]) {
  41. $str ="Password length between ".$rule["MinLen"]." and ".$rule["MaxLen"];
  42. }
  43. }
  44. return $str;
  45. }else{
  46. if (preg_match('/^\d*$/', $password) || preg_match('/^[a-zA-Z]+$/', $password)) {
  47. $str ="Must include letters and numbers";
  48. }
  49. $len = strlen($password);
  50. $t = substr($password, 0, 1);
  51. for ($i = 1; $i < $len; $i++) {
  52. $t1 = substr($password, $i, 1);
  53. if ($t != $t1) {
  54. return "";
  55. }
  56. }
  57. return "error";
  58. }
  59. }
  60. //隐藏邮箱地址
  61. public static function maskEmail($email) {
  62. $idex = strlen($email) - strrpos($email, ".");
  63. $mask = substr($email, 0, 1) . str_repeat('*', 6) . "@" . str_repeat('*', 3) . substr($email, -$idex);
  64. return $mask;
  65. }
  66. public static function getInSql($str, $not = false, $sep = ";") {
  67. $str = trim($str);
  68. $str = trim($str, $sep);
  69. $str = trim($str);
  70. if (empty($str) && $str !== "0" && $str !== 0)
  71. return "1<>1";
  72. $str = strtolower($str);
  73. if (utils::checkExist($str, $sep)) {
  74. $aa = explode($sep, $str);
  75. $msg = "";
  76. foreach ($aa as $value) {
  77. $value = trim($value);
  78. if (empty($value))
  79. continue;
  80. if (empty($msg))
  81. $msg = "'" . common::check_input($value) . "'";
  82. else
  83. $msg .= ",'" . common::check_input($value) . "'";
  84. }
  85. if ($not !== FALSE)
  86. return " not in (" . $msg . ")";
  87. else
  88. return " in (" . $msg . ")";
  89. } else {
  90. if ($not !== FALSE)
  91. return " != '" . common::check_input(trim($str)) . "'";
  92. else
  93. return " = '" . common::check_input(trim($str)) . "'";
  94. }
  95. }
  96. public static function checkExist($string, $search, $u = TRUE) {
  97. if ($u === TRUE) {
  98. if (stripos($string, $search) !== false)
  99. return TRUE;
  100. }else {
  101. if (strpos($string, $search) !== false)
  102. return TRUE;
  103. }
  104. return FALSE;
  105. }
  106. public static function endWith($string, $end, $u = TRUE) {
  107. if ($u === TRUE) {
  108. $string = strtolower($string);
  109. $end = strtolower($end);
  110. return strrchr($string, $end) == $end;
  111. }
  112. return strrchr($string, $end) == $end;
  113. }
  114. public static function _get($str) {
  115. $rs = isset($_POST[$str]) ? $_POST[$str] : null;
  116. if (empty($rs))
  117. $rs = isset($_GET[$str]) ? $_GET[$str] : null;
  118. return $rs;
  119. }
  120. public static function startWith($string, $start, $u = TRUE) {
  121. if ($u === TRUE)
  122. return stripos($string, $start) === 0;
  123. return strpos($string, $start) === 0;
  124. }
  125. public static function outDisplay($content, $is_time = 'f', $is_first = 'f', $is_boolean = 'f', $excel_export = FALSE) {
  126. if (empty($content) && $content !== 0 && $content !== "0")
  127. return "";
  128. if (strtolower($is_time) == 't')
  129. return utils::dealTimeDisplay($content);
  130. if (strtolower($is_first) == 't') {
  131. if ($excel_export !== FALSE)
  132. return utils::getCompanyName($content);
  133. else
  134. return '<span title="' . $content . '">' . utils::getCompanyName($content) . '</span>';
  135. }
  136. if (strtolower($is_boolean) == 't')
  137. return utils::outTrue($content);
  138. return nl2br($content);
  139. }
  140. public static function _output($value) {
  141. if (empty($value))
  142. return "&nbsp;";
  143. else
  144. return $value;
  145. }
  146. public static function dealTimeDisplay($date) {
  147. if (empty($date))
  148. return "";
  149. if (strlen($date) > 10)
  150. return date("m/d/Y H:i:s", strtotime($date));
  151. return date("m/d/Y", strtotime($date));
  152. }
  153. public static function outDisplayForMerge($frist,$last,$split = "/") {
  154. if($frist == $last){
  155. return $frist;
  156. }
  157. if (!empty($frist)){
  158. if(!empty($last)){
  159. return $frist.$split.$last;
  160. }else{
  161. return $frist;
  162. }
  163. }else{
  164. return $last;
  165. }
  166. }
  167. public static function outTrue($r) {
  168. if (empty($r))
  169. return "No";
  170. $r = strtolower($r);
  171. if ($r == "t")
  172. return "Yes";
  173. elseif ($r == "f")
  174. return "No";
  175. else
  176. return $r;
  177. }
  178. public static function getCompanyName($detail) {
  179. $detail = nl2br($detail);
  180. if (strpos($detail, '<br />') === FALSE)
  181. return $detail;
  182. return substr($detail, 0, strpos($detail, '<br />'));
  183. }
  184. public static function getEmail($serial_no) {
  185. $ocean = common::excuteObjectSql("select sales_rep, last_user, created_by, order_from, h_bol, consignee, dest_op, agent from public.kln_ocean where md5(serial_no)=md5('$serial_no') "
  186. . "order by schem_not_display nulls last limit 1");
  187. $schema = $ocean["order_from"] . ".";
  188. $dest_op_from_agent = common::excuteOneSql("select dest_op_from_agent from " . $schema . "ocean where md5(serial_no)=md5('$serial_no')");
  189. if ($ocean["agent"] == "KYMTL" || $ocean["agent"] == "KYYYZ") {
  190. $email = array();
  191. $email["email"] = "";
  192. if (!empty($dest_op_from_agent)) {
  193. $so_email = common::excuteOneSql("select email from " . $schema . "employee where employee_id='" . $dest_op_from_agent . "' and active=true");
  194. }
  195. if (!empty($so_email)) {
  196. if (empty($email["email"])) {
  197. $email["email"] = $so_email;
  198. } else {
  199. $email["email"] .= ";" . $so_email;
  200. }
  201. }
  202. if (!empty($ocean["sales_rep"])) {
  203. $rep_email = common::excuteOneSql("select email from " . $schema . "employee where lower(salesopcode)='" . strtolower($ocean["sales_rep"]) . "' and active=true");
  204. if (!empty($rep_email)) {
  205. if (empty($email["email"])) {
  206. $email["email"] = $rep_email;
  207. } else {
  208. $email["email"] .= ";" . $rep_email;
  209. }
  210. }
  211. }
  212. } else {
  213. $email = common::excuteObjectSql("select string_agg(e.email, ';') as email, string_agg(e.first_name, ';') as name from " . $schema . "ra_online_user u, " . $schema . "employee e WHERE u.employee_id = e.employee_id and "
  214. . "lower(u.user_login) in ('" . strtolower($ocean["created_by"]) . "', '" . strtolower($ocean["last_user"]) . "')");
  215. if (empty($dest_op_from_agent)) {
  216. if (!empty($ocean["dest_op"])) {
  217. $so_email = common::excuteOneSql("select email from " . $schema . "employee where employee_id='" . $ocean["dest_op"] . "' and active=true");
  218. }
  219. } else {
  220. $so_email = common::excuteOneSql("select email from " . $schema . "employee where employee_id='" . $dest_op_from_agent . "' and active=true");
  221. }
  222. if (empty($so_email)) {
  223. if ($ocean["agent"] == "APEXSFO") {
  224. $so_email = "oid2@apexshipping.com";
  225. }
  226. if ($ocean["agent"] == "APEXLAX") {
  227. $so_email = "laxoid@apexshipping.com";
  228. }
  229. if ($ocean["agent"] == "APEXNYC") {
  230. $so_email = "NYCOID@APEXSHIPPING.COM";
  231. }
  232. if ($ocean["agent"] == "APEXPNW") {
  233. $so_email = "pnwoid@apexshipping.com";
  234. }
  235. if ($ocean["agent"] == "STLUTA") {
  236. $so_email = "starlinkOID@apexshipping.com ";
  237. }
  238. if ($ocean["agent"] == "APEXORD") {
  239. $so_email = "ordoid@apexshipping.com";
  240. }
  241. }
  242. if (!empty($so_email)) {
  243. if (empty($email["email"])) {
  244. $email["email"] = $so_email;
  245. } else {
  246. $email["email"] .= ";" . $so_email;
  247. }
  248. }
  249. if (!empty($ocean["sales_rep"])) {
  250. $rep_email = common::excuteOneSql("select email from " . $schema . "employee where lower(salesopcode)='" . strtolower($ocean["sales_rep"]) . "' and active=true");
  251. if (!empty($rep_email)) {
  252. if (empty($email["email"])) {
  253. $email["email"] = $rep_email;
  254. } else {
  255. $email["email"] .= ";" . $rep_email;
  256. }
  257. }
  258. }
  259. }
  260. $email["h_bol"] = $ocean["h_bol"];
  261. $email["consignee"] = $ocean["consignee"];
  262. return $email;
  263. }
  264. /***
  265. * 过滤json中的某个数据
  266. * @param unknown $json
  267. * @param unknown $search
  268. * @param unknown $replace
  269. * @return mixed
  270. */
  271. public static function jsonFiltration($search,$replace,$json){
  272. //处理json中将斜杠转义问题
  273. $json = str_replace("\\/", "/", $json);
  274. return str_replace($search, $replace, $json);
  275. }
  276. /*
  277. * calculate eta destination by etd port
  278. */
  279. public static function calculate_ETA_Des($serial_no) {
  280. $sql = "SELECT m_eta as eat, mport_of_discharge as poul, place_of_delivery as pod,service from ocean where lower(serial_no) = '" . strtolower($serial_no) . "'";
  281. $rs = common::excuteObjectSql($sql);
  282. $date = "";
  283. if (!empty($rs['eat'])) {
  284. $date = utils::calculate_ETA_Dest($rs['eat'], $rs['poul'], $rs['pod'], $rs['service']);
  285. }
  286. return $date;
  287. }
  288. public static function calculate_ETA_Dest($eta, $poul, $pod, $service) {
  289. if (empty($poul) || empty($pod))
  290. return $eta;
  291. $sql = "SELECT door_days, cy_days
  292. FROM eta_dest
  293. WHERE eta_dest.state::text = ((( SELECT unlocode.state
  294. FROM ports, unlocode
  295. WHERE ports.uncode::text = unlocode.uncode::text AND ports.code::text = '" . common::check_input($pod) . "'
  296. LIMIT 1))::text) AND (','::text || eta_dest.pod::text) ~~* (('%,'::text || '" . common::check_input($poul) . "') || '%'::text)
  297. LIMIT 1";
  298. //$sql = "select door_days, cy_days from eta_dest where state = (select state from ports where code = '" . common::check_input($poul) . "' limit 1) and ','||pod ilike '%," . common::check_input($pod) . "%'";
  299. $rs = common::excuteObjectSql($sql);
  300. if (empty($rs))
  301. return $eta;
  302. if (utils::endWith($service, "cy"))
  303. return common::addDays($eta, $rs['cy_days']);
  304. else
  305. return common::addDays($eta, $rs['door_days']);
  306. }
  307. /*
  308. * password change, email alert
  309. */
  310. public static function sendEmailByPassword($username, $password, $email, $companyname='') {
  311. $sql = "select subject, ra_content as content from ra_online_email_tpl where lower(ra_type) = 'forgotpw'";
  312. $rs = common::excuteObjectSql($sql);
  313. if (!empty($rs)) {
  314. $subject = $rs['subject'];
  315. $content = $rs['content'];
  316. }
  317. if (!empty($subject) && !empty($content)) {
  318. $content = str_replace('<{username}>', $username, $content);
  319. $content = str_replace('<{password}>', $password, $content);
  320. $content = str_replace('<{companyname}>', $companyname, $content);
  321. global $db;
  322. common::excuteUpdateSql("INSERT INTO public.email_record_forgotpassword(type, title, from_email, to_email, content, insert_date,
  323. cc_email) VALUES ('forgot_password', '" . common::check_input($subject) . "', 'US.KApex.Online@kerryapex.com', '" .
  324. common::check_input($email) . "', '" . common::check_input($content) . "', now(), '');");
  325. return "success";
  326. //return Mail::sendMail($email, $subject, $content);
  327. } else
  328. return null;
  329. }
  330. public static function operation_log_records(){
  331. //排除opreation_log操作
  332. if( empty($_REQUEST["operate"])
  333. || ($_REQUEST["action"] == "login" && $_REQUEST["operate"] == "verifcation_code")
  334. || ($_REQUEST["action"] == "login" && $_REQUEST["operate"] == "check_uname")
  335. || ($_REQUEST["action"] == "ocean_order" && $_REQUEST["operate"] == "setting_ocean_order_display")
  336. || ($_REQUEST["action"] == "ocean_booking" && $_REQUEST["operate"] == "setting_display")){
  337. return;
  338. }
  339. if($_REQUEST["action"] == "login" && $_REQUEST["operate"] == "tracking_checked"){
  340. //public tracking_checked 的user name 记录对应IP 地址
  341. $user_type = "Customer";
  342. $user_name = common::ip();
  343. } elseif($_REQUEST["action"] == "login" && $_REQUEST["operate"] == "do_login"){
  344. //移除do_login 因为在登录的过程中,是没有用户信息的
  345. $user_name = $_REQUEST["uname"];
  346. } else{
  347. $user_name = _getLoginName();
  348. }
  349. $user_type = _isApexLogin() ? "Employee" : "Customer";
  350. //如果在没有登录前,没有登录信息,指定用户
  351. if(!isset($_SESSION['ONLINE_USER'])){
  352. $user_type = common::excuteOneSql("select user_type from public.ra_online_user u where lower(user_login) = '" . strtolower($user_name) . "'");
  353. }
  354. $operateInfo = utils::getPageByAction($_REQUEST["action"],$_REQUEST["operate"]);
  355. $page = $operateInfo["page"];
  356. $operation = $operateInfo["operate"];
  357. $operation_detail = utils::analyzeOperationDetail($_REQUEST["action"],$_REQUEST["operate"]);
  358. if(empty($operation_detail)){
  359. $operation_detail = common::check_input(utils::jsonFiltration("null", "\"\"", json_encode($_REQUEST)));
  360. }
  361. //过滤一分钟以内,相同用户的重复请求
  362. $exist_sql = "select count(1) from public.customer_service_operation_log
  363. where user_name = '$user_name'
  364. and page = '$page' and operation = '$operation' and operation_detail = '$operation_detail'
  365. and operation_time > NOW() - INTERVAL '1 minute' limit 1;";
  366. $exist_obj = common::excuteOneSql($exist_sql);
  367. if(empty($exist_obj)){
  368. $sql = "INSERT INTO public.customer_service_operation_log(user_type, user_name, page, operation, operation_detail,
  369. operation_time)
  370. VALUES ('$user_type', '$user_name', '$page', '$operation', '$operation_detail', now())";
  371. common::excuteUpdateSql($sql);
  372. }
  373. }
  374. public static function getPageByAction($action,$operate){
  375. //取消
  376. $operationConvertName = array(
  377. "login=do_login" => array("page" =>"Login","operate"=>"Login"),
  378. "login=forgot_password" => array("page" =>"Login","operate"=>"Forgot_PPassword"),
  379. "login=logout" => array("page" =>"logout","operate"=>"logout"),
  380. "login=update_pwd_expires" => array("page" =>"Login","operate"=>"Reset password"),
  381. "ocean_booking=search" => array("page" =>"Booking","operate"=>"Search"),
  382. "Booking_Search=save_setting_display" => array("page" =>"Booking","operate"=>"Customize Coulumns"),
  383. "booking=autody" => array("page" =>"Booking","operate"=>"More Filter"),
  384. "booking=autoport" => array("page" =>"Booking","operate"=>"More Filter"),
  385. "ocean_booking=detail" => array("page" =>"Booking","operate"=>"Open Detailed Page"),
  386. "ocean_booking=excel" => array("page" =>"Booking","operate"=>"Download"),
  387. "ocean_booking=save_communication" => array("page" =>"Booking","operate"=>"Send Email"),
  388. "opreation_log=search" => array("page" =>"Opreation_log","operate"=>"Search"),
  389. "login=tracking_checked" => array("page" =>"Tracking","operate"=>"Public tracking"),
  390. "ocean_order=search" => array("page" =>"Tracking","operate"=>"Search"),
  391. "Ocean_Search=save_setting_display" => array("page" =>"Tracking","operate"=>"Customize Coulumns"),
  392. "tracking=autody" => array("page" =>"Tracking","operate"=>"More Filter"),
  393. "tracking=autoport" => array("page" =>"Tracking","operate"=>"More Filter"),
  394. "ocean_order=detail" => array("page" =>"Tracking","operate"=>"Open Detailed Page"),
  395. "ocean_order=excel" => array("page" =>"Tracking","operate"=>"Download"),
  396. "ocean_order=download" => array("page" =>"Tracking","operate"=>"Download"),
  397. "ocean_order=save_communication" => array("page" =>"Booking","operate"=>"Send Email"),
  398. "ocean_order=ams_isf_log" => array("page" =>"Tracking","operate"=>"AMS/ISF"),
  399. "ocean_order=ocean_vgm" => array("page" =>"Tracking","operate"=>"Enter VGM"),
  400. "ocean_order=save_ocean_vgm" => array("page" =>"Tracking","operate"=>"Save VGM"),
  401. "ocean_order=share_shipment" => array("page" =>"Tracking","operate"=>"Share shipment"),
  402. "ocean_order=document_upload" => array("page" =>"Tracking","operate"=>"document_upload"),
  403. "ocean_order=document_upload_do" => array("page" =>"Tracking","operate"=>"document_upload_do"),
  404. "tools=mark_save" => array("page" =>"Tools","operate"=>"Mark_Save"),
  405. "password=" => array("page" =>"Profile","operate"=>"Change password"));
  406. if($action == "ajax" && $operate == "save_setting_display"){
  407. $model_name = $_REQUEST['model_name'];
  408. return $operationConvertName[$model_name."=".$operate];
  409. }
  410. if($action == "ajax" && ($operate == "autody" || $operate == "autoport")){
  411. $model_name = $_REQUEST['search_mode'];
  412. return $operationConvertName[$model_name."=".$operate];
  413. }
  414. return $operationConvertName[$action."=".$operate];
  415. }
  416. public static function analyzeOperationDetail($action,$operate){
  417. if($action == "login" && $operate == "do_login"){
  418. $detail = 'System Account';
  419. if($_REQUEST['token']){
  420. $detail = 'From Apex Online';
  421. }
  422. }
  423. if($action == "login" && $operate == "logout"){
  424. $detail = 'User Logout';
  425. }
  426. if($action == "login" && $operate == "tracking_checked"){
  427. $detail = 'Join public tracking action,Public tracking number:'.$_POST['reference_number'];
  428. }
  429. if($action == "password"){
  430. $detail = 'User Change password';
  431. }
  432. if(($action == "ocean_booking" || $action == "ocean_order") && $operate == "search"){
  433. $detail = "";
  434. //还有一个同以分钟内,不记录相同的查询 这个需要建表查询
  435. //{"action":"ocean_booking","operate":"search","_ntype":"ocean_booking","cp":"1","ps":"100","rc":"-1","other_filed":"","uname":"ra.admin","psw":"abc123456789"}
  436. $filter_common_field = array("action","operate","_ntype","cp","ps","rc","other_filed","uname","psw");
  437. foreach($_REQUEST as $selected_key => $selected){
  438. if(!utils::in_array($selected_key, $filter_common_field)){
  439. if(is_array($selected)){
  440. $selected = utils::implode(",",$selected);
  441. }
  442. $detail .="$selected_key:".$selected."; ";
  443. }
  444. }
  445. if(empty($detail)){
  446. $detail .="No search condition";
  447. }
  448. }
  449. if($action == "ajax" && $operate == "save_setting_display"){
  450. $detail = "";
  451. $type = $_REQUEST['model_name'] == "Booking_Search" ? "Booking_Search" : "Ocean_Search";
  452. //记录最终save 和 default 字段相比的结果
  453. // $default_ids = common::excuteListSql("select id,display_name from public.ra_online_search_display_cso where model_name = '$type'
  454. // and display_name in('Booking No.','MBL No.','HBL No.','Mode','Status',
  455. // 'Shipper','Consignee','Origin Agent','Destination Agent','Creation Time','ETD','ETA',
  456. // 'Voyage','Vessel','Week','Created by') order by default_order");
  457. $default_ids = common::excuteListSql("select id,display_name from public.ra_online_search_display_cso where model_name = '$type'
  458. and default_display = true order by default_order");
  459. $ids = utils::implode(";", $_POST['ids']);
  460. $save_ids = common::excuteListSql("select id,display_name from public.ra_online_search_display_cso where model_name = '$type'
  461. and id::text = any(regexp_split_to_array('$ids', ';')) order by default_order");
  462. $detele_detail = "";
  463. foreach($default_ids as $did){
  464. if(!utils::exist_array($did['id'],$save_ids)){
  465. $detele_detail .=$did['display_name']."/";
  466. }
  467. }
  468. $add_detail = "";
  469. foreach($save_ids as $sid){
  470. if(!utils::exist_array($sid['id'],$default_ids)){
  471. $add_detail .=$sid['display_name']."/";
  472. }
  473. }
  474. if(!empty($detele_detail)){
  475. $detail.="Detele fields: (".$detele_detail."). ";
  476. }
  477. if(!empty($add_detail)){
  478. $detail.="Add fields: (".$add_detail."). ";
  479. }
  480. if(empty($detail)){
  481. $detail = "The default field has not changed";
  482. }
  483. }
  484. if(($action == "ocean_booking" || $action == "ocean_order") && $operate == "detail"){
  485. $tabel = $action == "ocean_booking" ? "kln_booking" : "kln_ocean";
  486. $serial_no = common::deCode($_GET['a'], 'D');
  487. $sql = "SELECT booking_no,h_bol from public.$tabel where serial_no = '$serial_no' limit 1";
  488. $data = common::excuteObjectSql($sql);
  489. if(!empty($data['booking_no'])){
  490. $detail = 'Booking No.: '.$data['booking_no'];
  491. }else{
  492. $detail = 'HBOL: '.$data['h_bol'];
  493. }
  494. }
  495. if(($action == "ocean_booking" || $action == "ocean_order") && $operate == "save_communication"){
  496. $text = $_POST["text"];
  497. $detail = urldecode($text);
  498. }
  499. if(($action == "ocean_order") && $operate == "ams_isf_log"){
  500. $detail = "Enter AMS/ISF Page";
  501. }
  502. if(($action == "ocean_booking" || $action == "ocean_order") && $operate == "excel"){
  503. $detail = "Filter_condition:" . $_REQUEST['excel_filter_condition']." Selected Fields:". $_REQUEST['selected_fields'];
  504. }
  505. //Tracking詳情頁download的file(顯示file名稱)
  506. if(($action == "ocean_order") && $operate == "download"){
  507. $filename = common::deCode($_GET['url'], 'D');
  508. $filename = str_replace("/", DIRECTORY_SEPARATOR, $filename);
  509. $filename = str_replace("\\", DIRECTORY_SEPARATOR, $filename);
  510. $display_name = basename($filename);
  511. if (!file_exists($filename)){
  512. $detail = "Tracking Detail Attachment Download But File Not Exist : $display_name";
  513. }else{
  514. $detail = "Tracking Detail Attachment Download: $display_name";
  515. }
  516. }
  517. //Tracking詳情頁Upload Files(顯示file名稱)
  518. if(($action == "ocean_order") && $operate == "document_upload"){
  519. $detail = "Enter Upload Files page";
  520. }
  521. return $detail;
  522. }
  523. public static function calculateTicks($minValue, $maxValue, $targetTickCount = 10) {
  524. $tickSpacing = ($maxValue - $minValue);
  525. $tickSpacing = intval($tickSpacing);
  526. $interval = ceil($tickSpacing / $targetTickCount);
  527. $len = strlen($interval);
  528. if ($len >1){
  529. $interval = ceil($interval/pow(10,$len-1)) *pow(10,$len-1);
  530. }
  531. return $interval;
  532. }
  533. //只记录Public tracking
  534. public static function single_operation_log_save($user_type,$user_name,$page,$operation,$operation_detail){
  535. $sql = "INSERT INTO public.customer_service_operation_log(user_type, user_name, page, operation, operation_detail,
  536. operation_time)
  537. VALUES ('$user_type', '$user_name', '$page', '$operation', '$operation_detail', now())";
  538. common::excuteUpdateSql($sql);
  539. }
  540. public static function uuid() {
  541. return strtoupper(md5(uniqid("", TRUE) . mt_rand()));
  542. }
  543. public static function count($variable){
  544. if (is_array($variable)) {
  545. $count = count($variable);
  546. } else {
  547. $count = 0;
  548. }
  549. return $count;
  550. }
  551. public static function implode($sp,$variable){
  552. $variable = isset($variable) && is_array($variable) ? $variable : array();
  553. return implode($sp, $variable);
  554. }
  555. public static function in_array($str, $arr){
  556. if (is_array($arr)) {
  557. return in_array($str, $arr);
  558. } else {
  559. return false;
  560. }
  561. }
  562. public static function exist_array($key,$arr){
  563. $flag = false;
  564. foreach($arr as $v){
  565. if($v['id'] == $key ){
  566. $flag = true;
  567. }
  568. }
  569. return $flag;
  570. }
  571. public static function getConpanyForNotify($_schemas,$type){
  572. //如果有多個就留空
  573. $company = "";
  574. if($type == 'ocean'){
  575. $company = $_SESSION['ONLINE_USER']['company_name'];
  576. $company_arr = explode(";",$company);
  577. $temp = array();
  578. foreach($company_arr as $v){
  579. if(!empty($v)){
  580. $temp[] = $v;
  581. }
  582. }
  583. if(utils::count($temp) <= 1){
  584. return $company;
  585. }
  586. }
  587. if($type == 'air'){
  588. $company_id = $_SESSION['ONLINE_USER']['air_customers'];
  589. $company_id_arr = explode(";",$company_id);
  590. $temp = array();
  591. foreach($company_id_arr as $v){
  592. if(!empty($v)){
  593. $temp[] = $v;
  594. }
  595. }
  596. if(utils::count($temp) == 1){
  597. if ($_schemas == "public") {//apex ocean和air 分开
  598. $sql = "SELECT company from ocean.contacts where contact_id = '" . common::check_input($temp[0]) . "' ";
  599. } else {
  600. $sql = "SELECT company from $_schemas.contacts where contact_id = '" . common::check_input($temp[0]) . "' ";
  601. }
  602. $company = common::excuteOneSql($sql);
  603. }
  604. return $company;
  605. }
  606. }
  607. public static function getKlnDocNotifyContent($bol,$file_type,$upload_user_name,$upload_user_email,$company,$date_time){
  608. $report_setting = common::excuteObjectSql("select * from ra_online_auto_report_config where report_type = 'KLN_DOC_Notify' ");
  609. $report_content = $report_setting['report_content'];
  610. $columns = common::excuteListSql("select display_name,model_name,database_column_name,excel_width,order_by from public.ra_online_search_display_cso where model_name = 'KLN_DOC_Notify'");
  611. $missing_packing_th = "<tr>";
  612. foreach ($columns as $colk => $colvalue) {
  613. $missing_packing_th.='<td style="width:'.$colvalue['excel_width'].'pt;border:solid black 1.0pt;background:#1F4E78;padding:0cm 5.4pt 0cm 5.4pt;height:14.25pt">
  614. <p class="MsoNormal" align="left" style="text-align:left"><b><span lang="EN-US" style="font-size:8.0pt;font-family:&quot;Arial&quot;,sans-serif;color:white">'.$colvalue['display_name'].'</span></b></p>
  615. </td>';
  616. }
  617. $missing_packing_th .= "</tr>";
  618. $report_content = str_replace('<{missing_packing_th}>', $missing_packing_th, $report_content);
  619. $data = array(array("h_bol"=>$bol,"file_type"=>$file_type,"upload_by"=>$upload_user_name,"email"=>$upload_user_email,"company"=>$company,"upload_time"=>$date_time."(US/Pacific)"));
  620. $missing_packing_tr = "";
  621. foreach ($data as $rk => $rv) {
  622. $missing_packing_tr .= "<tr>";
  623. foreach ($columns as $ck => $cv) {
  624. if(utils::endWith($cv['display_name'], "email")){
  625. $missing_packing_tr.='<td style="font-size:8.0pt;font-family:&quot;Arial&quot;,sans-serif;color:black;border-top:none;
  626. border-left:none;border-bottom:solid black 1.0pt;border-right:solid black 1.0pt;padding:0cm 5.4pt 0cm 5.4pt;height:14.25pt">
  627. <a href="mailto:'.$rv[$cv['database_column_name']].'">'.$rv[$cv['database_column_name']].'</a>
  628. </td>';
  629. }else{
  630. $missing_packing_tr.='<td style="font-size:8.0pt;font-family:&quot;Arial&quot;,sans-serif;color:black;'
  631. . 'border-top:none;border-left:none;border-bottom:solid black 1.0pt;border-right:solid black 1.0pt;padding:0cm 5.4pt 0cm 5.4pt;height:14.25pt">'.$rv[$cv['database_column_name']].'</td>';
  632. }
  633. }
  634. $missing_packing_tr .= "</tr>";
  635. }
  636. $report_content = str_replace('<{missing_packing_tr}>', $missing_packing_tr, $report_content);
  637. return $report_content;
  638. }
  639. public static function _getSql($ids, $type,$shipment_mode,$sqlWhere) {
  640. $ids_arr = explode(',', $ids);
  641. $sql = "";
  642. if($type == "co2e_orgin"){
  643. $str = "SUM(COALESCE(carbon_emission,0)) as catnum ";
  644. $filed = "shippr_uncode";
  645. } else {
  646. $str = "SUM(COALESCE(carbon_emission,0)) as catnum ";
  647. $filed = "consignee_uncode";
  648. }
  649. $shipment_mode_where = " 1=1 ";
  650. //这里处理为空,目前没有数据
  651. $shipment_mode_where = " transport_mode = '$shipment_mode' ";
  652. $shipment_mode_where .= $sqlWhere;
  653. foreach ($ids_arr as $value) {
  654. if (!empty($value)) {
  655. if (empty($sql)) {
  656. $sql .= "SELECT $str FROM public.kln_ocean where $shipment_mode_where and $filed = '$value'";
  657. } else {
  658. $sql .= " union all SELECT $str from public.kln_ocean where $shipment_mode_where and $filed = '$value'";
  659. }
  660. }
  661. }
  662. return $sql;
  663. }
  664. public static function removeDuplicateArray($array){
  665. $result = array();
  666. foreach ($array as $value) {
  667. //过滤可能的空值,会引起前端页面有数据但无法显示
  668. if(!empty($value)){
  669. if (!utils::in_array($value, $result)) {
  670. $result[] = $value;
  671. }
  672. }
  673. }
  674. return $result;
  675. }
  676. public static function hasMacros($filePath) {
  677. $extension = pathinfo($filePath, PATHINFO_EXTENSION);
  678. if ($extension === 'xlsx') {
  679. // 检查 .xlsx 文件
  680. $zip = new ZipArchive();
  681. if ($zip->open($filePath) === TRUE) {
  682. // 检查是否存在 vbaProject.bin 文件
  683. $hasMacros = $zip->locateName('xl/vbaProject.bin') !== false;
  684. $zip->close();
  685. return $hasMacros;
  686. } else {
  687. return false; // 无法打开文件
  688. }
  689. } elseif ($extension === 'docx') {
  690. // 检查 .docx 文件
  691. $zip = new ZipArchive();
  692. if ($zip->open($filePath) === TRUE) {
  693. // 检查是否存在 vbaProject.bin 文件
  694. $hasMacros = $zip->locateName('word/vbaProject.bin') !== false;
  695. $zip->close();
  696. return $hasMacros;
  697. } else {
  698. return false; // 无法打开文件
  699. }
  700. } else {
  701. return false; // 不是支持的文件类型
  702. }
  703. }
  704. public static function arrayKeyToInt($arr){
  705. $ret = array();
  706. foreach($arr as $key => $val){
  707. $ret[] = $val;
  708. }
  709. return $ret;
  710. }
  711. public static function getDailyAndweeklyFrist($arr){
  712. $numericRecords = count($arr);
  713. $ret = array();
  714. $numericRecords_one = 0;
  715. $numericRecords_two = 0;
  716. foreach($arr as $key => $val){
  717. if($key == 0){
  718. $val["numericRecords"] = $numericRecords;
  719. $ret = $val;
  720. }
  721. if($val["notifiation_type"] == "Departure/Arrival_Delay"){
  722. if(utils::checkExist($val["delay_name"],"Departure_Delay")){
  723. $numericRecords_one +=1;
  724. }
  725. if(utils::checkExist($val["delay_name"],"Arrival_Delay")){
  726. $numericRecords_two +=1;
  727. }
  728. }
  729. if($val["notifiation_type"] == "ETD/ETA_Change"){
  730. if(utils::checkExist($val["date_change_name"],"ETD Change")){
  731. $numericRecords_one +=1;
  732. }
  733. if(utils::checkExist($val["date_change_name"],"ETA Change")){
  734. $numericRecords_two +=1;
  735. }
  736. }
  737. }
  738. //对Delay and change 特殊处理
  739. $ret["numericRecords_one"]= $numericRecords_one;
  740. $ret["numericRecords_two"]= $numericRecords_two;
  741. return $ret;
  742. }
  743. /**
  744. * ocean ->sea
  745. */
  746. public static function converModeToDB($shipment_transport_mode_arr){
  747. $converMode = array();
  748. foreach($shipment_transport_mode_arr as $model){
  749. if (strtolower($model) == "ocean"){
  750. $converMode[] = 'sea';
  751. }else{
  752. $converMode[] = strtolower($model);
  753. }
  754. }
  755. return utils::implode(";",$converMode);
  756. }
  757. /**
  758. * sea ->ocean
  759. */
  760. public static function converModeToDisplay($shipment_transport_mode){
  761. //数据转换前端需要的
  762. $converMode = array();
  763. $shipment_transport_mode_arr = explode(";", $shipment_transport_mode);
  764. foreach($shipment_transport_mode_arr as $model){
  765. if (strtolower($model) == "sea"){
  766. $converMode[] = 'Ocean';
  767. }else{
  768. $converMode[] = ucfirst($model);
  769. }
  770. }
  771. return utils::implode(";",$converMode);
  772. }
  773. public static function compareArrayEq($array1,$array2){
  774. $array1 = empty($array1) ? array():$array1;
  775. $array2 = empty($array2) ? array():$array2;
  776. // 使用array_diff比较并重置键名
  777. $diff1 = array_diff($array1, $array2);
  778. $diff2 = array_diff($array2, $array1);
  779. // 如果结果为空,说明两个数组一样
  780. if (empty($diff1) && empty($diff2)) {
  781. return true;
  782. } else {
  783. return false;
  784. }
  785. }
  786. public static function comvertutcinfo($time_zone){
  787. if(!empty($time_zone)){
  788. if(utils::checkExist($time_zone,"+")){
  789. $time_zone = str_replace('+', '-', $time_zone);
  790. }else{
  791. $time_zone = str_replace('-', '+', $time_zone);
  792. }
  793. }
  794. return $time_zone;
  795. }
  796. public static function arrayOrderBykeys($order,$data_kd,$key){
  797. $orderedData = []; // 用于存储按$order排序后的数据
  798. foreach ($order as $name) {
  799. foreach ($data_kd as $item) {
  800. if ($item[$key] == $name) {
  801. $orderedData[] = $item; // 将找到的元素添加到新数组中
  802. break; // 找到后跳出内层循环,继续外层循环处理下一个id
  803. }
  804. }
  805. }
  806. return $orderedData;
  807. }
  808. /**
  809. * 数组去掉null
  810. */
  811. public static function arrayRemoveNull($array){
  812. foreach ($array as &$value) {
  813. if (is_null($value)) {
  814. $value = '';
  815. }
  816. }
  817. unset($value); // 断开 $value 的引用
  818. return $array;
  819. }
  820. /**
  821. * public.kln_ocean 和 WHERE 的位置关系,进行条件拼接
  822. */
  823. public static function modifyString($input,$sqlWhere) {
  824. $search = 'public.kln_ocean';
  825. $pos = strpos($input, $search);
  826. if ($pos !== false) {
  827. $afterSearch = substr($input, $pos + strlen($search));
  828. $hasWhere = (stripos($afterSearch, 'WHERE') !== false);
  829. if ($hasWhere) {
  830. // 在 WHERE 后插入 1=1
  831. $wherePos = stripos($input, 'WHERE', $pos);
  832. $insertPos = $wherePos + strlen('WHERE');
  833. $sqlWhere =' ' .$sqlWhere.' and ';
  834. return substr_replace($input, $sqlWhere, $insertPos, 0);
  835. } else {
  836. // 在 public.kln_ocean 后插入 1=1
  837. $insertPos = $pos + strlen($search);
  838. $sqlWhere =' where ' .$sqlWhere.' ';
  839. return substr_replace($input, $sqlWhere, $insertPos, 0);
  840. }
  841. }
  842. return $input;
  843. }
  844. /**
  845. * LIMIT的处理,或者超过10
  846. */
  847. public static function processLimitClause($sql) {
  848. // 查找不区分大小写的 LIMIT 位置
  849. $limitPos = stripos($sql, 'LIMIT');
  850. if ($limitPos !== false) {
  851. // 截取 LIMIT 之前的部分,拼接固定内容
  852. $processed = substr($sql, 0, $limitPos) . 'LIMIT 10';
  853. } else {
  854. // 无 LIMIT 时直接追加
  855. $processed = $sql . ' LIMIT 10';
  856. }
  857. return $processed;
  858. }
  859. /**
  860. * 替换 single reference
  861. */
  862. public static function replacements($data, $template,$new_sql) {
  863. // 动态构建替换数组(格式:[key] => value)
  864. $replacements = [];
  865. foreach ($data as $key => $value) {
  866. $replacements["{{$key}}"] = $value;
  867. $replacements["{{{$key}}}"] = $value;
  868. }
  869. if(empty($data)){
  870. $fileds = common::extractSelectFields($new_sql);
  871. foreach($fileds as $key){
  872. $replacements["{{$key}}"] = "";
  873. $replacements["{{{$key}}}"] = "";
  874. }
  875. }
  876. // 执行替换
  877. $result = strtr($template, $replacements);
  878. // 输出结果
  879. return $result;
  880. }
  881. /**
  882. * 替换复杂的reference
  883. */
  884. public static function replacementsMultiline($data, $template,$new_sql) {
  885. //| {{h_bol}} | {{m_bol}} | {{transport_mode}} | {{service}} | 格式
  886. $replaceTemplate = "";
  887. $explode_str = "|";
  888. foreach($data as $key => $val){
  889. if($key == 0){
  890. foreach($val as $field => $fieldVal){
  891. $explode_str.=" {{{$field}}} |";
  892. }
  893. }else{
  894. continue;
  895. }
  896. }
  897. if(empty($data)){
  898. $fileds = common::extractSelectFields($new_sql);
  899. foreach($fileds as $fieldVal){
  900. $explode_str.=" {{{$fieldVal}}} |";
  901. }
  902. }
  903. //检查模板 是否已经带有特定表格的序列
  904. if(strpos($template, $explode_str) !== false){
  905. $spacing = utils::getMarkDownTableSpacing($template,$explode_str);
  906. $parts = explode("$explode_str", $template,2);
  907. // 生成所有行
  908. $generatedRows = [];
  909. foreach ($data as $row) {
  910. $replacements = [];
  911. foreach ($row as $key => $value) {
  912. $replacements["{{{$key}}}"] = $value;
  913. }
  914. $generatedRows[] = strtr($explode_str, $replacements);
  915. }
  916. $replaceTemplate = $parts[0] . implode($spacing, $generatedRows) . $parts[1];
  917. }else{
  918. //全文替换 上面统一有excuteListSql 这里的结果要变一下
  919. $replaceTemplate = utils::replacements($data[0],$template,$new_sql);
  920. }
  921. return $replaceTemplate;
  922. }
  923. /**
  924. * 替换复杂的reference 固定问题 分开
  925. */
  926. public static function replacementsFixedMultilineForFixed($data, $template,$explode_str) {
  927. //| {{h_bol}} | {{m_bol}} | {{transport_mode}} | {{service}} | 格式
  928. $replaceTemplate = "";
  929. //检查模板 是否已经带有特定表格的序列
  930. if(strpos($template, $explode_str) !== false){
  931. $spacing = utils::getMarkDownTableSpacing($template,$explode_str);
  932. $parts = explode("$explode_str", $template,2);
  933. // 生成所有行
  934. $generatedRows = [];
  935. foreach ($data as $row) {
  936. $replacements = [];
  937. foreach ($row as $key => $value) {
  938. $replacements["{{{$key}}}"] = $value;
  939. }
  940. $generatedRows[] = strtr($explode_str, $replacements);
  941. }
  942. $replaceTemplate = $parts[0] . implode($spacing, $generatedRows) . $parts[1];
  943. }else{
  944. //有异常,模板原样返回
  945. $replaceTemplate = $template;
  946. }
  947. return $replaceTemplate;
  948. }
  949. /**
  950. * 替换 single reference Fixed
  951. */
  952. public static function replacementsFixed($data, $template,$fileds) {
  953. // 动态构建替换数组(格式:[key] => value)
  954. $replacements = [];
  955. foreach ($data as $key => $value) {
  956. $replacements["{{$key}}"] = $value;
  957. $replacements["{{{$key}}}"] = $value;
  958. }
  959. if(empty($data)){
  960. foreach($fileds as $key){
  961. $replacements["{{$key}}"] = "";
  962. $replacements["{{{$key}}}"] = "";
  963. }
  964. }
  965. // 执行替换
  966. $result = strtr($template, $replacements);
  967. // 输出结果
  968. return $result;
  969. }
  970. public static function getMarkDownTableSpacing($str,$search){
  971. //$str = "|--------------|\n sdsds| E1205546127 | ";
  972. //$search = "| E1205546127 |";
  973. // 查找搜索字符串的位置
  974. $pos = strpos($str, $search);
  975. if ($pos !== false) {
  976. // 从搜索字符串前面开始向前查找 "|" 的位置
  977. for ($i = $pos - 1; $i >= 0; $i--) {
  978. if ($str[$i] === '|') {
  979. // 提取两个位置之间的内容
  980. $result = substr($str, $i + 1, $pos - $i - 1);
  981. return $result;
  982. }
  983. }
  984. } else {
  985. return "\n";
  986. }
  987. }
  988. public static function uniqueGroupbyData($unique_filed,$groups_filed,$rows){
  989. $uniqueData = [];
  990. $hBolSeen = [];
  991. //需要去重
  992. if(!empty($unique_filed)){
  993. foreach ($rows as $row) {
  994. $hBol = $row[$unique_filed]."_".$row[$groups_filed];
  995. if (!isset($hBolSeen[$hBol])) {
  996. $uniqueData[] = $row;
  997. $hBolSeen[$hBol] = true;
  998. }
  999. }
  1000. } else {
  1001. //不需要去重
  1002. $uniqueData = $rows;
  1003. }
  1004. //分组计数
  1005. $dateGroups = [];
  1006. if(!empty($groups_filed)){
  1007. foreach ($uniqueData as $item) {
  1008. $date = $item[$groups_filed];
  1009. if (!isset($dateGroups[$date])) {
  1010. $dateGroups[$date] = 0;
  1011. }
  1012. $dateGroups[$date]++;
  1013. }
  1014. }
  1015. return $dateGroups;
  1016. }
  1017. public static function getDmoeSqlForAi($type){
  1018. $data= array();
  1019. $data["Show shipments delayed in the last 30 days."] = "select count(*)
  1020. from public.kln_record kr
  1021. inner join LATERAL (select h_bol from public.kln_ocean oo where oo.serial_no = kr.serial_no and <{ExtendHand_KLN}> ) m on true
  1022. where kr.log_type like '%Delay'
  1023. and kr.log_time >= CURRENT_DATE - INTERVAL '30 day'
  1024. and kr.event_date is not null and kr.event_old_date is not null
  1025. and (kr.event_date||' '||COALESCE(kr.event_time,'00:00'))::timestamp >= (kr.event_old_date||' '||COALESCE(kr.event_old_time,'00:00'))::timestamp;select oo.h_bol,oo.place_of_receipt_exp,oo.place_of_delivery_exp,oo.serial_no,oo.order_from,
  1026. kr.log_type,kr.event_old_date, kr.event_old_time,kr.event_date, kr.event_time,
  1027. (EXTRACT(DAY FROM ((event_date||' '||COALESCE(event_time,'00:00'))::timestamp - (event_old_date||' '||COALESCE(event_old_time,'00:00'))::timestamp))) as duration
  1028. from public.kln_record kr
  1029. inner join LATERAL (select h_bol, place_of_receipt_exp, place_of_delivery_exp,serial_no,order_from
  1030. from public.kln_ocean oo where oo.serial_no = kr.serial_no and <{ExtendHand_KLN}> ) oo on true
  1031. where kr.log_type like '%Delay'
  1032. and kr.log_time >= CURRENT_DATE - INTERVAL '30 day'
  1033. and kr.event_date is not null and kr.event_old_date is not null
  1034. and (kr.event_date||' '||COALESCE(kr.event_time,'00:00'))::timestamp >= (kr.event_old_date||' '||COALESCE(kr.event_old_time,'00:00'))::timestamp
  1035. order by kr.log_time desc limit 10";
  1036. $data["Shipments arriving in the next 7 days."] = "select count(*)
  1037. from (
  1038. SELECT oo.serial_no,h_bol, place_of_receipt_exp, place_of_delivery_exp,m.description,eta,order_from, o.cargo_type
  1039. FROM public.kln_ocean oo
  1040. inner join LATERAL (select case when is_hazardous = 't' then 'Dangerous Goods'::text else 'General'::text end as cargo_type
  1041. from public.ocean o where o.serial_no = oo.serial_no) o on true
  1042. left join LATERAL (select a.code,a.description
  1043. from public.ocean_milestone a
  1044. inner join public.customer_service_milestone_sno s
  1045. on a.code = s.code
  1046. and s.type = 'sea'
  1047. and a.serial_no = oo.serial_no
  1048. and a.act_date is not null
  1049. order by s.sno desc limit 1) m on true
  1050. WHERE <{ExtendHand_KLN}> and oo.transport_mode = 'sea' and order_from = 'public' and m.code <> '' limit 10
  1051. ) t;select serial_no,h_bol,place_of_receipt_exp,place_of_delivery_exp,description,eta,order_from,cargo_type
  1052. from (
  1053. SELECT oo.serial_no,h_bol, place_of_receipt_exp, place_of_delivery_exp,m.description,eta,order_from, o.cargo_type
  1054. FROM public.kln_ocean oo
  1055. inner join LATERAL (select case when is_hazardous = 't' then 'Dangerous Goods'::text else 'General'::text end as cargo_type
  1056. from public.ocean o where o.serial_no = oo.serial_no) o on true
  1057. left join LATERAL (select a.code,a.description
  1058. from public.ocean_milestone a
  1059. inner join public.customer_service_milestone_sno s
  1060. on a.code = s.code
  1061. and s.type = 'sea'
  1062. and a.serial_no = oo.serial_no
  1063. and a.act_date is not null
  1064. order by s.sno desc limit 1) m on true
  1065. WHERE <{ExtendHand_KLN}> and oo.transport_mode = 'sea' and order_from = 'public' and m.code <> '' limit 20
  1066. ) t order by eta";
  1067. $data["List shipments with milestone updates in the last 7 days."] = "select count(*)
  1068. from (
  1069. select serial_no
  1070. from (SELECT oo.serial_no from public.ocean_milestone a
  1071. inner join public.customer_service_milestone_sno s on a.code = s.code
  1072. inner join public.kln_ocean oo on oo.serial_no = a.serial_no and (<{ExtendHand_KLN}>)
  1073. where s.type = 'sea'
  1074. and a.act_date is not null
  1075. and COALESCE(a.update_date, a.create_date) >= CURRENT_DATE - INTERVAL '7 days') po
  1076. union all
  1077. select serial_no
  1078. from (SELECT oo.serial_no from public.air_milestone a
  1079. inner join public.customer_service_milestone_sno s on a.code = s.code
  1080. inner join public.kln_ocean oo on oo.serial_no = a.serial_no and (<{ExtendHand_KLN}>)
  1081. where s.type = 'air'
  1082. and a.act_date is not null
  1083. and COALESCE(a.update_date, a.create_date) >= CURRENT_DATE - INTERVAL '7 days') pa
  1084. union all
  1085. select serial_no
  1086. from (SELECT oo.serial_no from sfs.air_milestone a
  1087. inner join public.customer_service_milestone_sno s on a.code = s.code
  1088. inner join public.kln_ocean oo on oo.serial_no = a.serial_no and (<{ExtendHand_KLN}>)
  1089. where s.type = 'air'
  1090. and a.act_date is not null
  1091. and COALESCE(a.update_date, a.create_date) >= CURRENT_DATE - INTERVAL '7 days') sa
  1092. )t;select serial_no,order_from,h_bol, description,update_date_format,update_date,
  1093. COALESCE(m.jsonb_data->>'milestone','')::jsonb->>'timezone' as timezone,
  1094. COALESCE(m.jsonb_data->>'milestone','')::jsonb->>'locations' as locations
  1095. from (
  1096. select serial_no,order_from,h_bol,description,to_char(update_date,'Mon DD') as update_date_format,update_date,code
  1097. from (SELECT oo.serial_no,oo.order_from,oo.h_bol,s.description,COALESCE(a.update_date, a.create_date) as update_date,a.code
  1098. from public.ocean_milestone a
  1099. inner join public.customer_service_milestone_sno s on a.code = s.code
  1100. inner join public.kln_ocean oo on oo.serial_no = a.serial_no and (<{ExtendHand_KLN}>)
  1101. where s.type = 'sea'
  1102. and a.act_date is not null
  1103. and COALESCE(a.update_date, a.create_date) >= CURRENT_DATE - INTERVAL '7 days') po
  1104. union all
  1105. select serial_no,order_from,h_bol,description,to_char(update_date,'Mon DD')as update_date_format,update_date,code
  1106. from (SELECT oo.serial_no,oo.order_from,oo.h_bol,s.description,COALESCE(a.update_date, a.create_date) as update_date,a.code
  1107. from public.air_milestone a
  1108. inner join public.customer_service_milestone_sno s on a.code = s.code
  1109. inner join public.kln_ocean oo on oo.serial_no = a.serial_no and (<{ExtendHand_KLN}>)
  1110. where s.type = 'air'
  1111. and a.act_date is not null
  1112. and COALESCE(a.update_date, a.create_date) >= CURRENT_DATE - INTERVAL '7 days') pa
  1113. union all
  1114. select serial_no,order_from,h_bol,description,to_char(update_date,'Mon DD')as update_date_format,update_date,code
  1115. from (SELECT oo.serial_no,oo.order_from,oo.h_bol,s.description,COALESCE(a.update_date, a.create_date) as update_date,a.code
  1116. from sfs.air_milestone a
  1117. inner join public.customer_service_milestone_sno s on a.code = s.code
  1118. inner join public.kln_ocean oo on oo.serial_no = a.serial_no and (<{ExtendHand_KLN}>)
  1119. where s.type = 'air'
  1120. and a.act_date is not null
  1121. and COALESCE(a.update_date, a.create_date) >= CURRENT_DATE - INTERVAL '7 days') sa
  1122. )t left join LATERAL (select public.getTimeAndLocationForKln(serial_no,code,''::text)::jsonb as jsonb_data) m on true
  1123. order by update_date limit 10;select aa.update_date_format, COUNT(*) AS total_count
  1124. from (
  1125. select DISTINCT ON (h_bol) h_bol, update_date_format
  1126. from (
  1127. select h_bol,to_char(update_date,'Mon DD') as update_date_format
  1128. from (SELECT oo.h_bol,COALESCE(a.update_date, a.create_date) as update_date
  1129. from public.ocean_milestone a
  1130. inner join public.kln_ocean oo on oo.serial_no = a.serial_no and (<{ExtendHand_KLN}>)
  1131. where a.act_date is not null
  1132. and COALESCE(a.update_date, a.create_date) >= CURRENT_DATE - INTERVAL '7 days') po
  1133. union all
  1134. select h_bol,to_char(update_date,'Mon DD') as update_date_format
  1135. from (SELECT oo.h_bol,COALESCE(a.update_date, a.create_date) as update_date
  1136. from public.air_milestone a
  1137. inner join public.kln_ocean oo on oo.serial_no = a.serial_no and (<{ExtendHand_KLN}>)
  1138. where a.act_date is not null
  1139. and COALESCE(a.update_date, a.create_date) >= CURRENT_DATE - INTERVAL '7 days') pa
  1140. union all
  1141. select h_bol,to_char(update_date,'Mon DD') as update_date_format
  1142. from (SELECT oo.h_bol,COALESCE(a.update_date, a.create_date) as update_date
  1143. from sfs.air_milestone a
  1144. inner join public.kln_ocean oo on oo.serial_no = a.serial_no and (<{ExtendHand_KLN}>)
  1145. where a.act_date is not null
  1146. and COALESCE(a.update_date, a.create_date) >= CURRENT_DATE - INTERVAL '7 days') sa
  1147. )t order by h_bol
  1148. ) aa
  1149. group by aa.update_date_format order by aa.update_date_format ";
  1150. $data["What is the current status of my active shipments?"] ="SELECT count(*)
  1151. FROM public.kln_ocean oo
  1152. WHERE <{ExtendHand_KLN}> and ((oo.ata is not null and oo.ata >= CURRENT_DATE - INTERVAL '3 months' AND oo.ata < CURRENT_DATE)
  1153. or not exists( select 1 from public.ocean_milestone a where a.serial_no = oo.serial_no and a.act_date is not null and a.code = 'IFFDEL')) and oo.transport_mode = 'sea' and order_from = 'public';with oo as(
  1154. SELECT h_bol, place_of_receipt_exp, place_of_delivery_exp,serial_no,transport_mode,order_from
  1155. FROM public.kln_ocean oo
  1156. WHERE <{ExtendHand_KLN}> and ((oo.ata is not null and oo.ata >= CURRENT_DATE - INTERVAL '3 months' AND oo.ata < CURRENT_DATE)
  1157. or not exists( select 1 from public.ocean_milestone a where a.serial_no = oo.serial_no and a.act_date is not null and a.code = 'IFFDEL')) and oo.transport_mode = 'sea' and order_from = 'public' order by id limit 10
  1158. )
  1159. SELECT oo.*,mil.description,mil.act_date,mil.act_time,o.cargo_type,
  1160. COALESCE(jsonb_data->>'milestone','')::jsonb->>'timezone' as timezone,
  1161. COALESCE(jsonb_data->>'milestone','')::jsonb->>'locations' as locations
  1162. from oo
  1163. inner join LATERAL (select case when is_hazardous = 't' then 'Dangerous Goods'::text else 'General'::text end as cargo_type
  1164. from public.ocean o where o.serial_no = oo.serial_no) o on true
  1165. left join LATERAL (select a.code,s.description,to_char(a.act_date, 'YYYY-MM-DD') as act_date ,a.act_time
  1166. from public.ocean_milestone a
  1167. left join public.customer_service_milestone_sno s on a.code = s.code
  1168. and s.type = 'sea'
  1169. and a.serial_no = oo.serial_no
  1170. and a.act_date is not null
  1171. order by s.sno desc limit 1) mil on true
  1172. left join LATERAL (select public.getTimeAndLocationForKln(oo.serial_no,mil.code,''::text)::jsonb as jsonb_data) lt on true
  1173. where oo.transport_mode = 'sea' and order_from = 'public'
  1174. union all
  1175. SELECT oo.*,mil.description,mil.act_date,mil.act_time,o.cargo_type,
  1176. COALESCE(jsonb_data->>'milestone','')::jsonb->>'timezone' as timezone,
  1177. COALESCE(jsonb_data->>'milestone','')::jsonb->>'locations' as locations
  1178. from oo
  1179. inner join LATERAL (select case when is_hazardous = 't' then 'Dangerous Goods'::text else 'General'::text end as cargo_type
  1180. from sfs.ocean o where o.serial_no = oo.serial_no) o on true
  1181. left join LATERAL (select a.code,s.description,to_char(a.act_date, 'YYYY-MM-DD') as act_date ,a.act_time
  1182. from public.ocean_milestone a
  1183. left join public.customer_service_milestone_sno s on a.code = s.code
  1184. and s.type = 'air'
  1185. and a.serial_no = oo.serial_no
  1186. and a.act_date is not null
  1187. order by s.sno desc limit 1) mil on true
  1188. left join LATERAL (select public.getTimeAndLocationForKln(oo.serial_no,mil.code,''::text)::jsonb as jsonb_data) lt on true
  1189. where oo.transport_mode = 'sea' and order_from = 'sfs'
  1190. union all
  1191. SELECT oo.*,mil.description,mil.act_date,mil.act_time,o.cargo_type,
  1192. COALESCE(jsonb_data->>'milestone','')::jsonb->>'timezone' as timezone,
  1193. COALESCE(jsonb_data->>'milestone','')::jsonb->>'locations' as locations
  1194. from oo
  1195. inner join LATERAL (select case when is_hazardous = 't' then 'Dangerous Goods'::text else 'General'::text end as cargo_type
  1196. from public.ocean o where o.serial_no = oo.serial_no) o on true
  1197. left join LATERAL (select a.code,s.description,to_char(a.act_date, 'YYYY-MM-DD') as act_date ,a.act_time
  1198. from public.air_milestone a
  1199. left join public.customer_service_milestone_sno s on a.code = s.code
  1200. and s.type = 'air'
  1201. and a.serial_no = oo.serial_no
  1202. and a.act_date is not null
  1203. order by s.sno desc limit 1) mil on true
  1204. left join LATERAL (select public.getTimeAndLocationForKln(oo.serial_no,mil.code,''::text)::jsonb as jsonb_data) lt on true
  1205. where oo.transport_mode = 'air' and order_from = 'public'
  1206. union all
  1207. SELECT oo.*,mil.description,mil.act_date,mil.act_time,o.cargo_type,
  1208. COALESCE(jsonb_data->>'milestone','')::jsonb->>'timezone' as timezone,
  1209. COALESCE(jsonb_data->>'milestone','')::jsonb->>'locations' as locations
  1210. from oo
  1211. inner join LATERAL (select case when is_hazardous = 't' then 'Dangerous Goods'::text else 'General'::text end as cargo_type
  1212. from sfs.ocean o where o.serial_no = oo.serial_no) o on true
  1213. left join LATERAL (select a.code,s.description,to_char(a.act_date, 'YYYY-MM-DD') as act_date ,a.act_time
  1214. from sfs.air_milestone a
  1215. left join public.customer_service_milestone_sno s on a.code = s.code
  1216. and s.type = 'air'
  1217. and a.serial_no = oo.serial_no
  1218. and a.act_date is not null
  1219. order by s.sno desc limit 1) mil on true
  1220. left join LATERAL (select public.getTimeAndLocationForKln(oo.serial_no,mil.code,''::text)::jsonb as jsonb_data) lt on true
  1221. where oo.transport_mode = 'air' and order_from = 'sfs'";
  1222. $data["List shipments with container status updates in the last 7 days."] = "select count(*)
  1223. FROM ra_online_container_status s
  1224. LEFT JOIN oc_container oc ON s.status_id = oc.status_id
  1225. LEFT JOIN ocean o ON o.serial_no::text = oc.serial_no::text
  1226. LEFT JOIN public.ra_online_edi_event e on s.event_base = e.ra_name
  1227. WHERE o.status::text <> 'Cancelled'::text
  1228. and is_display = true
  1229. and s.insert_date <= CURRENT_DATE AND s.insert_date >='2023-02-23'
  1230. and exists(select 1 from kln_ocean oo where <{ExtendHand_KLN}> and oo.serial_no = o.serial_no);select oo.serial_no,oo.order_from,s.event_base as event,s.container_no,
  1231. to_char(to_timestamp(s.event_date, 'YYYYMMDD'), 'YYYY-MM-DD') as eventdate,
  1232. to_char(to_timestamp(s.event_date, 'YYYYMMDD'),'Mon DD') as _eventdate,
  1233. to_char(to_timestamp(s.event_time, 'HH24MI'), 'HH24:MI') as eventtime,
  1234. (select time_zone from public.city_timezone where uncode = s.event_code) as timezone,
  1235. e.description,
  1236. s.event_city as uncity
  1237. FROM ra_online_container_status s
  1238. LEFT JOIN oc_container oc ON s.status_id = oc.status_id
  1239. LEFT JOIN ocean o ON o.serial_no::text = oc.serial_no::text
  1240. LEFT JOIN public.ra_online_edi_event e on s.event_base = e.ra_name
  1241. LEFT JOIN public.kln_ocean oo ON oo.serial_no::text = o.serial_no::text
  1242. WHERE o.status::text <> 'Cancelled'::text
  1243. and is_display = true
  1244. and s.insert_date <= CURRENT_DATE AND s.insert_date >='2023-02-23'
  1245. and exists(select 1 from kln_ocean oo where <{ExtendHand_KLN}> and oo.serial_no = o.serial_no) limit 10;select aa._eventdate, COUNT(*) AS total_count
  1246. from (select DISTINCT ON (s.container_no) s.container_no,
  1247. to_char(to_timestamp(s.event_date, 'YYYYMMDD'),'Mon DD') as _eventdate
  1248. FROM ra_online_container_status s
  1249. LEFT JOIN oc_container oc ON s.status_id = oc.status_id
  1250. LEFT JOIN ocean o ON o.serial_no::text = oc.serial_no::text
  1251. LEFT JOIN public.ra_online_edi_event e on s.event_base = e.ra_name
  1252. WHERE o.status::text <> 'Cancelled'::text
  1253. and is_display = true
  1254. and s.insert_date <= CURRENT_DATE AND s.insert_date >='2023-02-23'
  1255. and exists(select 1 from kln_ocean oo where <{ExtendHand_KLN}> and oo.serial_no = o.serial_no)
  1256. order by s.container_no
  1257. )aa group by _eventdate order by _eventdate";
  1258. $data["Today's shipments summary."] = "select count(*)
  1259. from (
  1260. select oo.serial_no
  1261. from (
  1262. select t.serial_no from (
  1263. SELECT
  1264. a.serial_no,
  1265. ROW_NUMBER() OVER(PARTITION BY a.serial_no ORDER BY s.sno DESC) AS rn
  1266. from public.ocean_milestone a
  1267. left join public.customer_service_milestone_sno s on a.code = s.code
  1268. where s.type = 'sea'
  1269. and a.act_date is not null
  1270. --and a.update_date >= CURRENT_DATE AND a.update_date < CURRENT_DATE + INTERVAL '1 day'
  1271. )t WHERE rn = 1
  1272. ) po inner join public.kln_ocean oo on oo.serial_no = po.serial_no and (<{ExtendHand_KLN}>)
  1273. union all
  1274. select oo.serial_no
  1275. from (
  1276. select t.serial_no from (
  1277. SELECT
  1278. a.code,a.serial_no,
  1279. ROW_NUMBER() OVER(PARTITION BY a.serial_no ORDER BY s.sno DESC) AS rn
  1280. from public.air_milestone a
  1281. left join public.customer_service_milestone_sno s on a.code = s.code
  1282. where s.type = 'sea'
  1283. and a.act_date is not null
  1284. --and a.update_date >= CURRENT_DATE AND a.update_date < CURRENT_DATE + INTERVAL '1 day'
  1285. )t WHERE rn = 1
  1286. ) pa inner join public.kln_ocean oo on oo.serial_no = pa.serial_no and (<{ExtendHand_KLN}>)
  1287. union all
  1288. select oo.serial_no
  1289. from (
  1290. select t.serial_no from (
  1291. SELECT
  1292. a.serial_no,
  1293. ROW_NUMBER() OVER(PARTITION BY a.serial_no ORDER BY s.sno DESC) AS rn
  1294. from sfs.air_milestone a
  1295. left join public.customer_service_milestone_sno s on a.code = s.code
  1296. where s.type = 'sea'
  1297. and a.act_date is not null
  1298. --and a.update_date >= CURRENT_DATE AND a.update_date < CURRENT_DATE + INTERVAL '1 day'
  1299. )t WHERE rn = 1
  1300. ) sa inner join public.kln_ocean oo on oo.serial_no = sa.serial_no and (<{ExtendHand_KLN}>)
  1301. )t;select *
  1302. from (
  1303. select *,oo.serial_no,oo.order_from,oo.h_bol,oo.transport_mode,oo.place_of_receipt_exp, oo.place_of_delivery_exp,
  1304. COALESCE(jsonb_data->>'milestone','')::jsonb->>'timezone' as timezone,
  1305. COALESCE(jsonb_data->>'milestone','')::jsonb->>'locations' as locations
  1306. from (
  1307. select *,public.getTimeAndLocationForKln(t.serial_no,t.code,''::text)::jsonb as jsonb_data
  1308. from (
  1309. SELECT
  1310. case when a.code = 'IFFDEP' then 'Departure'
  1311. when a.code = 'IFFARR' then 'Arrived'
  1312. when a.code = 'IFFDEL' then 'Delivered'
  1313. else s.description end as action_type,
  1314. a.update_date,a.code,a.serial_no,
  1315. to_char(a.update_date, 'Mon_DD_YYYY') as _update_date,
  1316. to_char(a.act_date, 'YYYY-MM-DD') as act_date ,
  1317. a.act_time,
  1318. ROW_NUMBER() OVER(PARTITION BY a.serial_no ORDER BY s.sno DESC) AS rn
  1319. from public.ocean_milestone a
  1320. left join public.customer_service_milestone_sno s on a.code = s.code
  1321. where s.type = 'sea'
  1322. and a.act_date is not null
  1323. --and a.update_date >= CURRENT_DATE AND a.update_date < CURRENT_DATE + INTERVAL '1 day'
  1324. )t WHERE rn = 1
  1325. ) po inner join public.kln_ocean oo on oo.serial_no = po.serial_no
  1326. union all
  1327. select *,oo.serial_no,oo.order_from,oo.h_bol,oo.transport_mode,oo.place_of_receipt_exp, oo.place_of_delivery_exp,
  1328. COALESCE(jsonb_data->>'milestone','')::jsonb->>'timezone' as timezone,
  1329. COALESCE(jsonb_data->>'milestone','')::jsonb->>'locations' as locations
  1330. from (
  1331. select *,public.getTimeAndLocationForKln(t.serial_no,t.code,''::text)::jsonb as jsonb_data
  1332. from (
  1333. SELECT
  1334. case when a.code = 'IFFDEP' then 'Departure'
  1335. when a.code = 'IFFARR' then 'Arrived'
  1336. when a.code = 'IFFDEL' then 'Delivered'
  1337. else s.description end as action_type,
  1338. a.update_date,a.code,a.serial_no,
  1339. to_char(a.update_date, 'Mon_DD_YYYY') as _update_date,
  1340. to_char(a.act_date, 'YYYY-MM-DD') as act_date ,
  1341. a.act_time,
  1342. ROW_NUMBER() OVER(PARTITION BY a.serial_no ORDER BY s.sno DESC) AS rn
  1343. from public.air_milestone a
  1344. left join public.customer_service_milestone_sno s on a.code = s.code
  1345. where s.type = 'sea'
  1346. and a.act_date is not null
  1347. --and a.update_date >= CURRENT_DATE AND a.update_date < CURRENT_DATE + INTERVAL '1 day'
  1348. )t WHERE rn = 1
  1349. ) pa inner join public.kln_ocean oo on oo.serial_no = pa.serial_no
  1350. union all
  1351. select *,oo.serial_no,oo.order_from,oo.h_bol,oo.transport_mode,oo.place_of_receipt_exp, oo.place_of_delivery_exp,
  1352. COALESCE(jsonb_data->>'milestone','')::jsonb->>'timezone' as timezone,
  1353. COALESCE(jsonb_data->>'milestone','')::jsonb->>'locations' as locations
  1354. from (
  1355. select *,public.getTimeAndLocationForKln(t.serial_no,t.code,''::text)::jsonb as jsonb_data
  1356. from (
  1357. SELECT
  1358. case when a.code = 'IFFDEP' then 'Departure'
  1359. when a.code = 'IFFARR' then 'Arrived'
  1360. when a.code = 'IFFDEL' then 'Delivered'
  1361. else s.description end as action_type,
  1362. a.update_date,a.code,a.serial_no,
  1363. to_char(a.update_date, 'Mon_DD_YYYY') as _update_date,
  1364. to_char(a.act_date, 'YYYY-MM-DD') as act_date ,
  1365. a.act_time,
  1366. ROW_NUMBER() OVER(PARTITION BY a.serial_no ORDER BY s.sno DESC) AS rn
  1367. from sfs.air_milestone a
  1368. left join public.customer_service_milestone_sno s on a.code = s.code
  1369. where s.type = 'sea'
  1370. and a.act_date is not null
  1371. --and a.update_date >= CURRENT_DATE AND a.update_date < CURRENT_DATE + INTERVAL '1 day'
  1372. )t WHERE rn = 1
  1373. ) sa inner join public.kln_ocean oo on oo.serial_no = sa.serial_no
  1374. )t limit 10;select sum(case when (action_type='Departure') then 1 else 0 end) as dep,
  1375. sum(case when (action_type='Arrived') then 1 else 0 end) as arr,
  1376. sum(case when (action_type='Delivered') then 1 else 0 end) as del
  1377. from (
  1378. select action_type
  1379. from (
  1380. select t.action_type,t.serial_no from (
  1381. SELECT
  1382. case when a.code = 'IFFDEP' then 'Departure'
  1383. when a.code = 'IFFARR' then 'Arrived'
  1384. when a.code = 'IFFDEL' then 'Delivered'
  1385. else s.description end as action_type,
  1386. a.serial_no,
  1387. ROW_NUMBER() OVER(PARTITION BY a.serial_no ORDER BY s.sno DESC) AS rn
  1388. from public.ocean_milestone a
  1389. left join public.customer_service_milestone_sno s on a.code = s.code
  1390. where s.type = 'sea'
  1391. and a.act_date is not null
  1392. --and a.update_date >= CURRENT_DATE AND a.update_date < CURRENT_DATE + INTERVAL '1 day'
  1393. )t WHERE rn = 1
  1394. ) po inner join public.kln_ocean oo on oo.serial_no = po.serial_no and (<{ExtendHand_KLN}>)
  1395. union all
  1396. select action_type
  1397. from (
  1398. select t.action_type,t.serial_no from (
  1399. SELECT
  1400. case when a.code = 'IFFDEP' then 'Departure'
  1401. when a.code = 'IFFARR' then 'Arrived'
  1402. when a.code = 'IFFDEL' then 'Delivered'
  1403. else s.description end as action_type,
  1404. a.serial_no,
  1405. ROW_NUMBER() OVER(PARTITION BY a.serial_no ORDER BY s.sno DESC) AS rn
  1406. from public.air_milestone a
  1407. left join public.customer_service_milestone_sno s on a.code = s.code
  1408. where s.type = 'sea'
  1409. and a.act_date is not null
  1410. --and a.update_date >= CURRENT_DATE AND a.update_date < CURRENT_DATE + INTERVAL '1 day'
  1411. )t WHERE rn = 1
  1412. ) pa inner join public.kln_ocean oo on oo.serial_no = pa.serial_no and (<{ExtendHand_KLN}>)
  1413. union all
  1414. select action_type
  1415. from (
  1416. select t.action_type,t.serial_no from (
  1417. SELECT
  1418. case when a.code = 'IFFDEP' then 'Departure'
  1419. when a.code = 'IFFARR' then 'Arrived'
  1420. when a.code = 'IFFDEL' then 'Delivered'
  1421. else s.description end as action_type,
  1422. a.serial_no,
  1423. ROW_NUMBER() OVER(PARTITION BY a.serial_no ORDER BY s.sno DESC) AS rn
  1424. from sfs.air_milestone a
  1425. left join public.customer_service_milestone_sno s on a.code = s.code
  1426. where s.type = 'sea'
  1427. and a.act_date is not null
  1428. --and a.update_date >= CURRENT_DATE AND a.update_date < CURRENT_DATE + INTERVAL '1 day'
  1429. )t WHERE rn = 1
  1430. ) sa inner join public.kln_ocean oo on oo.serial_no = sa.serial_no and (<{ExtendHand_KLN}>)
  1431. )t";
  1432. $data["Sort my active shipments by earliest arrival date."] = "select to_char(oo.eta,'DD-Mon') as eta, oo.h_bol,oo.transport_mode, oo.place_of_receipt_exp, oo.place_of_delivery_exp,oo.serial_no,oo.order_from,
  1433. case when oo.eta - CURRENT_DATE <= 0 then '< 1 days'::text
  1434. else (oo.eta - CURRENT_DATE)||' days'::text end as day_to_arr
  1435. from public.kln_ocean oo where 1=1 order by eta limit 10";
  1436. return $data[$type];
  1437. }
  1438. }
  1439. ?>