|
@@ -10,6 +10,7 @@ class mratio_control
|
|
|
private $mInterceptConfig;
|
|
|
private $mGrossRatios;
|
|
|
private $mDetailRatios;
|
|
|
+ private $mMchQTS;
|
|
|
private $mMixedPrices;
|
|
|
|
|
|
|
|
@@ -116,6 +117,19 @@ class mratio_control
|
|
|
if (!empty($detail_ratios)) {
|
|
|
$this->mDetailRatios = $detail_ratios;
|
|
|
}
|
|
|
+
|
|
|
+ $this->mMchQTS = [];
|
|
|
+ foreach ($detail_ratios as $key=>$val)
|
|
|
+ {
|
|
|
+ [$mchid,$quality,$card_type,$spec] = explode('-',$key);
|
|
|
+
|
|
|
+ $mchid = intval($mchid);
|
|
|
+ $quality = intval($quality);
|
|
|
+ $card_type = intval($card_type);
|
|
|
+ $spec = intval($spec);
|
|
|
+
|
|
|
+ $this->mMchQTS[$mchid][] = [$quality,$card_type,$spec];
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
public function setMixedPrice($mchid, $mixed_quality, $card_type, $spec, $prices)
|
|
@@ -253,6 +267,10 @@ class mratio_control
|
|
|
return $result;
|
|
|
}
|
|
|
|
|
|
+ private function getMerchantSuppleType($mchid) {
|
|
|
+ return $this->mTimesConfig[$mchid]['profit_formula'] ?? 'qts';
|
|
|
+ }
|
|
|
+
|
|
|
//return true 表示不可以补充。
|
|
|
public function ratio_match($mchid, $org_quality, $cur_quality, $card_type, $spec, $qualities)
|
|
|
{
|
|
@@ -266,15 +284,175 @@ class mratio_control
|
|
|
Log::record("{$header} gross_ratio = {$gross_ratio},lower_ratio={$ratio}",Log::DEBUG);
|
|
|
|
|
|
if($gross_ratio >= $ratio) return true;
|
|
|
- [$_succ, $_fail, $cur_ratio] = $this->detail_ratio($mchid, $cur_quality, $card_type, $spec, $period);
|
|
|
- Log::record("{$header} cur_ratio = {$cur_ratio},lower_ratio={$ratio}",Log::DEBUG);
|
|
|
-
|
|
|
- if($cur_ratio >= $ratio) return true;
|
|
|
|
|
|
if (!PolicyUtil::mixed_quality($org_quality)) {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
+ $type = $this->getMerchantSuppleType($mchid);
|
|
|
+ Log::record("type = {$type}",Log::DEBUG);
|
|
|
+ if($type === 'all') {
|
|
|
+ return $this->all_checker($mchid, $org_quality, $spec, $qualities, $period, $header, $ratio);
|
|
|
+ }
|
|
|
+ elseif($type === 'qt') {
|
|
|
+ return $this->qts_checker($mchid, $org_quality,$cur_quality, $card_type, $spec, $qualities,$period,$header,$ratio);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ return $this->qts_checker($mchid, $org_quality,$cur_quality, $card_type, $spec, $qualities,$period,$header,$ratio);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private function all_checker($mchid, $org_quality, $spec, $qualities, $period, $header, $low_ratio)
|
|
|
+ {
|
|
|
+ $qtsex = $this->mMchQTS[$mchid];
|
|
|
+ $profit_judger = function ($mchid, $qtsex, $org_quality, $period, $profit_ratio, $header)
|
|
|
+ {
|
|
|
+ $profit = 0;
|
|
|
+ $amount = 0;
|
|
|
+
|
|
|
+ foreach ($qtsex as $qts)
|
|
|
+ {
|
|
|
+ [$quality,$card_type,$spec] = $qts;
|
|
|
+ if($quality == $org_quality) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+// Log::record("quality={$quality},card_type ={$card_type},spec={$spec}",Log::DEBUG);
|
|
|
+
|
|
|
+ $prices = $this->getPrice($mchid, $org_quality, $card_type, $spec);
|
|
|
+ $out_price = $prices[$org_quality];
|
|
|
+ $in_price = $prices[$quality] ?? false;
|
|
|
+ if ($in_price === false || $in_price <= 0) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ [$succ, $fail, $ratio] = $this->detail_ratio($mchid, $quality,$card_type, $spec, $period);
|
|
|
+ $profit += $succ * ($out_price - $in_price);
|
|
|
+ $amount += $succ * $spec;
|
|
|
+
|
|
|
+// Log::record("out_price = {$out_price},in_price={$in_price} profit={$profit} amount={$amount}",Log::DEBUG);
|
|
|
+ }
|
|
|
+
|
|
|
+ $cur_pratio = round(($profit + 0.00001) / ($amount + 0.00001),4);
|
|
|
+ $profit_ratio = round($profit_ratio,4);
|
|
|
+ $profit_ratio = round($profit_ratio,4);
|
|
|
+
|
|
|
+ Log::record("{$header} all_checker cur_pratio = {$cur_pratio},profit_ratio={$profit_ratio}",Log::DEBUG);
|
|
|
+ return $cur_pratio > $profit_ratio;
|
|
|
+ };
|
|
|
+
|
|
|
+ $spec_max = function ($mchid,$qtsex, $org_quality, $qualities, $low_ratio,$period)
|
|
|
+ {
|
|
|
+ $specs = [];
|
|
|
+ $spec_qt = [];
|
|
|
+ foreach ($qtsex as $qts) {
|
|
|
+ [$quality, $card_type, $spec] = $qts;
|
|
|
+ $specs[] = $spec;
|
|
|
+ $spec_qt[$spec][] = [$quality,$card_type];
|
|
|
+ }
|
|
|
+
|
|
|
+ $specs = array_unique($specs);
|
|
|
+ sort($specs);
|
|
|
+
|
|
|
+ $ratio_calc = function ($mchid, $specs, $spec_qt, $max_spec, $org_quality, $qualities, $period)
|
|
|
+ {
|
|
|
+ $all_succ = 0;
|
|
|
+ $all_fail = 0;
|
|
|
+
|
|
|
+ foreach ($specs as $spec)
|
|
|
+ {
|
|
|
+ $qts = $spec_qt[$spec];
|
|
|
+ if($max_spec >= $spec) {
|
|
|
+ $fHigtRatio = true;
|
|
|
+ } else {
|
|
|
+ $fHigtRatio = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ $card_types = [];
|
|
|
+ foreach ($qts as $qt)
|
|
|
+ {
|
|
|
+ [$quality,$card_type] = $qt;
|
|
|
+ if($quality === $org_quality) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ $card_types[] = $card_type;
|
|
|
+ }
|
|
|
+
|
|
|
+ $detail_ratios = $this->detail_ratios($mchid, $qualities,$card_type, $spec, $period);
|
|
|
+ if($fHigtRatio)
|
|
|
+ {
|
|
|
+ $all = 0;
|
|
|
+ $ratios = [];
|
|
|
+ foreach ($detail_ratios as $quality => $sfr) {
|
|
|
+ [$succ,$fail,$ratio] = $sfr;
|
|
|
+// Log::record("high succ={$succ},fail={$fail},ratio = {$ratio}",Log::DEBUG);
|
|
|
+ $ratios[] = $ratio;
|
|
|
+ $all += $succ;
|
|
|
+ $all += $fail;
|
|
|
+ }
|
|
|
+
|
|
|
+ $max_ratios = max($ratios);
|
|
|
+ $succs = $max_ratios * $all;
|
|
|
+ $fails = $all - $succs;
|
|
|
+
|
|
|
+ $all_succ += $succs;
|
|
|
+ $all_fail += $fails;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ foreach ($detail_ratios as $quality => $sfr)
|
|
|
+ {
|
|
|
+ [$succ,$fail,$ratio] = $sfr;
|
|
|
+// Log::record("normal succ={$succ},fail={$fail},ratio = {$ratio}",Log::DEBUG);
|
|
|
+ $all_succ += $succ;
|
|
|
+ $all_fail += $fail;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ $ratio = ($all_succ + 0.00001)/ ($all_succ + $all_fail + 0.00001);
|
|
|
+ return round($ratio,4);
|
|
|
+ };
|
|
|
+
|
|
|
+ for ($i = 0; $i < count($specs); $i++)
|
|
|
+ {
|
|
|
+ $max_spec = $specs[$i];
|
|
|
+ $ratio = $ratio_calc($mchid, $specs, $spec_qt, $max_spec, $org_quality, $qualities, $period);
|
|
|
+// Log::record("spec={$max_spec},ratio={$ratio},low_ratio={$low_ratio}",Log::DEBUG);
|
|
|
+ if($ratio >= $low_ratio) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return $max_spec;
|
|
|
+ };
|
|
|
+
|
|
|
+ $profit_ratio = $this->profit_ratio($mchid);
|
|
|
+ $can_next = $profit_judger($mchid, $qtsex, $org_quality, $period, $profit_ratio, $header);
|
|
|
+
|
|
|
+ if($can_next)
|
|
|
+ {
|
|
|
+ $max_spec = $spec_max($mchid,$qtsex, $org_quality, $qualities, $low_ratio,$period);
|
|
|
+ Log::record("max_spec={$max_spec}",Log::DEBUG);
|
|
|
+ if($max_spec >= $spec) {
|
|
|
+ return false;
|
|
|
+ } else {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private function qts_checker($mchid, $org_quality,$cur_quality, $card_type, $spec, $qualities,$period,$header,$ratio)
|
|
|
+ {
|
|
|
+ [$_succ, $_fail, $cur_ratio] = $this->detail_ratio($mchid, $cur_quality, $card_type, $spec, $period);
|
|
|
+ Log::record("{$header} cur_ratio = {$cur_ratio},lower_ratio={$ratio}",Log::DEBUG);
|
|
|
+
|
|
|
+ if($cur_ratio >= $ratio) return true;
|
|
|
+
|
|
|
$prices = $this->getPrice($mchid, $org_quality, $card_type, $spec);
|
|
|
if ($prices === false) {
|
|
|
return false;
|
|
@@ -301,7 +479,7 @@ class mratio_control
|
|
|
$cur_pratio = round(($profit + 0.00001) / ($amount + 0.00001),4);
|
|
|
$profit_ratio = round($profit_ratio,4);
|
|
|
|
|
|
- Log::record("{$header} cur_pratio = {$cur_pratio},profit_ratio={$profit_ratio}",Log::DEBUG);
|
|
|
+ Log::record("{$header} qts_checker cur_pratio = {$cur_pratio},profit_ratio={$profit_ratio}",Log::DEBUG);
|
|
|
return $cur_pratio > $profit_ratio;
|
|
|
};
|
|
|
|