2015-07-11 152 views
0

我正在开发零售应用程序。通常在零售销售中可以有多种支付类型和金额(以及一段时间内的多种相同类型)。我遇到了一个错误,并希望确保我有意义的修复。确定每种付款类型实际使用多少付款和金额

这些付款总额可能大于或等于付款类型(用于出售)。我遇到了一个奇怪的场景,我不确定自己有没有正确的想法。

实例问题我有:

售总+20他们支付-2cash,然后debit+22。下面的功能报告+20现金和0借方。我想要一个方法来报告-2cash+22debit

还有其他一些简单的情况,如总销售+18,他们在cash支付+20。这种情况下工作并报告+18cash

还可以按不同的顺序输入付款;但我认为它应该根据它输入的顺序来完成。

我遇到的问题是积极销售的负支付。

逻辑首先获得总销售余额。 (可能对销售有积极影响,对于退货可能为负数;甚至可能为0)。从这里检查支付金额是正面还是负面。

  1. 如果是肯定的,它会尝试尽可能多地使用付款金额直到总销售余额(我认为这是正确的)。

2.负向支付类型存在逆逻辑。我认为在正面销售中出现负付款会造成问题。我不知道如何解决这个问题,我没有预想到这种情况。

经过这些检查后,它会从总销售余额中扣除付款,并对所有付款执行相同的逻辑。

$total_sale_balance = $sales_totals[$sale_id];  
foreach($payment_rows as $payment_row) 
{ 
    if ($payment_row['payment_amount'] >=0) 
    { 
     $payment_amount = $payment_row['payment_amount'] <= $total_sale_balance ? $payment_row['payment_amount'] : $total_sale_balance; 
    } 
    else 
    { 
     $payment_amount = $payment_row['payment_amount'] >= $total_sale_balance ? $payment_row['payment_amount'] : $total_sale_balance; 
    } 
    if (!isset($payment_data[$payment_row['payment_type']])) 
    { 
     $payment_data[$payment_row['payment_type']] = array('payment_type' => $payment_row['payment_type'], 'payment_amount' => 0); 
    } 

    $exists = $this->_does_payment_exist_in_array($payment_row['payment_id'], $payments_by_sale[$sale_id]); 

    if ($total_sale_balance != 0 && $exists) 
    { 
     $payment_data[$payment_row['payment_type']]['payment_amount'] += $payment_amount; 
    } 
    $total_sale_balance-=$payment_amount;     
} 

我正在寻找一种不同的方式来查看问题,因为我遇到了针对销售和退货的不同付款类型的问题。

我是否需要4种可能的逻辑?(这似乎是有道理的)

1:销售总阳性,付款方式正

$payment_amount = $payment_row['payment_amount'] <= $total_sale_balance ? $payment_row['payment_amount'] : $total_sale_balance; 

2:销售总阳性,付款类型负

$payment_amount = $payment_row['payment_amount']; 

3:住宅总负,付款类型正面

$payment_amount = $payment_row['payment_amount']; 

4:销售总计负面,付款方式负面

$payment_amount = $payment_row['payment_amount'] >= $total_sale_balance ? $payment_row['payment_amount'] : $total_sale_balance; 

我只是想确保覆盖所有场景。

这与上述逻辑的最终代码....我俯瞰什么?这似乎是有道理的吗?

$total_sale_balance = $sales_totals[$sale_id];  
foreach($payment_rows as $payment_row) 
{ 
    //Postive sale total, positive payment 
    if ($sales_totals[$sale_id] >= 0 && $payment_row['payment_amount'] >=0) 
    { 
     $payment_amount = $payment_row['payment_amount'] <= $total_sale_balance ? $payment_row['payment_amount'] : $total_sale_balance; 
    }//Negative sale total negative payment 
    elseif ($sales_totals[$sale_id] < 0 && $payment_row['payment_amount'] < 0) 
    { 
     $payment_amount = $payment_row['payment_amount'] >= $total_sale_balance ? $payment_row['payment_amount'] : $total_sale_balance; 
    }//Positive Sale total negative payment 
    elseif($sales_totals[$sale_id] >= 0 && $payment_row['payment_amount'] < 0) 
    { 
     $payment_amount = $payment_row['payment_amount']; 
    }//Negtive sale total postive payment 
    elseif($sales_totals[$sale_id] < 0 && $payment_row['payment_amount'] >= 0) 
    { 
     $payment_amount = $payment_row['payment_amount']; 
    } 

    if (!isset($payment_data[$payment_row['payment_type']])) 
    { 
     $payment_data[$payment_row['payment_type']] = array('payment_type' => $payment_row['payment_type'], 'payment_amount' => 0); 
    } 

    $exists = $this->_does_payment_exist_in_array($payment_row['payment_id'], $payments_by_sale[$sale_id]); 

    if ($total_sale_balance != 0 && $exists) 
    { 
     $payment_data[$payment_row['payment_type']]['payment_amount'] += $payment_amount; 
    } 

    $total_sale_balance-=$payment_amount; 
} 

回答

0

您需要确保所有负面交易都先发生(对于我所知道的所有情况,您都可以在其他地方)。有了您的最终代码块,共计+20,-2现金交易,而+22一切总计借记交易正确为0。但是,如果借方处理至上那么你+的总余额结束2因为第一个逻辑块(正数+正数)会将借记交易限制在20,因为那是该点的总余额。

另一件你可能想也可能不想要的事情是,如果总数是负数并且付款是正数,那么收费仍然会全额发生,从而推动总数进一步负数(即总数= -10,付款= 10,总数将变成-20)。由于您的第一个逻辑块直接尝试抵消负余额,因此您可能不需要这个。

另一种做法可能是:

$total_sale_balance = $sales_totals[$sale_id]; 
$positive_transactions = array(); // or [] if you're using a new enough PHP 
$negative_transactions = array(); 
foreach ($payment_rows as $payment_row) { 
    // Let's just check if the transaction exists here. 
    // No need to do anything else with it if this check fails. 
    if (!$this->_does_payment_exist_in_array($payment_row['payment_id'], $payments_by_sale[$sale_id])) { continue; } 

    if ($payment_row['payment_amount'] > 0) { 
    $positive_transactions[] = $payment_row; 
    } else if ($payment_row['payment_amount'] < 0) { 
    $negative_transactions[] = $payment_row; 
    } 
} // No logic for == 0 since it doesn't look like you're actually doing anything with that. 

foreach ($negative_transactions as $transaction) { 
    $total_sale_balance -= $transaction['payment_amount']; 
    $payment_data[$transaction['payment_type']]['payment_amount'] += $transaction['payment_amount']; 
} 

foreach ($positive_transactions as $transaction) { 
    if ($total_sale_balance <= 0) { break; } 
    $amount_to_pay = ($transaction['payment_amount'] < $total_sale_balance ? $transaction['payment_amount'] : $total_sale_balance); 
    $total_sale_balance -= $amount_to_pay; 
    $payment_data[$transaction['payment_type']]['payment_amount'] += $amount_to_pay; 
} 

如果你可以忽略的事实,我显然不坚持一些编码标准,你可以看到,我被到处转移的几件事情,使之更加耐用并节省一些计算周期。

在初始循环中首先进行'支付存在'检查,如果检查失败,基本上只是跳过所有事务,不需要在任何其他位置放置更多的逻辑来处理该事务,并且不会浪费计算时间来尝试逻辑我们通过交易的方式,无论如何我们不会做任何事情。

接下来,通过分割事务分为正面和负面的,可以简化的if-else逻辑,确保交易,防止滥,并保持理智的顺序发生。

在负块,就没有必要做任何额外的逻辑,因为(在你上面的代码)阴性交易不能不基于总的平衡。

在正块,唯一必要的检查是到付款金额约束到总。通过首先检查是否全部得到满足,我们就可以尽快结束循环为所需金额已经满足,或者总还是积极的,但比交易金额较低,我们可以只约束它。

同样值得注意的是,如果您删除了积极区块顶部的if语句,那么如果总数为负值,那么支付将自动被限制为可能或可能不需要的负值,这取决于例如,你是否想要偿还一个负的总余额。如果购买涉及退款(因此总额开始为负数 - 因为逻辑不允许负数总额)为20美元(总数= -20),那么下一次正面交易将被限制为-20,其将为零在总数和(其他地方,无论是在代码或现实世界)给我我的钱。当然,在这种情况下,您可能希望在肯定列表中包含0笔金额的交易(将第一个分栏中的if-statement更改为>= 0),因为这可能是退款的交易起点。