Skip to content

A comprehensive inventory management system for a retail business is developed by applying my knowledge in object-oriented programming (OOP) in Python. The imaginary e-commerce company called ShopSmart, a rapidly growing online retailer that sells a wide range of products, including electronics, clothing, and home goods. As the company expands, efficiently managing inventory becomes crucial to ensure smooth operations and customer satisfaction.

Object-oriented programming (OOP) is a programming paradigm that organizes software design around data or objects rather than functions and logic. OOP allows for modular, reusable, and maintainable code, which is particularly beneficial for complex systems like inventory management systems.

class Product:
    inventory = []
    def __init__(self, product_id, name, category, quantity, price, supplier):
        self.product_id = product_id
        self.name = name
        self.category = category
        self.quantity = quantity
        self.price = price
        self.supplier = supplier
        
    def add_product(cls, name, category, quantity, price, supplier):
        product_id = len(inventory)
        new_product = Product(product_id, name, category, quantity, price, supplier)
        inventory.append(new_product)
        
        print("Product added successfully")

    def update_product(cls, product_id, quantity=None, price=None, supplier=None):
        for product in inventory:
            if product_id == product.product_id:
                if quantity is not None:
                    product.quantity = quantity
                if price is not None:
                    product.price = price
                if supplier is not None:
                    product.supplier = supplier
                print("Product information updated successfully")
            else:
                print("Product not found")
            
    def delete_product(cls, product_id):
        for product in inventory:
            if product_id == product.product_id:
                inventory.remove(product)
                print("Product not found")
            else:
                print("Product deleted successfully")
       
                
        
    


class Order:
    products = []
    def __init__(self, order_id, products, customer_info=None):
        self.order_id = order_id
        self.products = products
        self.customer_info = customer_info

    def place_order(self, product_id, quantity, customer_info=None):
        products.append(tuple(product_id, quantity))
        print("Order placed successfully. Order ID: {self.order_id}")
            

You will define two classes Product and Order, using the implementation requirements detailed below:

Product

  • Constructor parameter(s): self, product_id, name, category, quantity, price, and supplier.
  • Class-level variable(s): inventory.

Product class method(s)

add_product()

  • Parameter(s): cls, name, category, quantity, price, and supplier.
  • Behavior:
    • Define the product_id assuming it's auto-generated incrementally, without any duplicate product_id values.
    • Define a new_product variable that will call the constructor of the Product class.
    • Return the message "Product added successfully" to know that the product was added successfully.

update_product()

  • Parameter(s): cls, product_id, quantity, price, and supplier.
    • quantity, price, and supplier should have default values of None.
  • Behavior:
    • Check if the product_id already exists in the inventory.
    • If product_id exists, check for the given parameters in the method if they have a value and update accordingly the product.
    • Return either one of these messages: "Product information updated successfully" or "Product not found".

delete_product()

  • Parameter(s): cls, product_id.
  • Behavior:
    • Check in the inventory list if the given product_id was passed as a parameter.
    • If product_id exists then remove the product from the list.
    • Return either one of these messages: "Product deleted successfully" or "Product not found".

Order

  • Constructor parameter(s): self, order_id, products, and customer_info.
    • customer_info should have a default value of None.

Order method(s)

place_order()

  • Parameter(s): self, product_id, quantity, and customer_info.
    • customer_info should have a default value of None.
  • Behavior:
    • Append to the products list a tuple containing product_id and quantity.
    • Assume that each order can only take one product.
    • Return the message: "Order placed successfully. Order ID: {self.order_id}".

As an example, your code must be able to create products like this:

p1 = Product.add_product("Laptop", "Electronics", 50, 1000, "Supplier A")

Update them like this:

update_p1 = Product.update_product(1, quantity=45, price=950)

Delete them like this:

delete_p1 = Product.delete_product(1)

And, create and place orders like this:

order = Order(order_id=1, products=[])

order_placement = order.place_order(1, 2, customer_info="John Doe")

Complete the following code so that the classes perform the same behavior as the examples provided.

from openai import OpenAI
client = OpenAI()
prompt = """
You are a senior QA engineer. Your task is to design a comprehensive test suite (manual + automated) for an Object-Oriented retail Inventory Management program.

## System Under Test (SUT)
Use the following Python code as the program under test (do not change it; treat defects as findings to be reported):
```python
class Product:
    inventory = []
    def __init__(self, product_id, name, category, quantity, price, supplier):
        self.product_id = product_id
        self.name = name
        self.category = category
        self.quantity = quantity
        self.price = price
        self.supplier = supplier
        
    def add_product(cls, name, category, quantity, price, supplier):
        product_id = len(inventory)
        new_product = Product(product_id, name, category, quantity, price, supplier)
        inventory.append(new_product)
        
        print("Product added successfully")

    def update_product(cls, product_id, quantity=None, price=None, supplier=None):
        for product in inventory:
            if product_id == product.product_id:
                if quantity is not None:
                    product.quantity = quantity
                if price is not None:
                    product.price = price
                if supplier is not None:
                    product.supplier = supplier
                print("Product information updated successfully")
            else:
                print("Product not found")
            
    def delete_product(cls, product_id):
        for product in inventory:
            if product_id == product.product_id:
                inventory.remove(product)
                print("Product not found")
            else:
                print("Product deleted successfully")
       
                
        
    


class Order:
    products = []
    def __init__(self, order_id, products, customer_info=None):
        self.order_id = order_id
        self.products = products
        self.customer_info = customer_info

    def place_order(self, product_id, quantity, customer_info=None):
        products.append(tuple(product_id, quantity))
        print("Order placed successfully. Order ID: {self.order_id}")
            
```

## Goals
1) Produce a structured **manual test plan** and **automated test skeletons** that validate core behaviors of the `Product` and `Order` classes.
2) Identify and list **defects/risks/ambiguities** discovered from reading the code (e.g., classmethod usage, shared state, incorrect messages, invalid method calls, missing validations).
3) Ensure coverage of **happy paths**, **edge cases**, and **negative scenarios**.

## Assumptions & Scope
- Inventory is an in-memory list.
- Product fields: `product_id`, `name`, `category`, `quantity`, `price`, `supplier`.
- Orders contain a list of `(product_id, quantity)` pairs and optional `customer_info`.
- If behavior is missing/undefined, state the assumption and test accordingly; also log it as a defect or open question.

## Deliverables

### A) Defect Triage (from static reading)
- Provide a bullet list of specific defects and code smells you see (e.g., methods marked with `cls` but lacking `@classmethod`, inconsistent use of `inventory` vs `self.inventory`, incorrect success/failure messages, `tuple()` misuse in `place_order`, global vs instance state, missing stock checks, missing return values, etc.). For each, include **impact** and **suggested fix**.

### B) Manual Test Cases (Markdown table)
Create a table with columns:
`ID | Title | Preconditions/Test Data | Steps | Expected Result | Notes`

Include at least these categories:
1. **Product Creation**
   - Valid product add
   - Duplicate ID handling
   - Boundary values for `quantity` (0, max int) and `price` (0.00, negative, very large)
   - Required fields missing or None
2. **Product Update**
   - Update only `quantity`
   - Update only `price`
   - Update only `supplier`
   - Update non-existent `product_id`
   - Concurrency-like scenario (simulate sequential rapid updates)
3. **Product Deletion**
   - Delete existing product
   - Delete non-existent product
   - Verify inventory length and contents after deletion
4. **Order Placement**
   - Add order with one product and sufficient stock (if stock decrements are expected; if not implemented, mark as defect)
   - Add order with multiple products
   - Add order with invalid `product_id`
   - Add order with quantity > available stock (expect rejection or defect)
   - Verify that order confirmation message uses the actual `order_id`
5. **Data Integrity & Messaging**
   - Verify printed messages match actual outcomes (e.g., “Product deleted successfully” only when deletion occurs)
   - Ensure no partial updates on failure paths
6. **Security & Validation (lightweight)**
   - Reject negative quantities/prices
   - Reject non-numeric quantities/prices
7. **State Management**
   - Shared class-level lists (`inventory`, `products`) isolation across tests
   - Tests that run independently (setUp/tearDown to reset state)

Provide at least **20** cases covering the above.

### C) Automated Tests (pytest skeleton)
Provide executable pytest-style test stubs that:
- Use `setup_function`/fixtures to **reset global state** between tests.
- Assert both **state changes** (inventory length, field values) and **side effects** (printed messages). For prints, capture stdout via `capsys`.
- Include tests that **demonstrate current defects** (expected to fail) and mark them with `xfail` and a reason.
- Name tests clearly, e.g., `test_add_product_valid()`, `test_update_product_not_found()`, `test_delete_product_message_inversion_defect()`, `test_place_order_tuple_misuse_defect()`.
- Where behavior is ambiguous, add TODO comments with assumptions.

### D) Coverage Matrix
Provide a small matrix mapping **requirements/behaviors** → **test IDs** to show coverage.

### E) Execution Instructions
- How to run the pytest suite locally (commands).
- How to structure the repository (e.g., `app.py`, `tests/test_inventory.py`).
- How to re-run only failing tests; how to view captured print output.

## Constraints & Quality Bar
- Manual tests: concise but unambiguous, each with deterministic expected results.
- Automated tests: runnable with `pytest` and standard library only.
- Use **clear, professional Markdown** formatting.
- Do **not** invent new features; when missing, call it out as a defect or assumption.

Ensure your response is in markdown. Delineate code snippets with ``` before the snippet starts and after the end.
"""
response = client.chat.completions.create(
        model="gpt-5",
        messages=[{ "role": "user", "content": prompt}],
    )
response = response.choices[0].message.content
from IPython.display import Markdown, display

display(Markdown(response))