<?php

//include_once("../include/auth.inc.php");
include_once("../include/global.inc.php");
include_once("../locating/xServer.inc.php");
include_once("../include/services_func.inc.php");

getSecHttpVars("1",array("hq_id", "cs_id", "vht_id", "jb_markup", "jb_ordertime", "a", "mode", "jb_id", "usr_id", "fake"));
writeLog_ajaxReqKmPrice("\$a = " . $a . ", \$hq_id = " . $hq_id . ", \$cs_id = " . $cs_id . ", \$vht_id = " . $vht_id . ", \$jb_markup = " . $jb_markup . ", \$jb_ordertime = " . $jb_ordertime . ", \$mode = " . $mode . ", \$jb_id = " . $jb_id . ", \$usr_id = " . $usr_id . ", \$fake = " . $fake);
//$mode = "zone";
$ajaxReqKmPrice = true;
$a = str_replace("\'", "'", $a);
$error_msg = "";
// extracted from [(isset($mode) && $mode == "coords")] because hq_id_dispo is needed in zone-price too
if (trim($a) == "") {
  $error_msg = "Adressangaben fehlen";
} else {
  $address_parts = explode(";", explode("|", $a)[0]);
writeLog_ajaxReqKmPrice("\$address_parts = " . json_encode($address_parts));
  if ($address_parts[4] == "DE" || $address_parts[4] == "D") {
writeLog_ajaxReqKmPrice("\$sqlquery = " . "SELECT hq_id FROM serviceplz WHERE srvp_plz = '" . $address_parts[2] . "'");
    $hq_id_dispo = $db->getOne("SELECT hq_id FROM serviceplz WHERE srvp_plz = '" . $address_parts[2] . "'");
    if ($hq_id_dispo == "")
      $hq_id_dispo = 0;
    writeLog_ajaxReqKmPrice("\$address_parts[2] = " . $address_parts[2] . ", \$address_parts[4] = " . $address_parts[4] . ", \$hq_id_dispo = " . $hq_id_dispo . "\n");
  } else {
    $sqlquery =
      "SELECT hq_id, hq_gps_long, hq_gps_lat" .
      " FROM headquarters WHERE hq_gps_long > 0 AND hq_gps_lat > 0 ORDER BY (SQRT(POW(ABS(hq_gps_lat - " . $address_parts[5] . "),2) + POW(ABS(hq_gps_long - " . $address_parts[6] . "),2)) * 111) LIMIT 3";
writeLog_ajaxReqKmPrice("\$sqlquery = " . $sqlquery);
    $res = $db->query($sqlquery);
    if (DB::isError($res)) reportDie ("$PHP_SELF: '$sqlquery': " . $res->getMessage());
    $round_kms_min = 0;
    $hq_id_min = 0;
    while ($row = $res->fetch_assoc()) {
      writeLog_ajaxReqKmPrice("\$retValue = " . $retValue . "\n");
      $round_kms = get_tour_distance(array(array($row["hq_gps_lat"], $row["hq_gps_long"]), array($address_parts[5], $address_parts[6])));
      writeLog_ajaxReqKmPrice("\$row[\"hq_id\"] = " . $row["hq_id"] . ", \$round_kms[0] = " . $round_kms[0]);
      if ($round_kms_min == 0 || $round_kms[0] < $round_kms_min) {
        $round_kms_min = $round_kms[0];
        $hq_id_min = $row["hq_id"];
      }
    }
    $res->free();
    $hq_id_dispo = $hq_id_min;
  }
}

if ($error_msg == "" && isset($mode) && $mode == "coords") {
  set_coords($address_parts[4], $address_parts[2], $address_parts[3], $address_parts[0], $address_parts[1], $address_parts[5], $address_parts[6], $address_parts[7]);
  $retValue = "retValue = " . $hq_id_dispo . ";";
  writeLog_ajaxReqKmPrice("\$retValue = " . $retValue . "\n");
  echo $retValue;
  exit();
}

if ($error_msg == "" && isset($mode) && $mode == "full_address") {
  list ($accuracy, $country, $postal_code, $locality, $route, $street_number) = get_address(0, 0, $a);
  $hq_id_dispo = $db->getOne("SELECT hq_id FROM serviceplz WHERE srvp_plz = '" . $postal_code . "'");
  if ($hq_id_dispo == "")
    $hq_id_dispo = 0;
  $retValue = "retValue = ['" . $accuracy . "','" . $country . "','" . $postal_code . "','" . $locality . "','" . $route . "','" . $street_number . "','" . $hq_id_dispo . "'];";
  writeLog_ajaxReqKmPrice("\$retValue = " . $retValue . "\n");
  echo $retValue;
  exit();
}

$hq_id_real = $hq_id;
if ($hq_id_dispo != 0)
  $hq_id = $hq_id_dispo;
writeLog_ajaxReqKmPrice("\$hq_id_real = " . $hq_id_real . ", \$hq_id_dispo = " . $hq_id_dispo . " (\$address_parts[2] = " . $address_parts[2] . ")" . ", \$hq_id = " . $hq_id . "\n");

if (trim($jb_ordertime) == "")
  $jb_ordertime = date("Y-m-d H:i:s");
$srvt_name = $db->getOne("SELECT mt_value FROM metatype WHERE mt_sort = '" . $vht_id . "' AND mt_type = 'vehicletype'");
if (trim($jb_markup) == "")
  $jb_markup = getFuelMarkup($srvt_name, $cs_id, $hq_id, $jb_ordertime);

$retValue = "";
$total_km = 0;
$total_km_osm = 0;
$zones = array();
$total_km_price = 0;
$total_km_cr_price = 0;
$points = "";
$pointsPZM = "";
$stops = array();
$addresses = explode("|", $a);
$weitere_adressen = 0;
$country_codes = get_country_codes();
$log_optimized_route = "";

if ($error_msg == "") {
 if (isset($mode) && $mode == "zone" && $vht_id == "") {
   $error_msg = "Fahrzeugtyp muss für PZM-Preis definiert sein";
 } else {
   if (isset($mode) && $mode == "plz") {
     $ad_zipcode = "";
     $ad_zipcode_prev = "";
     define("MASK_CASH_PAYER_SELECT", getParameterValue("0", "MASK_CASH_PAYER_SELECT", $hq_id));
     $dontcheckfakezipcodes = ($fake == "false");
   }
   for ($i = 0; $i < count($addresses); $i++) {
     $address_parts = explode(";", $addresses[$i]);
     $ad_street = my_str_check($address_parts[0]);
     $tr_hsno = my_str_check($address_parts[1]);
     if (isset($mode) && $mode == "plz")
       $ad_zipcode_prev = $ad_zipcode;
     $ad_zipcode = $address_parts[2];
     $ad_city = my_str_check($address_parts[3]);
     $ad_country = $address_parts[4];
 
     if ($i == 0 && isset($mode) && $mode == "zone" && $hq_id == "") {
       $hq_id = $db->getOne("SELECT hq_id FROM serviceplz WHERE srvp_plz = '" . $ad_zipcode . "'");
       if ($hq_id == "")
         $error_msg = "Niederlassung muss für PZM-Preis definiert sein";
     }
     if (isset($mode) && $mode == "plz") {
       // Wenn Auslandsadresse kann kein Preis ermittelt werden
       if ($ad_country != "DE" && $ad_country != "D") {
         $retValue = "retValue = [" . $jb_markup . ", ['" . $ad_country . "-" . $ad_zipcode . " ist im Ausland',0,0]";
         break;
       }
       if (!$dontcheckfakezipcodes) {
         // Wenn PLZ Fake-PLZs enthält, kann kein Preis ermittelt werden
         $fake_zipcode = $db->getOne("SELECT DISTINCT srvp1.srvp_plz AS srvp1_plz FROM servicesubareamapping AS srvsam, serviceplz AS srvp1 WHERE srvsam.srva_id = srvp1.srvp_id AND srvp1.srvp_plz IN ('" . $ad_zipcode . "', '" . $ad_zipcode . "')");
         if ($fake_zipcode != "") {
           $retValue = "retValue = [" . $jb_markup . ", ['" . $fake_zipcode . " hat Fake-PLZs',0,0]";
           break;
         }
       }
       if ($i == 0) {
         list ($fp, $fd, $fpm, $customer_specific) =
           saveServiceCosts("Grundpreis", $srvt_name, $hq_id, $cs_id, 0 /*$jb_id*/, 0, $jb_ordertime, 0 /*count*/, 1 /*$costsplit_count*/, 1 /*$getPriceOnly*/, false /*$jb_cash*/, "0" /*$csc_id_payer*/, 0 /*$jb_storno*/, false /*zipcode1*/, false /*zipcode2*/, false, $jb_markup, 0 /*$jb_cr_markup*/, $vht_id);
         $retValue = "retValue = [" . $jb_markup . ", ['" . $srvt_name . "'," . round($fp * ((100-$fd)/100), 2) . "," . round($fp * ((100-$fdm)/100), 2) . "]";
       } else {
         list ($fp, $fd, $fpm, $customer_specific) =
           saveServiceCosts($ad_zipcode_prev, $ad_zipcode, $hq_id, $cs_id, 0 /*$jb_id*/, 0, $jb_ordertime, 0 /*count*/, 1 /*$costsplit_count*/, 1 /*$getPriceOnly*/, false /*$jb_cash*/, "0" /*$csc_id_payer*/, 0 /*$jb_storno*/, false /*zipcode1*/, false /*zipcode2*/, true, $jb_markup, 0 /*$jb_cr_markup*/, $vht_id);
         // Ein einziger 0-Preis -> Gesamtpreis nicht ermittelbar
         if ($fp == 0) {
           $retValue = "retValue = [" . $jb_markup . ", ['". "PLZ " . $ad_zipcode_prev . " nach PLZ " . $ad_zipcode . " hat 0-Preis',0,0]";
           break;
         }
         $retValue .= ",['" . "PLZ " . $ad_zipcode_prev . " nach PLZ " . $ad_zipcode . "'," . round($fp * ((100-$fd)/100), 2) . "," . round($fp * ((100-$fdm)/100), 2) . "]";
       }
     } else {
       $coords = get_coords($ad_country, $ad_zipcode, $ad_city, $ad_street, $tr_hsno);
       if ($coords[0] != 0 && $coords[1] != 0) {
         $stops[] = $coords;
         $stopMap = str_replace("/", "%2F", my_str_check($ad_street)) . " " . str_replace("/", "%2F", $tr_hsno) . ", " . str_replace("/", "%2F", $ad_zipcode) . " " .
           str_replace("/", "%2F", my_str_check($ad_city)) . "," . $country_codes[($ad_country == "D" ? "DE" : $ad_country)];
         $points .= "/" . $stopMap;
         $pointsPZM .= "/" . $coords[0] . "," . $coords[1];
       } else {
         $error_msg = "Adresse in " . ($i + 1) . ". Station nicht ok";
         break;
       }
     }
   }
 }
}

//https://bwv-test.assecutor.de/include/ajaxReqKmPrice.php?hq_id=3&cs_id=828755&vht_id=5&jb_markup=8.5&jb_ordertime=2025-05-19%2007:00:00&mode=optimize&a=Buschkrugallee;43;12359;Berlin;DE|Schulgasse;1;14624;Dallgow;DE|Soltauer Str.;10;13509;Berlin;DE|Berliner Str.;17;13127;Berlin;DE|Bergfelder Str.;4;16547;Birkenwerder;DE|Fabrikstr.;8a;16761;Hennigsdorf;DE|Buschkrugallee;43;12359;Berlin;DE|Korkedamm;6;12524;Berlin;DE|Buschkrugallee;43;12359;Berlin;DE|Soltauer Str.;10;13509;Berlin;DE|Berliner Str.;17;13127;Berlin;DE|Bergfelder Str.;4;16547;Birkenwerder;DE|Fabrikstr.;8a;16761;Hennigsdorf;DE
//https://bwv-test.assecutor.de/include/ajaxReqKmPrice.php?hq_id=3&cs_id=828755&vht_id=5&jb_markup=8.5&jb_ordertime=2025-05-19%2007:00:00&mode=optimize&a=Buschkrugallee;43;12359;Berlin;DE|Schulgasse;1;14624;Dallgow;DE|Soltauer Str.;10;13509;Berlin;DE|Berliner Str.;17;13127;Berlin;DE

if ($error_msg == "") {
  if (isset($mode) && $mode == "plz") {
    $retValue .= "];";
    writeLog_ajaxReqKmPrice("\$retValue = " . $retValue . "\n");
    echo $retValue;
    exit();
  }
  if (count($stops) > 1) {
    if (isset($mode) && $mode == "zone") {
      $zones = get_zone_distance($stops, $hq_id);
      $total_km = (float) str_replace(" km", "", $zones["distance"] / 1000);
      $total_duration = (int) str_replace("s", "", $zones["duration"]);
      $total_hours = intdiv($total_duration, 3600);
      $total_minutes = round(($total_duration % 3600) / 60);
    } elseif (isset($mode) && (($mode == "optimize" && count($stops) > 3) || ($mode == "optimizeAll") && count($stops) > 2)) {
      // save distance of unchanged job for comparison reasons
      list($total_km_old, $total_km_osm_old) = get_tour_distance($stops);
      $total_km_min = 0;
      $start = count($stops) - 2;
      $end = count($stops) - 1;
      if ($mode == "optimizeAll") {
        $start = 1;
        for($i = 1; $i < count($stops); $i++)
          $realOptimizedStops[] = $i - 1;
        $end = count($stops);
      }
      for ($i = $start; $i < $end; $i++) {
        $zones = get_zone_distance($stops, $hq_id, 0, false, true);
writeLog_ajaxReqKmPrice("\$stops = " . json_encode($stops));
writeLog_ajaxReqKmPrice("\$zones[\"distance\"] = " . $zones["distance"] / 1000);
writeLog_ajaxReqKmPrice("\$realOptimizedStops = " . json_encode($realOptimizedStops));
        if (isset($zones["error"]))
          break;
        $total_km = (float) str_replace(" km", "", $zones["distance"] / 1000);
        if ($total_km_min == 0 || $total_km_min > $total_km) {
          if ($mode == "optimizeAll") {
            if (is_null($zones["optimizedRoute"]))
              $zones["optimizedRoute"] = array(0);
writeLog_ajaxReqKmPrice("\$zones[\"optimizedRoute\"] = " . json_encode($zones["optimizedRoute"]) . " (original)");
            for($j = 0; $j < count($zones["optimizedRoute"]); $j++)
              $zones["optimizedRoute"][$j] = $realOptimizedStops[$zones["optimizedRoute"][$j]];
writeLog_ajaxReqKmPrice("\$zones[\"optimizedRoute\"] = " . json_encode($zones["optimizedRoute"]) . " (replaced by values in \$realOptimizedStops)");
            $zones["optimizedRoute"][] = $realOptimizedStops[count($realOptimizedStops) - 1];
writeLog_ajaxReqKmPrice("\$zones[\"optimizedRoute\"] = " . json_encode($zones["optimizedRoute"]) . " (after adding last station)");
          }
          $total_km_min = $total_km;
          $retValue = "retValue = [" . $total_km_old . "," . $total_km . ",[" . implode(",", $zones["optimizedRoute"]) . "]];";
          $log_optimized_routeArr = array();
          for($j = 0; $j < count($zones["optimizedRoute"]); $j++)
            $log_optimized_routeArr[$j] = $zones["optimizedRoute"][$j] + 1;
          $log_optimized_route = implode(",", $log_optimized_routeArr);
          writeLog_ajaxReqKmPrice("\$retValue (preliminary) = " . $retValue);
        }
//stops = [0,1,2] realOptimizedStops = [0,1] optimizedRoute = [0,1]
//stops = [0,2,1] realOptimizedStops = [1,0] optimizedRoute = [1,0]

//stops = [0,1,2,3] realOptimizedStops = [0,1,2] optimizedRoute = [0,1]
//stops = [0,3,2,1] realOptimizedStops = [2,1,0] optimizedRoute = [1,0]

        if ($mode == "optimizeAll") {
          $tmp_stop = $stops[count($stops) - 1];
          $stops[count($stops) - 1] = $stops[$i];
          $stops[$i] = $tmp_stop;
          $tmp_real_stop = $realOptimizedStops[count($realOptimizedStops) - 1];
          $realOptimizedStops[count($realOptimizedStops) - 1] = $realOptimizedStops[$i - 1];
          $realOptimizedStops[$i - 1] = $tmp_real_stop;
        }
      }
    } elseif (isset($mode) && ($mode == "optimize" || $mode == "optimizeAll")) {
      $retValue = "retValue = ['ERROR','\$mode=" . $mode . ", count(\$stops) = " . count($stops) . "'];";
    } else {
      list($total_km, $total_km_osm) = get_tour_distance($stops);
//      list($total_km, $total_km_osm) = get_tour_distance($stops, $jb_ordertime);
    }
    $weitere_adressen = count($stops) - 2;
  }

  if (isset($mode) && ($mode == "optimize" || $mode == "optimizeAll")) {
    writeLog_ajaxReqKmPrice("\$retValue = " . $retValue . "\n");
    writeToLogDB(201, $hq_id_real, $jb_id, $usr_id, "", "", "", "MODE=" . $mode . "|TOTAL_KM_OLD=" . $total_km_old . "|TOTAL_KM=" . $total_km . "|OPTIMIZED=" . $log_optimized_route);
    if (isset($zones["error"]))
      $retValue = "retValue = ['ERROR','\$mode=" . $mode . ", count(\$stops) = " . count($stops) . "'];";
    echo $retValue;
    exit();
  }

writeLog_ajaxReqKmPrice("\$total_km = " . $total_km);
  if (!(isset($mode) && $mode == "zone"))
    $total_km = round($total_km, 2);
  $final_discount = $db->getOne("SELECT cs_discount FROM customer WHERE cs_id = '$cs_id'");
  if ($final_discount == "")
    $final_discount = 0;
  if ($cs_id == "")
    $cs_id = 0;
//  $srvt_name = $db->getOne("SELECT mt_value FROM metatype WHERE mt_sort = '" . $vht_id . "' AND mt_type = 'vehicletype'");

  if ($phpVersion >= "7.0"):
    $euro_sign = chr(128);
  else:
    $euro_sign = chr(0xe2) . chr(0x82) . chr(0xAC);
  endif;

writeLog_ajaxReqKmPrice("\$cs_id = " . $cs_id . ", \$srvt_name = " . $srvt_name);
  if (!(isset($mode) && $mode == "zone")) {
    list($price_per_km, $price_per_km_correction, $final_discount, $final_discount_correction, $cr_price_per_km, $final_cr_discount, $customer_specific) =
      getServicePrices("km-Preis", $srvt_name, $cs_id, $hq_id, $jb_ordertime, 0, $final_discount, 0, false);
    if ($cr_price_per_km == "")
      $cr_price_per_km = 0;
    writeLog_ajaxReqKmPrice("\$price_per_km = " . $price_per_km . ", \$cr_price_per_km = " . $cr_price_per_km);
  } else {
    $minimum_price = 0;
    $minimum_cr_price = 0;
    $minimum_price_name = "";
    $zoneDistanceStr = "";
    foreach ($zones["zoneDistance"] as &$zone_price) {
	  $srv_name = $zone_price["zone"];
      if (isset($srv_names_PZM[$hq_id][$zone_price["zone"]]))
        $srv_name = $srv_names_PZM[$hq_id][$zone_price["zone"]];
      writeLog_ajaxReqKmPrice("getServicePrices(" . $srv_name . ", $srvt_name, $cs_id, $hq_id, $jb_ordertime, 0, $final_discount, 0, false);");
      list($price_per_km, $price_per_km_correction, $final_discount, $final_discount_correction, $cr_price_per_km, $final_cr_discount, $customer_specific) =
        getServicePrices($srv_name, $srvt_name, $cs_id, $hq_id, $jb_ordertime, 0, $final_discount, 0, false);
      $zone_price["price_per_km"] = (float) $price_per_km;
      $zone_price["cr_price_per_km"] = (float) $cr_price_per_km;
writeLog_ajaxReqKmPrice("\$zone_price[\"price_per_km\"] = " . $zone_price["price_per_km"] . ", \$zone_price[\"cr_price_per_km\"] = " . $zone_price["cr_price_per_km"]);
      if ($zone_price["price_per_km"] > 0 && $zone_price["cr_price_per_km"] == 0) {
        list($cr_price_per_km, $cr_price_per_km_rate) =
          getCr_price_global($price_per_km, $hq_id, $cs_id, $jb_ordertime, $srvt_name, $vht_id);
writeLog_ajaxReqKmPrice("\$cr_price_per_km_rate = " . $cr_price_per_km_rate);
        // take unrounded value
        $zone_price["cr_price_per_km"] = $price_per_km * (100 - $cr_price_per_km_rate) / 100;
      }
      if ($zone_price["price_per_km"] > 0) {
        $total_km_price += (strpos($zone_price["zone"], "_fix") === false ? round($zone_price["price_per_km"] * round($zone_price["distance"] / 1000, 2), 2) : round($zone_price["price_per_km"], 2));
        $total_km_cr_price += (strpos($zone_price["zone"], "_fix") === false ? round($zone_price["cr_price_per_km"] * round($zone_price["distance"] / 1000, 2), 2) : round($zone_price["cr_price_per_km"], 2));
        $zoneDistanceStr .= ($zoneDistanceStr != "" ? " + " : "") .
          (strpos($zone_price["zone"], "_fix") === false ? format_amount(round($zone_price["distance"] / 1000, 2)) . "km " : "") . str_replace("KM-Preis ", "", $srv_names_PZM[$hq_id][$zone_price["zone"]]) .
          (strpos($zone_price["zone"], "_fix") === false ? " * " : " ") . format_amount($zone_price["price_per_km"]) . $euro_sign;
      }
      $srv_name_min = str_replace("_km", "", str_replace("_fix", "", $zone_price["zone"])) . "_min"; // eap_fix wird für Benamsung des Mindestpreises missbraucht
      if (isset($srv_names_PZM[$hq_id][$srv_name_min]))
        $srv_name_min = $srv_names_PZM[$hq_id][$srv_name_min];
writeLog_ajaxReqKmPrice("\$srv_name_min = " . $srv_name_min);
      list($minimum_price_tmp, $minimum_price_correction, $minimum_discount, $minimum_discount_correction, $minimum_cr_price_tmp, $minimum_cr_discount, $customer_specific) =
        getServicePrices($srv_name_min, $srvt_name, $cs_id, $hq_id, $jb_ordertime, 0, $final_discount, 0, false);
      if ($minimum_price < $minimum_price_tmp) {
        $minimum_price = $minimum_price_tmp;
        $minimum_cr_price = $minimum_cr_price_tmp;
        $minimum_price_name = $srv_name_min;
      }
//      list($price_fix, $price_fix_correction, $final_discount, $final_discount_correction, $cr_price_fix, $final_cr_discount, $customer_specific) =
//        getServicePrices($zone_price["zone"] . "_fix", $srvt_name, $cs_id, $hq_id, $jb_ordertime, 0, $final_discount, 0, false);
//      $zone_price["price_fix"] = (float) $price_fix;
//      $zone_price["cr_price_fix"] = (float) $cr_price_fix;
//      if ($zone_price["price_fix"] > 0 && $zone_price["cr_price_fix"] == 0) {
//        list($cr_price_fix, $cr_price_fix_rate) =
//          getCr_price_global($price_fix, $hq_id, $cs_id, $jb_ordertime, $srvt_name, $vht_id);
//        // take unrounded value
//        $zone_price["cr_price_fix"] = $price_fix * (100 - $cr_price_fix_rate) / 100;
//      }
//      if ($zone_price["price_fix"] > 0) {
//        $total_km_price += round($zone_price["price_fix"], 2);
//        $total_km_cr_price += round($zone_price["cr_price_fix"], 2);
//        $zoneDistanceStr .= ($zoneDistanceStr != "" ? " + " : "" ) . $zone_price["zone"] . "_fix" . " (" . format_amount($zone_price["price_fix"]) . " " . $euro_sign . ")";
//      }
	}
	unset($zone_price);
//    if ($zoneDistanceStr != "")
//      $zoneDistanceStr = "(" . $zoneDistanceStr . ")";
    writeLog_ajaxReqKmPrice("\$zones[\"zoneDistance\"] = " . var_export($zones["zoneDistance"], true));

    $extraApproachDistanceStr = "";
    foreach ($zones["extraApproachDistance"] as &$eap_price) {
	  $srv_name = $eap_price["zone"];
      if (isset($srv_names_PZM[$hq_id][$eap_price["zone"]]))
        $srv_name = $srv_names_PZM[$hq_id][$eap_price["zone"]];
      list($price_per_km, $price_per_km_correction, $final_discount, $final_discount_correction, $cr_price_per_km, $final_cr_discount, $customer_specific) =
        getServicePrices($srv_name, $srvt_name, $cs_id, $hq_id, $jb_ordertime, 0, $final_discount, 0, false);
      $eap_price["price_per_km"] = (float) $price_per_km;
      $eap_price["cr_price_per_km"] = (float) $cr_price_per_km;
      if ($eap_price["price_per_km"] > 0 && $eap_price["cr_price_per_km"] == 0) {
        list($cr_price_per_km, $cr_price_per_km_rate) =
          getCr_price_global($price_per_km, $hq_id, $cs_id, $jb_ordertime, $srvt_name, $vht_id);
        // take unrounded value
        $eap_price["cr_price_per_km"] = $price_per_km * (100 - $cr_price_per_km_rate) / 100;
      }
      if ($eap_price["price_per_km"] > 0) {
        $total_km_price_old = $total_km_price;
        $total_km_price += (strpos($eap_price["zone"], "_fix") === false ? $eap_price["price_per_km"] * round($eap_price["distance"] / 1000, 2) : round($eap_price["price_per_km"], 2));
        $total_km_cr_price += (strpos($eap_price["zone"], "_fix") === false ? $eap_price["cr_price_per_km"] * round($eap_price["distance"] / 1000, 2) : round($eap_price["cr_price_per_km"], 2));
        $extraApproachDistanceStr .= ($extraApproachDistanceStr != "" ? " + " : "" ) .
          format_amount(round($eap_price["distance"] / 1000, 2)) . "km " . str_replace("KM-Preis ", "", $srv_names_PZM[$hq_id][$eap_price["zone"]]) .
          " * " . format_amount($eap_price["price_per_km"]) . $euro_sign;
        if ($total_km_price_old != $total_km_price)
          $total_km += round($eap_price["distance"] / 1000, 2);
      }
//      list($price_fix, $price_fix_correction, $final_discount, $final_discount_correction, $cr_price_fix, $final_cr_discount, $customer_specific) =
//        getServicePrices($eap_price["zone"] . "_eap_fix", $srvt_name, $cs_id, $hq_id, $jb_ordertime, 0, $final_discount, 0, false);
//      $eap_price["price_fix"] = (float) $price_fix;
//      $eap_price["cr_price_fix"] = (float) $cr_price_fix;
//      if ($eap_price["price_fix"] > 0 && $eap_price["cr_price_fix"] == 0) {
//        list($cr_price_fix, $cr_price_fix_rate) =
//          getCr_price_global($price_fix, $hq_id, $cs_id, $jb_ordertime, $srvt_name, $vht_id);
//        // take unrounded value
//        $eap_price["cr_price_fix"] = $price_fix * (100 - $cr_price_fix_rate) / 100;
//      }
//      if ($eap_price["price_fix"] > 0) {
//        $total_km_price += round($eap_price["price_fix"], 2);
//        $total_km_cr_price += round($eap_price["cr_price_fix"], 2);
//        $extraApproachDistanceStr .= ($extraApproachDistanceStr != "" ? " + " : "" ) . $eap_price["zone"] . "_eap_fix" . " (" . format_amount($eap_price["price_fix"]) . " " . $euro_sign . ")";
//      }
	}
	unset($eap_price);
//    if ($extraApproachDistanceStr != "")
//      $extraApproachDistanceStr = "An-/Abfahrt in " . $extraApproachDistanceStr;
    writeLog_ajaxReqKmPrice("\$zones[\"extraApproachDistance\"] = " . var_export($zones["extraApproachDistance"], true));

    $extraDepartureCalculationStr = "";
    foreach ($zones["extraDepartureCalculation"] as &$edc_price) {
      $edc_price["zone"] = str_replace("_edc", "_eap", $edc_price["zone"]);
	  $srv_name = $edc_price["zone"];
      if (isset($srv_names_PZM[$hq_id][$edc_price["zone"]]))
        $srv_name = $srv_names_PZM[$hq_id][$edc_price["zone"]];
      list($price_per_km, $price_per_km_correction, $final_discount, $final_discount_correction, $cr_price_per_km, $final_cr_discount, $customer_specific) =
        getServicePrices($srv_name, $srvt_name, $cs_id, $hq_id, $jb_ordertime, 0, $final_discount, 0, false);
      $edc_price["price_per_km"] = (float) $price_per_km;
      $edc_price["cr_price_per_km"] = (float) $cr_price_per_km;
      if ($edc_price["price_per_km"] > 0 && $edc_price["cr_price_per_km"] == 0) {
        list($cr_price_per_km, $cr_price_per_km_rate) =
          getCr_price_global($price_per_km, $hq_id, $cs_id, $jb_ordertime, $srvt_name, $vht_id);
        // take unrounded value
        $edc_price["cr_price_per_km"] = $price_per_km * (100 - $cr_price_per_km_rate) / 100;
      }
      if ($edc_price["price_per_km"] > 0) {
        $total_km_price_old = $total_km_price;
        $total_km_price += (strpos($edc_price["zone"], "_fix") === false ? $edc_price["price_per_km"] * round($edc_price["distance"] / 1000, 2) : round($edc_price["price_per_km"], 2));
        $total_km_cr_price += (strpos($edc_price["zone"], "_fix") === false ? $edc_price["cr_price_per_km"] * round($edc_price["distance"] / 1000, 2) : round($edc_price["cr_price_per_km"], 2));
        $extraDepartureCalculationStr .= ($extraDepartureCalculationStr != "" ? " + " : "" ) .
          format_amount(round($edc_price["distance"] / 1000, 2)) . "km " . str_replace("KM-Preis ", "", $srv_names_PZM[$hq_id][$edc_price["zone"]]) .
          " * " . format_amount($edc_price["price_per_km"]) . $euro_sign;
        if ($total_km_price_old != $total_km_price)
          $total_km += round($edc_price["distance"] / 1000, 2);
      }
      $edc_price["zone"] = str_replace("_eap", "_edc", $edc_price["zone"]);
	}
	unset($edc_price);
    writeLog_ajaxReqKmPrice("\$zones[\"extraDepartureCalculation\"] = " . var_export($zones["extraDepartureCalculation"], true));
  }
  $price_per_stop = 0;
  $cr_price_per_stop = 0;
  list($price_per_stop, $price_per_stop_correction, $final_discount, $final_discount_correction, $cr_price_per_stop, $final_cr_discount, $customer_specific) =
    getServicePrices("Weitere<br>Adressen", $srvt_name, $cs_id, $hq_id, $jb_ordertime, 0, $final_discount, 0, false);
  if ($cr_price_per_stop == "")
    $cr_price_per_stop = 0;
writeLog_ajaxReqKmPrice("\$price_per_stop = " . $price_per_stop . ", \$cr_price_per_stop = " . $cr_price_per_stop);
  $basic_price = 0;
  $basic_cr_price = 0;
  $no_basic_price = getParameterValue("0", "MASK_NO_BASIC_PRICE_FOR_KM_PRICE", $hq_id);
  if ($no_basic_price != "1") {
    list($basic_price, $basic_price_correction, $basic_discount, $basic_discount_correction, $basic_cr_price, $basic_cr_discount, $customer_specific) =
      getServicePrices("Grundpreis", $srvt_name, $cs_id, $hq_id, $jb_ordertime, 0, $final_discount, 0, false);
//  $fuel_markup = getFuelMarkup($srvt_name, (trim($cs_id) != "" ? $cs_id : 0), $hq_id, $jb_ordertime);
    if ($basic_cr_price == "")
      $basic_cr_price = 0;
  }
writeLog_ajaxReqKmPrice("\$basic_price = " . $basic_price);
  if (!(isset($mode) && $mode == "zone")) {
    $total_km_price = round($price_per_km * $total_km + $weitere_adressen * $price_per_stop + $basic_price, 2);
writeLog_ajaxReqKmPrice("\$total_km_price = " . $total_km_price . " ($price_per_km * $total_km + $weitere_adressen * $price_per_stop + $basic_price)");
  } else {
    $total_km_price += $weitere_adressen * $price_per_stop + $basic_price;
writeLog_ajaxReqKmPrice("\$total_km_price = " . $total_km_price . " ($total_km_price + $weitere_adressen * $price_per_stop + $basic_price)");
  }

  $isMinimum = false;
  if (!(isset($mode) && $mode == "zone")) {
    list($minimum_price, $minimum_price_correction, $minimum_discount, $minimum_discount_correction, $minimum_cr_price, $minimum_cr_discount, $customer_specific) =
      getServicePrices("Mindestpreis", $srvt_name, $cs_id, $hq_id, $jb_ordertime, 0, $final_discount, 0, false);
  }
  if ($total_km_price < $minimum_price) {
    $total_km_price = $minimum_price;
    $isMinimum = true;
  }

writeLog_ajaxReqKmPrice("\$minimum_price = " . $minimum_price);
writeLog_ajaxReqKmPrice("\$total_km_price = " . $total_km_price);
writeLog_ajaxReqKmPrice("\$isMinimum = " . $isMinimum);
  if (MASK_CR_PRICE_MODE == "1") {
    if ($basic_cr_price == 0) {
      list($basic_cr_price, $basic_cr_price_rate) =
        getCr_price_global($basic_price, $hq_id, $cs_id, $jb_ordertime, $srvt_name, $vht_id);
      // take unrounded value
      $basic_cr_price = $basic_price * (100 - $basic_cr_price_rate) / 100;
    }
writeLog_ajaxReqKmPrice("\$basic_cr_price = " . $basic_cr_price);
    if ($cr_price_per_km == 0 && !(isset($mode) && $mode == "zone")) {
      list($cr_price_per_km, $cr_price_per_km_rate) =
        getCr_price_global($price_per_km, $hq_id, $cs_id, $jb_ordertime, $srvt_name, $vht_id);
      // take unrounded value
      $cr_price_per_km = $price_per_km * (100 - $cr_price_per_km_rate) / 100;
    }
writeLog_ajaxReqKmPrice("\$cr_price_per_km = " . $cr_price_per_km);
    if ($cr_price_per_stop == 0) {
      list($cr_price_per_stop, $cr_price_per_stop_rate) =
        getCr_price_global($price_per_stop, $hq_id, $cs_id, $jb_ordertime, $srvt_name, $vht_id);
      // take unrounded value
      $cr_price_per_stop = $price_per_stop * (100 - $cr_price_per_stop_rate) / 100;
    }
writeLog_ajaxReqKmPrice("\$cr_price_per_stop = " . $cr_price_per_stop);
    if (!(isset($mode) && $mode == "zone")) {
      $total_km_cr_price = round($cr_price_per_km * $total_km + $weitere_adressen * $cr_price_per_stop + $basic_cr_price, 2);
writeLog_ajaxReqKmPrice("\$total_km_cr_price = " . $total_km_cr_price . " ($cr_price_per_km * $total_km + $weitere_adressen * $cr_price_per_stop + $basic_cr_price)");
    } else {
      $total_km_cr_price += $weitere_adressen * $cr_price_per_stop + $basic_cr_price;
writeLog_ajaxReqKmPrice("\$total_km_cr_price = " . $total_km_cr_price . " (total_km_cr_price + $weitere_adressen * $cr_price_per_stop + $basic_cr_price)");
    }

    if ($minimum_cr_price == 0)
      list($minimum_cr_price, $minimum_cr_price_rate) =
        getCr_price_global($total_km_price, $hq_id, $cs_id, $jb_ordertime, $srvt_name, $vht_id);
writeLog_ajaxReqKmPrice("\$minimum_cr_price = " . $minimum_cr_price);
    if($total_km_cr_price < $minimum_cr_price)
      $total_km_cr_price = $minimum_cr_price;
writeLog_ajaxReqKmPrice("\$total_km_cr_price = " . $total_km_cr_price);
  }

//writeLog_ajaxReqKmPrice("\$basic_price = $basic_price, \$basic_cr_price = $basic_cr_price, \$basic_cr_price_rate = $basic_cr_price_rate, \$price_per_km = $price_per_km, \$cr_price_per_km = $cr_price_per_km, \$cr_price_per_km_rate = $cr_price_per_km_rate, \$price_per_km * (100 - \$cr_price_per_km_rate) / 100 = " . ($price_per_km * (100 - $cr_price_per_km_rate) / 100));
  $retValue = "retValue = [" .
    " '" . format_amount(round($total_km_price * (100 + $jb_markup)) / 100) . " " . $euro_sign . ($isMinimum ? " [M]" : "") . "'," . 
    (!(isset($mode) && $mode == "zone")
      ? " '" . rawurlencode($points . "/") . "',"
//      : " '" . rawurlencode(str_replace("\\", ".", $zones["poliline"])) . "&p1=" . (isset($zones["eapLeg"][0]["polyline"]["encodedPolyline"]) ? rawurlencode(str_replace("\\", ".", $zones["eapLeg"][0]["polyline"]["encodedPolyline"])) : "") .
        : " '" . $zones["di_ids"]["legs"] . "&p1=" . $zones["di_ids"]["eapLeg"] . "&p2=" . $zones["di_ids"]["edcLeg"] .
        "&s=" . rawurlencode($points) . rawurlencode($pointsPZM) . "',"
    ) .
    " '" . format_amount($total_km) . " Km'," .
    (!(isset($mode) && $mode == "zone")
      ? " '" . format_amount($price_per_km) . " " . $euro_sign . " pro Km', '" .
        ($weitere_adressen > 0 && $price_per_stop > 0
          ? " + " . format_amount($price_per_stop) . " " . $euro_sign . " pro " . $weitere_adressen . " weitere Adresse(n) "
          : ""
        ) .
        ($basic_price > 0
          ? " + " . format_amount($basic_price) . " " . $euro_sign . " Anfahrt " . $srvt_name
          : ($no_basic_price != "1" ? " (Anfahrtskosten fehlen!)" : "")
        ) .
        " = " . format_amount($price_per_km * $total_km + $price_per_stop * $weitere_adressen + $basic_price) . " " . $euro_sign .  " + " . format_amount($jb_markup) . "% Tz.',"
      : " '(" . $extraApproachDistanceStr . ($extraApproachDistanceStr != "" ? " + " : "") . $zoneDistanceStr . ($extraDepartureCalculationStr != "" ? " + " : "") . $extraDepartureCalculationStr . ")" . ($basic_price > 0 ? " + " . format_amount($basic_price) . " " . $euro_sign . " " . $srvt_name : "") .
        ($price_per_stop > 0 && $weitere_adressen > 0 ? " + " . format_amount($price_per_stop) . " " . $euro_sign . " pro " . $weitere_adressen . " weitere Adresse(n)" : "") . "'," .
        "' = " . format_amount($total_km_price) . " " . $euro_sign .  " + " . format_amount($jb_markup) . "% Tz.',"
    ) .
    " '" .
    (!(isset($mode) && $mode == "zone") || $srv_names_PZM[$hq_id]["runden"]
      ? format_amount(ceil($total_km_price))
      : format_amount($total_km_price)
    ) .
    "'," .
    " '" . format_amount($total_km_cr_price) . "'," .
    " '" . $mode . "', '" .
    ((isset($mode) && $mode == "zone")
      ? $zones["di_ids"]["legs"] . (trim($zones["di_ids"]["eapLeg"]) != "" ? ";" : "") . $zones["di_ids"]["eapLeg"] . (trim($zones["di_ids"]["edcLeg"]) != "" ? ";" : "") . $zones["di_ids"]["edcLeg"] . "', '" . $total_hours . ":" . $total_minutes
      : ""
    ) . "', '" .
    ($isMinimum ? "[M] " . $minimum_price_name : "") . "'" .
    "];";
//https://www.google.de/maps/dir/Luruper+Weg+6,+25469+Halstenbek/Ottensener+Str.+8,+22525+Hamburg
//writeLog_ajaxReqKmPrice("hallo1");

} else {
  $retValue = "retValue = ['ERROR'," .
    " '" . $error_msg . "'];";
}
writeLog_ajaxReqKmPrice("\$retValue = " . $retValue . "\n");
echo $retValue;

function format_amount($the_price){
  return(str_replace(".", ",", sprintf("%01.2f", $the_price)));
}

function writeLog_ajaxReqKmPrice($log_text) {
  global $mode;

  if (!(isset($mode) && ($mode == "zone" || $mode == "optimize" || $mode == "optimizeAll" || $mode == "coords" || $mode == "full_address" || $mode == "plz")))
    $mode = "km";
  $fileHandle = @fopen("../log/ajaxReqKmPrice_" . $mode . "_" . date("Ym") . ".log", 'a');
  if (!$fileHandle) {
    $fileHandle = @fopen("../log/ajaxReqKmPrice_" . $mode . "_" . date("Ym") . ".web.log", 'a');
  }
  fwrite($fileHandle, "[" . date("Y-m-d H:i:s") . "] " . $log_text .  "\n");
  @fclose($fileHandle);
  return;
}

?>  
