# Creating Material Requirements

One goal of Procurement is to allow multiple people to collaborate around their separate procurement needs. For example, an employee working in the warehouse can report a shortage of a particular paper, or a printer could report a shortage of ink. We represent these requirements in our system as an object called a "material requirement", which is a group of data about which product is needed, when and where it should be delivered, as well as lots of optional metadata such as the print job it is associated with.

Material requirements are a useful concept for purchasers, as they have the ability to combine multiple material requirements into a single order, hopefully to reduce their costs.

Material requirements are also the first time you can determine the price for a particular item. Pricing can be highly complex, based on many factors, such as the quantity being ordered, where it's being delivered, time-sensitive promotional pricing, etc. Some of our suppliers also support pricing/availability updates as well, meaning we can show accurate prices/delivery information before creating an order.

Let's step through a typical workflow to demonstrate the feature. We'll create a material requirement, wait for an accurate price, and then order it.

We'll need a variant_id representing a Variant that we searched for, as well as an amount & unit, but we can also express other parameters like site, job details and even specific SKUs. Please note, that if you don't specify a site, we'll use the default one associated with this organization, otherwise you can view/create sites using the Hub sites API beforehand.

POST /api/v2/material_requirements
Content-Type: application/json

{
  "material_requirement": {
    "variant_id": "0167d323-57ac-52dc-9c81-c7514f8eab12",
    "amount": 500,
    "unit": "sheet"
  }
}

HTTP 201 Created
{
  "id": "c727467d-83ff-4711-9ddc-9f84eaa7af71",
  "state": "draft",
  "required_material": { ... },
  "pricing": {
    "accuracy": "in_verification",
    "currency": "EUR",
    "price": "14"
  },
  ...
}

In this case, the pricing.accuracy is "in_verification", which means that the price we're showing here is our best estimate based on existing data, but we're asking the supplier for a more up-to-date value (if the accuracy was "estimated", it means we are unable to check the price with the supplier and so this price will not change in future).

So, in the "in_verification" state, you should periodically check back to see if a more accurate price has arrived. Typically responses arrive within a few seconds, occasionally up to a minute after request, so you should indicate to your customers that the prices they are seeing might change (e.g. by showing a loading icon).

If your system is able to handle Zaikio webhooks, you can subscribe to the procurement_consumer.material_requirement_conditions_verified event, which is emitted when the supplier has provided more accurate price/delivery information. The event will look like this:

{
  "id": "62abcc92-e17e-4db0-b78e-13369251474b",
  "name": "procurement_consumer.material_requirement_conditions_verified",
  "subject": "Org/2b271d51-e447-4a16-810f-5abdc596700a",
  "timestamp": "2022-04-05T10:58:09.664Z",
  "version": "1.0",
  "payload": {
    "material_requirement_id": "c727467d-83ff-4711-9ddc-9f84eaa7af71"
  },
  "received_at": "2022-04-05T10:58:09.664Z"
}

Alternatively, you can also periodically re-fetch the material requirement like so:

GET /api/v2/material_requirements/c727467d-83ff-4711-9ddc-9f84eaa7af71

HTTP 200 OK
{
  "pricing": {
    "accuracy": "in_verification"
  },
  ...
}

Once the pricing.accuracy switches to "verified", it means the supplier has given us price/availability information and the product is likely orderable. This is a good opportunity to present the user with the updated prices and let them decide whether they wish to continue with ordering.

Please note that the accuracy of a requirement can switch from "verified" to "outdated" - for example, if you recorded a requirement today but weren't ready to order until next week, the availability & pricing may change in the meantime. For these sorts of requirements, we offer a refresh API to ask Procurement to go and fetch some updated prices.

Material requirements are easy to create, and by default are not presented to the users in the Procurement web interface (this can be changed by setting the visible_in_web: true parameter when creating the requirement). This means that you can quickly accumulate a large amount of requirements that won't be ordered. Procurement will periodically clean up requirements older than 6 months, however you can also delete unused requirements yourself if preferred.

When the user is happy to proceed with ordering, they can begin ordering the requirement.

# Material Requirement retention

All material requirements that have been ordered will be persisted forever.

All other material requirements will be automatically deleted if they haven't been updated for a prolonged time and thus are considered stale. You can expect material requirements to disappear after about a month of not having been updated.