[英]recursive batch reconciliation of a subset of credit card charges
我找到了一個解決方案 ,請參見下面的答案和/或具有新的優化功能的Github Gist 。
我有一系列的信用卡費用和一批總金額...有時金額的SUM()=批總金額,因此很容易歸為一批,我們可以核對當天存入的交易支票帳戶。
有時,適當的金額是這些費用中的一部分,第二天將分批支付1或更多。 您會以編程方式幫助我解決這個問題嗎? 這是給我的authorize.net批處理記帳的,很麻煩,所以我正在為簿記員制作工具。
+------------+--------+
| transId | amount |
+------------+--------+
| 2863996511 | 154.00 |
| 2863992361 | 762.20 |
| 2863898975 | 49.00 |
| 2863894564 | 5.44 |
| 2863879671 | 10.88 |
| 2863858891 | 209.00 |
| 2863856334 | 148.00 |
| 2863367273 | -25.01 |
+------------+--------+
當天的總批量為$ 1302.63。 經常發生的是,電荷並沒有最終出現在該批次中,因此該批次是陣列中電荷總和的一部分。 在這種情況下,$ 10.88的費用是在第二天的批次中。 這一點偽代碼可以通過兩個嵌套的for循環來捕獲:
for( $skipdx=0; $skipdx<$size; $skipdx++){
$total=0;
for( $idx=0; $idx<$size; $idx++){
if($idx!=$skipdx){
$total+=$charges[$idx]['amount'];
$thisBatch[]=$charges[$idx]['transId'];
}
if( abs($total-$batch['total']) < .04 ) {
echo "sum of charges matches $date batch total: $$total (line: ". __LINE__ .")\n";
$foundIt=TRUE;
break;
}
}
if($foundIt==TRUE)
break;
}
如何動態選擇搜索未添加兩個費用的費用? 那三點 我可以看到,如果$skipdx
省略了一個費用,則跳過兩個費用將添加一個skip2dx
嵌套循環。 如果仍然找不到,則skip3dx
將是嵌套的第3級。
我通常非常擅長算法,直到遞歸為止,然后我變得愚蠢。
它來找我! 遞歸的“當前層”執行以下操作:
工作代碼( Github也有更新的優化 ):
$charges=Array(
'2863996511' => 154.00 ,'2863879671' => 10.88
,'2863992361' => 762.20 ,'2863858891' => 209.00
,'2863898975' => 49.00 ,'2863856334' => 148.00
,'2863894564' => 5.44 ,'2863367273' => -25.01
); print_r($charges);
$targets=Array(1302.63, 1327.64, 1322.20 );
foreach( $targets as $batch ) {
printf( "We seek combination of transIds to = $%-7.2f\n", $batch);
$answer=reco( $batch, $charges );
if( is_array($answer) )
echo eval( "return ".implode("+",$answer).";" )."\nWIN!\n";
else
echo "Bust!\n";
}
function reco( $target, $arr ){
if( count($arr) < 2 )
return FALSE;
$killid='';
$sum = eval( "return ".implode("+",$arr).";" );
foreach( $arr as $id=>$amt ){
if( abs($sum-$target-$amt) < .01 ) {
$killid=$id;
break;
}
}
if( strlen($killid) > 1 ) {
echo ". omit $killid : ".$arr[$killid]."\n";
unset($arr[$killid]);
return $arr;
}
foreach( $arr as $id=>$amt ){
$tmp=$arr;
unset($tmp[$id]);
$rtn = reco( $target, $tmp );
if( is_array($rtn) ) {
echo ".. omit $id : ".$arr[$id]."\n";
return $rtn;
}
}
return FALSE;
}
並輸出:
We seek combination of transIds to = $1302.63
. omit 2863879671 : 10.88
1302.63
WIN!
We seek combination of transIds to = $1327.64
. omit 2863367273 : -25.01
.. omit 2863879671 : 10.88
1327.64
WIN!
We seek combination of transIds to = $1322.20
. omit 2863367273 : -25.01
.. omit 2863879671 : 10.88
.. omit 2863894564 : 5.44
1322.2
WIN!
性能不是一個大問題。 到第三級遞歸,大約需要一秒鍾。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.