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:
- โข Create new offers with multiple products
- โข Display offer listings with client information
- โข View detailed offer information including products
- โข Edit existing offers and their products
- โข Manage offer product quantities and pricing
- โข Track inventory availability and shortage data
Primary Functions
- โ Create client offers with multiple products
- โ Display offer forms with product selection
- โ Manage offer product quantities and pricing
- โ Track store quantities vs. available vs. shortage amounts
- โ Show offer listings with client details
- โ Provide detailed offer viewing capabilities
- โ Enable offer editing and updates
Related Controllers
- โข offerorder.php - Order creation from offers
- โข clientController.php - Customer management
- โข productController.php - Product management
- โข sellbillController.php - Sales processing
---
๐๏ธ Database Tables
Primary Tables (Direct Operations)
| Table Name | Purpose | Key Columns | |
|---|---|---|---|
| **offerclient** | Offer master records | id, datenow, userid, del, client, mydate, alltotal, allquantity, allquantstore, pricestore, allquantavailable, priceavailable, allquantmiun, pricemiun, oldoffer | |
| **offerproduct** | Offer product line items | clientid (offer id), productid, quantity, storequant, availablequant, miunquant, price, total |
| Table Name | Purpose | Key Columns | |
|---|---|---|---|
| **client** | Customer master data | clientid, clientname, clientphone, clientmobile | |
| **product** | Product master data | productId, 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
---
๐ URL Routes & Actions
| URL Parameter | Function Called | Description | |
|---|---|---|---|
| `do=` (empty) | Default action | Offer creation form | |
| `do=add` | `add()` | Process offer creation | |
| `do=show` | Show action | List all offers with client info | |
| `do=detail` | Detail action | Show detailed offer information | |
| `do=edit` | Edit action | Offer editing form | |
| `do=sucess` | Success template | Success confirmation | |
| `do=error` | Error template | Error display |
Offer Creation (do=add):
- โข
client- Client ID - โข
mydate- Offer date - โข
alltotal- Total offer value - โข
allquantity- Total quantity - โข
allquantstore- Total store quantity - โข
allquantavailable- Total available quantity - โข
allquantminus- Total shortage quantity - โข
itr- Number of product iterations - โข
product{N}- Product ID for line N - โข
quantity{N}- Quantity for product N - โข
price{N}- Price for product N
Offer Details (do=detail):
- โข
id- Offer client ID
Offer Edit (do=edit):
- โข
id- Offer client ID
---
๐งฎ 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
- โข CLAUDE.md - PHP 8.2 migration guide
- โข offerorder.md - Order creation from offers
- โข sellbillController.md - Sales processing
- โข Database Schema Documentation - Table relationships
---
Documented By: AI Assistant
Review Status: โ Complete
Next Review: When major changes occur