# POS System - Developer Guide

## Table of Contents
1. [System Overview](#system-overview)
2. [Architecture](#architecture)
3. [Development Environment Setup](#development-environment-setup)
4. [Project Structure](#project-structure)
5. [Modern Typography System](#modern-typography-system)
6. [Adding New Features](#adding-new-features)
7. [Bug Fixing Guidelines](#bug-fixing-guidelines)
8. [Code Standards](#code-standards)
9. [Database Schema](#database-schema)
10. [API Documentation](#api-documentation)
11. [Testing](#testing)
12. [Deployment](#deployment)

---

## System Overview

This is a comprehensive Point of Sale (POS) system built with PHP CodeIgniter framework, MySQL database, and modern web technologies including Bootstrap, jQuery, and AdminLTE.

### Technology Stack
- **Backend**: PHP 7.x+ with CodeIgniter 3.x framework
- **Frontend**: HTML5, CSS3, JavaScript (ES5/ES6), jQuery
- **UI Framework**: Bootstrap 3.x with AdminLTE 2.x theme
- **Database**: MySQL 5.7+
- **Server**: Apache (XAMPP recommended for local development)
- **Additional Libraries**:
  - DataTables for table management
  - Select2 for enhanced dropdowns
  - DateRangePicker for date selection
  - Chart.js for data visualization

---

## Architecture

### MVC Pattern
The application follows CodeIgniter's MVC (Model-View-Controller) architecture:

```
application/
├── controllers/     # Business logic and request handling
├── models/         # Database interactions and data manipulation
├── views/          # UI templates and presentation layer
├── libraries/      # Custom libraries and helpers
└── config/         # Configuration files
```

### Key Components

1. **Controllers**: Handle HTTP requests, process data, load models/views
2. **Models**: Database operations, data validation, business rules
3. **Views**: HTML templates with embedded PHP
4. **Libraries**: Reusable components (PDF generation, barcode, etc.)

---

## Development Environment Setup

### Prerequisites
- XAMPP (Apache + PHP 7.x + MySQL)
- Git for version control
- Code editor (VS Code, Sublime Text, PHPStorm)
- Modern web browser (Chrome, Firefox)

### Installation Steps

1. **Install XAMPP**
   ```bash
   Download from: https://www.apachefriends.org/
   Install to default directory: C:\xampp
   ```

2. **Clone/Download Project**
   ```bash
   cd C:\xampp\htdocs
   git clone <repository-url> pos
   # OR extract ZIP to C:\xampp\htdocs\pos
   ```

3. **Configure Database**
   ```bash
   # Start XAMPP Control Panel
   # Start Apache and MySQL services
   # Access phpMyAdmin: http://localhost/phpmyadmin
   ```

4. **Import Database**
   - Create new database: `pos_system`
   - Import SQL file from `/database/pos_system.sql`
   - Update database credentials in `application/config/database.php`

5. **Configure Application**
   ```php
   // application/config/config.php
   $config['base_url'] = 'http://localhost/pos/';

   // application/config/database.php
   $db['default'] = array(
       'hostname' => 'localhost',
       'username' => 'root',
       'password' => '',
       'database' => 'pos_system'
   );
   ```

6. **Set Permissions** (Linux/Mac)
   ```bash
   chmod -R 755 application/
   chmod -R 777 uploads/
   ```

7. **Access Application**
   - URL: `http://localhost/pos/`
   - Default login credentials in database

---

## Project Structure

```
pos/
├── application/
│   ├── controllers/
│   │   ├── Auth.php              # Authentication controller
│   │   ├── Dashboard.php         # Dashboard controller
│   │   ├── Products.php          # Product management
│   │   ├── Sales.php             # Sales/POS operations
│   │   ├── Customers.php         # Customer management
│   │   ├── Reports.php           # Reporting functionality
│   │   └── Settings.php          # System settings
│   │
│   ├── models/
│   │   ├── Auth_model.php
│   │   ├── Product_model.php
│   │   ├── Sale_model.php
│   │   └── Customer_model.php
│   │
│   ├── views/
│   │   ├── template/             # Main layout templates
│   │   ├── auth/                 # Login/register pages
│   │   ├── dashboard/            # Dashboard views
│   │   ├── products/             # Product CRUD views
│   │   ├── sales/                # POS interface
│   │   └── reports/              # Report views
│   │
│   ├── libraries/
│   │   ├── dompdf/               # PDF generation
│   │   └── Zend/                 # Barcode generation
│   │
│   └── config/
│       ├── config.php            # Main configuration
│       ├── database.php          # Database configuration
│       ├── routes.php            # URL routing rules
│       └── autoload.php          # Auto-loaded resources
│
├── theme/
│   ├── dist/
│   │   └── css/
│   │       ├── modern-theme.css  # Custom modern theme
│   │       ├── modern-login.css  # Login page styling
│   │       └── AdminLTE.css      # Base AdminLTE theme
│   │
│   ├── css/
│   │   └── bill-style.css        # Invoice/receipt styling
│   │
│   ├── plugins/                  # jQuery plugins
│   │   ├── datatables/
│   │   ├── select2/
│   │   ├── daterangepicker/
│   │   └── ...
│   │
│   └── bootstrap/                # Bootstrap framework
│
├── uploads/                      # User uploaded files
├── docs/                         # Documentation
└── database/                     # Database SQL files
```

---

## Modern Typography System

### Overview
The system uses a modern, scalable typography system based on CSS custom properties (CSS variables) following a 1.25 Major Third ratio scale.

### Typography Scale

#### Main Application (`modern-theme.css`)

```css
:root {
  /* Base Configuration */
  --font-size-base: 16px;

  /* Type Scale (1.25 Major Third Ratio) */
  --font-size-display-xl: 2.441rem;  /* 39px - Hero/Dashboard titles */
  --font-size-display-lg: 1.953rem;  /* 31px - Large headings */
  --font-size-h1: 1.563rem;          /* 25px - Page titles */
  --font-size-h2: 1.25rem;           /* 20px - Section titles */
  --font-size-h3: 1.125rem;          /* 18px - Subsections */
  --font-size-body: 1rem;            /* 16px - Body text, base */
  --font-size-small: 0.875rem;       /* 14px - Secondary text */
  --font-size-tiny: 0.813rem;        /* 13px - Labels, captions */
  --font-size-min: 0.75rem;          /* 12px - Minimum readable */

  /* Line Heights */
  --line-height-tight: 1.25;
  --line-height-normal: 1.5;
  --line-height-relaxed: 1.75;

  /* Font Weights */
  --font-weight-normal: 400;
  --font-weight-medium: 500;
  --font-weight-semibold: 600;
  --font-weight-bold: 700;
  --font-weight-extrabold: 800;
}
```

#### Invoice/Bills (`bill-style.css`)

```css
:root {
  --bill-font-size-base: 16px;
  --bill-font-size-large: 1.25rem;    /* 20px */
  --bill-font-size-medium: 1rem;      /* 16px */
  --bill-font-size-small: 0.875rem;   /* 14px */
  --bill-font-size-tiny: 0.813rem;    /* 13px */
}
```

### Using Typography in Your Code

#### HTML/PHP
```html
<!-- Page Title -->
<h1 class="page-title">Dashboard</h1>

<!-- Section Title -->
<h2 class="section-title">Recent Sales</h2>

<!-- Body Text -->
<p class="body-text">Regular content goes here</p>

<!-- Small Text -->
<span class="text-small">Secondary information</span>

<!-- Labels/Badges -->
<span class="badge">New</span>
```

#### CSS Custom Styles
```css
/* Custom component with proper typography */
.my-custom-element {
  font-size: var(--font-size-body);
  line-height: var(--line-height-normal);
  font-weight: var(--font-weight-normal);
}

.my-heading {
  font-size: var(--font-size-h2);
  line-height: var(--line-height-tight);
  font-weight: var(--font-weight-bold);
}

.my-small-text {
  font-size: var(--font-size-small);
  line-height: var(--line-height-normal);
  font-weight: var(--font-weight-normal);
}
```

### Accessibility Guidelines
- Minimum font size: 12px (0.75rem) - use sparingly
- Optimal body text: 16px (1rem)
- Line height for body text: 1.5
- Line height for headings: 1.25
- Always test readability on different screen sizes

---

## Adding New Features

### Step-by-Step Process

#### 1. Plan Your Feature
- Define requirements clearly
- Identify affected components
- Design database schema changes (if needed)
- Plan user interface mockups

#### 2. Create Database Tables/Modify Schema
```sql
-- Example: Adding a new feature for loyalty points
CREATE TABLE IF NOT EXISTS loyalty_points (
    id INT PRIMARY KEY AUTO_INCREMENT,
    customer_id INT NOT NULL,
    points INT DEFAULT 0,
    earned_date DATETIME DEFAULT CURRENT_TIMESTAMP,
    expiry_date DATE,
    FOREIGN KEY (customer_id) REFERENCES customers(id)
);
```

#### 3. Create Model
```php
// application/models/Loyalty_model.php
<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Loyalty_model extends CI_Model {

    public function __construct() {
        parent::__construct();
        $this->load->database();
    }

    // Get customer points
    public function get_customer_points($customer_id) {
        $this->db->select_sum('points');
        $this->db->where('customer_id', $customer_id);
        $this->db->where('expiry_date >', date('Y-m-d'));
        $query = $this->db->get('loyalty_points');
        return $query->row()->points ?? 0;
    }

    // Add points
    public function add_points($customer_id, $points, $expiry_days = 365) {
        $data = array(
            'customer_id' => $customer_id,
            'points' => $points,
            'expiry_date' => date('Y-m-d', strtotime("+{$expiry_days} days"))
        );
        return $this->db->insert('loyalty_points', $data);
    }

    // Use points
    public function use_points($customer_id, $points) {
        // Implementation here
    }
}
```

#### 4. Create Controller
```php
// application/controllers/Loyalty.php
<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Loyalty extends CI_Controller {

    public function __construct() {
        parent::__construct();
        $this->load->model('Loyalty_model');
        $this->load->library('session');

        // Check if user is logged in
        if (!$this->session->userdata('logged_in')) {
            redirect('auth/login');
        }
    }

    // View loyalty points page
    public function index() {
        $data['title'] = 'Loyalty Points';
        $data['customers'] = $this->Loyalty_model->get_all_customers_with_points();

        $this->load->view('template/header', $data);
        $this->load->view('template/sidebar');
        $this->load->view('loyalty/index', $data);
        $this->load->view('template/footer');
    }

    // Add points via AJAX
    public function add_points() {
        if ($this->input->method() === 'post') {
            $customer_id = $this->input->post('customer_id');
            $points = $this->input->post('points');

            // Validation
            $this->load->library('form_validation');
            $this->form_validation->set_rules('customer_id', 'Customer', 'required|integer');
            $this->form_validation->set_rules('points', 'Points', 'required|integer');

            if ($this->form_validation->run()) {
                $result = $this->Loyalty_model->add_points($customer_id, $points);

                if ($result) {
                    echo json_encode(['success' => true, 'message' => 'Points added successfully']);
                } else {
                    echo json_encode(['success' => false, 'message' => 'Failed to add points']);
                }
            } else {
                echo json_encode(['success' => false, 'message' => validation_errors()]);
            }
        }
    }
}
```

#### 5. Create View
```php
<!-- application/views/loyalty/index.php -->
<div class="content-wrapper">
  <section class="content-header">
    <h1>
      Loyalty Points Management
      <small>Manage customer reward points</small>
    </h1>
  </section>

  <section class="content">
    <div class="box">
      <div class="box-header with-border">
        <h3 class="box-title">Customer Points</h3>
        <button class="btn btn-primary pull-right" data-toggle="modal" data-target="#addPointsModal">
          <i class="fa fa-plus"></i> Add Points
        </button>
      </div>

      <div class="box-body">
        <table id="loyaltyTable" class="table table-bordered table-striped">
          <thead>
            <tr>
              <th>Customer Name</th>
              <th>Current Points</th>
              <th>Total Earned</th>
              <th>Actions</th>
            </tr>
          </thead>
          <tbody>
            <?php foreach ($customers as $customer): ?>
            <tr>
              <td><?= htmlspecialchars($customer['name']) ?></td>
              <td><?= number_format($customer['current_points']) ?></td>
              <td><?= number_format($customer['total_earned']) ?></td>
              <td>
                <button class="btn btn-sm btn-info" onclick="viewHistory(<?= $customer['id'] ?>)">
                  <i class="fa fa-history"></i> History
                </button>
              </td>
            </tr>
            <?php endforeach; ?>
          </tbody>
        </table>
      </div>
    </div>
  </section>
</div>

<!-- Add Points Modal -->
<div class="modal fade" id="addPointsModal" tabindex="-1">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal">&times;</button>
        <h4 class="modal-title">Add Points</h4>
      </div>
      <form id="addPointsForm">
        <div class="modal-body">
          <div class="form-group">
            <label>Customer</label>
            <select name="customer_id" class="form-control select2" required>
              <option value="">Select Customer</option>
              <!-- Options populated via AJAX or PHP -->
            </select>
          </div>
          <div class="form-group">
            <label>Points</label>
            <input type="number" name="points" class="form-control" required min="1">
          </div>
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
          <button type="submit" class="btn btn-primary">Add Points</button>
        </div>
      </form>
    </div>
  </div>
</div>

<script>
$(document).ready(function() {
    // Initialize DataTable
    $('#loyaltyTable').DataTable({
        responsive: true,
        order: [[2, 'desc']]
    });

    // Initialize Select2
    $('.select2').select2();

    // Handle form submission
    $('#addPointsForm').on('submit', function(e) {
        e.preventDefault();

        $.ajax({
            url: '<?= base_url('loyalty/add_points') ?>',
            type: 'POST',
            data: $(this).serialize(),
            dataType: 'json',
            success: function(response) {
                if (response.success) {
                    toastr.success(response.message);
                    $('#addPointsModal').modal('hide');
                    location.reload();
                } else {
                    toastr.error(response.message);
                }
            },
            error: function() {
                toastr.error('An error occurred. Please try again.');
            }
        });
    });
});

function viewHistory(customerId) {
    // Implementation for viewing points history
}
</script>
```

#### 6. Add Menu Item
```php
<!-- application/views/template/sidebar.php -->
<li class="treeview">
  <a href="#">
    <i class="fa fa-gift"></i>
    <span>Loyalty Program</span>
    <span class="pull-right-container">
      <i class="fa fa-angle-left pull-right"></i>
    </span>
  </a>
  <ul class="treeview-menu">
    <li><a href="<?= base_url('loyalty') ?>"><i class="fa fa-circle-o"></i> Manage Points</a></li>
    <li><a href="<?= base_url('loyalty/settings') ?>"><i class="fa fa-circle-o"></i> Settings</a></li>
  </ul>
</li>
```

#### 7. Add Route (Optional)
```php
// application/config/routes.php
$route['loyalty'] = 'loyalty/index';
$route['loyalty/add'] = 'loyalty/add_points';
```

---

## Bug Fixing Guidelines

### 1. Identify the Issue
- Reproduce the bug consistently
- Note error messages and logs
- Check browser console for JavaScript errors
- Review PHP error logs in XAMPP

### 2. Locate Error Logs
```bash
# PHP Errors
C:\xampp\apache\logs\error.log

# CodeIgniter Logs
application/logs/log-YYYY-MM-DD.php

# JavaScript Console
Press F12 in browser → Console tab
```

### 3. Debug PHP Code
```php
// Enable debugging in CodeIgniter
// application/config/config.php
$config['log_threshold'] = 4; // 0=Disabled, 4=All messages

// Add debug output
log_message('debug', 'Variable value: ' . print_r($data, true));

// Or use var_dump for immediate output
var_dump($variable);
exit; // Stop execution to see output
```

### 4. Debug JavaScript
```javascript
// Console logging
console.log('Variable value:', myVariable);
console.error('Error occurred:', error);
console.table(arrayData); // For arrays/objects

// Debugger breakpoint
debugger; // Execution will pause here

// AJAX error handling
$.ajax({
    // ... ajax settings
    error: function(xhr, status, error) {
        console.error('AJAX Error:', {
            status: status,
            error: error,
            response: xhr.responseText
        });
    }
});
```

### 5. Common Bugs and Fixes

#### Database Connection Error
```php
// Error: Unable to connect to database
// Fix: Check database.php configuration
$db['default'] = array(
    'hostname' => 'localhost',
    'username' => 'root',
    'password' => '',
    'database' => 'pos_system',
    'dbdriver' => 'mysqli', // Make sure this is correct
);
```

#### 404 Page Not Found
```php
// Error: 404 - Controller not found
// Fix 1: Check .htaccess file exists
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]

// Fix 2: Enable URL rewriting in Apache
// Enable mod_rewrite in httpd.conf
```

#### Session Issues
```php
// Error: Session data not persisting
// Fix: Check session configuration
// application/config/config.php
$config['sess_driver'] = 'files';
$config['sess_save_path'] = APPPATH . 'cache/';

// Make sure cache directory has write permissions
chmod 777 application/cache/
```

### 6. Testing the Fix
1. Clear browser cache and cookies
2. Test the fix in different browsers
3. Verify no new bugs were introduced
4. Check related functionality still works
5. Document the fix for future reference

---

## Code Standards

### PHP Coding Standards

```php
<?php
// File header
/**
 * Controller Name
 *
 * Description of the controller
 *
 * @package    POS_System
 * @subpackage Controllers
 * @category   Sales
 * @author     Your Name
 * @link       http://example.com
 */

defined('BASEPATH') OR exit('No direct script access allowed');

class Product extends CI_Controller {

    // Constants in UPPERCASE
    const DEFAULT_LIMIT = 10;

    // Properties with visibility
    private $user_id;
    protected $permissions;
    public $data;

    /**
     * Constructor
     * Load required models and libraries
     */
    public function __construct() {
        parent::__construct();
        $this->load->model('Product_model');
    }

    /**
     * Method documentation
     *
     * @param int $id Product ID
     * @return array Product details
     */
    public function get_product($id) {
        // Validate input
        if (!is_numeric($id) || $id <= 0) {
            return false;
        }

        // Use meaningful variable names
        $product_details = $this->Product_model->get_by_id($id);

        // Early return for error conditions
        if (empty($product_details)) {
            return false;
        }

        // Process and return
        return $this->format_product_data($product_details);
    }

    /**
     * Private/Protected methods for internal use
     */
    private function format_product_data($data) {
        // Implementation
    }
}
```

### JavaScript/jQuery Standards

```javascript
/**
 * Product Management JavaScript
 * Handles product CRUD operations
 */

// Use strict mode
'use strict';

// Module pattern for organization
var ProductModule = (function($) {

    // Private variables
    var config = {
        apiUrl: baseUrl + 'products/api/',
        tableId: '#productsTable'
    };

    // Private methods
    function initDataTable() {
        $(config.tableId).DataTable({
            responsive: true,
            ajax: {
                url: config.apiUrl + 'list',
                type: 'POST'
            },
            columns: [
                { data: 'name' },
                { data: 'price' },
                { data: 'stock' },
                { data: 'actions', orderable: false }
            ]
        });
    }

    function handleFormSubmit(event) {
        event.preventDefault();

        var formData = $(this).serialize();

        $.ajax({
            url: config.apiUrl + 'save',
            type: 'POST',
            data: formData,
            dataType: 'json',
            success: function(response) {
                if (response.success) {
                    toastr.success(response.message);
                    reloadTable();
                } else {
                    toastr.error(response.message);
                }
            },
            error: function(xhr, status, error) {
                console.error('Error:', error);
                toastr.error('An error occurred. Please try again.');
            }
        });
    }

    function reloadTable() {
        $(config.tableId).DataTable().ajax.reload();
    }

    // Public methods
    return {
        init: function() {
            initDataTable();

            // Event listeners
            $('#productForm').on('submit', handleFormSubmit);
            $(document).on('click', '.delete-product', this.deleteProduct);
        },

        deleteProduct: function() {
            var productId = $(this).data('id');

            if (confirm('Are you sure you want to delete this product?')) {
                // Delete implementation
            }
        }
    };

})(jQuery);

// Initialize on document ready
$(document).ready(function() {
    ProductModule.init();
});
```

### CSS Standards

```css
/**
 * Component: Product Card
 * Usage: Display product information in card format
 */

/* Use meaningful class names */
.product-card {
  /* Group related properties */
  /* 1. Display & Box Model */
  display: flex;
  flex-direction: column;
  padding: 20px;
  margin-bottom: 20px;

  /* 2. Positioning */
  position: relative;

  /* 3. Typography */
  font-size: var(--font-size-body);
  line-height: var(--line-height-normal);
  font-weight: var(--font-weight-normal);

  /* 4. Visual */
  background: white;
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);

  /* 5. Animation */
  transition: var(--transition);
}

/* Pseudo-classes */
.product-card:hover {
  box-shadow: var(--shadow-lg);
  transform: translateY(-5px);
}

/* Nested selectors - max 3 levels */
.product-card .product-image {
  width: 100%;
  border-radius: var(--radius-sm);
}

.product-card .product-title {
  font-size: var(--font-size-h3);
  font-weight: var(--font-weight-bold);
  margin-top: 15px;
}

/* Responsive design */
@media (max-width: 768px) {
  .product-card {
    padding: 15px;
  }
}

/* Comments for complex sections */
/**
 * Special discount badge
 * Positioned absolutely in top-right corner
 */
.product-card .discount-badge {
  position: absolute;
  top: 10px;
  right: 10px;
  /* ... */
}
```

---

## Database Schema

### Core Tables Structure

```sql
-- Users Table
CREATE TABLE users (
    id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(100) UNIQUE NOT NULL,
    email VARCHAR(150) UNIQUE NOT NULL,
    password VARCHAR(255) NOT NULL,
    role ENUM('admin', 'manager', 'cashier') DEFAULT 'cashier',
    status ENUM('active', 'inactive') DEFAULT 'active',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    last_login DATETIME NULL,
    INDEX idx_username (username),
    INDEX idx_email (email)
);

-- Customers Table
CREATE TABLE customers (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(150) NOT NULL,
    email VARCHAR(150),
    phone VARCHAR(20),
    address TEXT,
    city VARCHAR(100),
    postal_code VARCHAR(20),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    INDEX idx_phone (phone),
    INDEX idx_email (email)
);

-- Categories Table
CREATE TABLE categories (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(100) NOT NULL,
    description TEXT,
    status ENUM('active', 'inactive') DEFAULT 'active',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    INDEX idx_name (name)
);

-- Products Table
CREATE TABLE products (
    id INT PRIMARY KEY AUTO_INCREMENT,
    category_id INT,
    name VARCHAR(200) NOT NULL,
    description TEXT,
    barcode VARCHAR(50) UNIQUE,
    sku VARCHAR(50) UNIQUE,
    cost_price DECIMAL(10,2) NOT NULL DEFAULT 0.00,
    selling_price DECIMAL(10,2) NOT NULL DEFAULT 0.00,
    stock_quantity INT NOT NULL DEFAULT 0,
    min_stock_level INT DEFAULT 10,
    image VARCHAR(255),
    status ENUM('active', 'inactive') DEFAULT 'active',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    FOREIGN KEY (category_id) REFERENCES categories(id) ON DELETE SET NULL,
    INDEX idx_barcode (barcode),
    INDEX idx_sku (sku),
    INDEX idx_category (category_id)
);

-- Sales Table
CREATE TABLE sales (
    id INT PRIMARY KEY AUTO_INCREMENT,
    invoice_no VARCHAR(50) UNIQUE NOT NULL,
    customer_id INT,
    user_id INT NOT NULL,
    sale_date DATE NOT NULL,
    subtotal DECIMAL(10,2) NOT NULL DEFAULT 0.00,
    tax_amount DECIMAL(10,2) NOT NULL DEFAULT 0.00,
    discount_amount DECIMAL(10,2) NOT NULL DEFAULT 0.00,
    total_amount DECIMAL(10,2) NOT NULL DEFAULT 0.00,
    payment_method ENUM('cash', 'card', 'online') DEFAULT 'cash',
    payment_status ENUM('paid', 'partial', 'unpaid') DEFAULT 'paid',
    notes TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (customer_id) REFERENCES customers(id) ON DELETE SET NULL,
    FOREIGN KEY (user_id) REFERENCES users(id),
    INDEX idx_invoice (invoice_no),
    INDEX idx_sale_date (sale_date),
    INDEX idx_customer (customer_id),
    INDEX idx_user (user_id)
);

-- Sale Items Table
CREATE TABLE sale_items (
    id INT PRIMARY KEY AUTO_INCREMENT,
    sale_id INT NOT NULL,
    product_id INT NOT NULL,
    quantity INT NOT NULL DEFAULT 1,
    unit_price DECIMAL(10,2) NOT NULL,
    discount DECIMAL(10,2) DEFAULT 0.00,
    total DECIMAL(10,2) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (sale_id) REFERENCES sales(id) ON DELETE CASCADE,
    FOREIGN KEY (product_id) REFERENCES products(id),
    INDEX idx_sale (sale_id),
    INDEX idx_product (product_id)
);
```

### Database Relationships

```
users (1) ----< (∞) sales
customers (1) ----< (∞) sales
categories (1) ----< (∞) products
products (1) ----< (∞) sale_items
sales (1) ----< (∞) sale_items
```

---

## API Documentation

### Authentication Endpoints

#### POST /auth/login
Login user and create session

**Request:**
```json
{
  "username": "admin",
  "password": "password123"
}
```

**Response:**
```json
{
  "success": true,
  "message": "Login successful",
  "user": {
    "id": 1,
    "username": "admin",
    "role": "admin"
  }
}
```

### Product Endpoints

#### GET /products/list
Get all products with pagination

**Parameters:**
- `page` (int): Page number (default: 1)
- `limit` (int): Items per page (default: 10)
- `search` (string): Search term (optional)
- `category_id` (int): Filter by category (optional)

**Response:**
```json
{
  "success": true,
  "data": [
    {
      "id": 1,
      "name": "Product Name",
      "barcode": "123456789",
      "price": 99.99,
      "stock": 50,
      "category": "Electronics"
    }
  ],
  "pagination": {
    "total": 100,
    "page": 1,
    "limit": 10,
    "pages": 10
  }
}
```

#### POST /products/save
Create or update product

**Request:**
```json
{
  "id": 1,
  "name": "New Product",
  "category_id": 2,
  "barcode": "987654321",
  "cost_price": 50.00,
  "selling_price": 99.99,
  "stock_quantity": 100
}
```

**Response:**
```json
{
  "success": true,
  "message": "Product saved successfully",
  "product_id": 1
}
```

#### DELETE /products/delete/{id}
Delete a product

**Response:**
```json
{
  "success": true,
  "message": "Product deleted successfully"
}
```

### Sales Endpoints

#### POST /sales/create
Create new sale

**Request:**
```json
{
  "customer_id": 5,
  "items": [
    {
      "product_id": 1,
      "quantity": 2,
      "unit_price": 99.99
    },
    {
      "product_id": 3,
      "quantity": 1,
      "unit_price": 149.99
    }
  ],
  "payment_method": "cash",
  "discount": 10.00
}
```

**Response:**
```json
{
  "success": true,
  "message": "Sale completed successfully",
  "invoice_no": "INV-20250120-001",
  "total_amount": 339.97
}
```

---

## Testing

### Manual Testing Checklist

#### Authentication
- [ ] Login with valid credentials
- [ ] Login with invalid credentials
- [ ] Logout functionality
- [ ] Session persistence
- [ ] Password reset

#### Product Management
- [ ] Create new product
- [ ] Edit existing product
- [ ] Delete product
- [ ] Search products
- [ ] Filter by category
- [ ] Low stock alerts

#### Sales/POS
- [ ] Add items to cart
- [ ] Update quantities
- [ ] Remove items
- [ ] Apply discounts
- [ ] Complete sale with cash
- [ ] Complete sale with card
- [ ] Print receipt
- [ ] Generate invoice PDF

#### Reports
- [ ] Daily sales report
- [ ] Product sales report
- [ ] Low stock report
- [ ] Customer purchase history

### Browser Testing
- Chrome (latest)
- Firefox (latest)
- Safari (latest)
- Edge (latest)
- Mobile browsers (iOS Safari, Chrome Mobile)

### Performance Testing
- Page load times < 2 seconds
- Database queries optimized
- Images optimized and compressed
- JavaScript minified for production

---

## Deployment

### Pre-Deployment Checklist
- [ ] All features tested and working
- [ ] Database backup created
- [ ] Environment configuration updated
- [ ] Debug mode disabled
- [ ] Error logging enabled
- [ ] Security settings reviewed
- [ ] File permissions set correctly

### Production Configuration

```php
// application/config/config.php (Production)
$config['base_url'] = 'https://yourdomain.com/';
$config['index_page'] = '';
$config['log_threshold'] = 1; // Only log errors
$config['encryption_key'] = 'STRONG_RANDOM_KEY_HERE';

// application/config/database.php (Production)
$db['default'] = array(
    'hostname' => 'production-db-host',
    'username' => 'db_username',
    'password' => 'STRONG_PASSWORD',
    'database' => 'production_db',
    'dbdriver' => 'mysqli',
    'db_debug' => FALSE, // Disable in production
);
```

### Deployment Steps

1. **Backup Production Database**
   ```bash
   mysqldump -u username -p database_name > backup_$(date +%Y%m%d).sql
   ```

2. **Upload Files**
   - Use FTP/SFTP or Git deployment
   - Exclude unnecessary files (.git, docs, database/)

3. **Import Database Changes**
   ```bash
   mysql -u username -p database_name < migration.sql
   ```

4. **Update Configuration**
   - Update base_url
   - Update database credentials
   - Disable debug mode

5. **Set File Permissions**
   ```bash
   # Directories
   find . -type d -exec chmod 755 {} \;

   # Files
   find . -type f -exec chmod 644 {} \;

   # Uploads directory
   chmod -R 777 uploads/
   ```

6. **Test Production**
   - Check all critical functionality
   - Monitor error logs
   - Verify database connections

### Maintenance Mode

```php
// Create maintenance.php in root
<?php
header('HTTP/1.1 503 Service Temporarily Unavailable');
header('Status: 503 Service Temporarily Unavailable');
header('Retry-After: 3600'); // 1 hour
?>
<!DOCTYPE html>
<html>
<head>
    <title>Under Maintenance</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            text-align: center;
            padding: 50px;
        }
    </style>
</head>
<body>
    <h1>We'll be back soon!</h1>
    <p>Sorry for the inconvenience. We're performing maintenance. Check back soon.</p>
</body>
</html>
```

---

## Support and Resources

### Internal Documentation
- `/docs/USER_MANUAL.md` - End user documentation
- `/docs/DATABASE_SCHEMA.md` - Detailed database documentation
- `/docs/API_REFERENCE.md` - Complete API documentation

### External Resources
- CodeIgniter Documentation: https://codeigniter.com/userguide3/
- Bootstrap 3 Documentation: https://getbootstrap.com/docs/3.4/
- AdminLTE Theme: https://adminlte.io/themes/AdminLTE/documentation/
- DataTables: https://datatables.net/manual/

### Getting Help
- Check error logs first
- Search existing documentation
- Review similar implementations in codebase
- Contact senior developer if stuck

---

**Last Updated:** January 2025
**Version:** 1.0
**Maintained by:** Development Team
