Jump to content

Inventory Manager on Vacation


Go to solution Solved by Olumide,

Recommended Posts

I expected 4 items to arrive. Here are the SKU numbers:
1111
2222
2222
3333
When the box arrived and I opened it, I found these SKU numbers:
1111
2222
3333
3333
Upon opening the box, I immediately saw:
• SKU 2222 was missing
• there was an extra SKU 3333

My simple PHP script correctly shows the missing SKUs and the reconciled SKUs..... but why is it not showing the extra SKU?

<?php
$expected = array(
'1111',
'2222',
'2222',
'3333'
);

$received = array(
'1111',
'2222',
'3333',
'3333'
);

$expected = array_filter($expected);
$received = array_filter($received);

$expected_counts = array_count_values($expected);
$received_counts = array_count_values($received);

$not_received = array();
$reconciled = array();
$extra = array();

foreach ($expected_counts as $sku => $expected_count) {
    if (isset($received_counts[$sku])) {
        if ($received_counts[$sku] >= $expected_count) {
            $reconciled = array_merge($reconciled, array_fill(0, $expected_count, $sku));
        } else {
            $reconciled = array_merge($reconciled, array_fill(0, $received_counts[$sku], $sku));
            $not_received = array_merge($not_received, array_fill(0, $expected_count - $received_counts[$sku], $sku));
        }
    } else {
        $not_received = array_merge($not_received, array_fill(0, $expected_count, $sku));
    }
}

foreach ($received_counts as $sku => $received_count) {
    if (!isset($expected_counts[$sku])) {
        $extra = array_merge($extra, array_fill(0, $received_count, $sku));
    }
}

// Output the results
print_r($not_received); // SKUs that are missing
print_r($reconciled); // SKUs that reconcile
print_r($extra); // EXTRA (unexpected) SKUs
?>

 

Link to comment
https://forums.phpfreaks.com/topic/317518-inventory-manager-on-vacation/
Share on other sites

Try

$expected = array(
'1111',
'2222',
'2222',
'3333'
);

$received = array(
'1111',
'2222',
'3333',
'3333'
);

$cExp = array_count_values($expected);
$cRec = array_count_values($received);

foreach (array_keys($cExp+$cRec) as $prod)  {
    $e = $cExp[$prod] ?? 0;
    $r = $cRec[$prod] ?? 0;
    switch ($e <=>$r)  {
        case -1: $check = 'Over'; break;
        case 0: $check = 'OK'; break;
        case 1: $check = 'Under'; break;
    }
    echo $prod . " Ordered: $e  Received: $r  - $check <br>";
}

giving

1111 Ordered: 1 Received: 1 - OK 
2222 Ordered: 2 Received: 1 - Under 
3333 Ordered: 1 Received: 2 - Over 

 

  • Like 1
  • Great Answer 1
1 hour ago, ChenXiu said:

but why is it not showing the extra SKU?

Because you are only counting extras if they were not expected at all ($expected_counts[$sku] is not set).  Your extra 3333 item was an expected sku, you just got too many.

Your code can be much simpler by just calculating the counts of expected vs received for each sku rather than doing your array_fill stuff and checking index existence.

$all_skus = array_merge(array_keys($expected_counts), array_keys($received_counts));

$reconciled = [];
foreach ($all_skus as $sku){
    $reconciled[$sku] = ($expected_counts[$sku] ?? 0) - ($received_counts[$sku] ?? 0);
}
$reconciled = array_filter($reconciled);

First get a combined list of all possible SKUs, then loop over that list and for each SKU calculate # of expected (0 if unexpected) - # of received (0 if none received).

Finally, filter out all the entries that ended up as 0 (received and expected match).

You're left with an array of SKUs with either positive (missing) or negative (too many) items.

If you really need an array of SKU's, you can expand the reconciled array out as necessary.

  • Solution

There is a slight error in the second foreach loop where you check for extra SKUs. You are comparing the received count with the expected count, but you should be checking if the received count is greater than the expected count. Try replacing the second foreach statement with this:

foreach ($received_counts as $sku => $received_count) {
    if (!isset($expected_counts[$sku])) {
        $extra = array_merge($extra, array_fill(0, $received_count, $sku));
    } elseif ($received_count > $expected_counts[$sku]) {
        $extra = array_merge($extra, array_fill(0, $received_count - $expected_counts[$sku], $sku));
    }
}

 

 

  • Thanks 1
On 12/7/2023 at 11:59 AM, Olumide said:
foreach ($received_counts as $sku => $received_count) {
    if (!isset($expected_counts[$sku])) {
        $extra = array_merge($extra, array_fill(0, $received_count, $sku));
    } elseif ($received_count > $expected_counts[$sku]) {
        $extra = array_merge($extra, array_fill(0, $received_count - $expected_counts[$sku], $sku));
    }
}

I believe I mis-spoke. Olumide, your answer seems to work! Thank you for that!!
You have restored my faith in PHP 😀

Edited by ChenXiu
This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.