(This project is done as an assignment given by the Fatmug)
Vendor Management System is a platform that companies can use to manage its external workforce. For businesses, Vendor stands for an external supplier of goods and/or services. This project is a simple implementation of a vendor management system using Django Rest Framework with the database being SQLite3
This system employs following four models:
This model stores essential information about each vendor and their performancemetrics.
Fields:
- name: CharField - Vendor's name.
- contact_details: TextField - Contact information of the vendor.
- address: TextField - Physical address of the vendor.
- vendor_code: CharField - A unique identifier for the vendor.
- on_time_delivery_rate: FloatField - Tracks the percentage of on-time deliveries.
- quality_rating_avg: FloatField - Average rating of quality based on purchase orders.
- average_response_time: FloatField - Average time taken to acknowledge purchase orders.
- fulfillment_rate: FloatField - Percentage of purchase orders fulfilled successfully.
This model captures the details of each purchase order and is used to calculate various performance metrics.
Fields:
- po_number: CharField - Unique number identifying the PO.
- vendor: ForeignKey - Link to the Vendor model.
- order_date: DateTimeField - Date when the order was placed.
- delivery_date: DateTimeField - Expected or actual delivery date of the order.
- items: JSONField - Details of items ordered.
- quantity: IntegerField - Total quantity of items in the PO.
- status: CharField - Current status of the PO (e.g., pending, completed, canceled).
- quality_rating: FloatField - Rating given to the vendor for this PO (nullable).
- issue_date: DateTimeField - Timestamp when the PO was issued to the vendor.
- acknowledgment_date: DateTimeField, nullable - Timestamp when the vendor
- acknowledged the PO.
- completion_date: DateTimeField - Timestamp when the vendor completed the order
This model optionally stores historical data on vendor performance, enabling trend analysis.
Fields:
- vendor: ForeignKey - Link to the Vendor model.
- date: DateTimeField - Date of the performance record.
- on_time_delivery_rate: FloatField - Historical record of the on-time delivery rate.
- quality_rating_avg: FloatField - Historical record of the quality rating average.
- average_response_time: FloatField - Historical record of the average response time.
- fulfillment_rate: FloatField - Historical record of the fulfilment rate.
This model is for customizing management of users in the system.
Fields:
- email: EmailField - Email of the user
- password: Predefined password field
- Open your terminal or command prompt.
- Navigate to the directory where you want to clone the repository.
- Run the following command to clone the repository:
git clone https://github.com/ksreyansh/vendor-management-system.git
- This will create a local copy of the repository on your machine.
- After cloning the repository, navigate into the project directory by running:
cd vendor-management-system
- It's recommended to use a virtual environment to manage dependencies for your Django project.
- Create a virtual environment by running:
python -m venv venv
- On Windows:
venv\Scripts\activate
- On macOS and Linux:
source venv/bin/activate
- With the virtual environment activated, install the project dependencies using pip:
pip install -r requirements.txt
- Configure Database: Open the settings.py file inside the vendor_management_system directory.
- In the DATABASES section, configure your database settings according to your preference. By default, Django uses SQLite for local development.
- Run the following command to apply migrations and set up the initial database schema:
python manage.py migrate
- If you want to access the Django admin interface, create a superuser account by running:
python manage.py createsuperuser
- Follow the prompts to enter a email, and password for the superuser.
- Start the development server by running:
python manage.py runserver
- This will start the development server, and you can access the Django project in a web browser at http://127.0.0.1:8000/.
The following are the details of all the API endpoints along with their usage description.
Login into the system
POST /auth/login/
Data parameters:
Parameter | Type | Description |
---|---|---|
email |
string |
Registered email |
password |
string |
Registered password |
Logs out the user
POST /auth/logout/
Gets details of all the vendors in the database
GET /api/vendor/
Fetches details of individual vendor by its unique identifier
GET /api/vendor/{vendor_code}/
Parameter | Type | Description |
---|---|---|
vendor_code |
string |
Unique identifier of the vendor |
Creates a new vendor profile with initial values being 0.0 for all the metrics
POST /api/vendor/
Updates details of the vendor by its unique identifier
PUT /api/vendor/{vendor_code}
Parameter | Type | Description |
---|---|---|
vendor_code |
string |
Unique identifier of the vendor |
Deletes a vendor profile
DELETE /api/vendor/{vendor_code}
Parameter | Type | Description |
---|---|---|
vendor_code |
string |
Unique identifier of the vendor |
Fetches details of all the purchase orders in the database
GET /api/purchase_orders/
Fetches details of a individual purchase order by its unique identifier
GET /api/purchase_orders/{po_number}/
Parameter | Type | Description |
---|---|---|
po_number |
string |
Unique identifier of the purchase order |
Creates a new purchase order
POST /api/purchase_orders/
Updates details of the order by its unique identifier
PUT /api/purchase_orders/{po_number}
Parameter | Type | Description |
---|---|---|
po_number |
string |
Unique identifier of the purchase order |
Deletes a purchase order
DELETE /api/purchase_orders/{po_number}
Parameter | Type | Description |
---|---|---|
po_number |
string |
Unique identifier of the purchase order |
This API endpoint is to simulate a vendor acknowledging a purchase order. This would trigger a signal in the backend which would calculate the average response time (performance metrics) of the vendor for historical performance of the vendor.
The signal also simulataneously updates the metrics in Vendor model.
PATCH performance/{po_number}/acknowledge/
Parameter | Type | Description |
---|---|---|
po_number |
string |
Unique identifier of the purchase order |
Fetches performance metrics for a vendor by unique identifier of the vendor
GET /api/vendor/{vendor_code}/performance/
Parameter | Type | Description |
---|---|---|
vendor_code |
string |
Fetches performance metrics for a vendor by unique identifier of the vendor |
The test suite for this package comes with the following tests
- Navigate to the directory containing the Django project (vendor_management_system).
- Run the following command to execute the test suite:
python manage.py test
Successful completion returns a message of the format "Test: TestName -> Completed" in the command prompt
The following is a brief description of the test cases defined for this application.
The authentication module consists of a custom user model (CustomUserModel) with a separate model manager for it
Purpose: Test the creation of a normal user.
- Steps:
- Create a user with a specified email and password.
- Assert that the user's email matches the specified email.
- Assert that the user is active, not a staff member, and not a superuser.
- Assert that the user does not have a username.
- Test various error cases:
- Attempt to create a user without any arguments.
- Attempt to create a user with an empty email.
- Attempt to create a user with an empty email and password.
Purpose: Test the creation of a superuser.
- Steps:
- Create a superuser with a specified email and password.
- Assert that the superuser's email matches the specified email.
- Assert that the superuser is active, a staff member, and a superuser.
- Assert that the superuser does not have a username.
- Test an error case:
- Attempt to create a superuser with an invalid is_superuser flag.
Purpose: Set up the necessary objects for API authentication testing.
- Steps:
- Create a custom user with a specified email and password.
- Generate an authentication token for the user.
Purpose: Test successful user login via API.
- Steps:
- Send a POST request to the login endpoint with valid credentials.
- Assert that the response status code is HTTP 200 OK.
- Assert that the response contains a token.
Purpose: Test user login failure due to invalid credentials via API.
- Steps:
- Send a POST request to the login endpoint with invalid credentials.
- Assert that the response status code is HTTP 401 UNAUTHORIZED.
- Assert that the response contains an error message.
Purpose: Test user login failure due to missing credentials via API.
- Steps:
- Send a POST request to the login endpoint without specifying the password.
- Assert that the response status code is HTTP 400 BAD REQUEST.
Purpose: Test user login failure due to using an invalid HTTP method via API.
- Steps:
- Send a GET request to the login endpoint.
- Assert that the response status code is HTTP 405 METHOD NOT ALLOWED.
Purpose: Set up the necessary objects for testing user logout via API.
- Steps:
- Create a superuser with a specified email and password.
- Generate an authentication token for the superuser.
- Set up an API client and force authentication with the superuser.
Purpose: Test successful user logout via API.
- Steps:
- Send a POST request to the logout endpoint with a valid token.
- Assert that the response status code is HTTP 200 OK.
- Assert that the response contains a success message.
Purpose: Test user logout failure due to using an invalid token via API.
- Steps:
- Send a POST request to the logout endpoint with an invalid token.
- Assert that the response status code is HTTP 401 UNAUTHORIZED.
- Assert that the response contains an error message.
Purpose: Set up necessary objects and data for testing GET requests related to vendors.
- Steps:
- Create a superuser for testing.
- Authenticate the test client with the superuser.
- Generate an authentication token for the superuser.
- Create ten sample vendor objects using Faker library for generating fake data.
Purpose: Test retrieving details of all vendors.
- Steps:
- Send a GET request to the endpoint for retrieving all vendors.
- Assert that the response status code is HTTP 200 OK.
- Assert that the number of retrieved vendors matches the expected count.
Purpose: Test retrieving details of a specific vendor by its ID.
- Steps:
- Send a GET request to the endpoint for retrieving a vendor by its ID.
- Assert that the response status code is HTTP 200 OK.
Purpose: Test retrieving details of a vendor with a non-existent ID.
- Steps:
- Send a GET request to the endpoint for retrieving a vendor with a non-existent ID.
- Assert that the response status code is HTTP 404 NOT FOUND.
Purpose: Set up necessary objects and data for testing POST requests related to vendors.
- Steps: Same as in VendorTestCaseGet.setUp().
Purpose: Test creating a new vendor.
- Steps:
- Send a POST request to the endpoint for creating a vendor with valid data.
- Assert that the response status code is HTTP 201 CREATED.
- Assert that the created vendor's details match the provided data.
Purpose: Test creating a new vendor with invalid data.
- Steps:
- Send a POST request to the endpoint for creating a vendor with invalid data.
- Assert that the response status code is HTTP 400 BAD REQUEST.
Purpose: Set up necessary objects and data for testing PUT requests related to vendors.
- Steps: Same as in VendorTestCaseGet.setUp().
Purpose: Test updating vendor details with valid data.
- Steps:
- Send a PUT request to the endpoint for updating a vendor's details with valid data.
- Assert that the response status code is HTTP 200 OK.
- Assert that the vendor's details have been updated as expected.
Purpose: Test updating vendor details with invalid data.
- Steps:
- Send a PUT request to the endpoint for updating a vendor's details with invalid data.
- Assert that the response status code is HTTP 400 BAD REQUEST.
Purpose: Set up necessary objects and data for testing DELETE requests related to vendors.
- Steps: Same as in VendorTestCaseGet.setUp().
Purpose: Test deleting a vendor.
- Steps:
- Send a DELETE request to the endpoint for deleting a vendor.
- Assert that the response status code is HTTP 204 NO CONTENT.
- Assert that the vendor has been deleted from the database.
Purpose: Test attempting to delete a non-existent vendor.
- Steps:
- Send a DELETE request to the endpoint for deleting a non-existent vendor.
- Assert that the response status code is HTTP 404 NOT FOUND.
Purpose: Set up necessary objects and data for testing GET requests related to purchase orders.
- Steps:
- Create a superuser for testing.
- Authenticate the test client with the superuser.
- Generate an authentication token for the superuser.
- Create a vendor object for testing.
- Create ten sample purchase order objects using Faker library for generating fake data.
Purpose: Test retrieving details of all purchase orders.
- Steps:
- Send a GET request to the endpoint for retrieving all purchase orders.
- Assert that the response status code is HTTP 200 OK.
- Assert that the number of retrieved purchase orders matches the expected count.
Purpose: Test retrieving details of a specific purchase order by its ID.
- Steps:
- Send a GET request to the endpoint for retrieving a purchase order by its ID.
- Assert that the response status code is HTTP 200 OK.
Purpose: Test retrieving details of a purchase order with a non-existent ID.
- Steps:
- Send a GET request to the endpoint for retrieving a purchase order with a non-existent ID.
- Assert that the response status code is HTTP 404 NOT FOUND.
Purpose: Set up necessary objects and data for testing POST requests related to purchase orders.
- Steps: Same as in POTestCaseSetUpGet.setUp().
Purpose: Test creating a new purchase order.
- Steps:
- Send a POST request to the endpoint for creating a purchase order with valid data.
- Assert that the response status code is HTTP 201 CREATED.
- Assert that the created purchase order's details match the provided data.
Purpose: Test creating a new purchase order with invalid data.
- Steps:
- Send a POST request to the endpoint for creating a purchase order with invalid data.
- Assert that the response status code is HTTP 400 BAD REQUEST.
Purpose: Set up necessary objects and data for testing PUT requests related to purchase orders.
- Steps: Same as in POTestCaseSetUpGet.setUp().
Purpose: Test updating purchase order details with valid data.
- Steps:
- Send a PUT request to the endpoint for updating a purchase order's details with valid data.
- Assert that the response status code is HTTP 200 OK.
- Assert that the purchase order's details have been updated as expected.
Purpose: Test updating purchase order details with invalid data.
- Steps:
- Send a PUT request to the endpoint for updating a purchase order's details with invalid data.
- Assert that the response status code is HTTP 400 BAD REQUEST.
Purpose: Set up necessary objects and data for testing DELETE requests related to purchase orders.
- Steps: Same as in POTestCaseSetUpGet.setUp().
Purpose: Test deleting a purchase order.
-Steps: 1. Send a DELETE request to the endpoint for deleting a purchase order. 2. Assert that the response status code is HTTP 204 NO CONTENT. 3. Assert that the purchase order has been deleted from the database.
Purpose: Test attempting to delete a non-existent purchase order.
- Steps:
- Send a DELETE request to the endpoint for deleting a non-existent purchase order.
- Assert that the response status code is HTTP 404 NOT FOUND.
Purpose: Set up necessary objects and data for testing the acknowledgment of purchase orders.
- Steps:
- Create a superuser for testing.
- Authenticate the test client with the superuser.
- Generate an authentication token for the superuser.
- Create a vendor object for testing.
- Create a sample purchase order object for testing acknowledgment.
Purpose: Test acknowledging a purchase order with a valid PO number.
- Steps:
- Send a PATCH request to the endpoint for acknowledging the purchase order.
- Assert that the response status code is HTTP 200 OK.
- Refresh the purchase order object from the database and assert that the acknowledgment date is not None.
Purpose: Test acknowledging a purchase order with an invalid PO number.
- Steps:
- Send a PATCH request to the endpoint for acknowledging a purchase order with an invalid PO number.
- Assert that the response status code is HTTP 404 NOT FOUND.
Purpose: Set up necessary objects and data for testing the acknowledgment of purchase orders.
- Steps:
- Create a superuser for testing.
- Authenticate the test client with the superuser.
- Generate an authentication token for the superuser.
- Create a vendor object for testing.
- Create a sample purchase order object for testing acknowledgment.
Purpose: Test acknowledging a purchase order with a valid PO number.
- Steps:
- Send a PATCH request to the endpoint for acknowledging the purchase order.
- Assert that the response status code is HTTP 200 OK.
- Refresh the purchase order object from the database and assert that the acknowledgment date is not None.
Purpose: Test acknowledging a purchase order with an invalid PO number.
- Steps:
- Send a PATCH request to the endpoint for acknowledging a purchase order with an invalid PO number.
- Assert that the response status code is HTTP 404 NOT FOUND.
Purpose: Set up necessary objects and data for testing historical performance data.
- Steps:
- Create a superuser for testing.
- Authenticate the test client with the superuser.
- Generate an authentication token for the superuser.
- Create a vendor object for testing.
- Create a sample historical performance data object for the vendor.
Purpose: Test retrieving historical performance data for a valid vendor.
- Steps:
- Send a GET request to the endpoint for retrieving performance data of the vendor.
- Assert that the response status code is HTTP 200 OK.
- Assert that the response contains data for one historical performance entry.
- Assert that the vendor code in the response matches the vendor code used for testing.
Purpose: Test retrieving historical performance data for an invalid vendor.
-
Steps:
- Send a GET request to the endpoint for retrieving performance data of an invalid vendor.
- Assert that the response status code is HTTP 404 NOT FOUND.
-
(Thank you for considering my application)