|
|
@@ -4421,23 +4421,23 @@ class common {
|
|
|
"oo.h_bol" => "hbol_hawb_no",
|
|
|
"oo.invoice_no" => "invoice_no",
|
|
|
"oo.booking_no" => "booking_no",
|
|
|
- //"oo.po_no"=>"shipment_po_no",
|
|
|
+ "COALESCE(oe.import_po_no,oo.po_no)"=>"shipment_po_no", //代表oo里的组合字段,需要特殊处理
|
|
|
"oo.quote_no" => "quote_no",
|
|
|
"oo.carrier_booking" => "carrier_booking_no",
|
|
|
"oo.contract" => "contract_no",
|
|
|
"oo.manifest_hbol" => "manifest_hbol",
|
|
|
"oo.transport_mode" => "transportation_mode",
|
|
|
"oo.service" => "service_type",
|
|
|
- //"oe.manifest_type"=>"shipment_type",
|
|
|
+ "oe.manifest_type"=>"shipment_type",
|
|
|
"oo.ex_im" => "ex_im",
|
|
|
"oo.incoterms" => "incoterms",
|
|
|
- //"oe.loadterm"=>"load_terms",
|
|
|
- //"oo.status" => "status",
|
|
|
+ "oe.loadterm"=>"load_terms",
|
|
|
+ "oo.new_status" => "status",
|
|
|
"oo.carbon_emission" => "total_co2_emission",
|
|
|
"oo.qty" => "shipment_qty",
|
|
|
"oo.piece_count" => "shipment_gross_weight",
|
|
|
"oo.weight" => "chargeable_weight",
|
|
|
- //"oe.volume"=>"shipment_volume",
|
|
|
+ "oe.volume"=>"shipment_volume",
|
|
|
"oo.shipper" => "shipper",
|
|
|
"oo.shipper_id" => "shipper_id",
|
|
|
"oo.consignee" => "consignee",
|
|
|
@@ -4463,8 +4463,8 @@ class common {
|
|
|
"oo.place_of_delivery_exp" => "place_of_delivery",
|
|
|
"oo.port_of_transshipment_name" => "port_of_transhipment",
|
|
|
"oo.carrier" => "carrier",
|
|
|
- //"oo.voyage"=>"voyage_flight",
|
|
|
- //"oo.vessel"=>"vessel_airline",
|
|
|
+ "oo._voyage"=>"voyage_flight",
|
|
|
+ "oo._vessel"=>"vessel_airline",
|
|
|
"oo.ams_status" => "ace_m1_status",
|
|
|
"oo.isisf" => "is_isf",
|
|
|
"oo.obl_set" => "obl_set",
|
|
|
@@ -4484,7 +4484,19 @@ class common {
|
|
|
"oi.grs_kgs" => "item_weight",
|
|
|
"oi.vol_cbm" => "item_volume",
|
|
|
"oi.description" => "description",
|
|
|
- "oi.inner_pcs" => "inner_pcs"
|
|
|
+ "oi.inner_pcs" => "inner_pcs",
|
|
|
+ "(COALESCE(co2_r.pickup_distances, 0) +COALESCE(co2_r.routes_distances, 0) +COALESCE(co2_r.delivery_distances, 0))" => "total_distance",
|
|
|
+ "co2_r.pickup_carbon_emission" => "pickup_co2_emission",
|
|
|
+ "co2_r.pickup_distances" => "pickup_distance",
|
|
|
+ "co2_r.routes_carbon_emission" => "main_route_co2_emission",
|
|
|
+ "co2_r.routes_distances" => "main_route_distance",
|
|
|
+ "co2_r.delivery_carbon_emission" => "delivery_co2_emission",
|
|
|
+ "co2_r.delivery_distances" => "delivery_distance",
|
|
|
+ "(SELECT case when coalesce(trim((item.value ->> 'delivery_datetime')),'') <>''
|
|
|
+ then to_timestamp(trim((item.value ->> 'delivery_datetime')), 'YYYY-MM-DD')
|
|
|
+ else '1997-01-01'::timestamp end
|
|
|
+ FROM jsonb_array_elements(oe.lmdds) item(value)
|
|
|
+ WHERE (item.value ->> 'ctnr'::text) = oc.ctnr limit 1) " => "last_mile_delivery"
|
|
|
];
|
|
|
return $kln_ocean;
|
|
|
}
|
|
|
@@ -4736,5 +4748,219 @@ class common {
|
|
|
// 3. 默认
|
|
|
return new \DateTimeZone('UTC');
|
|
|
}
|
|
|
+
|
|
|
+ // 判断某个字段是否属于特定逻辑表
|
|
|
+ // $filterFields = [
|
|
|
+ // 'Description', // 来自 oi
|
|
|
+ // 'Status', // 来自 oo
|
|
|
+ // 'Load Terms' // 来自 oe
|
|
|
+ // ];
|
|
|
+ public static function getRequiredTables(array $filterFields)
|
|
|
+ {
|
|
|
+ $FIELD_TABLE_MAP = [
|
|
|
+ // 主表 oo (kln_ocean)
|
|
|
+ 'Status' => ['oo'],
|
|
|
+ 'Transportation Mode' => ['oo'],
|
|
|
+ 'Voyage/Flight' => ['oo'],
|
|
|
+ 'Vessel/Airline' => ['oo'],
|
|
|
+ 'Container No. (House)' => ['oo'],
|
|
|
+ 'Shipment PO No.' => ['oo', 'oe'], // 可能来自 oe.import_po_no
|
|
|
+
|
|
|
+ // oc_container
|
|
|
+ 'Container No.' => ['oc'],
|
|
|
+ 'Container Size' => ['oc'],
|
|
|
+ 'Container Qty' => ['oc'],
|
|
|
+ 'Container Unit' => ['oc'],
|
|
|
+ 'Container Weight' => ['oc'],
|
|
|
+ 'Container Volume' => ['oc'],
|
|
|
+ 'Container PO No.' => ['oc'],
|
|
|
+ 'Item No.' => ['oc'],
|
|
|
+ 'Invoice No.' => ['oc'],
|
|
|
+
|
|
|
+ // oc_container_item (oi)
|
|
|
+ 'Item PO No.' => ['oi'],
|
|
|
+ 'SKU NO.' => ['oi'],
|
|
|
+ 'Item Qty' => ['oi'],
|
|
|
+ 'Item Unit' => ['oi'],
|
|
|
+ 'Item Weight' => ['oi'],
|
|
|
+ 'Item Volume' => ['oi'],
|
|
|
+ 'Description' => ['oi'],
|
|
|
+ 'Inner PCS' => ['oi'],
|
|
|
+
|
|
|
+ // kln_ocean_extend (oe)
|
|
|
+ 'Shipment Type' => ['oe'],
|
|
|
+ 'Container Size (House)' => ['oe'],
|
|
|
+ 'Load Terms' => ['oe'],
|
|
|
+
|
|
|
+ // calculate_co2_result (co2_r)
|
|
|
+ 'Total Distance' => ['co2_r'],
|
|
|
+ 'Pickup CO2 Emission' => ['co2_r'],
|
|
|
+ 'Pickup Distance' => ['co2_r'],
|
|
|
+ 'Main Route CO2 Emission' => ['co2_r'],
|
|
|
+ 'Main Route Distance' => ['co2_r'],
|
|
|
+ 'Delivery CO2 Emission' => ['co2_r'],
|
|
|
+ 'Delivery Distance' => ['co2_r'],
|
|
|
+
|
|
|
+ // 特殊字段:依赖 oc + oe
|
|
|
+ 'Last Mile Delivery' => ['oc', 'oe'],
|
|
|
+ ];
|
|
|
+
|
|
|
+ $tables = [];
|
|
|
+
|
|
|
+ foreach ($filterFields as $fieldAlias) {
|
|
|
+ if (isset($FIELD_TABLE_MAP[$fieldAlias])) {
|
|
|
+ foreach ($FIELD_TABLE_MAP[$fieldAlias] as $table) {
|
|
|
+ $tables[$table] = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return array_keys($tables); // e.g., ['oo', 'oi']
|
|
|
+ }
|
|
|
+
|
|
|
+ public static function buildCountSql(array $filterFieldAliases,$level)
|
|
|
+ {
|
|
|
+ $requiredTables = common::getRequiredTables($filterFieldAliases);
|
|
|
+
|
|
|
+ // 是否需要容器/项数据(即区分 public / sfs)
|
|
|
+ $needContainerData = in_array('oc', $requiredTables);
|
|
|
+ $needItemData = in_array('oi', $requiredTables);
|
|
|
+ $needOceanExtend = in_array('oe', $requiredTables) || in_array('Last Mile Delivery', $filterFieldAliases);
|
|
|
+ $needCO2 = in_array('co2_r', $requiredTables);
|
|
|
+
|
|
|
+ //在根据层级分配是否需要字段
|
|
|
+ if($level == 'Container Level'){
|
|
|
+ $needContainerData = true;
|
|
|
+ }elseif($level == 'Item Level'){
|
|
|
+ $needItemData = true;
|
|
|
+ $needContainerData = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ // --- CTE: oo (主表) ---
|
|
|
+ $sql = "
|
|
|
+ with oo as (
|
|
|
+ SELECT CASE
|
|
|
+ WHEN (m_iffcpu is null and m_iffrec is null and m_iffdep is null and m_iffarr is null and m_iffdel is null) THEN 'Created'::text
|
|
|
+ WHEN ((m_iffcpu is not null or m_iffrec is not null) and m_iffdep is null and m_iffarr is null and m_iffdel is null) THEN 'Cargo Received'::text
|
|
|
+ WHEN (m_iffdep is not null and m_iffarr is null and m_iffdel is null) THEN 'Departed'::text
|
|
|
+ WHEN (m_iffarr is not null and m_iffdel is null) THEN 'Arrived'::text
|
|
|
+ WHEN (m_iffdel is not null) THEN 'Completed'::text
|
|
|
+ ELSE 'Created'
|
|
|
+ END AS new_status,
|
|
|
+ CASE
|
|
|
+ WHEN transport_mode_extend = 'sea' THEN 'Ocean Freight'::text
|
|
|
+ WHEN transport_mode_extend = 'air' THEN 'Air Freight'::text
|
|
|
+ WHEN transport_mode_extend = 'rail' THEN 'Rail Freight'::text
|
|
|
+ WHEN transport_mode_extend = 'road' THEN 'Road Freight'::text
|
|
|
+ ELSE ''
|
|
|
+ END AS new_transport_mode_extend,
|
|
|
+ CASE
|
|
|
+ WHEN oo.voyage IS NOT DISTINCT FROM oo.f_voyage THEN oo.voyage
|
|
|
+ WHEN NULLIF(TRIM(oo.voyage), '') IS NOT NULL AND NULLIF(TRIM(oo.f_voyage), '') IS NOT NULL
|
|
|
+ THEN oo.f_voyage || '/' || oo.voyage
|
|
|
+ WHEN NULLIF(TRIM(oo.voyage), '') IS NOT NULL
|
|
|
+ THEN oo.voyage
|
|
|
+ ELSE oo.f_voyage
|
|
|
+ END AS _voyage,
|
|
|
+ CASE
|
|
|
+ WHEN oo.vessel IS NOT DISTINCT FROM oo.f_vessel THEN oo.vessel
|
|
|
+ WHEN NULLIF(TRIM(oo.vessel), '') IS NOT NULL AND NULLIF(TRIM(oo.f_vessel), '') IS NOT NULL
|
|
|
+ THEN oo.f_vessel || '/' || oo.vessel
|
|
|
+ WHEN NULLIF(TRIM(oo.vessel), '') IS NOT NULL
|
|
|
+ THEN oo.vessel
|
|
|
+ ELSE oo.f_vessel
|
|
|
+ END AS _vessel, * FROM public.kln_ocean oo <{klnOceanSearchKLN}>
|
|
|
+ )";
|
|
|
+
|
|
|
+ // 如果不需要容器/项数据,直接 COUNT
|
|
|
+ if (!$needContainerData) {
|
|
|
+ return $sql . "\n select count(*) from oo <{ocItemSearchKLN}> ;";
|
|
|
+ }
|
|
|
+
|
|
|
+ // --- 需要容器数据:构建 vv_public 和 vv_sfs ---
|
|
|
+
|
|
|
+ // 构建 LATERAL 子查询(按需)
|
|
|
+ $oeLateral = '';
|
|
|
+ if ($needOceanExtend) {
|
|
|
+ $oeLateral = "
|
|
|
+ LEFT JOIN LATERAL (
|
|
|
+ SELECT
|
|
|
+ loadterm,
|
|
|
+ manifest_type,
|
|
|
+ container_size,
|
|
|
+ import_po_no,
|
|
|
+ (SELECT jsonb_agg(to_jsonb(de.*)) FROM (
|
|
|
+ SELECT
|
|
|
+ split_part(lmd, '/', 1) AS ctnr,
|
|
|
+ split_part(lmd, '/', 2) AS delivery_datetime
|
|
|
+ FROM regexp_split_to_table(COALESCE(oe.last_mile_delivery_date, ''), ';') AS lmd
|
|
|
+ WHERE lmd <> ''
|
|
|
+ ) de) AS lmdds
|
|
|
+ FROM public.kln_ocean_extend oe
|
|
|
+ WHERE oe.serial_no::text = oo.serial_no::text
|
|
|
+ AND oe.order_from::text = oo.order_from::text
|
|
|
+ LIMIT 1
|
|
|
+ ) oe ON true";
|
|
|
+ }
|
|
|
+
|
|
|
+ $co2Lateral = '';
|
|
|
+ if ($needCO2) {
|
|
|
+ $co2Lateral = "
|
|
|
+ LEFT JOIN LATERAL (
|
|
|
+ SELECT
|
|
|
+ pickup_carbon_emission,
|
|
|
+ pickup_distances,
|
|
|
+ routes_carbon_emission,
|
|
|
+ routes_distances,
|
|
|
+ delivery_carbon_emission,
|
|
|
+ delivery_distances
|
|
|
+ FROM public.calculate_co2_result ccr
|
|
|
+ WHERE ccr.serial_no::text = oo.serial_no::text
|
|
|
+ LIMIT 1
|
|
|
+ ) co2_r ON true";
|
|
|
+ }
|
|
|
+
|
|
|
+ $joinPublic = "
|
|
|
+ LEFT JOIN public.oc_container oc ON oo.serial_no::text = oc.serial_no::text AND oo.order_from = 'public'";
|
|
|
+
|
|
|
+ $joinSfs = "
|
|
|
+ LEFT JOIN sfs.oc_container oc ON oo.serial_no::text = oc.serial_no::text AND oo.order_from = 'sfs'";
|
|
|
+
|
|
|
+ // 公共部分:JOIN 容器和 item
|
|
|
+ if ($needContainerData && $needItemData) {
|
|
|
+ $joinPublic = "
|
|
|
+ LEFT JOIN public.oc_container oc ON oo.serial_no::text = oc.serial_no::text AND oo.order_from = 'public'
|
|
|
+ LEFT JOIN public.oc_container_item oi ON oc.id = oi.oc_container_id";
|
|
|
+
|
|
|
+ $joinSfs = "
|
|
|
+ LEFT JOIN sfs.oc_container oc ON oo.serial_no::text = oc.serial_no::text AND oo.order_from = 'sfs'
|
|
|
+ LEFT JOIN sfs.oc_container_item oi ON oc.id = oi.oc_container_id";
|
|
|
+ }
|
|
|
+
|
|
|
+ $sql .= ",
|
|
|
+ vv_public AS (
|
|
|
+ SELECT 1
|
|
|
+ FROM oo
|
|
|
+ {$joinPublic}
|
|
|
+ {$oeLateral}
|
|
|
+ {$co2Lateral}
|
|
|
+ <{ocItemSearchKLN}>
|
|
|
+ ),
|
|
|
+ vv_sfs AS (
|
|
|
+ SELECT 1
|
|
|
+ FROM oo
|
|
|
+ {$joinSfs}
|
|
|
+ {$oeLateral}
|
|
|
+ {$co2Lateral}
|
|
|
+ <{ocItemSearchKLN}>
|
|
|
+ )
|
|
|
+ SELECT COUNT(*) FROM (
|
|
|
+ SELECT * FROM vv_public
|
|
|
+ UNION ALL
|
|
|
+ SELECT * FROM vv_sfs
|
|
|
+ ) vv <{vvSearchKLN}>;";
|
|
|
+
|
|
|
+ return $sql;
|
|
|
+ }
|
|
|
}
|
|
|
?>
|