Jump to content

Need some help with this function


ajhanna88

Recommended Posts

Hi there

 

i have recently started working with php so I will probably be a familiar name around here. I have been giving a task that I have got a bit stuck with. To give a brief overview I have products that are stocked in x number of warehouses, when a customer places an order depending on their location I will ship from the warehouse that is closest to them if it has all products in stock. 

 

I have the following two arrays 

 

The first represents a customers order containing the id of the product and the quantity they have selected. e.g. product id:35659, qty:1

Array
(
    [35659] => 1
    [35699] => 1
    [35734] => 2
)

The second array shows the quantity in stock for each product in each 3 warehouses that stock it e.g. 35659 being the product id, [9][114][126] being the warehouse and 10,1,0 being the quantity of stock for that item in the warehouse.

Array
(
    [35659] => Array
        (
            [9] => 10
            [114] => 1
            [126] => 0
        )

    [35699] => Array
(
            [9] => 8
            [114] => 0
            [126] => 5
        )

    [35734] => Array
(
            [9] => 10
            [114] => 0
            [126] => 0
        )

)
function check_warehouse_stock($order=array(), $stock=array(), $warehouse=0) {
     foreach($order as $id => $qty)
       if($stock[$id][$warehouse] < $qty)
         return false;
     return true;
}

// $warehouses is an array of my warehouses already in their preference order
foreach($warehouses as $w) {
   if(check_warehouse_stock($order, $stock, $w))
      break;
   $w = false;
}

// $w is now the first warehouse with all the stock, or false if no warehouses have any stock

So far I have got the above code which loops through each warehouse and goes into a function that checks each item in their order and sees if any item in their basket is below the quantity in the warehouse, if no items is below the quantity it returns true and that is the first warehouse with all items in stock, if no warehouse has all items in stock it returns false. 

 

This is where I am getting stuck, if no warehouse has all items in stock I need to go into a similar function and have some sort of rule that checks  if no one warehouse has all products in stock I will ship from wherever has each product in stock starting with the closest and so on... e.g. if the first warehouse had 2 of the 3 items in stock and the second warehouse had 1 in stock we would ship 2 products from the first and 1 from the second. 

 

Any help would be greatly appreciated, even with just the logic on how to approach this. 

 

Thanks

Link to comment
Share on other sites

My brain is a bit fried but I think this will take care of both cases: closest warehouse with all the goods, or closest warehouses that can provide all the goods together.

 

Function takes the order and warehouse stock information.

1. Go through all the warehouses and figure out if any of them can provide all the items in the order. If so, return it

2. Otherwise begin looking at each warehouse individually:

- 1. Make a copy of that warehouse's stock information

- 2. Subtract from the stock whatever the warehouse can provide to suit the order. Update the order to count the items remaining

- 3. Call the function recursively using the modified order and stock information. If the function returns false then also return false

- 4. Restore the warehouse's original stock information before continuing

3. Return false since neither of the above algorithms could find a valid combination of warehouses

 

You'll want to deal with an array of warehouses, not just a single ID. And probably make it return not just the warehouses but the items each can fill, which you then use to update their inventories.

Edited by requinix
Link to comment
Share on other sites

My brain is a bit fried but I think this will take care of both cases: closest warehouse with all the goods, or closest warehouses that can provide all the goods together.

 

Function takes the order and warehouse stock information.

1. Go through all the warehouses and figure out if any of them can provide all the items in the order. If so, return it

2. Otherwise begin looking at each warehouse individually:

- 1. Make a copy of that warehouse's stock information

- 2. Subtract from the stock whatever the warehouse can provide to suit the order. Update the order to count the items remaining

- 3. Call the function recursively using the modified order and stock information. If the function returns false then also return false

- 4. Restore the warehouse's original stock information before continuing

3. Return false since neither of the above algorithms could find a valid combination of warehouses

 

You'll want to deal with an array of warehouses, not just a single ID. And probably make it return not just the warehouses but the items each can fill, which you then use to update their inventories.

 

Thanks for the reply, that makes sense dealing with an array of warehouses. Would you be able to give some advice on how i would achieve the steps that I have bolded above in php? thanks

Link to comment
Share on other sites

Forget what I said: it's overly complex and won't give you quite the results you want. And needs some editing.

 

However I do suggest you rearrange your warehouse/stock array into not an array of products and the warehouse quantities, but of warehouses and the products they contain. That should make it easier to get a list of warehouses that provide the quantity to fill an order.

array(
	9 => array(
		35659 => 10,
		35699 => 8,
		35734 => 10
	),
	114 => array(
		35659 => 1,
		35699 => 0,
		35734 => 0
	),
	126 => array(
		35659 => 0,
		35699 => 5,
		35734 => 0
	)
)
Now, the missing part: multiple warehouses.

Go through each warehouse in turn and figure out what it can contribute towards the order. For example, with

$order = array(
	35659 => 10,
	35699 => 10
);
The first warehouse #9 can do all of #35659 but only eight of #35699. That leaves you with effectively

$order = array(
	35659 => 0,
	35699 => 2
);
Then look at the second warehouse. It can't help. However the third has more than enough of #35699 and so you get (perhaps) a result of

$filled = array(
	9 => array(
		35659 => 10,
		35699 => 8
	),
	126 => array(
		35699 => 2
	)
);
Link to comment
Share on other sites

Ok so I have managed to loop through and check each warehouse individually for where products meet the quanitity required. I am now left with the following two arrays:

 

The first being their order:

Array
(
    [35659] => 1
    [35699] => 1
    [35734] => 2
)

And the second being each warehouse that has the quantity of the product available

Array
(
    [9] => Array
        (
            [35659] => 1
            [35699] => 1
            [35734] => 2
        )

    [114] => Array
        (
            [35659] => 1
        )

    [126] => Array
        (
            [35699] => 1
        )

)

What I now need to do is to compare the first array (product id) to the second array (product id) for each warehouse indivual warehouse to see the differences. I have been playing about with array_diff but haven't been able to get it yet.

 

Thanks

Link to comment
Share on other sites

Don't try for some kind of one-line solution. At least not until you have a normal solution working first.

Go with the most obvious option: a foreach loop of the (remaining) products in the order, which would itself be inside a foreach of the warehouses.

Link to comment
Share on other sites

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.