|
@@ -4551,11 +4551,24 @@ class common {
|
|
|
"co2_r.routes_distances" => "main_route_distance",
|
|
"co2_r.routes_distances" => "main_route_distance",
|
|
|
"co2_r.delivery_carbon_emission" => "delivery_co2_emission",
|
|
"co2_r.delivery_carbon_emission" => "delivery_co2_emission",
|
|
|
"co2_r.delivery_distances" => "delivery_distance",
|
|
"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"
|
|
|
|
|
|
|
+
|
|
|
|
|
+ "COALESCE(wo_pickup.postal_code,routing_pickup.postal_code)" => "pickup_postal_code",
|
|
|
|
|
+ "COALESCE(wo_pickup.mode_type,routing_pickup.mode_type)" => "pickup_mode_type",
|
|
|
|
|
+ "COALESCE(wo_delivery.postal_code,routing_delivery.postal_code)" => "last_mile_delivery_postal_code",
|
|
|
|
|
+ "COALESCE(wo_delivery.mode_type,routing_delivery.mode_type)" => "last_mile_delivery_mode_type",
|
|
|
|
|
+
|
|
|
|
|
+ "wo_delivery.est_delivery_date" => "last_mile_delivery_date",
|
|
|
|
|
+ "wo_delivery.est_delivery_time" => "last_mile_delivery_time",
|
|
|
|
|
+ "wo_delivery.city" => "last_mile_delivery_city",
|
|
|
|
|
+ "wo_delivery.full_address" => "last_mile_delivery _address",
|
|
|
|
|
+ "(CASE WHEN COALESCE(NULLIF(trim(oo.piece_count), ''), '0')::numeric > 0
|
|
|
|
|
+ AND (COALESCE(co2_r.pickup_distances, 0) +COALESCE(co2_r.routes_distances, 0) +COALESCE(co2_r.delivery_distances, 0)) > 0
|
|
|
|
|
+ AND COALESCE(oo.carbon_emission, 0) > 0
|
|
|
|
|
+ THEN ROUND(COALESCE(oo.carbon_emission, 0) / 1000.0
|
|
|
|
|
+ / (1.0 / 1000.0)
|
|
|
|
|
+ / (1.0 / 1000.0)
|
|
|
|
|
+ / (COALESCE(NULLIF(trim(oo.piece_count), ''), '0')::numeric / (1.0 / (COALESCE(co2_r.pickup_distances, 0) +COALESCE(co2_r.routes_distances, 0) +COALESCE(co2_r.delivery_distances, 0))) / 1000.0),4)
|
|
|
|
|
+ END)" => "co2e_intensity"
|
|
|
];
|
|
];
|
|
|
return $kln_ocean;
|
|
return $kln_ocean;
|
|
|
}
|
|
}
|
|
@@ -4860,12 +4873,21 @@ class common {
|
|
|
'Main Route Distance' => ['co2_r'],
|
|
'Main Route Distance' => ['co2_r'],
|
|
|
'Delivery CO2 Emission' => ['co2_r'],
|
|
'Delivery CO2 Emission' => ['co2_r'],
|
|
|
'Delivery Distance' => ['co2_r'],
|
|
'Delivery Distance' => ['co2_r'],
|
|
|
|
|
+ 'CO2e Intensity' => ['co2_r'],
|
|
|
|
|
|
|
|
// 特殊字段:依赖 oc + oe
|
|
// 特殊字段:依赖 oc + oe
|
|
|
- 'Last Mile Delivery' => ['oc', 'oe'],
|
|
|
|
|
-
|
|
|
|
|
'Controlling Customer' => ['oo','Controlling Customer'],
|
|
'Controlling Customer' => ['oo','Controlling Customer'],
|
|
|
- 'CARRIER TEU' => ['oe','CARRIER TEU']
|
|
|
|
|
|
|
+ 'CARRIER TEU' => ['oe','CARRIER TEU'],
|
|
|
|
|
+
|
|
|
|
|
+ 'Pickup-Postal Code' => ['pickup'],
|
|
|
|
|
+ 'Pickup-Mode Type' => ['pickup'],
|
|
|
|
|
+ 'Last mile delivery-Postal Code' => ['delivery'],
|
|
|
|
|
+ 'Last mile delivery-Mode Type' => ['delivery'],
|
|
|
|
|
+
|
|
|
|
|
+ 'Last Mile Delivery Date' => ['delivery'],
|
|
|
|
|
+ 'Last Mile Delivery Time' => ['delivery'],
|
|
|
|
|
+ 'Last Mile Delivery City' => ['delivery'],
|
|
|
|
|
+ 'Last Mile Delivery Address' => ['delivery']
|
|
|
];
|
|
];
|
|
|
|
|
|
|
|
$tables = [];
|
|
$tables = [];
|
|
@@ -4890,6 +4912,8 @@ class common {
|
|
|
$needItemData = in_array('oi', $requiredTables);
|
|
$needItemData = in_array('oi', $requiredTables);
|
|
|
$needOceanExtend = in_array('oe', $requiredTables) || in_array('Last Mile Delivery', $filterFieldAliases);
|
|
$needOceanExtend = in_array('oe', $requiredTables) || in_array('Last Mile Delivery', $filterFieldAliases);
|
|
|
$needCO2 = in_array('co2_r', $requiredTables);
|
|
$needCO2 = in_array('co2_r', $requiredTables);
|
|
|
|
|
+ $need_pickup = in_array('pickup', $requiredTables);
|
|
|
|
|
+ $need_delivery = in_array('delivery', $requiredTables);
|
|
|
|
|
|
|
|
$needteu = in_array('CARRIER TEU', $requiredTables);
|
|
$needteu = in_array('CARRIER TEU', $requiredTables);
|
|
|
$needCustomer = in_array('Controlling Customer', $requiredTables);
|
|
$needCustomer = in_array('Controlling Customer', $requiredTables);
|
|
@@ -4929,22 +4953,6 @@ class common {
|
|
|
END AS \"CARRIER TEU\", ";
|
|
END AS \"CARRIER TEU\", ";
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // --- CTE: oo (主表) ---
|
|
|
|
|
- $sql = "
|
|
|
|
|
- with oo as (
|
|
|
|
|
- SELECT * FROM public.kln_ocean oo <{klnOceanSearchKLN}>
|
|
|
|
|
- )";
|
|
|
|
|
-
|
|
|
|
|
- // 如果不需要容器/项数据,直接 COUNT
|
|
|
|
|
- if (!$needContainerData) {
|
|
|
|
|
- if(!empty($needCustomerSQL)){
|
|
|
|
|
- return $sql . "\n ,vv as (select {$needCustomerSQL} 1 from oo <{ocItemSearchKLN}>) select count(*) from vv <{vvSearchKLN}>;";
|
|
|
|
|
- }
|
|
|
|
|
- return $sql . "\n select count(*) from oo <{ocItemSearchKLN}> ;";
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // --- 需要容器数据:构建 vv_public 和 vv_sfs ---
|
|
|
|
|
-
|
|
|
|
|
// 构建 LATERAL 子查询(按需)
|
|
// 构建 LATERAL 子查询(按需)
|
|
|
$oeLateral = '';
|
|
$oeLateral = '';
|
|
|
if ($needOceanExtend) {
|
|
if ($needOceanExtend) {
|
|
@@ -4986,6 +4994,83 @@ class common {
|
|
|
) co2_r ON true";
|
|
) co2_r ON true";
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ $pickupLateral = '';
|
|
|
|
|
+ if ($need_pickup) {
|
|
|
|
|
+ $pickupLateral = "
|
|
|
|
|
+ LEFT JOIN LATERAL (
|
|
|
|
|
+ SELECT
|
|
|
|
|
+ cap.postal_code,
|
|
|
|
|
+ h.mode_type
|
|
|
|
|
+ FROM station_data.do_header h
|
|
|
|
|
+ LEFT JOIN public.contacts_address cap ON cap.sync_key = h.collect_addr_key AND cap.addr_type = 'D'
|
|
|
|
|
+ WHERE h.serial_no = oo.serial_no AND NULLIF(TRIM(cap.postal_code), '') IS NOT NULL AND h.collect_addr_key is not null ORDER BY h.id DESC LIMIT 1
|
|
|
|
|
+ ) AS wo_pickup ON true
|
|
|
|
|
+ LEFT JOIN LATERAL (
|
|
|
|
|
+ SELECT
|
|
|
|
|
+ pickup_postal_code AS postal_code,
|
|
|
|
|
+ pickup_mode_type AS mode_type
|
|
|
|
|
+ FROM (
|
|
|
|
|
+ SELECT pickup_postal_code, pickup_mode_type
|
|
|
|
|
+ FROM station_data.ocean_pickup_delivery
|
|
|
|
|
+ WHERE serial_no = oo.serial_no AND oo.transport_mode = 'sea' AND NULLIF(TRIM(pickup_postal_code), '') IS NOT NULL
|
|
|
|
|
+ UNION ALL
|
|
|
|
|
+ SELECT pickup_postal_code, pickup_mode_type
|
|
|
|
|
+ FROM station_data.air_pickup_delivery
|
|
|
|
|
+ WHERE serial_no = oo.serial_no AND oo.transport_mode = 'air' AND NULLIF(TRIM(pickup_postal_code), '') IS NOT NULL
|
|
|
|
|
+ ) u
|
|
|
|
|
+ LIMIT 1
|
|
|
|
|
+ ) AS routing_pickup ON true ";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $deliveryLateral = '';
|
|
|
|
|
+ if ($need_delivery) {
|
|
|
|
|
+ $deliveryLateral = "
|
|
|
|
|
+ LEFT JOIN LATERAL (
|
|
|
|
|
+ SELECT
|
|
|
|
|
+ cad.postal_code,
|
|
|
|
|
+ h.mode_type,
|
|
|
|
|
+ h.est_delivery_date,
|
|
|
|
|
+ h.est_delivery_time,
|
|
|
|
|
+ CONCAT_WS('',cad.ctry_code,cad.city_code) as city,
|
|
|
|
|
+ COALESCE(cad.addr1, '') || ' ' || COALESCE(cad.addr2, '') || ' ' || COALESCE(cad.addr3, '') || ' ' || COALESCE(cad.addr4, '') AS full_address
|
|
|
|
|
+ FROM station_data.do_header h
|
|
|
|
|
+ LEFT JOIN public.contacts_address cad ON cad.sync_key = h.consignee_addr_key AND cad.addr_type = 'D'
|
|
|
|
|
+ WHERE h.serial_no = oo.serial_no AND NULLIF(TRIM(cad.postal_code), '') IS NOT NULL AND h.consignee_addr_key is not null ORDER BY h.id DESC LIMIT 1
|
|
|
|
|
+ ) AS wo_delivery ON true
|
|
|
|
|
+ LEFT JOIN LATERAL (
|
|
|
|
|
+ SELECT
|
|
|
|
|
+ delivery_postal_code AS postal_code,
|
|
|
|
|
+ delivery_mode_type AS mode_type
|
|
|
|
|
+ FROM (
|
|
|
|
|
+ SELECT delivery_postal_code, delivery_mode_type
|
|
|
|
|
+ FROM station_data.ocean_pickup_delivery
|
|
|
|
|
+ WHERE serial_no = oo.serial_no AND oo.transport_mode = 'sea' AND NULLIF(TRIM(delivery_postal_code), '') IS NOT NULL
|
|
|
|
|
+ UNION ALL
|
|
|
|
|
+ SELECT delivery_postal_code, delivery_mode_type
|
|
|
|
|
+ FROM station_data.air_pickup_delivery
|
|
|
|
|
+ WHERE serial_no = oo.serial_no AND oo.transport_mode = 'air' AND NULLIF(TRIM(delivery_postal_code), '') IS NOT NULL
|
|
|
|
|
+ ) u
|
|
|
|
|
+ LIMIT 1
|
|
|
|
|
+ ) AS routing_delivery ON true ";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ // --- CTE: oo (主表) ---
|
|
|
|
|
+ $sql = "
|
|
|
|
|
+ with oo as (
|
|
|
|
|
+ SELECT * FROM public.kln_ocean oo <{klnOceanSearchKLN}>
|
|
|
|
|
+ )";
|
|
|
|
|
+
|
|
|
|
|
+ // 如果不需要容器/项数据,直接 COUNT
|
|
|
|
|
+ if (!$needContainerData) {
|
|
|
|
|
+ if(!empty($needCustomerSQL)){
|
|
|
|
|
+ return $sql . "\n ,vv as (select {$needCustomerSQL} 1 from oo {$oeLateral} {$co2Lateral} {$pickupLateral} {$deliveryLateral} <{ocItemSearchKLN}>)
|
|
|
|
|
+ select count(*) from vv <{vvSearchKLN}>;";
|
|
|
|
|
+ }
|
|
|
|
|
+ return $sql . "\n select count(*) from oo {$oeLateral} {$co2Lateral} {$pickupLateral} {$deliveryLateral} <{ocItemSearchKLN}>;";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // --- 需要容器数据:构建 vv_public 和 vv_sfs ---
|
|
|
$joinPublic = "
|
|
$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 oc ON oo.serial_no::text = oc.serial_no::text AND oo.order_from = 'public'";
|
|
|
|
|
|
|
@@ -4996,11 +5081,11 @@ class common {
|
|
|
if ($needContainerData && $needItemData) {
|
|
if ($needContainerData && $needItemData) {
|
|
|
$joinPublic = "
|
|
$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 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";
|
|
|
|
|
|
|
+ LEFT JOIN public.oc_container_item oi ON oc.edi_serial_no = oi.edi_container_serial_no";
|
|
|
|
|
|
|
|
$joinSfs = "
|
|
$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 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";
|
|
|
|
|
|
|
+ LEFT JOIN sfs.oc_container_item oi ON oc.edi_serial_no = oi.edi_container_serial_no";
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
$sql .= ",
|
|
$sql .= ",
|
|
@@ -5010,6 +5095,8 @@ class common {
|
|
|
{$joinPublic}
|
|
{$joinPublic}
|
|
|
{$oeLateral}
|
|
{$oeLateral}
|
|
|
{$co2Lateral}
|
|
{$co2Lateral}
|
|
|
|
|
+ {$pickupLateral}
|
|
|
|
|
+ {$deliveryLateral}
|
|
|
<{ocItemSearchKLN}>
|
|
<{ocItemSearchKLN}>
|
|
|
),
|
|
),
|
|
|
vv_sfs AS (
|
|
vv_sfs AS (
|
|
@@ -5018,6 +5105,8 @@ class common {
|
|
|
{$joinSfs}
|
|
{$joinSfs}
|
|
|
{$oeLateral}
|
|
{$oeLateral}
|
|
|
{$co2Lateral}
|
|
{$co2Lateral}
|
|
|
|
|
+ {$pickupLateral}
|
|
|
|
|
+ {$deliveryLateral}
|
|
|
<{ocItemSearchKLN}>
|
|
<{ocItemSearchKLN}>
|
|
|
)
|
|
)
|
|
|
SELECT COUNT(*) FROM (
|
|
SELECT COUNT(*) FROM (
|
|
@@ -5144,5 +5233,17 @@ class common {
|
|
|
|
|
|
|
|
return $data;
|
|
return $data;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 判断数组值为空
|
|
|
|
|
+ */
|
|
|
|
|
+ public static function isArrayAllEmpty($arr) {
|
|
|
|
|
+ foreach ($arr as $value) {
|
|
|
|
|
+ if (trim((string)$value) !== '') {
|
|
|
|
|
+ return false; // 只要有一个非空,就返回 false
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return true; // 全部为空
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
?>
|
|
?>
|