Produce quality inspection - IBM/intelligence-suite-supply-chain-solutions GitHub Wiki
As a supply quality manager for a grocery retailer, I need a dashboard which helps me measure produce quality inbound to my distribution centers (DCs), so I can provide feedback to my suppliers and take action to get cost recovery, plus drive continuous improvement of inbound produce.
This tutorial will show you how to develop a dashboard and work queues which can be used to measure and act on produce quality inspection documents. These documents can be powered by the Transparent Supply SCIS add-on, or any other source may be used. For demonstration purposes, we will be using sample data which is representative of the Transparent Supply inspection form, but we will not be actually connecting the data in this tutorial (to create a live connection for demo or POC purposes, please contact the product team).
We will be implementing attributes for product firmness, ripeness, sweetness, and weight, then monitoring the incoming inspections performed at the DC for any sample lots which are measured to be above or below control limits which are set by product. For example, grapefruits must weigh between 200-300 grams, and any measurements above or below that range will trigger an "out of bounds" condition and be reported on the dashboard.
To demonstrate how a user could interact with these exceptions, we will create the following structure:
- Quality Summary dashboard with donut charts showing in-bounds, high, and low counts for inspections for the four metrics
- Failure rate by supplier visuals to show which suppliers have the best and worst exception rates aggregated by product category
- All inspections dashboard which will allow a user to search and interact with the raw inspection data
- Work queues for all eight exceptions around high and low ripeness, firmness, sweetness, and weight
Here are some sample screenshots of the expected output:
This use case assumes you are familiar with implementing solutions in SCIS. You can find relevant tutorials for all of the instructions here in the User interface, Data platform, and Data import-export wikis.
Note - these tutorials are provided as-is for educational purposes only. We do our best to make them fully useable, however there will be gaps as published. If you have suggestions for improvements please submit an issue.
Data model
In this use case we are going to use the control tower InventoryLot
business object to capture inspection records. As with all SCIS business objects, InventoryLot
uses a flexible "type" structure which allows one object to be used for several different purposes at once. To differentiate inspection lots from other types of lots which may be present in an instance, we will use the attribute inventoryParentType = "INSPECTION_LOT"
and reference this as a filter in all queries. Note - Supplier
is represented as a custom attribute on InventoryLot
in this example, but it will be included as a first-class foreign key on this entity in a future release.
Attributes
We will register five extension attributes on InventoryLot
to capture the inspection measurements: firmnessFloat
, sweetnessFloat
, ripenessFloat
, weightFloat
, and weightUnitsString
. Each lot will be compared to standard Product
control limits recorded as extension attributes: firmnessUpperLimit
, firmnessLowerLimit
, sweetnessUpperLimit
, sweetnessLowerLimit
, ripenessUpperLimit
, ripenessLowerLimit
, weightUpperLimit
, weightLowerLimit
, and weightLimitUnits
Calculations
While we could directly query and compare the measurements to the limits for the dashboard and query, a better practice will be to register derived data fields to pre-compute the offset (gap to the limits) and a status of each lot, which will simplify queries, perform faster, and allow additional features like column sort. For that purpose we will register 8 derived fields such as InventoryLot.firmnessAboveUpperLimitFloat
and 4 status fields such as InventoryLot.firmnessStatusString
. See the json files to see the complete list.
All json registration content is available in this zip file
Please note - you will need to change the tenantId in all json files to your tenant ID
- Load sample data
- Define custom attributes
- Register rules
- Register work queues
- Create widgets
- Create pages
- Create dashboards
- Register overrides
- Test on https://www.supply-chain.ibm.com/
- Register data import rules to pick up files from object storage (if your tenant does not already have CSV and JSON import rules registered)
- Load sample data to your COS bucket - note, there are both CSV and JSON files for import
POST https://api.ibm.com/infohub/run/metadata/api/v1/na/schema/custom-attributes
Custom attributes as outlined above -- note that each custom attribute is registered in a separate API call
- All custom attributes: produce_quality_custom_attributes.json
POST https://api.ibm.com/infohub/run/metadata/api/v1/na/derived/rules
Calculated status and above upper / below lower attributes on InventoryLot
- Firmness: dd_inventoryLot_firmnessStatus.json
- Ripeness: dd_inventoryLot_ripenessStatus.json
- Sweeness: dd_inventoryLot_sweetnessStatus.json
- Weight: dd_inventoryLot_weightStatus.json
POST https://api.ibm.com/infohub/run/metadata/api/v1/na/workqueues
Work queue for above-upper and below-lower for each of our four measurements
- Firmness above upper: wq-productFirmnessAboveUpperLimit.json
- Firmness below lower: wq-productFirmnessBelowLowerrLimit.json
- Ripeness above upper: wq-productRipenessAboveUpperLimit.json
- Ripeness below lower: wq-productRipenessBelowLowerrLimit.json
- Sweetness above upper: wq-productSweetenessBelowLowerrLimit.json
- Sweetness below lower: wq-productSweetnessAboveUpperLimit.json
- Weight above upper: wq-productWeightAboveUpperLimit.json
- Weight below lower: wq-productWeightBelowLowerrLimit.json
POST https://api.ibm.com/supplychainui/run/na/api/v1/wms/widget_definitions
POST https://api.ibm.com/supplychainui/run/na/api/v1/wms/subscriptions/subscribe
-
Donut widgets
- Firmness: widget-firmnessSummaryWidget.json
- Ripeness: widget-ripenessSummaryWidget.json
- Sweetness: widget-sweetnessSummaryWidget.json
- Weight: widget-weightSummaryWidget.json
-
Summary widget
- Inspection count: widget-inventorylot_count.json
-
List widgets
- Failed inspection count by category: widget-failedInspectionsByCategory.json
- Failed inspection count by supplier: widget-failedInspectionsBySupplier.json
-
List of all inspections
- All inspections: widget-inspections_list.json
-
Detail page widgets
- Inspection drill down table: widget-inspectionDrillDown.json
- Product quality threshold table: widget-productQualityThresholdTable.json
- TS iframe widget: widget-iframe.json
Override to display Transparent Supply form
- Title: docLayoutTemplate.json
POST https://api.ibm.com/supplychainui/run/na/api/v1/wms/layout_templates
- Title: widget-iframe.json
POST https://api.ibm.com/supplychainui/run/na/api/v1/wms/widget_definitions
- Title: workItemAdditionalDetailsIframeSubscription.json
POST https://api.ibm.com/supplychainui/run/na/api/v1/wms/subscriptions/subscribe
POST https://api.ibm.com/supplychainui/run/na/api/v1/wms/layout_templates
then POST https://api.ibm.com/supplychainui/run/na/api/v1/wms/subscriptions/subscribe
Subscription body should be of the form:
{
"id": "<TEMPLATE_ID>_subscription",
"offeringId": "SCO",
"state": "ACTIVE",
"subscriptionConfig": [],
"tenantId": "<tenant_id>",
"templateId": "<TEMPLATE_ID>"
}
Two dashboard tabs
- Quality summary: dash-quality_summary.json
- All inspections: dash-all_inspections.json
Detail page
- Inspection drill down summary: drilldown-inspections.json
POST https://api.ibm.com/supplychainui/run/na/api/v1/wms/subscriptions/subscribe
Clean up column titles on work queues
- Overrides: override_subscriptions.json