SaveType Documentation

Save Type Controller Documentation

File: /controllers/saveTypeController.php

Purpose: Manages cash register/safe categories and types for organizational classification

Last Updated: December 20, 2024

Total Functions: 5 operations

Lines of Code: ~74

---

๐Ÿ“‹ Overview

The Save Type Controller is a simple CRUD (Create, Read, Update, Delete) management system for categorizing different types of cash registers and safes. It provides the foundational classification system that helps organize cash storage locations by their purpose, location, or operational characteristics.

Primary Functions

Related Controllers

---

๐Ÿ—„๏ธ Database Tables

Primary Table (Direct Operations)

Table NamePurposeKey Columns
**savetype**Save type definitionsid, name, del, adddate, adduserid, updatedate, updateuserid, deldate, deluserid
Table Structure:

CREATE TABLE savetype (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    del TINYINT DEFAULT 0,           -- 0=active, 1=updated, 2=deleted
    adddate DATETIME,                -- Creation timestamp
    adduserid INT,                   -- User who created
    updatedate DATETIME,             -- Last update timestamp
    updateuserid INT,                -- User who last updated
    deldate DATETIME,                -- Deletion timestamp
    deluserid INT                    -- User who deleted
);

---

๐Ÿ”‘ Key Functions

1. Default Action - Add Form Display

Location: Lines 7-10

Purpose: Display form for creating new save types

Process Flow:

1. Display header template

2. Show add form template

3. Display footer template

Template: savetypeview/add.html

---

2. show() - Display Save Types List

Location: Lines 11-16

Purpose: Show all active save types with management options

Process Flow:

1. Query all save types with del < 2 (exclude hard-deleted)

2. Assign data to template

3. Display list with edit/delete options

Query:

$savetype = R::findAll('savetype','del < 2');

Template: savetypeview/show.html

---

3. edit() - Edit Form Display

Location: Lines 17-23

Purpose: Display edit form for existing save type

Process Flow:

1. Get save type ID from GET parameter

2. Load save type data by ID

3. Display edit form with current values

Template: savetypeview/edit.html

---

4. savedata() - Save/Update Save Type

Location: Lines 24-46

Purpose: Handle both new creation and updates of save types

Function Logic:

$name = filter_input(INPUT_POST, 'name');
$id = filter_input(INPUT_POST, 'id');

if (!$id) {
    // CREATE NEW
    $savetype = R::dispense('savetype');
    $savetype->del = 0;
    $savetype->adddate = date("Y-m-d H:i:s");        
    $savetype->adduserid = $_SESSION['userid'];
    $savetype->deldate = '';      
    $savetype->deluserid = '';
} else {
    // UPDATE EXISTING
    $savetype = R::load('savetype', $id);
    $savetype->del = 1;  // Mark as updated
    $savetype->updatedate = date("Y-m-d H:i:s");         
    $savetype->updateuserid = $_SESSION['userid'];
}

$savetype->name = $name;
R::store($savetype);

Process Flow:

1. Determine Operation: Check if ID provided (update) or not (create)

2. Create New: Dispense new bean with creation metadata

3. Update Existing: Load existing bean and set update metadata

4. Set Data: Assign name and save to database

5. Redirect: Return to show page on success

---

5. delete() - Soft Delete Save Type

Location: Lines 47-54

Purpose: Mark save type as deleted without removing from database

Process Flow:

1. Get save type ID from GET parameter

2. Load save type record

3. Mark as deleted (del = 2)

4. Set deletion metadata

5. Save changes and redirect

Deletion Logic:

$id = filter_input(INPUT_GET, 'id');
$tables = R::load('savetype', $id);
$tables->del = 2;  // Soft delete
$tables->deldate = date("Y-m-d H:i:s");
$tables->deluserid = $_SESSION['userid'];
R::store($tables);

---

6. savetype - AJAX Search

Location: Lines 55-70

Purpose: Provide AJAX search functionality for dropdown selection

Function Signature:

// POST parameter
$name = $_POST['searchTerm'];  // Search query

Process Flow:

1. Get search term from POST

2. Query save types with LIKE matching

3. Format results for Select2/dropdown

4. Return JSON response

Query & Response:

$allSaveType = R::getAll("SELECT id, name as name
                         FROM savetype 
                         WHERE del < 2 and name LIKE '%" . $name . "%' 
                         limit 50");

foreach ($allSaveType as $pro) {
    $row_array['id'] = $pro['id'];
    $row_array['text'] = $pro['name'];
    array_push($return_arr, $row_array);
}

echo json_encode($return_arr);

Response Format:

[
    {"id": 1, "text": "Main Safe"},
    {"id": 2, "text": "Cash Register 1"},
    {"id": 3, "text": "Petty Cash"}
]

---

๐Ÿ”„ Workflows

Workflow 1: Create New Save Type

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
START: Create New Save Type
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
1Display Add Form
- Show empty form
- Include name input field
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
2User Input
- Enter save type name
- Submit form
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
3Process Creation
- Validate input
- Create new record with metadata
- Set creation timestamp and user
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
4Save and Redirect
- Store in database
- Redirect to list view
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

---

Workflow 2: Edit Save Type

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
START: Edit Save Type
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
1Load Edit Form
- Get save type ID from URL
- Load current data
- Display pre-filled form
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
2User Modification
- Modify save type name
- Submit updated form
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
3Process Update
- Load existing record
- Mark as updated (del = 1)
- Set update timestamp and user
- Update name field
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
4Save and Redirect
- Store changes in database
- Redirect to list view
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

---

๐ŸŒ URL Routes & Actions

URL ParameterFunction CalledDescription
(empty)Default actionDisplay add form
`do=show`Show listDisplay all save types
`do=edit`Edit formDisplay edit form
`do=savedata`Save/UpdateProcess form submission
`do=delete`DeleteSoft delete save type
`do=savetype`AJAX searchReturn JSON for dropdowns
### Required Parameters by Action

Display Form (empty do):

Show List (do=show):

Edit Form (do=edit):

Save Data (do=savedata):

Delete (do=delete):

AJAX Search (do=savetype):

---

๐Ÿงฎ Calculation Methods

Status Flag Logic

// Save type status meanings
$del = 0;  // Active/New record
$del = 1;  // Updated record  
$del = 2;  // Soft deleted record

// Query active records
WHERE del < 2  // Shows active and updated records
WHERE del = 0  // Shows only new/unmodified records
WHERE del = 2  // Shows only deleted records

AJAX Search Scoring

// Simple LIKE matching with limit
WHERE name LIKE '%searchterm%' LIMIT 50

---

๐Ÿ”’ Security & Permissions

Authentication

Input Validation

$name = filter_input(INPUT_POST, 'name');
$id = filter_input(INPUT_POST, 'id');

Validation Rules:

Data Integrity

---

๐Ÿ“Š Performance Considerations

Database Optimization

1. Indexes Recommended:

- savetype(del) for filtering active records

- savetype(name) for search functionality

- savetype(id, del) composite for specific lookups

2. Query Efficiency:

- Simple SELECT queries with minimal JOINs

- LIMIT clause on search results

- Proper WHERE clause usage

Memory Management

Known Performance Issues

// Potential issue: No input sanitization for LIKE search
WHERE name LIKE '%" . $name . "%'
// Consider: Prepared statements or proper escaping for search terms

---

๐Ÿ› Common Issues & Troubleshooting

1. Duplicate Save Type Names

Issue: Multiple save types with same name created

Cause: No uniqueness constraint or validation

Fix: Add name uniqueness check before creation

$existing = R::findOne('savetype', 'name = ? AND del < 2', [$name]);
if ($existing) {
    // Handle duplicate error
}

2. AJAX Search Not Working

Issue: Dropdown search returns no results

Cause: Incorrect search parameter or query

Debug:

// Add debugging to AJAX function
error_log("Search term: " . $name);
error_log("Query results: " . print_r($allSaveType, true));

3. Soft Delete Confusion

Issue: "Deleted" records still appear in some lists

Cause: Inconsistent use of del flag filtering

Fix: Standardize queries to use WHERE del < 2

4. Session Issues

Issue: User ID not recorded in audit fields

Cause: Session not properly initialized

Debug:

if (!isset($_SESSION['userid'])) {
    echo "Session not initialized";
}

---

๐Ÿงช Testing Scenarios

Test Case 1: Create Save Type

1. Access save type management
2. Click add new save type
3. Enter descriptive name
4. Submit form
5. Verify record appears in list
6. Check audit fields populated

Test Case 2: Edit Save Type

1. Select existing save type for edit
2. Modify name
3. Submit changes
4. Verify updated name appears
5. Check del flag set to 1
6. Verify update timestamps

Test Case 3: Delete Save Type

1. Select save type for deletion
2. Confirm deletion
3. Verify record no longer in list
4. Check del flag set to 2
5. Verify delete timestamp set

Test Case 4: AJAX Search

1. Access dropdown with save type search
2. Enter partial name
3. Verify matching results appear
4. Check JSON format correct
5. Test with no matches

Test Case 5: Bulk Operations

1. Create multiple save types
2. Edit some records
3. Delete some records
4. Verify list shows correct statuses
5. Check audit trail completeness

Debug Mode Enable

// Add debugging at top of file
error_reporting(E_ALL);
ini_set('display_errors', 1);

// Debug save operations
echo "Name: $name<br>";
echo "ID: $id<br>";
echo "User ID: " . $_SESSION['userid'] . "<br>";

---

๐Ÿ“š Related Documentation

---

Documented By: AI Assistant

Review Status: โœ… Complete

Next Review: When major changes occur