确定多种付款和金额实际使用的每种付款类型的数量

时间:2015-07-11 22:35:03

标签: php

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

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

我遇到的示例问题:

他们在+20上支付-2,然后在cash+22支付的总销售额debit。以下功能在借记卡上报告+20现金和0。我希望有一种方法可以在-2cash +22上报告debit

还有其他一些简单的方案,例如+18的总销售额,并在+20中支付cash。此方案适用于+18中的cash

付款也可以不同的顺序输入;但我认为它应该根据输入的顺序来做。

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

逻辑首先获得总销售余额。 (可能对销售产生积极影响或对回报产生负面影响;甚至为0)。从这里它检查付款金额是正面还是负面。

  1. 如果是积极的,它会尝试尽可能多地使用付款金额直至总销售余额(我认为这是对的)。
  2. 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;
    }
    

1 个答案:

答案 0 :(得分: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语句,那么如果总数为负数,则支付将自动约束为负数,这可能是也可能不是,这取决于是否或不是,你会想要,例如,抵消负的总余额。 IE如果购买涉及退款(因此总开始为负 - 因为逻辑不允许否定总数否则)为20美元(总计= -20),那么下一个正交易将被限制为-20,这将为零总计和(在其他地方,无论是代码还是现实世界)给我钱。当然,在这种情况下,您可能希望在肯定列表中包含0个金额交易(将第一个块中的if语句更改为>= 0),因为这可能是退款的交易起点。