Streamlining e-commerce fulfilment system to reduce turnaround by half

SquareArk - Fulfilment Portal

Client Industry
Supply Chain, E-commerce
Type
Product Management, UX Design
Duration
3 months

Summary

For a e-commerce product, our fulfilment turnaround was too slow for our users. I identified the issues of duplicated input and misaligned output on our fulfilment system, which contributed to the inefficient fulfilment process. Upon revamping the workflow on order management processes and API integration with our warehouse partner, we achieved the following results:

42→14 steps from creating products to inbound
3 days→1 day per order handling time

Where it started?

After the UX revamp on the product listing page on customer-facing web-app, the conversion rate has been doubled, but retention is still quite low. We spoke with a few current users, and long fulfilment turnaround time seems to be the issue. Many finished their first purchase, and never returned. End customers accepts 2 to 3 weeks delivery as long as the price is low enough. But it’s certainly unacceptable for social sellers as they purchase in bulk, and their cash flow is limited.

We also observed a turnover in the ops team. No teammate in ops stayed more than 2 months. It’s because of the repetitive and inefficient fulfilment process that triggered their decision. The fulfilment turnaround has become a critical gap to both internal and external stakeholders.

Problem

There are 2 facets to the gap:

1. Duplicated input of the same piece of data

The same piece of data, like like product names, SKUs, prices, has to be input multiple times at different stages of the fulfilment process over multiple disconnected systems.

2. Misaligned system output

Displayed records and exported spreadsheets requires manual updates, and even out-of-system tracking in order to fit the needs of each business units:

  • Operations: had to keep track of inbound and outbound status on a separate spreadsheet as fulfilment status is not tired with our warehouse system.
  • Procurement: fill up a different spreadsheet for orders that didn’t meet the MOQ requirement yet got exported in purchase orders anyways.
  • Accounting: keep track of every transaction on another spreadsheet, as individual orders are not connected with purchase orders.

Goal

  1. Remove all duplicated input: to reduce ops team’s workload, and speed up internal fulfilment turnaround.
  2. Reduce manual fulfilment process per sales transaction to less than a day.

Chunk #1: Product creation

Products can be added or updated individually. There‘s a bulk upload template, which can be filled with multiple products info. By uploading the template to our fulfilment system, those products would be added or updated. However, due to redundant fields on the bulk upload template, the ops team opted for individual upload over bulk upload. When they absolutely have to upload with bulk template, they built their own separate converting spreadsheet.

Problem space

What does it mean by redundant fields? As our fulfilment system utilised Sailor, an open-sourced order fulfilment system, there were defaults that aren’t applicable to the current business. The ops team had no idea on how these inputs would impact the system, nor the tech team attempted to hide the unused fields. The below is the original workflow:

User flow review on current product creation process
Original workflow for creating new products on fulfilment portal

There are 3 main issues:

  1. Unused fields: fields like shipping weights, available date, product type are not used but still required to be filled in in order to successfully upload. So the ops team had to spend at least 30% more time filling up fake data into these fields before uploading.
  2. Hard-to-find slugs: product categories, suppliers, product type require users to fill in with system-generated slugs. However, slugs are not available on display in the system. We had to export the slugs, and view them on the exported spreadsheet. Therefore, the ops team is actually keeping their own spreadsheet of slugs so that they don’t have to check every time before uploading. Yet when the slugs are edited, ops often forgot to update their slug spreadsheet, causing tagging errors.
  3. Expanding price tier rates on individual product level:
  • At least 5 price tiers have been created. Each tier has a different discount rate in percentage. Social sellers who orders more receive a deeper discount, while smaller sellers get less discount. However, when adding products with the bulk upload template, discount rates have to be expanded into actual numbers for each and every individual products.
  • What’s worse is along with price, quantities and tier names are clustered in their own columns. Each values are only separated with semicolons. For example, given there are 5 tiers, user has to first input 5 tier names, separated with semicolons, in sequence in the first column, then the 5 prices in the same sequence to match with the tiers in the previous column. Imagine repeating these steps 6 times for every single product. When a new price tier is added, the workload is doubled. It’s impossible to double check for errors.
5 of the columns for price tiers. Each tier is only separated by ";" in the same column.

As the result, the ops team came up with a few temporary solutions below:

  • Copy and paste the same values every time before uploading, yet it’s easy to miss some of them, which leads to unsuccessful upload.
  • Create their own converting spreadsheet before duplicating the converted values onto the upload template.
  • Curate a spreadsheet for storing slugs
  • Avoid using the mass upload template at all, upload one by one instead.

Problem Statement

Solution space

The strategy is to first remove unused fields that doesn’t fit the business now. Then, to minimise errors, defaults and drop-downs are added to the template:

New user flow on product creation
  1. Removing unused fields
    • Shipping weight is temporarily disabled because we charge shipping fee by a flat rate, and we didn’t have the resource to measure the weight of products either.
    • Simplifying publish date: available date and publish date has a very similar function on controlling when to open the products for sale. But as we didn’t provide pre-order options, available date becomes useless. Once the product is published, it should immediately be available for sale. So these two dates has been combined into a single field.
  2. Replacing with default values: for product type and collection, as the values are the same for all products, these fields is set as default and hidden.
  3. Introducing drop downs for slugs: upon confirmation with development team, slugs can’t be replaced due to system limitations. Therefore, we managed to provide drop-downs of slugs where the ops team can directly choose without browsing our system, locating every slug one by one.
  4. Price tiering logic refactoring: instead of expanding prices with discount rates for each product, we added a discount rate input at the supplier level per user tier. So whenever any new products are added, manual calculation is no longer required. The assigned price tier discount rate would be applied automatically.
  5. Product data uploaded will be inherited in the following steps, so no product data would be required at later chunks. (PO and inbound will use the same pool of data)
The original 38-columns bulk upload template has been reduced to 20 columns, which cuts the product uploading time by half.
New product uploading template with slug dropdowns for selection.
Price tiers will be applied directly to the corresponding products. No longer required to calculate manually when creating new products
Service blueprint

Chunk #2: Purchase order (PO)

A purchase order is meant for ordering stocks from suppliers, so that we can sell them to other social sellers. The original PO system was designed for event-based purpose for a single supplier. All orders within the event timespan will be included in a single PO automatically, so the PO could be directly sent to the event supplier. Until the previous PO has been fulfilled, new POs can’t be generated. In addition, we didn’t have to keep stock as suppliers deliver the stocks to us before each event. So inventory wasn’t factored into consideration. As the business model changed, it no longer fits our need.

Problem space

Since we work with multiple suppliers now, whenever we generate a new PO, all orders with multiple suppliers between the previous PO and now would be added to the new PO. Multiple suppliers’ POs would be clustered into one file. The workflow looks like below:

Original workflow on creating new purchase orders (PO)

Hence, the team faced the following issues:

  • The generated POs includes orders from multiple suppliers. Beside the first sheet with all products ordered, a sub-PO in a separate sheet would be created for each supplier. Yet their MOQ requirements are different for every supplier. So for any suppliers sub-PO that doesn’t meet the MOQ requirement, the procurement team had to store the list elsewhere, and combine with any future POs when the MOQ is met. As a result, products often get ordered multiple times, or overseen because the PO management process is manual, and stored out of system.
  • Multiple suppliers mean multiple POs. After the first generated PO, the team cannot generate any new POs. So the ops team had to fake “fulfil” the PO on the system, and keep track of the PO status on a separate spreadsheet to make sure it’s actually fulfilled when the stocks arrive. It takes extra attention to keep track of which ones are actually fulfilled and which aren’t. It’s prone to error.
  • Since we now keep stocks, yet stock count at warehouse wasn’t synced with our database, the team had to checks on the warehouse system, and deduct the number of stocks from the PO manually, so that we don’t overstock. Unfortunately, such manual procedures have created multiple incidents of over-ordering and under0ordering.
  • The PO format is misaligned that on a single PO, every supplier has their own page. So when the procurement team needed to send out the PO to each supplier, the team had to manually split the POs one by one for each supplier.

Solution space

Revamped purchase order user flow, integrated with inbound workflow

The PO page is revamped into 2 pages: Create PO page and the Overview page. At the create PO page, a list of orders will be available for the procurement team to pick and generate new POs. The generated POs can be viewed at the Overview page, along with the order numbers that the PO was created for.

  1. Create PO
    • Multiple POs can be generated at the same time. When we need to order from multiple suppliers, we can generate multiple times without fake “fulfilling” any previous POs. Hence, it doesn't require separate tracking spreadsheets.
    • The hard-coded limit, that all orders within the latest timespan would be included into the new PO, is removed. The user has the flexibility to filter by supplier or by time to pick orders to create a new PO.
    • With the selected orders for any new PO, previews of the total value per brand are shown in the confirmation window, so that the user can double check whether MOQ requirements are met or not.
    • When the new PO is generated, Stocks on hand will be deducted by system automatically from the new PO to avoid over-ordering and manual calculation errors. (Stock count on batch code level is now available through API integration with our warehouse system. See Inbound)
    • The status of “Generated” and “Not Generated” is added to indicate if we’ve placed the PO with the suppliers or not, so that we don’t miss or over-order by mistake. Doesn't require separate tracking spreadsheet either, which is another factor for manual errors.
  2. PO Overview
    • New generated POs will be split by supplier level, meaning the PO spreadsheets would be ready for sending directly to suppliers without any manual edits.

With the current workflow, the team don’t have to manage orders and maintain POs on any spreadsheets. Pick orders to generate POs for, download and send over the PO document directly to suppliers are the only remaining steps. All of these is visible on our fulfilment system, leaving way less room for error and faster turnaround.

Wireframing draft

Chunk #3: Inbound

Once the PO is confirmed, an inbound has to be scheduled with our warehouse partner, so that our warehouse knows what stocks will be sent over, and when it would be sent. When the stocks arrive, a round of quality control (QC) check will be conducted to identify any discrepancy before adding the stocks to our inventory.

In short, it takes at least 15 steps and 3+ separate spreadsheets over 4 channels to complete a single inbound. It involves:

  1. Warehouse management system (WMS) provided by our warehouse partner for scheduling upcoming inbounds.
  2. WhatsApp group with our WMS partner for day-to-day communication.
  3. Shared drive for uploading damaged product images for QC approvals.
  4. Spreadsheets for inbound status tracking, delivery note for each inbound, and tracking damaged inventory. Inbound was completely absent from our own system.

Yet none of these is visible on our own fulfilment system. The detailed workflow can be viewed below:

Problem space

After conducting a task analysis, there are actually only 3 main steps required for inbound:

  1. Scheduling an inbound with estimated arrival date
  2. QC review and approval
  3. Updating on-hand inventory: on-hand & damage quantity

However, these 3 steps tangled up with numerous quick fixes, which eventually became too much to unravel. It caused the following problems:

  • Duplicated product input: The same product data has to be input repeatedly whenever there’s a new medium. First time when scheduling an inbound on WMS. Second time when creating a delivery note. Third time when tracking damaged products. Jumping in between mediums and channels has contributed to manual error, and increasing inbound handling time.
  • Scattered channels causing inefficient processing: matching inbounds across spreadsheets, WMS, WhatsApp, shared drive drastically decrease efficiency. Missing any of these elements forbids the team from knowing how far the inbound has been processed, even stop the entire inbound process. It’s more challenging when other business functions to follow up. For example, if the sales team need to get back to their clients enquiry on their order status, it’s impossible for the sales team to do  it themselves as they have no visibility to inbound status. They could only reach out to ops team for help, which adds again extra workload.
  • Inadequate visibility on stock count: as the inventory on the WMS is disconnected with our fulfilment system, the quantities on our own system requires manual updates. However, the prolonged procedures have held back our team to do so. As a result, we don’t know how many stocks we have, and how many are incoming. Hence, even when the inbound is completed, the inventory count shown on our fulfilment system is still inaccurate.
  • Broken discrepancy review process: As our warehouse partner would upload unnamed photos of the damaged products to our shared drive without product barcodes, the ops team had to spent extra time to match the photo with the product one by one. Reasons of damage are also unstated here. The photos are often close ups that could indicate wrong batch code, wrong barcode, discolourations and dents on the packaging. Without stating the damage type, our team needs to second guess. Damage quantity is not specified, and can only be found on the delivery note updated from the warehouse partner after this QC is approved.
Usability tests with users

Solution space

We integrated our fulfilment system with our WMS partner’s API to synchronised all inbound interactions. Creating inbounds, loading product data, and discrepancy review can be done on our fulfilment system, which will be synced with the WMS.

For all three chunks, we wrote complete SOPs after completing usability test with our internal team. It’s shared on the Notion board for the ops team, making sure the knowledge and process are well defined and preserved.

Results

Overall fulfilment capacity is doubled by cutting out all duplicated input & manual handling processes. Streamlining the first half of the fulfilment process on our fulfilment system has boosted the efficiency, and given not only the ops team, but the entire cross-functional team higher visibility into the fulfilment process.

  • Product creation: reducing 30% of input, and cutting half of the time required for inputting products.
  • Inbound: decreased 75% in inbound handling time
  • Sales team finds the new PO and inbound process particularly helpful
“I can finally check order status, and get back to clients myself. When the ops team forgot to place PO for certain orders, I’m able to tell and give timely feedback to our team for follow up. Happy to gain so much more visibility to the fulfilment progress.” - Sales Manager
Other projects