我需要在PHP中创建一个计算以下内容的会计算法。
我正在开发一个应用程序,供会员每天缴纳固定金额的款项。假设每天的捐款额是200美元,会员可以在给定的天数内预付。
例如,如果捐款的开始日期是2015年4月1日,并且会员支付了600美元,则算法应将金额从2015年4月份1日分配到2015年4季度3日。
如果他在2015年4月10日支付下一笔捐款并支付2000美元,则算法应首先支付2015年4月份4日至2015年4季度10日期间总计1400美元的赤字,然后分配2015年4月末11日至2015年度4月13日期间总计600美元的余额。
我尝试使用以下代码,它试图添加逻辑来检测用户何时多付了钱,如果多付了钱的话,则添加如上所述均匀分配金额的算法。如果他少付了工资,算法应该在"拖欠者"行中添加一行,最后一个支付日期应该选择为供款表中最近添加的行。
public function actionBackdate() {
$start = new DateTime("2015-03-1");
$now=new DateTime();
$now->modify('+1 day');
$days = $now->diff($start);
echo $now->format('Y-m-d g:i a');
echo "<br/>";
echo $days->format('%a')." have passed since";
echo "<br/>";
$contributionAmount=200;
$TotalContributed=5400;
$amountContributed=0;
$oustandingBalance=0;
$contributionDetails=array(
"memberid" =>4,
"payment_mode"=>"CASH",
"payment_for" =>"Chama Daily",
"payment_ref" =>rand(9,9999),
"amount" =>"",
"currency" =>"KSH",
"created_at" =>"",
"updated_at" =>""
);
$defaulter=array(
"memberid" =>4,
"currency" =>"KSH",
"amount_defaulted"=>"",
"date_defaulted" =>"Daily Contrib",
"fine_amount" =>50,
"note" =>"Contribution defaulter",
"status" =>0
);
for( $i=0;$i<(int)$days->format('%a')+1;$i++){
//underpayment from expeted contribution amount
if($TotalContributed<$contributionAmount && $TotalContributed>0 ){
echo "He had a balance of ".($contributionAmount-$TotalContributed)." at date ".$start->format('Y-m-d g:i a')."<br/>";
$oustandingBalance+=($contributionAmount-$TotalContributed);
}elseif($TotalContributed==0){
// paid 0
$oustandingBalance+=($contributionAmount-$TotalContributed);
$defaulter['amount_defaulted']=$contributionAmount;
$defaulter['date_defaulted'] =$start->format('Y-m-d H:i:s');
$model=new ChamaDefaulter;
$model->attributes=$defaulter;
if(!$model->save()){
throw new Exception("Error saving details", 1);
}
}elseif($TotalContributed<0){
// he has balance expected
$oustandingBalance+=$contributionAmount;
$defaulter['amount_defaulted']=$contributionAmount;
$defaulter['date_defaulted'] =$start->format('Y-m-d H:i:s');
$model=new ChamaDefaulter;
$model->attributes=$defaulter;
if(!$model->save()){
throw new Exception("Error saving details", 1);
}
}else{
//Contribution received as expected;
$amountContributed+=$contributionAmount;
$contributionDetails["amount"]=$contributionAmount;
$contributionDetails["date_paid"]=$start->format('Y-m-d H:i:s');
$model=new ChamaContribution;
$model->attributes=$contributionDetails;
if(!$model->save()){
throw new Exception("Error saving details", 1);
}
}
$TotalContributed-=$contributionAmount;
$start->modify('+1 day');
}
exit("User oustanding Balance is KSH $oustandingBalance");
}
您要求我澄清我的评论,因此:
用户的余额可以为负数,以后的付款也可以为正数。
当然。你需要一张付款表,由于你每天都要收费,所以你需要每天都记一笔账。你可以每周收费,然后每周收费——这取决于你。
假设您只维护一个付款记录,并在需要时动态计算余额。您的条目可能如下所示:
User Value Purpose Date
1 600 Payment 2015-04-03
1 -200 Daily 2015-04-03
1 -200 Daily 2015-04-04
1 -200 Daily 2015-04-05
1 -200 Daily 2015-04-06
你可以在这里看到,这个用户在4月3日成为会员,每天被收取200多英镑的费用。他们的余额可以计算为-200(假设以上是该用户的所有记录);你是否允许他们在该州参加会员活动完全取决于你。例如,您可以允许用户默认一定的天数,或者只默认一定的数量。
当这个用户进行新的支付时,会以通常的方式添加,这可能会也可能不会让他们重新获得信用。
由于付款存在分歧,请始终添加数据行,不要更新它们-如果您丢失了历史记录,则无法解决财务纠纷
存储用户的余额不如存储他们的个人付款重要——你可以根据他们的付款减去他们的费用来计算他们的余额,但你不能根据他们的余额来计算他们。
让我们假设你不接受我的建议,只使用一个平衡表:
User Balance Last updated
1 -200 2015-04-06
现在用户声称他们昨天付款了,这可能是真的,也可能不是真的。你可以要求他们出示证明(例如支付网关收据),但如果你能在自己的系统中找到这些信息,那就容易多了。