0

I'm trying to combine two arrays and subtract a value within the array if two keys match each other.

This is the code I've written so far.

$dat = array();
for ($i = 0; $i <= (count($cashdrawer_sales) - 1); $i++) {
$obj = $cashdrawer_sales[$i];
foreach ($cashdrawer_refund as $k=>$ref) {
    if ($obj['cash_drawer']==$ref['cash_drawer'] && $ref['department_id']==$obj['department_id']) {
        $cash_drawer_total = $obj['cash_drawer_sale_total'] - $ref['cash_drawer_refund_total'];
        $arr = array('department_id'=>$obj['department_id'], 'cash_drawer' => $obj['cash_drawer'], 'cash_drawer_total' => $cash_drawer_total);
        array_push($dat,$arr);
    } else {
        $cash_drawer_total = $obj['cash_drawer_sale_total'];
        //  echo $cash_drawer_total."<br>";
        $arr = array('department_id'=>$obj['department_id'], 'cash_drawer' => $obj['cash_drawer'], 'cash_drawer_total' => $cash_drawer_total);
        array_push($dat,$arr);
    }
}
}
print_r($dat);

Here's an example of the $cashdrawer_sales and $cashdrawer_refund arrays that I'm wanting to manipulate.

cashdrawer_sales

Array
(
[0] => Array
    (
        [department_id] => 80000
        [cash_drawer] => 21112
        [cash_drawer_sale_total] => 64.00
    )

[1] => Array
    (
        [department_id] => 80000
        [cash_drawer] => 21117
        [cash_drawer_sale_total] => 15.00
    )

[2] => Array
    (
        [department_id] => 80000
        [cash_drawer] => No Cash Drawer
        [cash_drawer_sale_total] => 50.00
    )

[3] => Array
    (
        [department_id] => 50502
        [cash_drawer] => 21112
        [cash_drawer_sale_total] => 193.00
    )

[4] => Array
    (
        [department_id] => 50502
        [cash_drawer] => 21113
        [cash_drawer_sale_total] => 30.00
    )

[5] => Array
    (
        [department_id] => 50502
        [cash_drawer] => 21117
        [cash_drawer_sale_total] => 10.00
    )

[6] => Array
    (
        [department_id] => 50502
        [cash_drawer] => No Cash Drawer
        [cash_drawer_sale_total] => 80.00
    )

[7] => Array
    (
        [department_id] => No Department
        [cash_drawer] => 21112
        [cash_drawer_sale_total] => 50.00
    )

[8] => Array
    (
        [department_id] => No Department
        [cash_drawer] => No Cash Drawer
        [cash_drawer_sale_total] => 125.00
    )

)

cashdrawer_refund

Array
(
[0] => Array
    (
        [department_id] => 50502
        [cash_drawer] => 21112
        [cash_drawer_refund_total] => 103.00
    )

[1] => Array
    (
        [department_id] => No Department
        [cash_drawer] => No Cash Drawer
        [cash_drawer_refund_total] => 25.37
    )
)

I feel like I'm really close to a solution but I can't get it right

When I run this code I'm getting two amounts for each original value. So (from what I can tell) I am meeting my conditional on multiple passes.

Array
(
[0] => Array
    (
        [department_id] => 80000
        [cash_drawer] => 21112
        [cash_drawer_total] => 64.00
    )

[1] => Array
    (
        [department_id] => 80000
        [cash_drawer] => 21112
        [cash_drawer_total] => 64.00
    )

[2] => Array
    (
        [department_id] => 80000
        [cash_drawer] => 21117
        [cash_drawer_total] => 15.00
    )

[3] => Array
    (
        [department_id] => 80000
        [cash_drawer] => 21117
        [cash_drawer_total] => 15.00
    )

[4] => Array
    (
        [department_id] => 80000
        [cash_drawer] => No Cash Drawer
        [cash_drawer_total] => 50.00
    )

[5] => Array
    (
        [department_id] => 80000
        [cash_drawer] => No Cash Drawer
        [cash_drawer_total] => 50.00
    )

[6] => Array
    (
        [department_id] => 50502
        [cash_drawer] => 21112
        [cash_drawer_total] => 90
    )

[7] => Array
    (
        [department_id] => 50502
        [cash_drawer] => 21112
        [cash_drawer_total] => 193.00
    )

[8] => Array
    (
        [department_id] => 50502
        [cash_drawer] => 21113
        [cash_drawer_total] => 30.00
    )

[9] => Array
    (
        [department_id] => 50502
        [cash_drawer] => 21113
        [cash_drawer_total] => 30.00
    )

[10] => Array
    (
        [department_id] => 50502
        [cash_drawer] => 21117
        [cash_drawer_total] => 10.00
    )

[11] => Array
    (
        [department_id] => 50502
        [cash_drawer] => 21117
        [cash_drawer_total] => 10.00
    )

[12] => Array
    (
        [department_id] => 50502
        [cash_drawer] => No Cash Drawer
        [cash_drawer_total] => 80.00
    )

[13] => Array
    (
        [department_id] => 50502
        [cash_drawer] => No Cash Drawer
        [cash_drawer_total] => 80.00
    )

[14] => Array
    (
        [department_id] => No Department
        [cash_drawer] => 21112
        [cash_drawer_total] => 50.00
    )

[15] => Array
    (
        [department_id] => No Department
        [cash_drawer] => 21112
        [cash_drawer_total] => 50.00
    )

[16] => Array
    (
        [department_id] => No Department
        [cash_drawer] => No Cash Drawer
        [cash_drawer_total] => 125.00
    )

[17] => Array
    (
        [department_id] => No Department
        [cash_drawer] => No Cash Drawer
        [cash_drawer_total] => 99.63
    )

)

I'm assuming this is happening because I'm iterating through each sale twice to analyze the refund. However, I'm not sure what to do about this.

This is my ultimate goal:

Array
(
[0] => Array
    (
        [department_id] => 80000
        [cash_drawer] => 21112
        [cash_drawer_total] => 64.00
    )

[1] => Array
    (
        [department_id] => 80000
        [cash_drawer] => 21117
        [cash_drawer_total] => 15.00
    )


[2] => Array
    (
        [department_id] => 80000
        [cash_drawer] => No Cash Drawer
        [cash_drawer_total] => 50.00
    )


[3] => Array
    (
        [department_id] => 50502
        [cash_drawer] => 21112
        [cash_drawer_total] => 90
    )


[4] => Array
    (
        [department_id] => 50502
        [cash_drawer] => 21113
        [cash_drawer_total] => 30.00
    )


[5] => Array
    (
        [department_id] => 50502
        [cash_drawer] => 21117
        [cash_drawer_total] => 10.00
    )

[6] => Array
    (
        [department_id] => 50502
        [cash_drawer] => No Cash Drawer
        [cash_drawer_total] => 80.00
    )


[7] => Array
    (
        [department_id] => No Department
        [cash_drawer] => 21112
        [cash_drawer_total] => 50.00
    )

[8] => Array
    (
        [department_id] => No Department
        [cash_drawer] => No Cash Drawer
        [cash_drawer_total] => 99.63
    )
)

Any suggestions?

6
  • Do you want to separate sale and refund for each cash_drawer? Commented Mar 21, 2016 at 18:51
  • I want to subtract the refund total from the corresponding sale total and have a new array with new totals. Commented Mar 21, 2016 at 18:53
  • OK, but are you trying to do this job for each cash_drawer? Because your sales array has 7 elements and your refund array has 2 elements. Commented Mar 21, 2016 at 18:56
  • yes, I am trying to do this for each cash drawer by department_id (cash_drawer is not unique, deptartment_id is). Commented Mar 21, 2016 at 18:57
  • The idea is that a sale total might not have a refund, but if it does have a refund I need to subtract that from the corresponding total and create my new array. Commented Mar 21, 2016 at 18:58

4 Answers 4

1

Use a combination of department_id and cash_drawer to create result keys:

$result = array();

foreach( $cashdrawer_sales as $row )
{
    $key = $row['department_id'].'|'.$row['cash_drawer'];                      # <------
    if( !isset( $result[$key] ) )
    {
        $result[$key] = $row;
        unset( $result[$key]['cash_drawer_sale_total'] );
        $result[$key]['cash_drawer_total'] = 0;
    }
    $result[$key]['cash_drawer_total'] += $row['cash_drawer_sale_total'];
}

foreach( $cashdrawer_refund as $row )
{
    $key = $row['department_id'].'|'.$row['cash_drawer'];                      # <------
    if( !isset( $result[$key] ) )
    {
        $result[$key] = $row;
        unset( $result[$key]['cash_drawer_refund_total'] );
        $result[$key]['cash_drawer_total'] = 0;
    }
    $result[$key]['cash_drawer_total'] -= $row['cash_drawer_refund_total'];
}

Then delete keys using array_values():

$result = array_values($result);

This is $result now:

Array
(
    [0] => Array
        (
            [department_id] => 80000
            [cash_drawer] => 21112
            [cash_drawer_total] => 64
        )

    [1] => Array
        (
            [department_id] => 80000
            [cash_drawer] => 21117
            [cash_drawer_total] => 15
        )

    [2] => Array
        (
            [department_id] => 80000
            [cash_drawer] => No Cash Drawer
            [cash_drawer_total] => 50
        )

    [3] => Array
        (
            [department_id] => 50502
            [cash_drawer] => 21112
            [cash_drawer_total] => 90
        )

    [4] => Array
        (
            [department_id] => 50502
            [cash_drawer] => 21113
            [cash_drawer_total] => 30
        )

    [5] => Array
        (
            [department_id] => 50502
            [cash_drawer] => 21117
            [cash_drawer_total] => 10
        )

    [6] => Array
        (
            [department_id] => 50502
            [cash_drawer] => No Cash Drawer
            [cash_drawer_total] => 80
        )

    [7] => Array
        (
            [department_id] => No Department
            [cash_drawer] => 21112
            [cash_drawer_total] => 50
        )

    [8] => Array
        (
            [department_id] => No Department
            [cash_drawer] => No Cash Drawer
            [cash_drawer_total] => 99.63
        )

)
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for this. It's a solution I wouldn't have came to on my own and it is much more logical than what I was attempting.
0

I've made some changes to your code and I think I have what you're looking for...

$dat = array();
for ($i = 0; $i < (count($cashdrawer_sales)); $i++) {
    $obj = $cashdrawer_sales[$i];
    foreach ($cashdrawer_refund as $k=>$ref) {
        if ($obj['cash_drawer']==$ref['cash_drawer'] && $ref['department_id']==$obj['department_id']) {
            $cash_drawer_total = $obj['cash_drawer_sale_total'] - $ref['cash_drawer_refund_total'];
            $arr = array('department_id'=>$obj['department_id'], 'cash_drawer' => $obj['cash_drawer'], 'cash_drawer_total' => $cash_drawer_total);
            $dat[] = $arr;
        } else {
            if (!in_array($obj, $dat)) {  // <-- check the array for the item, if it's not there then add it
                $dat[] = $obj;
            }
        }
    }
}

foreach($dat as $test){
    print_r($test);
    echo "<br>";
}

Basically, before adding the current item back to the array, i check to see if it already exists.

Comments

0
$dat = array();
for ($i = 0; $i <= (count($cashdrawer_sales) - 1); $i++) {


    $obj = $cashdrawer_sales[$i];
    $match=false; // assume initially that this $obj does not match any $ref till now
    foreach ($cashdrawer_refund as $k=>$ref) {
    //check if this ref matches if yes then break//you are for all obj each time it mathches as well as not matches an obj
         if ($obj['cash_drawer']==$ref['cash_drawer'] && $ref['department_id']==$obj['department_id']) {
              $match=true;
              break;    
         } 
     }
     // this accounts for one obj only once in your output
     if($match){
         $cash_drawer_total = $obj['cash_drawer_sale_total'] - $ref['cash_drawer_refund_total'];
         $arr = array('department_id'=>$obj['department_id'], 'cash_drawer' => $obj['cash_drawer'], 'cash_drawer_total' => $cash_drawer_total);
         array_push($dat,$arr);
     }else{
         $cash_drawer_total = $obj['cash_drawer_sale_total'];
             //  echo $cash_drawer_total."<br>";
         $arr = array('department_id'=>$obj['department_id'], 'cash_drawer' => $obj['cash_drawer'], 'cash_drawer_total' => $cash_drawer_total);
         array_push($dat,$arr);
     }
}
print_r($dat);

1 Comment

I'd also add that this is not the fastest method to do this. You can sort array 1 and array 2 and then employ a better check to complete this in O(n logn) instead of O(n^2)
0

To solve issues like this, the best way is to solve it in your mind or in a paper then implement it.

As i understood, you want to modify sale total for those who have refunds. Then you need check all your sales:

foreach ($cashdrawer_sales as $sale_key => $sale) {
}

Then we want to check if cash drawer in this department has had a refund. We check all refund:

foreach ($cashdrawer_sales as $sale_key => $sale) {
    foreach ($cashdrawer_refund as $refund_key => $refund) {
        if ($sale['cash_drawer'] === $refund['cash_drawer'] && 
                $sale['department_id'] === $refund['department_id']) {
            // and if there was refund then we need to subtract it:
            $cashdrawer_sales[$sale_key]['new_total'] = $sale['cash_drawer_sale_total'] -
                    $refund['cash_drawer_refund_total'];
        }
    }
}

This should do the job. Not that to submit changes in the same array, I used key ($cashdrawer_sales[$sale_key]['new_total']).

Hope that helps.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.