Predictive Inventory Management Service


The Predictive Inventory Management Service enables API callers to generate stock replenishment proposals based on historical data which includes supplier orders and customer orders.

Access info

Endpoint https://predictive-inventory-management-api.socrate.io/graphql
Required access keys Tenant-level service access key
Pricing Please contact us for details at contact@bitsoftware.ro
Notes To call the service, the access key must be provided in the x-api-key header of the HTTP request. If you are using the GraphQL console, you can view the service’s documentation and schema only after entering an access key. Make sure that the scope of the key allows access to the queries and mutations that you require. For example, to grant the key access to all queries and mutations, the keys’s scope must be set to predictive-inventory-management-api:query:* predictive-inventory-management-api:mutation:*.

Usage

Prerequisites

  • The organization(s) for which reporting is done must exist in the SBS system. You can add new organizations either from the Organizations UI or programmatically from the Organizations Service.
  • The following CSV files are required as input to te Predictive Inventory Management service (click the links below for information about the structure of the file):
    1. CustomerOrders.csv
    2. SupplierOrders.csv

Generating a replenishment proposal

To generate a replenishment proposal:

  1. Obtain from your ERP system the input CSV files to be used as input. For the structure of each file, see Appendix 1: Input structure.
  2. Create a new replenishment proposal by calling the createReplenishmentProposal mutation. You must supply as input argument, at the minimum, the target month, in the format YYYY-MM. As a result, a new replenishment proposal object is created, and the response contains the unique proposal ID. You will need to work with this ID in subsequent steps to further process the proposal and monitor its status.
  3. Add all the input CSV files to the proposal. See Preparing input files.
  4. Run the computeReplenishmentProposal mutation. This triggers a computation that takes place from several minutes to several hours, depending on the size of input CSV files.

The outcome of computing a proposal, including any possible errors, is reported in the Process object when querying the respective proposal. If the computation was successful, the process includes one or more of the following attributes:

  • productCentricResult - This is the default result and it is always present. It contains, among other attributes, the name and download URL of the output file, with computation results grouped by product. For the structure of the output file, see Appendix 2: Output structure.
  • customerCentricResult - This result is present if the proposal was created with the input parameter splitByCustomer = true. The result has the same structure as above, except that data inside the output file are grouped by customer.
  • industryCentricResult - This result is present if the proposal was created with the input parameter splitByIndustry = true. The result has the same structure as above, except that data inside the output file are grouped by industry code.

Preparing input files

After you have create a replenishment proposal, you can add all the CSV input files to it.

For each input CSV file, the steps are as follows:

  1. Run the prepareFile mutation, for example:
mutation prepareFile($replenishmentProposalId:ID!, $input:PrepareFileInput!) {
  prepareFile(replenishmentProposalId:$replenishmentProposalId, input:$input) {
    id
    fileType
    name
    contentLength
    uploadUrl
    downloadUrl
    createdAt
  }
}
{
    "replenishmentProposalId": "YOUR_REPLENISHMENT_PROPOSAL_ID",
    "input": {
        "fileType": "CustomerOrders",
        "name": "customer-orders.csv"
    }
}

In the response, you get the file’s upload URL at which you can upload the actual file.

  1. In the programming language of your API, make an HTTP PUT request to upload the file content to the upload URL. This step is similar to how you would create a file and then upload its content in the File Management Service, as described in the Tutorial: Create a file.

Note that you can add multiple files of the same type for the same replenishment proposal. For example, you can add several input CSV files of type “CustomerOrders”. If multiple files of the same type exist, SBS will aggregate and compute data found in all respective files.

After adding all the CSV files, you can check if they are indeed attached to the replenishment proposal by running the replenishmentProposal query, for example:

query ReplenishmentProposal ($id:ID! $fileId:ID, $processId:ID) {
  replenishmentProposal(id:$id) {
    id
    organizationId
    files(id: $fileId) {
        id fileType name contentLength uploadUrl downloadUrl createdAt
    }
    createdAt
  }
}
{
   "id": "YOUR_REPLENISHMENT_PROPOSAL_ID"
}

If your replenishment proposal looks good so far, you can proceed to running the computeReplenishmentProposal mutation, for example:

mutation ComputeReplenishmentProposal ($id:ID!) {
  computeReplenishmentProposal(id:$id) {
    id 
    status
    dataRange { from to } 
    targetMonth
    errorMessages
    createdAt
  }
}
{
   "id": "YOUR_REPLENISHMENT_PROPOSAL_ID"
}

Dealing with large input files

As mentioned above, when you add a file to the replenishment proposal, there are two steps involved:

  1. Run prepareFile and obtain the upload URL.
  2. In the programming language of your API, make an HTTP PUT request to upload the file content to the upload URL.

For the second step, note, however, that the maximum file size that you can send in a single PUT request is 5 GB. Should you need to add larger files to the replenishment proposal, you can do so through the multipart upload mutations provided by the File Management Service. In this scenario, the process looks as follows:

  1. Run prepareFile and take notice the data.prepareFile.id returned in the response body. This ID corresponds to a file id of a file in File Management Service.
  2. Provide the id above as input to the initiateMultipartUpload mutation and continue with the rest of steps required for multipart upload, as described in Uploading large files.

Processes

Each time when you run computeReplenishmentProposal, a new process with status NEW is attached to the replenishment proposal. You can view the proposal and the status of all its processes by running the replenishmentProposal query and requesting the processes field in the response, for example:

query ReplenishmentProposal ($id:ID! $fileId:ID, $processId:ID) {
  replenishmentProposal(id:$id) {
    id
    organizationId
    targetMonth
    splitByCustomer
    splitByIndustry
    files (id: $fileId) {
        id fileType name contentLength uploadUrl downloadUrl createdAt
    }
    processes (id: $processId) { 
        id 
        status
        dataRange { from to } 
        targetMonth
        errorMessages 
        productCentricResult { id name contentLength createdAt downloadUrl }
        customerCentricResult { id name contentLength createdAt downloadUrl }
        industryCentricResult { id name contentLength createdAt downloadUrl }
        totals {
           csvLines { customerOrders supplierOrders allFileLines }
        }
        createdAt
    }
    createdAt
  }
}
{
   "id": "YOUR_REPLENISHMENT_PROPOSAL_ID"
}

The status of any process is initially NEW. The status NEW will normally change to INPROCESS after approximately 1 minute. Note that, if you run computeReplenishmentProposal multiple times for the same proposal, each run will start a new process. In this case, you will need to track the status of each process separately. The processes field of the replenishmentProposal query provides a filter (by process ID) for that purpose.

The INPROCESS status of a process may take from a few minutes to a few hours, depending on the size of the input CSV files. After the INPROCESS status, the status may change to either ERROR (if errors are encountered) or DONE (upon successful processing).

If the status ERROR is encountered, check the errorMessages response field of the respective process for details.

If the process completes with status DONE, it generates 1-3 CSV output files. As mentioned previously, the number of files depends on the input parameters supplied at proposal creation time to the createReplenishmentProposal mutation.

If necessary, you may stop a running process through a call to killProcess. However, this is possible only if the process has not generated any results (that is, if the result field of the process is empty).

You may also delete a process through the deleteProcess mutation. Deleting a running process is possible only if the process has generated no result yet.

Deleting replenishment proposals

You can delete replenishment proposals through a call to deleteReplenishmentProposal. Note, however, that it is not possible to delete a replenishment proposal if it has at least one running process that has already generated some result file. To delete such a proposal, you will need to wait for the process to finish first.

Queries

organizations

Returns a list of active organizations defined for the given tenant.

Result

The result is an array of Organization.

Organization type
Attribute Type Description
id ID! Specifies the organization’s unique identifier.
name String Specifies the organization’s name.

replenishmentProposals

Returns the list of replenishment proposals for the organization ID supplied as input.

Arguments

Argument Type Description
organizationId ID! Mandatory. The identifier of the organization to which the replenishment proposal belongs.
filter ReplenishmentProposalsFilter Optional. Supplies filtering criteria to the query.
ReplenishmentProposalsFilter input
Argument Type Description
createdAt DateFilter Optional. Provides filtering options to the query.
DateFilter input
Attribute Type Description
from Date Optional. Specifies a date in YYYY-MM-DD format. If provided, only records where the creation date starts with this date will be retrieved.
to Date Optional. Specifies a date in YYYY-MM-DD format. If provided, the query will retrieve only records having the creation date up to and including this date.

Result

The result is an array of objects of type ReplenishmentProposal.

replenishmentProposal

Retrieves a single replenishment proposal by ID.

Arguments

Argument Type Description
id ID! Mandatory. The ID of the replenishment proposal to retrieve.

Result

See the ReplenishmentProposal type.

Mutations

computeReplenishmentProposal

Starts a process that computes a replenishment proposal, based on its current input data. Running this mutation will start a new process on each run.

Arguments

Attribute Type Description
id ID! Mandatory. The identifier of the replenishment proposal to be computed.

Result

See the Process type.

createReplenishmentProposal

Creates a replenishment proposal.

Arguments

Attribute Type Description
organizationId ID! Mandatory. The identifier of the organization for which this replenishment proposal is created.
input CreateReplenishmentProposalInput! Mandatory. Provides the actual input data to the mutation.
CreateReplenishmentProposalInput input
Attribute Type Description
targetMonth Month! Mandatory. The month for which the replenishment proposal is computed. The value must have the YYYY-MM format.
splitByCustomer Boolean Optional. If this value is supplied, computing the proposal will generate a separate CSV output file in addition to the default one, with results grouped by customer ID.
splitByIndustry Boolean Optional. If this value is supplied, computing the proposal will generate CSV output file will be created in addition to the default one, with results grouped by industry code ID.
demandCoverageType DemandCoverageType Optional. An enum with the following valid values: Calendaristic, Business.

Result

ReplenishmentProposal type
Attribute Type Description
id ID The identifier of the replenishment proposal.
organizationId ID The identifier of the organization for which this replenishment proposal was created.
targetMonth Month The target month for which the replenishment proposal was created.
splitByCustomer Boolean If true, indicates that the replenishment proposal was created with an option to produce a separate output file with results grouped by customer.
splitByIndustry Boolean If true, indicates that the replenishment proposal was created with an option to produce a separate output file with results grouped by industry.
demandCoverageType DemandCoverageType An enum with the following valid values: Calendaristic, Business.
files (id: ID) [File] The list of input files associated with the current proposal. You can optionally filter files by ID, by supplying the file ID as input argument to this field.
processes (id: ID) [Process] The list of processes associated with the current proposal. You can optionally filter processes by ID, by supplying the process ID as input argument to this field.
createdAt DateTime The date and time when the replenishment proposal was created.
File type
Attribute Type Description
id ID The unique identifier of the file. You an use this ID to refer to the file also through the File Management Service.
fileType CsvFileType The type of data reported by the file. Valid values: CustomerOrders, SupplierOrders.
name String The file name.
contentLength Float The file size in bytes.
uploadUrl(expiresIn: Int) Uri The URL at which the file content can be uploaded. Note that the upload URL expires after the number of seconds supplied in the expiresIn parameter.
downloadUrl(expiresIn: Int) Uri The URL at which the file content can be downloaded. Note that the download URL expires after the number of seconds supplied in the expiresIn parameter.
createdAt DateTime The date and time when the file was created.
Process type
Attribute Type Description
id ID The unique identifier of the file.
status ReplenishmentProposalStatus The status of the replenishment proposal. Valid values: NEW - computation has not started yet, INPROCESS - computation is in progress, DONE - computation has completed without errors, ERROR - computation has completed with errors.
dataRange DataRange The date range for which the replenishment proposal was created.
targetMonth Month! The month for which the replenishment proposal was created, in YYYY-MM format.
errorMessages [String] The list of error messages, if applicable.
productCentricResult ResultFile The standard output file created by the process. In the standard file, results are grouped by product ID.
customerCentricResult ResultFile An output file where results are grouped by customer ID. This file is created only if the replenishment proposal was created with the option splitByCustomer = true.
industryCentricResult ResultFile An output file where results are grouped by industry code ID. This file is created only if the replenishment proposal was created with the option splitByIndustry = true.
totals Totals The totals computed by this process.
createdAt DateTime The date and time when the process was created.
DataRange type
Attribute Type Description
from Date The starting date of the range.
to Date The ending date of the range.
ResultFile type
Attribute Type Description
id ID The unique identifier of the file. You an use this ID to refer to the file also through the File Management Service.
name String The file name.
contentLength Float The file size in bytes.
downloadUrl(expiresIn) Uri The URL at which the file content can be downloaded. Note that the download URL expires after the number of seconds supplied in the expiresIn parameter.
createdAt DateTime The date and time when the file was created.
Totals type
Attribute Type Description
csvLines CsvFileLines The number of lines in each of the CSV files, as a CsvFileLines type.
CsvFileLines type
Attribute Type Description
customerOrders Float Reports the number of lines in CustomerOrders.csv.
supplierOrders Float Reports the number of lines in SupplierOrders.csv.
allFileLines Float Reports the number of lines in both files above.

deleteFile

Deletes a previously uploaded CSV file.

Arguments

Attribute Type Description
replenishmentProposalId ID! Mandatory. The identifier of the replenishment proposal.
fileId ID! Mandatory. The identifier of the CSV file to be deleted.

Result

DeletedFile type
Attribute Type Description
id ID The unique identifier of the file. You an use this ID to refer to the file also through the File Management Service.
fileType CsvFileType The type of data reported by the file. Valid values: CustomerOrders, SupplierOrders.
name String The file name.
createdAt DateTime The date and time when the file was created.

deleteProcess

Deletes a computation process and the result files.

Arguments

Attribute Type Description
replenishmentProposalId ID! Mandatory. The identifier of the replenishment proposal.
processId ID! Mandatory. The identifier of the process to be deleted.

Result

See the Process type.

deleteReplenishmentProposal

Deletes a replenishment proposal, including all its input and output files and processes.

Arguments

Attribute Type Description
id ID! Mandatory. The ID of the replenishment proposal to be deleted.

Result

See the ReplenishmentProposal type.

killProcess

Stops a running computation process.

Arguments

Attribute Type Description
replenishmentProposalId ID! Mandatory. The identifier of the replenishment proposal.
processId ID! Mandatory. The identifier of the process to be deleted.

Result

See the Process type.

prepareFile

Generates a URL at which you can upload a CSV file to be used as input to the computation. Run this mutation for each CSV file that is to be supplied as input for a replenishment proposal.

Arguments

Attribute Type Description
replenishmentProposalId ID! Mandatory. The identifier of the replenishment proposal.
input PrepareFileInput! Mandatory. Supplies the input data to the mutation.
PrepareFileInput input
Attribute Type Description
fileType CsvFileType! Mandatory. This is an enumeration that identifies the type of the CSV file. Valid values: CustomerOrders, SupplierOrders.
name String Optional. Supplies the name of the CSV file.

Result

See the File type.

Appendix 1: Input structure

The input to the Predictive Inventory Management Service consists of two CSV files:

  1. CustomerOrders.csv
  2. SupplierOrders.csv

You may supply multiple files of the same type as input as long as they follow the structure described below. Note the following:

  • Each CSV file is comma-separated
  • The first row in the CSV file should provide the column names (that is, the CSV file must include the header).

CustomerOrders.csv

Column Type Mandatory? Description
product_id String Yes The unique product identifier. Must not contain spaces.
customer_id String No The customer identifier. Must not contain spaces.
industry_code_id String No The industry code identifier. Must not contain spaces.
product_group_id String No The product group identifier. Must not contain spaces.
is_return Boolean Yes Indicates whether the order was a return. Valid values: true, false. The values 0 and 1 are also accepted.
order_date String Yes The date when the order was placed, in DD.MM.YYYY format. NOTE: The combination product_id + order_date + order_quantity must be unique, to ensure that no data was duplicated by mistake.
order_quantity Float Yes The quantify of products ordered.
supplier_id String Yes The provider identifier.

SupplierOrders.csv

Column Type Mandatory? Description
product_id String Yes The unique product identifier. Must not contain spaces.
is_return Boolean Yes Indicates whether the order was a return. Valid values: true, false. The values 0 and 1 are also accepted.
order_date String Yes The date when the order was placed, in DD.MM.YYYY format. NOTE: The combination product_id + order_date + order_quantity must be unique, to ensure that no data was duplicated by mistake.
order_quantity Float Yes The quantify of products ordered.
lead_time Integer Yes The number of days in which the products were delivered.
supplier_id String Yes The identifier of the supplier.

Appendix 2: Output structure

The result of computing a replenishment proposal is a CSV file having the structure described below.

Column Type Description
product_id String The unique product identifier.
customer_id String The customer identifier.
industry_code_id String The industry code identifier.
product_group_id String The product group identifier.
one_step_ahead String The month for which the levels are calculated (year-month).
service_level Float The percentage level of service to cover.
min_estimate_regular Integer Safety stock level under regular supply conditions (trigger-regular).
max_estimate_regular Integer Replenish stock level under regular supply conditions (supply proposal-regular).
min_estimate_conservative Integer Safety stock level under conservative supply conditions (trigger-conservative).
max_estimate_conservative Integer Replenish stock level under conservative supply conditions (supply proposal-conservative).
order_freq_estimate Integer Sales level for the delay time between supply orders.
months_with_data Integer Number of months with historical data.
model String The statistical model applied.
monthly_sales_service_level_forecast Integer Monthly sales forecast at the given service level.
monthly_sales_mean_prediction Float Average sales forecast.
monthly_sales_std_prediction Float Standard deviation of the sales forecast.
lead_time_mean Float Historical average of supply lead time.
lead_time_std Float Historical standard deviation of supply lead time.