Name: Demac_MultiLocationInventory
Owner: AOE
Description: null
Created: 2015-02-25 15:35:33.0
Updated: 2016-07-20 04:34:39.0
Pushed: 2017-09-06 22:50:45.0
Homepage: null
Size: 205
Language: PHP
GitHub Committers
User | Most Recent Commit | # Commits |
---|
Other Committers
User | Most Recent Commit | # Commits |
---|
Allows the creation of multiple inventory locations in Magento along with assigning those inventory locations to store views.
Multi Location Inventory is likely a good fit if any of the following statements accurately describe the needs of the inventory and shipping management solution.
Multi Location Inventory does not support the following situations out of the box, but it is likely a good starting point if you ship from multiple locations, have no restrictions on where each warehouse ships to, and have a reason to store inventory data separately in Magento (e.g. shipping quotes depend on inventory location)
Verify that you aren't running any other extensions that may conflict with Multi Location Inventory.
Some common extensions that conflict include:
Please contribute other extensions you find that are not compatible either by sending a pull request updating this README or opening a GitHub issue.
Below is a list of several major components of this extension that should help you to get started with it.
It is recommended to disable this functionality and allow integrations to push inventory updates. The easiest way to disable this functionality is to set the following config setting: Configuration > Catalog > Inventory > Stock Options > Decrease stock when order is placed
If stock updates need to happen on the Magento side the recommended approach is to update the getPriorityForOrderLocationQuoteItem method in app/code/community/Demac/MultiLocationInventory/Helper/Location.php. This method is run once per location on every quote item. Inventory is reduced from the location which returns the highest number first and works its way down until all of the inventory requested is fulfilled. If there is only one warehouse per store view this function can be left as is.
Indexers take data from the demac_multilocationinventory_stock table that is attached to stores and summarizes it per store view in the demac_multilocationinventory_stock_status_index table. This allows for the data to be added to product collections with a single join.
Various parts of the Magento core expect stock item objects.
To work around this we create a stock item and populate it with store view specific data.
For example…
ckItem = Mage::getModel(?cataloginventory/stock_item?)
ckItem->setIsInStock(1)
ckItem->setBackorders(1)
ckItem->setQty(100)
By taking this approach we can leave the underlying tables untouched allowing multi location inventory to easily be disabled and minimize rewrites to stockItem.
Example: app/code/community/Demac/MultiLocationInventory/Model/CatalogInventory/Stock.php
The getPriorityForOrderLocationQuoteItem method in app/code/community/Demac/MultiLocationInventory/Helper/Location.php is called once per location, per product in an order (during checkout, as the inventory is being assigned).
Currently we return a random number from this method. This is suitable when there is only 1 warehouse per storeview, or when inventory isn?t being reduced at the time of checkout and is instead being handled by integrations (highly recommended).
In other cases we can take one of these approaches: Create a scoring algorithm that looks at products individually inside of a quote as this is called. Create a singleton with the algorithm that looks at the data and ranks it in a single call, and have it called to return the appropriate results from getPriorityForOrderLocationQuoteItem.
We have built our own iterator - Demac_MultiLocationInventory_Model_Resource_Iterator
This implements the exact same walk functionality as the built in iterator but allows you to break the iterator loop by returning false from the callback function. This was necessary as sometimes we return more stores than necessary to avoid having to do additional lookups when removing quantity.
Example: app/code/community/Demac/MultiLocationInventory/Model/CatalogInventory/Observer.php Line 309
heck if all fields are optional
TE temporary TABLE IF NOT EXISTS
c_multilocationinventory_bundled_indexer_tmp AS
ELECT catalog_product_entity.entity_id,
Sum(catalog_product_bundle_option.required) AS required_count
ROM catalog_product_entity
JOIN catalog_product_bundle_option
ON catalog_product_bundle_option.parent_id =
catalog_product_entity.entity_id
HERE type_id = 'bundle'
ROUP BY catalog_product_entity.entity_id);
LL OPTIONAL: get all child products, if sum of is_in_stock > 0 then set is_in_stock = 1 and qty = some really big number
LOBAL:
TE demac_multilocationinventory_stock_status_index dest,
(SELECT catalog_product_bundle_selection.parent_product_id AS product_id,
IF(Sum(is_in_stock) > 0, 99999, 0) AS qty,
IF(Sum(is_in_stock) > 0, 1, 0) AS is_in_stock
FROM catalog_product_bundle_selection
JOIN demac_multilocationinventory_bundled_indexer_tmp
ON demac_multilocationinventory_bundled_indexer_tmp.entity_id =
catalog_product_bundle_selection.parent_product_id
JOIN demac_multilocationinventory_stock
ON demac_multilocationinventory_stock.product_id =
catalog_product_bundle_selection.product_id
WHERE required_count = 0
GROUP BY catalog_product_bundle_selection.parent_product_id) src
dest.qty = src.qty,
dest.is_in_stock = src.is_in_stock,
dest.backorders = 0,
dest.manage_stock = 1
E dest.store_id = 0
AND dest.product_id = src.product_id;
TORE SPECIFIC:
TE demac_multilocationinventory_stock_status_index dest,
(SELECT demac_multilocationinventory_stores.store_id
AS
store_id,
catalog_product_bundle_selection.parent_product_id
AS
product_id,
IF(Sum(demac_multilocationinventory_stock.is_in_stock) > 0, 99999
, 0) AS
qty,
IF(Sum(demac_multilocationinventory_stock.is_in_stock) > 0, 1, 0)
AS
is_in_stock
FROM catalog_product_bundle_selection
JOIN demac_multilocationinventory_bundled_indexer_tmp
ON demac_multilocationinventory_bundled_indexer_tmp.entity_id =
catalog_product_bundle_selection.parent_product_id
JOIN demac_multilocationinventory_stock
ON demac_multilocationinventory_stock.product_id =
catalog_product_bundle_selection.product_id
JOIN demac_multilocationinventory_stores
ON demac_multilocationinventory_stock.location_id =
demac_multilocationinventory_stores.location_id
WHERE required_count = 0
GROUP BY Concat(catalog_product_bundle_selection.parent_product_id, '_'
,
demac_multilocationinventory_stores.store_id)) src
dest.qty = src.qty,
dest.is_in_stock = src.is_in_stock,
dest.backorders = 0,
dest.manage_stock = 1
E dest.store_id = src.store_id
AND dest.product_id = src.product_id;
OME REQUIRED: Verify that each required option has at least one child item in stock (sum is_in_stock grouped by option, if all are greater than 1)
LOBAL:
TE demac_multilocationinventory_stock_status_index dest,
(SELECT src.product_id
AS
product_id,
IF(Concat(',', Group_concat(src.is_in_stock), ',') LIKE ',0,', 0,
1)
AS
is_in_stock,
IF(Concat(',', Group_concat(src.is_in_stock), ',') LIKE ',0,', 0,
99999)
AS qty
FROM (SELECT catalog_product_bundle_selection.option_id
AS
option_id,
catalog_product_bundle_selection.parent_product_id
AS
product_id,
IF(Sum(demac_multilocationinventory_stock.is_in_stock) >
0, 1, 0
) AS
is_in_stock
FROM catalog_product_bundle_selection
JOIN demac_multilocationinventory_bundled_indexer_tmp
ON
c_multilocationinventory_bundled_indexer_tmp.entity_id
log_product_bundle_selection.parent_product_id
JOIN catalog_product_bundle_option
ON catalog_product_bundle_option.option_id =
catalog_product_bundle_selection.option_id
JOIN demac_multilocationinventory_stock
ON demac_multilocationinventory_stock.product_id =
catalog_product_bundle_selection.product_id
WHERE required_count > 0
AND catalog_product_bundle_option.required = 1
GROUP BY Concat(
catalog_product_bundle_selection.parent_product_id,
'_',
catalog_product_bundle_selection.option_id)
) src
GROUP BY Concat(src.product_id)) src2
dest.qty = src2.qty,
dest.is_in_stock = src2.is_in_stock,
dest.backorders = 0,
dest.manage_stock = 1
E dest.store_id = 0
AND dest.product_id = src2.product_id;
TORE SPECIFIC:
TE demac_multilocationinventory_stock_status_index dest,
(SELECT src.store_id,
src.product_id,
IF(Concat(',', Group_concat(src.is_in_stock), ',') LIKE ',0,', 0,
1)
AS
is_in_stock,
IF(Concat(',', Group_concat(src.is_in_stock), ',') LIKE ',0,', 0,
99999)
AS qty
FROM (SELECT demac_multilocationinventory_stores.store_id
AS
store_id,
catalog_product_bundle_selection.option_id
AS
option_id,
catalog_product_bundle_selection.parent_product_id
AS
product_id,
IF(Sum(demac_multilocationinventory_stock.is_in_stock) >
0, 1, 0
) AS
is_in_stock
FROM catalog_product_bundle_selection
JOIN demac_multilocationinventory_bundled_indexer_tmp
ON
c_multilocationinventory_bundled_indexer_tmp.entity_id
log_product_bundle_selection.parent_product_id
JOIN catalog_product_bundle_option
ON catalog_product_bundle_option.option_id =
catalog_product_bundle_selection.option_id
JOIN demac_multilocationinventory_stock
ON demac_multilocationinventory_stock.product_id =
catalog_product_bundle_selection.product_id
JOIN demac_multilocationinventory_stores
ON demac_multilocationinventory_stock.location_id =
demac_multilocationinventory_stores.location_id
WHERE required_count > 0
AND catalog_product_bundle_option.required = 1
GROUP BY Concat(
catalog_product_bundle_selection.parent_product_id,
'_',
c_multilocationinventory_stores.store_id, '_',
log_product_bundle_selection.option_id)) src
P BY Concat(src.product_id, '_', src.store_id)) src2
dest.qty = src2.qty,
dest.is_in_stock = src2.is_in_stock,
dest.backorders = 0,
dest.manage_stock = 1
E dest.store_id = src2.store_id
AND dest.product_id = src2.product_id;
LEANUP:
TABLE IF EXISTS demac_multilocationinventory_bundled_indexer_tmp;