Skip to content

Purchase Service Documentation

How it works

The order service is a microservice that allows users to place orders for products on iPOS. It interacts with several other microservices to perform its operations, such as the auth service, product service, business service, and inventory service. The order service is responsible for managing the order lifecycle, including creating, updating, and canceling orders.

The ordering process begins when a user selects one or more products they want to purchase. The order service then retrieves the product details from the product service, including its price, name, and description. The iPOS owner will be required to aggregate the order details and confirm the order. Once the order is approved, the order service will create an order in the database and send a message to the inventory service to update the inventory and the order is marked as approved.

Authentication and Authorization

The order service relies on the auth service to authenticate users before allowing them to place orders. The auth service generates JSON Web Tokens (JWTs) when a user logs in, which are then sent to the order service as part of the HTTP requests made by the user. The order service verifies the JWTs to ensure that the user is authorized to place orders and has required roles and permissions.

Error Handling

The order microservice returns error responses with appropriate status codes and error messages in case of invalid requests or errors in the order management operations.

Installation Guide

Before we begin, please make sure you have the following prerequisites:

  • A Google Cloud Platform (GCP) account
  • A project set up on GCP
  • A service account with the necessary permissions to create resources in GCP
  • Terraform installed on your local machine
  • A Bitbucket repository to host your code
  • Docker installed on your local machine

Architecture

This guide will help you install order service built on Laravel, hosted on GCP, and deployed to GKE using terraform. The service has three branches, namely staging, qa, and master each pointing to a different environment. We also use Git conventions for commits and host our repository on Bitbucket.

Installing Locally

If you want to install the service locally for development purposes, follow these steps:

Clone the repository from Bitbucket using Git. You can use the following command:

git clone git@bitbucket.org:iprocure-v2/order-service.git

Checkout the branch you want to work on. We have three branches: staging, qa, and master.
The staging branch points to the staging environment, qa points to qa environment and master points to production environment.

git checkout <branch-name>

Install the dependencies using Composer. Make sure you are in the root directory of the project, where the composer.json is located.

composer install

Create a .env file by copying the .env.example file and filling in the necessary environment variables.

cp .env.example .env

Generate the application key.

php artisan key:generate

Set up database: Next, you need to set up a database for your service. Open up the .env file in the root of your app and fill in the details for your database connection. For example:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=ipos_db
DB_USERNAME=root
DB_PASSWORD=

Note: You'll need to create a new database in your MySQL server first before you can connect to it.

Once you've filled in the details for your database connection, run the following command in your terminal:

php artisan migrate

This will create the necessary tables in your database.

Seeding Data

php artisan db:seed

This will seed the database with the necessary data.

Serve the application using the following command:

php artisan serve

You should now be able to access the service at http://localhost:8000.

Running Tests

Before you run tests, get Bearer token from auth service and set it in your .env file.

TEST_TOKEN=<token>

To run your tests, run the following command in your terminal:

./vendor/bin/pest

This will run all the tests in your tests directory. If any of the tests fail, you'll see an error message in your terminal.

GKE installation

Clone the repository from Bitbucket using Git. You can use the following command:

git clone git@bitbucket.org:iprocure-v2/order-service.git

Checkout the branch you want to install. We have three branches: staging, qa, and master. The staging branch points to the staging environment, qa points to qa environment and master points to production environment.

git checkout <branch-name>

Build the Docker image for the service. Make sure you are in the root directory of the project, where the Dockerfile is located.

docker build -t <image-name> .

Push the Docker image to Google Container Registry. Replace with your GCP project ID, and with the image name you used in the previous step.

docker tag <image-name> gcr.io/<project-id>/<image-name>
docker push gcr.io/<project-id>/<image-name>

Deploy the service to GKE. Replace with the name of your GKE cluster, with the image name you used above, and with the desired name of your Kubernetes service.

kubectl create deployment <service-name> --image=gcr.io/<project-id>/<image-name>
kubectl expose deployment <service-name> --type=LoadBalancer --port 80 --target-port 80

Wait for the load balancer IP to be assigned. You can check the status of the service using the following command:

kubectl get service <service-name>

Git Conventions

We use the conventional commits specification for our Git commits. Please make sure to follow these guidelines when making commits.

  • Use present tense, imperative mood (e.g. "add feature" instead of "Added feature").
  • Keep commit messages short and descriptive.
  • Separate the subject from the body with a blank line.
  • Use bullet points to list the changes made in the commit.

Commit Types

  • build: Changes that affect the build system or external dependencies (example scopes: gulp, npm)
  • ci: Changes to CI configuration files and scripts (example scopes: Travis, Circle)
  • chore: Changes which doesn't change source code or tests e.g. changes to the build process, auxiliary tools, libraries
  • docs: Documentation only changes
  • feat: A new feature
  • fix: A bug fix
  • perf: A code change that improves performance
  • refactor: A code change that neither fixes a bug nor adds a feature
  • revert: Revert something
  • style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
  • test: Adding missing tests or correcting existing tests

API Documentation

The order Service API is a RESTful API designed to allow frontend developers to interact with the Service. The API provides endpoints for creating, updating, and deleting orders.

Base URL

All endpoints have the base URL of https://order-service.test/api/v1/orders/

Authentication

All endpoints require authentication via a Bearer Token, which is provided by the Auth Service system.

Tip: All API Endpoints are available on the Swagger Section

Sample API Endpoints

Orders

The orders endpoints fetches all orders.

GET /orders/{id}

Retrieve the order with the given ID.

Request Parameters

id: The ID of the order to retrieve.

Response

A JSON object containing the contents of the order.

Example Request

GET https://yourapi.com/api/v1/order-service/orders/12345
Authorization: Bearer {TOKEN}

Example Response

{
  "data": {
    "id": 18,
    "productId": 20,
    "shopId": 1,
    "companyId": 1,
    "inventoryTypeId": 1,
    "localId": "67e20861-8e69-4169-abf5-dc497fc51744",
    "isQuarantine": false,
    "productCost": 750,
    "shopWholesalePrice": 600,
    "shopRetailPrice": 800,
    "shopAgentPrice": 0,
    "inventoryQuantity": 5,
    "reorderQuantity": 1,
    "discountPercentage": 0,
    "createdBy": 1,
    "updatedBy": null,
    "deletedBy": null,
    "deletedAt": null,
    "createdAt": "2023-03-20T09:02:24.000000Z",
    "updatedAt": "2023-03-20T09:02:24.000000Z",
    "inventoryTypeName": "Normal",
    "bundles": []
  }
}

POST /orders

Create a new order.

Request Body

A JSON object containing the order ID and the order details.

{
  "productId": 20,
  "companyId": 1,
  "newValue": 0,
  "oldValue": 0,
  "batchDetails": [
    {
      "productId": 20,
      "localId": "78afb87a-2787-4295-b5e3-fef8863aa739",
      "batchTypeId": 1,
      "batchNumber": "",
      "batchQuantity": "5",
      "unitCost": "750",
      "sellingPrice": "800",
      "shopBatches": [
        {
          "shopId": 11,
          "inventoryId": null,
          "localId": "ad400389-ecdb-4c3d-9732-26e7aecc28dc",
          "priority": 1,
          "initialQuantity": 0,
          "currentQuantity": "5",
          "isQuarantine": false,
          "activeStatus": true
        }
      ]
    }
  ],
  "localId": "7615100d-acb6-4991-baee-b4f788565ab7",
  "inventoryLocalId": "67e20861-8e69-4169-abf5-dc497fc51744",
  "transactionType": "INVENTORY_CREATION",
  "isQuarantine": false,
  "allowDeductFromInventory": true,
  "inventoryTypeId": 1,
  "shopId": 1,
  "discountPercentage": 0,
  "productCost": "750",
  "shopRetailPrice": "800",
  "shopWholesalePrice": "600",
  "transactionQuantity": "5",
  "reorderQuantity": "1"
}

Response

A JSON object confirming the creation of the order.

Example Request

POST https://yourapi.com/api/v1/orders
Authorization: Bearer {TOKEN}
Content-Type: application/json
{
"productId": "2",
"shopId": "1",
...
}

Example Response

{
  "data": {
    "productId": 20,
    "shopId": 1,
    "companyId": 1,
    "inventoryTypeId": 1,
    "localId": "67e20861-8e69-4169-abf5-dc497fc51744",
    "isQuarantine": false,
    "productCost": "750",
    "shopWholesalePrice": "600",
    "shopRetailPrice": "800",
    "shopAgentPrice": 0,
    "inventoryQuantity": "5",
    "reorderQuantity": "1",
    "discountPercentage": 0,
    "createdBy": 1,
    "updatedAt": "2023-03-20T09:02:24.000000Z",
    "createdAt": "2023-03-20T09:02:24.000000Z",
    "id": 18
  }
}

DELETE /orders/{id}

Remove an order from the system.

Request Parameters

id: The ID of the order to remove.

Response

A JSON object confirming the removal of the order.

Example Request

DELETE https://yourapi.com/api/v1/orders/12345
Authorization: Bearer {TOKEN}

Example Response

{
  "message": "Order deleted successfully",
  "success": true
}

Authentication Workflow

Process Flow

  • The user sends a request to the Authentication Service with their credentials.
  • The Authentication Service checks the credentials and returns a JWT token if the credentials are valid.
  • The user sends a request to the Inventory Service with the JWT token in the Authorization header.
  • The Inventory Service verifies the JWT token and returns the requested data if the token is valid.
  • The inventory service sends a request to batch service to create a new batch.
  • The batch service creates a new batch and returns the batch ID.
  • The inventory service creates a new inventory and returns the inventory ID.

System Workflow

Process Flow

  • User accesses the inventory using mobile or web application.
  • Request is sent to Google API gateway.
  • Google API gateway forwards the request to the inventory service.
  • The inventory service checks the JWT token and returns the requested data if the token is valid.
  • The inventory service sends a request to batch service to create a new batch.
  • The batch service creates a new batch and returns the batch ID.
  • The inventory service creates a new inventory and returns the inventory ID.
  • After an inventory is created an event is published to the event bus (Google Pub/Sub).
  • The event is consumed by the inventory service.

Database Structure

Workflow Service Db Diagram

Conclusion

The order service is a critical component of your microservices architecture, allowing users to place orders for products in your system. By relying on other microservices for authentication, product details, and shop details, the order service is able to streamline the ordering process while ensuring that all necessary data is available to complete the order.