Offerclient Documentation

Offer Client Controller Documentation

File: /controllers/offerclient.php

Purpose: Manages client product offers including creation, viewing, editing, and product detail management

Last Updated: December 20, 2024

Total Functions: 2

Lines of Code: ~234

---

๐Ÿ“‹ Overview

The Offer Client Controller handles the creation and management of product offers for clients. It provides functionality to:

Primary Functions

Related Controllers

---

๐Ÿ—„๏ธ Database Tables

Primary Tables (Direct Operations)

Table NamePurposeKey Columns
**offerclient**Offer master recordsid, datenow, userid, del, client, mydate, alltotal, allquantity, allquantstore, pricestore, allquantavailable, priceavailable, allquantmiun, pricemiun, oldoffer
**offerproduct**Offer product line itemsclientid (offer id), productid, quantity, storequant, availablequant, miunquant, price, total
### Reference Tables

Table NamePurposeKey Columns
**client**Customer master dataclientid, clientname, clientphone, clientmobile
**product**Product master dataproductId, productName, logo, productprice
---

๐Ÿ”‘ Key Functions

1. Default Action (Empty $do) - Offer Creation Form

Location: Lines 75-80

Purpose: Display offer creation form

Function Signature:

// Triggered when: empty $do
// Displays: offerclient/add.html template

Process Flow:

1. Include authentication check

2. Display offer creation form template

3. Allow user to add products and client information

---

2. add() - Create New Offer

Location: Lines 161-230

Purpose: Process offer creation with product details

Function Signature:

function add()

Process Flow:

1. Extract form data for offer header

2. Create offer master record with totals

3. Process each product line item

4. Store quantities and pricing information

5. Link to original offer if exists

Key Variables Processed:

$oldoffer = filter_input(INPUT_POST, 'oldoffer');
$datenow = date("Y-m-d");
$userid = $_SESSION["userid"];
$del = 0;
$client = filter_input(INPUT_POST, 'client');
$mydate = filter_input(INPUT_POST, 'mydate');
$alltotal = filter_input(INPUT_POST, 'alltotal');
$allquantity = filter_input(INPUT_POST, 'allquantity');
$allquantstore = filter_input(INPUT_POST, 'allquantstore');
$allquantavailable = filter_input(INPUT_POST, 'allquantavailable');
$allquantminus = filter_input(INPUT_POST, 'allquantminus');

Product Processing Logic:

$itr = filter_input(INPUT_POST, 'itr'); // Number of products
for ($i = 1; $i <= $itr; $i++) {
    if (isset($_POST['product' . $i]) && !empty($_POST['product' . $i])) {
        $product = filter_input(INPUT_POST, 'product' . $i);
        $quantproduct = filter_input(INPUT_POST, 'quantity' . $i);
        $quantstore = filter_input(INPUT_POST, 'prostore' . $i);
        $quantavailable = filter_input(INPUT_POST, 'proavailable' . $i);
        $quantminus = filter_input(INPUT_POST, 'prominus' . $i);
        $price = filter_input(INPUT_POST, 'price' . $i);
        $total = filter_input(INPUT_POST, 'total' . $i);
        
        $offerProduct->clientid = $id; // Offer ID
        $offerProduct->productid = $product;
        $offerProduct->quantity = $quantproduct;
        $offerProduct->storequant = $quantstore;
        $offerProduct->availablequant = $quantavailable;
        $offerProduct->miunquant = $quantminus;
        $offerProduct->price = $price;
        $offerProduct->total = $total;
        
        $offerProductDAO->insert($offerProduct);
    }
}

---

3. show - Offer Listing

Location: Lines 94-102

Purpose: Display all offers with client information

Process Flow:

1. Query all offer client records

2. Load client names using RedBeanPHP

3. Assign data to template

4. Display offer listing

Client Name Enhancement:

foreach ($allclient as $client) {
    $proclient = R::findOne('client', 'clientid = ' . $client->client);
    $client->proclient = $proclient->clientname;
}

---

4. detail - Offer Details View

Location: Lines 104-121

Purpose: Display detailed offer information with all products

Process Flow:

1. Load offer client data by ID

2. Get client information

3. Query all offer products

4. Enhance products with logos and names

5. Display detailed view

Product Enhancement:

foreach ($offerProduct as $offerPro) {
    $productid = $ProductDAO->load($offerPro->productid);
    $offerPro->prologo = $productid->logo;
    $offerPro->proname = $productid->productName;
}

---

5. edit - Offer Editing Form

Location: Lines 122-145

Purpose: Load offer data for editing

Process Flow:

1. Load existing offer data

2. Get client information

3. Load all offer products with details

4. Enhance products with logos, names, and IDs

5. Display edit form with populated data

Product Data Enhancement for Editing:

foreach ($offerProduct as $offerPro) {
    $productid = $ProductDAO->load($offerPro->productid);
    $offerPro->prologo = $productid->logo;
    $offerPro->proname = $productid->productName;
    $offerPro->id = $productid->id; // Added for editing form
}

---

๐Ÿ”„ Workflows

Workflow 1: Client Offer Creation

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
START: Create New Client Offer
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
1Display Offer Form
- Select client
- Add multiple products
- Set quantities for each product
- Define store/available/shortage quantities
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
2Process Form Submission
- Validate client and product selections
- Calculate total quantities and prices
- Prepare offer header data
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
3Save Offer Data
- Insert offerclient master record
- Insert offerproduct records for each item
- Store quantity breakdowns
- Link to original offer if applicable
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
4Confirmation
- Display success message
- Redirect to success page
- Offer ready for order conversion
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

---

๐ŸŒ URL Routes & Actions

URL ParameterFunction CalledDescription
`do=` (empty)Default actionOffer creation form
`do=add``add()`Process offer creation
`do=show`Show actionList all offers with client info
`do=detail`Detail actionShow detailed offer information
`do=edit`Edit actionOffer editing form
`do=sucess`Success templateSuccess confirmation
`do=error`Error templateError display
### Required Parameters by Action

Offer Creation (do=add):

Offer Details (do=detail):

Offer Edit (do=edit):

---

๐Ÿงฎ Calculation Methods

Quantity Tracking System

// Three-tier quantity tracking
$storequant = filter_input(INPUT_POST, 'prostore' . $i);      // In store
$availablequant = filter_input(INPUT_POST, 'proavailable' . $i); // Available
$miunquant = filter_input(INPUT_POST, 'prominus' . $i);       // Shortage

// Total calculations across all products
$allquantstore += $storequant;         // Sum of store quantities
$allquantavailable += $availablequant; // Sum of available quantities
$allquantminus += $miunquant;          // Sum of shortage quantities

Pricing Calculations

// Line item total
$total = filter_input(INPUT_POST, 'total' . $i); // price * quantity

// Offer totals
$alltotal = array_sum($all_line_totals);
$pricestore = $price_for_store_quantity;
$priceavailable = $price_for_available_quantity;
$pricemiun = $price_for_shortage_quantity;

Offer Reference Tracking

$oldoffer += 0; // Convert to numeric, reference to previous offer
// Used for tracking offer history and revisions

---

๐Ÿ”’ Security & Permissions

Authentication Requirements

// All actions require authentication
include_once("../public/authentication.php");

Input Sanitization

// All inputs properly sanitized
$client = filter_input(INPUT_POST, 'client');
$product = filter_input(INPUT_POST, 'product' . $i);
$quantproduct = filter_input(INPUT_POST, 'quantity' . $i);
$price = filter_input(INPUT_POST, 'price' . $i);

Session Management

$userid = $_SESSION["userid"]; // Track offer creator
$datenow = date("Y-m-d");      // System date stamp

---

๐Ÿ“Š Performance Considerations

Database Optimization Tips

1. Indexes Required:

- offerclient(client, mydate)

- offerproduct(clientid, productid)

- client(clientid)

- product(productId)

2. Query Optimization:

- Batch product loading by offer ID

- Efficient client name lookups

- Proper use of foreign key relationships

3. Memory Management:

- Process products in iterations to handle large offers

- Clean up product arrays after processing

- Limit concurrent offer creation

Known Performance Issues

// N+1 query issue in client name loading
foreach ($allclient as $client) {
    $proclient = R::findOne('client', 'clientid = ' . $client->client);
    // Better: JOIN query to get all client names at once
}

---

๐Ÿ› Common Issues & Troubleshooting

1. Missing Product Information

Issue: Products show without names or logos in detail view

Cause: Product loading failure or deleted products

Debug:

SELECT op.*, p.productName, p.logo 
FROM offerproduct op 
LEFT JOIN product p ON p.productId = op.productid 
WHERE op.clientid = [OFFER_ID];

2. Quantity Calculation Errors

Issue: Total quantities don't match sum of line items

Cause: Invalid or missing quantity inputs

Fix: Add validation:

// Ensure numeric values
$quantproduct = (int) filter_input(INPUT_POST, 'quantity' . $i);
$quantstore = (int) filter_input(INPUT_POST, 'prostore' . $i);
$quantavailable = (int) filter_input(INPUT_POST, 'proavailable' . $i);

// Validate quantities are positive
if ($quantproduct <= 0) continue;

3. Client Name Display Issues

Issue: Client names showing as null

Cause: Client ID mismatch or deleted clients

Debug:

-- Check client existence
SELECT * FROM client WHERE clientid IN (
    SELECT DISTINCT client FROM offerclient WHERE del = 0
);

4. Offer Total Mismatch

Issue: Offer totals don't match line item sums

Cause: JavaScript calculation errors or form manipulation

Server-side Verification:

$serverTotal = 0;
for ($i = 1; $i <= $itr; $i++) {
    $price = (float) filter_input(INPUT_POST, 'price' . $i);
    $quantity = (int) filter_input(INPUT_POST, 'quantity' . $i);
    $serverTotal += ($price * $quantity);
}

if (abs($serverTotal - $alltotal) > 0.01) {
    // Handle total mismatch
    throw new Exception("Total mismatch detected");
}

---

๐Ÿงช Testing Scenarios

Test Case 1: Basic Offer Creation

1. Access offer creation form
2. Select valid client
3. Add multiple products with different quantities
4. Set store/available/shortage amounts
5. Submit form
6. Verify offerclient and offerproduct records created
7. Check all totals calculated correctly

Test Case 2: Offer with Product Variants

1. Create offer with same product, different quantities
2. Test different store/available combinations
3. Verify each line item stored correctly
4. Check total calculations across variants

Test Case 3: Offer Editing

1. Create test offer
2. Load edit form with existing data
3. Modify quantities and products
4. Submit changes
5. Verify updates applied correctly
6. Check data integrity maintained

Test Case 4: Large Offer Handling

1. Create offer with 50+ products
2. Test form submission performance
3. Verify all products processed
4. Check memory usage and timeouts

---

๐Ÿ“š Related Documentation

---

Documented By: AI Assistant

Review Status: โœ… Complete

Next Review: When major changes occur