[
https://issues.apache.org/jira/browse/OFBIZ-6964?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Shrenik Bhura updated OFBIZ-6964:
---------------------------------
Description:
At the onset let me define a few terms clearly as I mean it in the story
description below :
Requirement - A request generated for a particular product for a specific
quantity that needs to be purchased for a supplier for satisfying certain
inventory needs of a particular facility.
Replenishment - A request generated for a particular product for a specific
quantity that needs to be transferred from a "backup facility" for satisfying
certain inventory needs of a particular facility.
Fulfilment - The process of reserving, picking, packing and shipping the
ordered quantity of product(s) as per a sales order.
Terms 'warehouse' and 'facility' have been used interchangeably.
The Use Case:
Consider a scenario wherein there is a website and a physical retail store of
the same Company.
Each having its own facility i.e. 1:1 mapping.
*Store A (webstore) -> associated with facility 1 (webstore facility)*
*Store B (retailstore) -> associated with facility 2 (retailstore facility)*
However, both the stores share the same catalog/products. But both have
different inventory requirement and replenishment rules for the same product
primarily for driving inventory efficiencies across the organisation.
There is a Requirement Method Enum ID (RMEI) of each product which is
applicable irrespective of the store and supersedes the RMEI defined, if any,
on a store??.
A product's inventory thresholds (Minimum Stock, Reorder Quantity) are
independently managed via the facilities tab for the product. A product has its
ATP and QOH levels on a per facility basis. **Do note that all these inventory
levels are at a facility level and has no bearing at a store level.**
Where the difficulty crops up with the current implementation is the way
requirements are generated. A product can have only one RMEI. When an order is
placed from any store, then based on the combination of a product's RMEI and
the store mapped facility's inventory threshold, requirements are generated.
This is without consideration of the inventory status (surplus or otherwise) at
another facility of the same Company. I assume (not validated) that if a store
has multiple facilities associated with it then the one defined in the
ProductStore entity -> inventoryFacilityId field would be considered for
picking the inventory threshold values.
Assumptions based on most probable real-world scenarios:
1. Usually an organisation would have a main facility/warehouse where
all the purchases are received and sub-facilities which are replenished from
the main facility after QA, internal processes, etc. OR
2. For each product there would be a primary facility where the product
is received from the supplier (to derive benefits of demographic convenience
and consumption patterns) and then replenished to other facilities on a demand
based pull basis.
However, to drive efficiencies across an organisation there should be a method
to consider open requirements across multiple facilities and propose inventory
transfers across them to facilitate better stocking and thus fulfilment.
Coming back to our use case, the webstore warehouse is the main facility at
which incoming shipments from suppliers are received for the entire Company but
sales order fulfilment happens only for the webstore. The retail warehouse is
primarily 're-stocked' via replenishment requests a.k.a. indents raised to the
webstore warehouse and thus need not issue direct purchase orders to suppliers.
However, if the need be, requirement generated based on the product's RMEI and
the retail facility's inventory thresholds can also be approved, converted into
Purchase order and issued.
Proposed Solution :
There doesn't seem to be an out of the box solution for this in OFBiz. This
could work if either we build in support for a solution that I have encountered
in Opentaps (a system built atop OFBiz) -
Introduce a ProductFacility specific *Replenishment Method Enum ID (RPMEI)*
with values such as -
**Code snippets are from Opentaps**
{code:xml}
<!-- Enumeration for ProductFacility replenishMethodEnumId -->
<EnumerationType enumTypeId="PFAC_REPL_METHOD" hasTable="N"
description="Product Facility Replenish Methods"/>
<Enumeration enumId="PF_RM_NEVER" description="Never transfer"
enumTypeId="PFAC_REPL_METHOD"/>
<Enumeration enumId="PF_RM_BACKUP" description="Transfer from backup
warehouse if available" enumTypeId="PFAC_REPL_METHOD"/>
<Enumeration enumId="PF_RM_SPECIF" description="Transfer from specified
warehouse if available" enumTypeId="PFAC_REPL_METHOD"/>
<Enumeration enumId="PF_RM_BACKUP_ALW" description="Always transfer from
backup warehouse" enumTypeId="PFAC_REPL_METHOD"/>
<Enumeration enumId="PF_RM_SPECIF_ALW" description="Always transfer from
specified warehouse" enumTypeId="PFAC_REPL_METHOD"/>
{code}
and extend the entity ProductFacility -
{code:xml}
<extend-entity entity-name="ProductFacility">
<field name="replenishMethodEnumId" type="id"/>
<field name="replenishFromFacilityId" type="id-ne"/>
<relation type="one" rel-entity-name="Facility" fk-name="PF_R_FAC"
title="ResplenishFromFacility">
<key-map field-name="facilityId"/>
</relation>
<relation title="ResplenishMethod" fk-name="PF_R_METH"
rel-entity-name="Enumeration" type="one">
<key-map field-name="replenishMethodEnumId" rel-field-name="enumId"/>
</relation>
</extend-entity>
{code}
Create new entities -
{code:xml}
<entity entity-name="FacilityAssoc" package-name="org.opentaps.common.facility"
title="Define associations between facilities">
<field name="facilityId" type="id-ne"/>
<field name="facilityIdTo" type="id-ne"/>
<field name="facilityAssocTypeId" type="id-ne"/>
<field name="fromDate" type="date-time"/>
<field name="thruDate" type="date-time"/>
<field name="sequenceNum" type="numeric"/>
<prim-key field="facilityId"/>
<prim-key field="facilityIdTo"/>
<prim-key field="facilityAssocTypeId"/>
<prim-key field="fromDate"/>
<relation type="one" fk-name="FACASSOC_FAC" title="From"
rel-entity-name="Facility">
<key-map field-name="facilityId"/>
</relation>
<relation type="one" fk-name="FACASSOC_FACTO" title="To"
rel-entity-name="Facility">
<key-map field-name="facilityIdTo" rel-field-name="facilityId"/>
</relation>
<relation type="one" fk-name="FACASSOC_TYPE"
rel-entity-name="FacilityAssocType">
<key-map field-name="facilityAssocTypeId"/>
</relation>
</entity>
<entity entity-name="FacilityAssocType"
package-name="org.opentaps.common.facility"
title="Define associations between facilities">
<field name="facilityAssocTypeId" type="id-ne"/>
<field name="description" type="description"/>
<prim-key field="facilityAssocTypeId"/>
</entity>
<FacilityAssocType facilityAssocTypeId="BACKUP_INVENTORY" description="Holds
backup inventory"/>
{code}
Hence now we can define a replenishment method at a product level and that too
on a per facility basis.
Additional now we can provision for defining of backup facility for any
facility. (May consider using the parentFacilityId available on the Facility
entity but am not sure about its purpose and there is no way to define the
relation between the parent and child.)
We have to safeguard these:
1. There should be no direct or indirect cyclic backup facility
relation between any 2 facilities due to backup facility relation definition.
2. There should be no direct or indirect cyclic replenishment facility
relation created due to defining of replenishFromFacilityId in a
ProductFacility entry for a product.
Now when an order is placed on the retail store and ATP falls below Minimum
Stock at the primary facility mapped to the retail store, then depending on the
product's or store's RMEI setting combined with the facility's inventory
thresholds a purchase requirement may be generated. However, we are not
interested in this and may even block the generation of such a purchase
requirement for product's which have a RPMEI defined for a particular facility.
Instead on a subsequent MRP run for the retailstore facility, based on the open
sales orders, we should generate/propose 'Inventory transfer requirement' from
the backup facility or the replenishFromFacilityId based on the definition in
the ProductFacility entity.
This solution should hold good even in the case of many:many mapping between
stores and facilities as existing implementation is to reserve inventory
against the facility that is mapped to the store via inventoryFacilityId. Hence
there is no chance of the same sales order resulting in redundant requirements
on multiple facilities.
And since the RPMEI (Replenishment Method Enum Id) is defined at the
ProductFacility level there is no possibility of a general definition at a
facility or store level to contend with.
This seems to be a rather important feature without which many businesses
operating brick and mortar stores as well as an ecommerce web-front can't
favourable use OFBiz.
was:
Consider a use case wherein there is a website and a physical retail store.
Each having its own store and facility (for example, retail facility and
webstore facility). Both the stores share the same catalog/products.
*Store A (webstore) -> associated with facility 1 (webstore facility)*
*Store B (retailstore) -> associated with facility 2 (retailstore facility)*
However, both have different inventory management rules for the same product.
Store A has a Requirement Method Enum ID (RMEI) of its own for the product and
Store B also needs a mechanism to fulfil its own requirement.
The inventory quantities can continue to be independently managed via the
facilities tab for a product.
Where the difficulty crops up is the management of Requirements. A product can
have only one RMEI.
The webstore warehouse is the main facility at which replenishment from
suppliers and order fulfilment and shipping happens. The retail warehouse is
just 'stocked' via indents/replenishment requests from the webstore warehouse
and does not issue direct purchase orders to suppliers.
The desired behaviour is that whenever item quantity is below ATP for the
retail facility, then a request to re-stock is sent to the webstore facility.
In turn if the webstore facility has ample quantity in stock(ATP) then it
should approve and initiate a transfer else it should generate a requirement
based on its RMEI setting.
There doesn't seem to be an out of the box solution for this in OFBiz. This
could work if either we build in support for store specific RMEI or there is
another solution that I have encountered in Opentaps (a system built atop
OFBiz) - Introduce a facility specific *Replenishment Method Enum ID (RPMEI)*
with values such as -
{code:xml}
<!-- Enumeration for ProductFacility replenishMethodEnumId -->
<EnumerationType enumTypeId="PFAC_RESPL_METHOD" hasTable="N"
description="Product Facility Resplenish Methods"/>
<Enumeration enumId="PF_RM_NEVER" description="Never transfer"
enumTypeId="PFAC_RESPL_METHOD"/>
<Enumeration enumId="PF_RM_BACKUP" description="Transfer from backup
warehouse if available" enumTypeId="PFAC_RESPL_METHOD"/>
<Enumeration enumId="PF_RM_SPECIF" description="Transfer from specified
warehouse if available" enumTypeId="PFAC_RESPL_METHOD"/>
<Enumeration enumId="PF_RM_BACKUP_ALW" description="Always transfer from
backup warehouse" enumTypeId="PFAC_RESPL_METHOD"/>
<Enumeration enumId="PF_RM_SPECIF_ALW" description="Always transfer from
specified warehouse" enumTypeId="PFAC_RESPL_METHOD"/>
{code}
Once a product is configured with a facility specific RPMEI, an MRP run should
create the appropriate Inventory Transfer request and then the flow can
continue from there.
This seems to be a rather important feature without which many businesses
operating brick and mortar stores as well as an ecommerce web-front can't
easily use OFBiz.
> Support for replenishment of a secondary warehouse from a main warehouse
> ------------------------------------------------------------------------
>
> Key: OFBIZ-6964
> URL: https://issues.apache.org/jira/browse/OFBIZ-6964
> Project: OFBiz
> Issue Type: New Feature
> Components: manufacturing, product
> Reporter: Shrenik Bhura
> Labels: features
> Fix For: Upcoming Branch
>
>
> At the onset let me define a few terms clearly as I mean it in the story
> description below :
> Requirement - A request generated for a particular product for a specific
> quantity that needs to be purchased for a supplier for satisfying certain
> inventory needs of a particular facility.
> Replenishment - A request generated for a particular product for a specific
> quantity that needs to be transferred from a "backup facility" for satisfying
> certain inventory needs of a particular facility.
> Fulfilment - The process of reserving, picking, packing and shipping the
> ordered quantity of product(s) as per a sales order.
> Terms 'warehouse' and 'facility' have been used interchangeably.
> The Use Case:
> Consider a scenario wherein there is a website and a physical retail store of
> the same Company.
> Each having its own facility i.e. 1:1 mapping.
> *Store A (webstore) -> associated with facility 1 (webstore facility)*
> *Store B (retailstore) -> associated with facility 2 (retailstore facility)*
> However, both the stores share the same catalog/products. But both have
> different inventory requirement and replenishment rules for the same product
> primarily for driving inventory efficiencies across the organisation.
> There is a Requirement Method Enum ID (RMEI) of each product which is
> applicable irrespective of the store and supersedes the RMEI defined, if any,
> on a store??.
> A product's inventory thresholds (Minimum Stock, Reorder Quantity) are
> independently managed via the facilities tab for the product. A product has
> its ATP and QOH levels on a per facility basis. **Do note that all these
> inventory levels are at a facility level and has no bearing at a store
> level.**
> Where the difficulty crops up with the current implementation is the way
> requirements are generated. A product can have only one RMEI. When an order
> is placed from any store, then based on the combination of a product's RMEI
> and the store mapped facility's inventory threshold, requirements are
> generated. This is without consideration of the inventory status (surplus or
> otherwise) at another facility of the same Company. I assume (not validated)
> that if a store has multiple facilities associated with it then the one
> defined in the ProductStore entity -> inventoryFacilityId field would be
> considered for picking the inventory threshold values.
> Assumptions based on most probable real-world scenarios:
> 1. Usually an organisation would have a main facility/warehouse where
> all the purchases are received and sub-facilities which are replenished from
> the main facility after QA, internal processes, etc. OR
> 2. For each product there would be a primary facility where the product
> is received from the supplier (to derive benefits of demographic convenience
> and consumption patterns) and then replenished to other facilities on a
> demand based pull basis.
> However, to drive efficiencies across an organisation there should be a
> method to consider open requirements across multiple facilities and propose
> inventory transfers across them to facilitate better stocking and thus
> fulfilment.
> Coming back to our use case, the webstore warehouse is the main facility at
> which incoming shipments from suppliers are received for the entire Company
> but sales order fulfilment happens only for the webstore. The retail
> warehouse is primarily 're-stocked' via replenishment requests a.k.a.
> indents raised to the webstore warehouse and thus need not issue direct
> purchase orders to suppliers. However, if the need be, requirement generated
> based on the product's RMEI and the retail facility's inventory thresholds
> can also be approved, converted into Purchase order and issued.
> Proposed Solution :
> There doesn't seem to be an out of the box solution for this in OFBiz. This
> could work if either we build in support for a solution that I have
> encountered in Opentaps (a system built atop OFBiz) -
> Introduce a ProductFacility specific *Replenishment Method Enum ID (RPMEI)*
> with values such as -
> **Code snippets are from Opentaps**
> {code:xml}
> <!-- Enumeration for ProductFacility replenishMethodEnumId -->
> <EnumerationType enumTypeId="PFAC_REPL_METHOD" hasTable="N"
> description="Product Facility Replenish Methods"/>
> <Enumeration enumId="PF_RM_NEVER" description="Never transfer"
> enumTypeId="PFAC_REPL_METHOD"/>
> <Enumeration enumId="PF_RM_BACKUP" description="Transfer from backup
> warehouse if available" enumTypeId="PFAC_REPL_METHOD"/>
> <Enumeration enumId="PF_RM_SPECIF" description="Transfer from specified
> warehouse if available" enumTypeId="PFAC_REPL_METHOD"/>
> <Enumeration enumId="PF_RM_BACKUP_ALW" description="Always transfer from
> backup warehouse" enumTypeId="PFAC_REPL_METHOD"/>
> <Enumeration enumId="PF_RM_SPECIF_ALW" description="Always transfer from
> specified warehouse" enumTypeId="PFAC_REPL_METHOD"/>
> {code}
> and extend the entity ProductFacility -
> {code:xml}
> <extend-entity entity-name="ProductFacility">
> <field name="replenishMethodEnumId" type="id"/>
> <field name="replenishFromFacilityId" type="id-ne"/>
> <relation type="one" rel-entity-name="Facility" fk-name="PF_R_FAC"
> title="ResplenishFromFacility">
> <key-map field-name="facilityId"/>
> </relation>
> <relation title="ResplenishMethod" fk-name="PF_R_METH"
> rel-entity-name="Enumeration" type="one">
> <key-map field-name="replenishMethodEnumId" rel-field-name="enumId"/>
> </relation>
> </extend-entity>
> {code}
> Create new entities -
> {code:xml}
> <entity entity-name="FacilityAssoc"
> package-name="org.opentaps.common.facility"
> title="Define associations between facilities">
> <field name="facilityId" type="id-ne"/>
> <field name="facilityIdTo" type="id-ne"/>
> <field name="facilityAssocTypeId" type="id-ne"/>
> <field name="fromDate" type="date-time"/>
> <field name="thruDate" type="date-time"/>
> <field name="sequenceNum" type="numeric"/>
> <prim-key field="facilityId"/>
> <prim-key field="facilityIdTo"/>
> <prim-key field="facilityAssocTypeId"/>
> <prim-key field="fromDate"/>
> <relation type="one" fk-name="FACASSOC_FAC" title="From"
> rel-entity-name="Facility">
> <key-map field-name="facilityId"/>
> </relation>
> <relation type="one" fk-name="FACASSOC_FACTO" title="To"
> rel-entity-name="Facility">
> <key-map field-name="facilityIdTo" rel-field-name="facilityId"/>
> </relation>
> <relation type="one" fk-name="FACASSOC_TYPE"
> rel-entity-name="FacilityAssocType">
> <key-map field-name="facilityAssocTypeId"/>
> </relation>
> </entity>
> <entity entity-name="FacilityAssocType"
> package-name="org.opentaps.common.facility"
> title="Define associations between facilities">
> <field name="facilityAssocTypeId" type="id-ne"/>
> <field name="description" type="description"/>
> <prim-key field="facilityAssocTypeId"/>
> </entity>
> <FacilityAssocType facilityAssocTypeId="BACKUP_INVENTORY" description="Holds
> backup inventory"/>
> {code}
> Hence now we can define a replenishment method at a product level and that
> too on a per facility basis.
> Additional now we can provision for defining of backup facility for any
> facility. (May consider using the parentFacilityId available on the Facility
> entity but am not sure about its purpose and there is no way to define the
> relation between the parent and child.)
> We have to safeguard these:
> 1. There should be no direct or indirect cyclic backup facility
> relation between any 2 facilities due to backup facility relation definition.
> 2. There should be no direct or indirect cyclic replenishment facility
> relation created due to defining of replenishFromFacilityId in a
> ProductFacility entry for a product.
> Now when an order is placed on the retail store and ATP falls below Minimum
> Stock at the primary facility mapped to the retail store, then depending on
> the product's or store's RMEI setting combined with the facility's inventory
> thresholds a purchase requirement may be generated. However, we are not
> interested in this and may even block the generation of such a purchase
> requirement for product's which have a RPMEI defined for a particular
> facility.
> Instead on a subsequent MRP run for the retailstore facility, based on the
> open sales orders, we should generate/propose 'Inventory transfer
> requirement' from the backup facility or the replenishFromFacilityId based on
> the definition in the ProductFacility entity.
> This solution should hold good even in the case of many:many mapping between
> stores and facilities as existing implementation is to reserve inventory
> against the facility that is mapped to the store via inventoryFacilityId.
> Hence there is no chance of the same sales order resulting in redundant
> requirements on multiple facilities.
> And since the RPMEI (Replenishment Method Enum Id) is defined at the
> ProductFacility level there is no possibility of a general definition at a
> facility or store level to contend with.
> This seems to be a rather important feature without which many businesses
> operating brick and mortar stores as well as an ecommerce web-front can't
> favourable use OFBiz.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)