• Skip to secondary menu
  • Skip to main content
  • Skip to primary sidebar
  • Home
  • Projects
  • Products
  • Themes
  • Tools
  • Request for Quote

Vengala Vinay

Having 12+ Years of Experience in Software Development

  • Home
  • WordPress
  • PHP
    • Codeigniter
  • Django
  • Magento
  • Selenium
  • Server
Home » Implementing automated compliance reporting for custom custom product catalogs ledgers using TCPDF generator script

Implementing automated compliance reporting for custom custom product catalogs ledgers using TCPDF generator script

Data Model for Product Catalog Ledgers

To implement automated compliance reporting, we first need a robust data model for our custom product catalog ledgers. This model should capture essential details for each product entry, including its unique identifier, name, description, pricing, stock levels, and crucially, any compliance-related metadata. For reporting purposes, we’ll also need to track historical changes to these attributes, effectively creating an audit trail. A relational database schema is well-suited for this. Consider a table structure like the following:

`products` Table

This table stores the current state of each product.

CREATE TABLE products (
    product_id INT AUTO_INCREMENT PRIMARY KEY,
    sku VARCHAR(50) UNIQUE NOT NULL,
    name VARCHAR(255) NOT NULL,
    description TEXT,
    price DECIMAL(10, 2) NOT NULL,
    stock_quantity INT NOT NULL DEFAULT 0,
    compliance_status ENUM('compliant', 'non_compliant', 'pending_review') NOT NULL DEFAULT 'pending_review',
    compliance_details TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

`product_ledger` Table

This table acts as the immutable ledger, recording every change to a product’s state. This is critical for auditability and compliance reporting.

CREATE TABLE product_ledger (
    ledger_id BIGINT AUTO_INCREMENT PRIMARY KEY,
    product_id INT NOT NULL,
    change_timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    changed_by_user_id INT, -- Foreign key to a users table if applicable
    action VARCHAR(50) NOT NULL, -- e.g., 'create', 'update', 'delete', 'compliance_status_change'
    field_changed VARCHAR(100), -- The specific field that was modified
    old_value TEXT,
    new_value TEXT,
    FOREIGN KEY (product_id) REFERENCES products(product_id) ON DELETE CASCADE
);

The `action` and `field_changed` columns in `product_ledger` are crucial for granular reporting. For instance, a change in `compliance_status` would be logged with `action = ‘compliance_status_change’` and `field_changed = ‘compliance_status’`. The `old_value` and `new_value` store the state before and after the change, respectively.

Integrating TCPDF for PDF Generation

We’ll leverage the TCPDF library for generating PDF reports. TCPDF is a mature and feature-rich PHP library that allows for programmatic creation of PDF documents. First, ensure you have TCPDF installed. If you’re using Composer, add it to your project:

composer require tecnickcom/tcpdf

Next, we’ll create a PHP script that queries the product ledger and generates a compliance report. This script will be designed to be callable via a cron job or a secure internal endpoint.

Compliance Report Generation Script (`generate_compliance_report.php`)

<?php
// Include Composer's autoloader
require_once __DIR__ . '/vendor/autoload.php';

// Include TCPDF
require_once __DIR__ . '/vendor/tecnickcom/tcpdf/tcpdf.php';

// --- Database Configuration ---
$dbHost = 'localhost';
$dbUser = 'your_db_user';
$dbPass = 'your_db_password';
$dbName = 'your_database_name';

// --- Report Configuration ---
$reportTitle = 'Product Catalog Compliance Report';
$outputFileName = 'compliance_report_' . date('Ymd_His') . '.pdf';
$complianceStatusFilter = 'non_compliant'; // e.g., 'non_compliant', 'pending_review', or null for all

// --- Database Connection ---
$conn = new mysqli($dbHost, $dbUser, $dbPass, $dbName);
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}

// --- TCPDF Setup ---
class MYPDF extends TCPDF {
    // Page header
    public function Header() {
        // Logo
        $logo_file = K_PATH_IMAGES.'logo_example_color.png'; // Replace with your logo path
        $this->Image($logo_file, 10, 10, 15, '', 'PNG', '', 'T', false, 300, '', false, false, 0, false, false, false);
        // Set font
        $this->SetFont('helvetica', 'B', 20);
        // Title
        $this->Cell(0, 15, $this->getAliasNumPage().'/'.$this->getAliasNbPages().' - '.$this->title, 0, false, 'C', 0, '', 0, false, 'M', 'M');
        $this->SetFont('helvetica', '', 10);
        $this->writeHTMLCell(0, 10, '', '', '<b>Generated On: </b>' . date('Y-m-d H:i:s'), 0, 1, 0, true, 'R', true);
    }

    // Page footer
    public function Footer() {
        // Position at 15 mm from bottom
        $this->SetY(-15);
        // Set font
        $this->SetFont('helvetica', 'I', 8);
        // Page number
        $this->Cell(0, 10, 'Page '.$this->getAliasNumPage().'/'.$this->getAliasNbPages(), 0, false, 'C', 0, '', 0, false, 'T', 'M');
    }
}

// Create new PDF document
$pdf = new MYPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);

// Set document information
$pdf->SetCreator(PDF_CREATOR);
$pdf->SetAuthor('Your Company');
$pdf->SetTitle($reportTitle);
$pdf->SetSubject('Compliance Report');
$pdf->SetKeywords('compliance, report, product, catalog');

// Set default header data
$pdf->SetHeaderData(PDF_HEADER_LOGO, PDF_HEADER_LOGO_WIDTH, PDF_HEADER_TITLE.' 001', PDF_HEADER_STRING);

// Set header and footer fonts
$pdf->setHeaderFont(Array(PDF_FONT_NAME_MAIN, '', PDF_FONT_SIZE_MAIN));
$pdf->setFooterFont(Array(PDF_FONT_NAME_DATA, '', PDF_FONT_SIZE_DATA));

// Set default monospaced font
$pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);

// Set margins
$pdf->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP, PDF_MARGIN_RIGHT);
$pdf->SetHeaderMargin(PDF_MARGIN_HEADER);
$pdf->SetFooterMargin(PDF_MARGIN_FOOTER);

// Set auto page breaks
$pdf->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM);

// Set image scale factor
$pdf->setImageScale(PDF_IMAGE_SCALE_FACTOR);

// Add a page
$pdf->AddPage();

// Set font
$pdf->SetFont('helvetica', '', 10);

// Report Title
$pdf->SetFont('helvetica', 'B', 16);
$pdf->Cell(0, 15, $reportTitle, 0, false, 'C', 0, '', 0, false, 'M', 'M');
$pdf->Ln(10);

// --- Fetch Data ---
$sql = "SELECT
            p.sku,
            p.name,
            p.compliance_status,
            p.compliance_details,
            pl.change_timestamp,
            pl.action,
            pl.field_changed,
            pl.old_value,
            pl.new_value
        FROM products p
        LEFT JOIN product_ledger pl ON p.product_id = pl.product_id
        WHERE p.compliance_status = ?"; // Filter by status

$stmt = $conn->prepare($sql);
if (!$stmt) {
    die("Error preparing statement: " . $conn->error);
}

$statusToQuery = $complianceStatusFilter ?? 'compliant'; // Default to compliant if filter is null
$stmt->bind_param("s", $statusToQuery);
$stmt->execute();
$result = $stmt->get_result();

// --- Generate Report Content ---
$html = '<h2>Products with Status: ' . ucfirst($statusToQuery) . '</h2>';
$html .= '<table border="1" cellpadding="5" cellspacing="0" style="width:100%;">';
$html .= '<thead><tr style="background-color:#f2f2f2;">
            <th>SKU</th>
            <th>Product Name</th>
            <th>Compliance Status</th>
            <th>Compliance Details</th>
            <th>Last Ledger Action</th>
            <th>Field Changed</th>
            <th>Timestamp</th>
          </tr></thead><tbody>';

if ($result->num_rows > 0) {
    while($row = $result->fetch_assoc()) {
        $html .= '<tr>';
        $html .= '<td>' . htmlspecialchars($row['sku']) . '</td>';
        $html .= '<td>' . htmlspecialchars($row['name']) . '</td>';
        $html .= '<td>' . htmlspecialchars($row['compliance_status']) . '</td>';
        $html .= '<td>' . htmlspecialchars($row['compliance_details']) . '</td>';
        $html .= '<td>' . htmlspecialchars($row['action']) . '</td>';
        $html .= '<td>' . htmlspecialchars($row['field_changed']) . '</td>';
        $html .= '<td>' . htmlspecialchars($row['change_timestamp']) . '</td>';
        $html .= '</tr>';
    }
} else {
    $html .= '<tr><td colspan="7">No products found matching the criteria.</td></tr>';
}

$html .= '</tbody></table>';

// Write HTML content
$pdf->writeHTML($html, true, false, true, false, '');

// Close and output PDF document
$pdf->Output($outputFileName, 'I'); // 'I' for inline display, 'D' for download

$stmt->close();
$conn->close();
?>

Explanation:

  • Autoloader and TCPDF Inclusion: Ensures that Composer’s dependencies and the TCPDF library are correctly loaded.
  • Database Configuration: Placeholder variables for your MySQL connection details.
  • Report Configuration: Sets the report title, output filename, and a filter for compliance status. You can set `$complianceStatusFilter` to `’non_compliant’`, `’pending_review’`, or `null` to include all statuses.
  • Database Connection: Establishes a connection to your MySQL database using `mysqli`. Error handling is included.
  • Custom TCPDF Class (`MYPDF`): This class extends the base `TCPDF` class to provide custom headers and footers, including page numbering and generation timestamps. You’ll need to adjust the logo path (`K_PATH_IMAGES.’logo_example_color.png’`) to your actual logo file.
  • TCPDF Initialization: Sets up document metadata, margins, auto page breaks, and fonts.
  • Data Fetching: A SQL query retrieves product information along with the latest ledger entry for each product, filtered by the specified compliance status. The query joins `products` and `product_ledger` tables. Note the use of a prepared statement for security.
  • HTML Generation: The fetched data is formatted into an HTML table. `htmlspecialchars()` is used to prevent XSS vulnerabilities when displaying data.
  • `writeHTML()`: TCPDF’s `writeHTML()` method renders the generated HTML into the PDF document.
  • `Output()`: The `Output()` method determines how the PDF is delivered. `’I’` sends it inline to the browser, while `’D’` prompts a download.

Automating Report Generation with Cron Jobs

To make this reporting process truly automated, we’ll schedule the PHP script to run at regular intervals using cron. This ensures that compliance reports are generated consistently without manual intervention.

Cron Job Setup

1. **Access your server’s crontab:**

crontab -e

2. **Add a cron entry:** To run the report daily at 2:00 AM, add the following line. Ensure you replace `/path/to/your/project/` with the actual absolute path to your PHP script.

0 2 * * * /usr/bin/php /path/to/your/project/generate_compliance_report.php >> /path/to/your/project/logs/cron.log 2>&1

Explanation:

  • 0 2 * * *: This is the cron schedule. It means “at 0 minutes past the 2nd hour, every day, every month, every day of the week.”
  • /usr/bin/php: The absolute path to your PHP executable. You might need to find this using `which php`.
  • /path/to/your/project/generate_compliance_report.php: The absolute path to your PHP script.
  • >> /path/to/your/project/logs/cron.log 2>&1: This redirects both standard output and standard error to a log file. This is crucial for debugging cron job failures. Make sure the `logs` directory exists and is writable by the user running the cron job.

With this setup, the `generate_compliance_report.php` script will execute daily, query the database for products matching the specified compliance status, and generate a PDF report. The report will be saved (or displayed inline, depending on the `Output` method) and any output or errors will be logged.

Advanced Considerations and Enhancements

To further enhance this solution:

  • Report Distribution: Instead of just outputting the PDF, modify the script to email the report to relevant stakeholders using PHP’s Mailer libraries (e.g., PHPMailer) or integrate with cloud storage services (like AWS S3 or Google Cloud Storage) to save reports.
  • Dynamic Filtering: For more interactive reporting, create a WordPress admin interface where users can select filters (date range, compliance status, product category) and trigger report generation on demand. This would involve creating custom WordPress plugin pages and AJAX endpoints.
  • Error Handling and Monitoring: Implement more sophisticated error logging and alerting. If the cron job fails or the report generation encounters an issue, notifications should be sent to the system administrator.
  • Data Archiving: For very large product catalogs and long-term compliance, consider a strategy for archiving old ledger data to maintain database performance.
  • Security: If the report generation script is exposed via a web endpoint, ensure robust authentication and authorization mechanisms are in place to prevent unauthorized access. For cron jobs, ensure the script and its configuration files are protected.
  • Report Templating: For highly complex reports with custom branding and layouts, explore TCPDF’s HTML template capabilities or consider libraries like Dompdf if HTML-to-PDF conversion is preferred.

By combining a well-structured data model, the power of TCPDF, and the automation capabilities of cron jobs, you can establish a reliable and efficient system for automated compliance reporting for your custom product catalog ledgers.

Primary Sidebar

A little about the Author

Having 12+ Years of Experience in Software Development, Vinay is a principal software architect, senior systems engineer, and elite technical consultant. He specializes in bespoke PHP/WordPress development, high-performance Magento 2 & Shopify architectures, custom plugin/theme development from scratch, and legacy code modernization (including VB6, VB.NET, PyQt, and Crystal Reports). Known for solving complex database bottlenecks, speed optimization (Core Web Vitals), and advanced security code auditing, Vinay engineers production-ready systems designed to scale under heavy concurrent load conditions.



Chat on WhatsApp

Recent Posts

  • WordPress Development Recipe: Secure token-based API authentication for OpenAI Completion API in custom plugins
  • How to construct high-throughput import engines for large custom subscription logs sets using custom XML/JSON parsers
  • How to implement custom Filesystem API endpoints with token authentication in Gutenberg blocks
  • How to analyze and reduce CPU consumption of custom Command Query Responsibility Segregation (CQRS) event mediators
  • Step-by-Step Guide: Refactoring legacy hooks to use Active Record Wrapper pattern in theme layers

Categories

  • apache (1)
  • Business & Monetization (390)
  • Centos (4)
  • Comparisons & Decision Making (55)
  • Debian (2)
  • Debugging & Troubleshooting (652)
  • Desktop Applications (14)
  • DevOps (7)
  • DevOps & Cloud Scaling (962)
  • Django (1)
  • Laravel (4)
  • Migration & Architecture (192)
  • Mobile Applications (24)
  • MySQL (1)
  • Performance & Optimization (868)
  • PHP (5)
  • PHP Development (38)
  • Plugins & Themes (244)
  • Programming Languages (9)
  • Python (20)
  • Ruby on Rails (1)
  • Security & Compliance (636)
  • SEO & Growth (492)
  • Server (23)
  • Ubuntu (9)
  • VB6 & VB.NET (8)
  • Web Applications & Frontend (19)
  • Web Assembly (Wasm) (2)
  • WordPress (22)
  • WordPress Plugin Development (319)
  • WordPress Theme Development (357)

Recent Posts

  • WordPress Development Recipe: Secure token-based API authentication for OpenAI Completion API in custom plugins
  • How to construct high-throughput import engines for large custom subscription logs sets using custom XML/JSON parsers
  • How to implement custom Filesystem API endpoints with token authentication in Gutenberg blocks

Top Categories

  • DevOps & Cloud Scaling (962)
  • Performance & Optimization (868)
  • Debugging & Troubleshooting (652)
  • Security & Compliance (636)
  • SEO & Growth (492)
  • Business & Monetization (390)

Our Products

  • ERP & LMS Systems (4)
  • Directories & Marketplaces (4)
  • Healthcare Portals (3)
  • Point of Sale (POS) (2)
  • E-Commerce Engines (2)

Our Services

  • E-Commerce Development (10)
  • WordPress Development (8)
  • Python & Desktop GUI (7)
  • General Consulting (7)
  • Legacy Modernization (5)
  • Mobile App Development (4)

Copyright © 2026 · Vinay Vengala