You are not logged in.

Announcement

 Téléchargez la dernière version stable de GLPI      -     Et vous, que pouvez vous faire pour le projet GLPI ? :  Contribuer
 Download last stable version of GLPI                      -     What can you do for GLPI ? :  Contribute

#1 2025-02-25 10:37:26

eLBruto
Member
Registered: 2025-01-16
Posts: 23

[SOLVED]GLPI Order Purchase Orders though tickets

I have lost faith in ChatGPT and attempted to set this up with Claude.ai . Could any of the developers be able to tell me if any if the code that Claude wrote is accurate ?

I'm posting here because unfortunately for GLPI it doesn't have the Test Environment -> Production Evirnoment feature to be able to test something out before deployment and atm I am unnable to create a new VM for it as our VSphere is under maintenance.

Hello! Setting up an automated purchase order workflow in GLPI with approval and custom PDF generation is definitely possible. Let me walk you through the steps to achieve this.

## Setting Up Purchase Order Workflow in GLPI 10.0.17

### 1. Install Required Plugins
You'll need these plugins:
- **Order Management plugin** (for purchase orders)
- **PDF Generation plugin** (for custom PDF templates)
- **Approvals plugin** (for approval workflows)

### 2. Configure Order Management

1. After installing the plugins, go to Setup > Plugins
2. Configure the Order Management plugin:
   - Set up order categories matching your needs (toner, hardware, software)
   - Create order templates with your custom fields
   - Link these to your ticket categories

### 3. Create Approval Workflow

1. Navigate to Administration > Rules > Business Rules for Tickets
2. Create a new rule with these conditions:
   - Ticket category is related to purchasing
   - Ticket contains specific keywords or tags
3. Set actions:
   - Change ticket status to "Waiting for Approval"
   - Assign approval to appropriate manager based on department/cost center

### 4. Set Up Custom PDF Template

1. In the PDF Generation plugin, create a custom template matching your required form
2. Add placeholders for:
   - Ticket information (ID, requester, date, items)
   - Price and vendor details
   - Manager approval information
   - Digital signature field

### 5. Automate the Process with a Script

You'll need to create a server-side script to:
1. Monitor tickets with approved purchase orders
2. Generate the PDF with the custom template
3. Populate the fields from the ticket and approval data
4. Add the approver's digital signature

### 6. Integration with Cron Job

Set up a cron job to run the script periodically:

```bash
# Run the purchase order processor every 15 minutes
*/15 * * * * php /path/to/your/script.php > /dev/null 2>&1
```

### 7. Setting Up Digital Signatures

For the manager approval signatures, you have several options:

1. **Pre-stored signatures**: Have managers upload their signatures once
2. **Digital signature service**: Integrate with DocuSign or similar
3. **In-app signature**: Create a custom page where managers can draw their signature on approval

### 8. User Interface Customizations

To make this user-friendly, you might want to:

1. Create a custom ticket form for purchase requests
2. Add a simplified view for managers to see pending approvals
3. Include clear status indicators at each stage

### Implementation Notes

1. You'll need to adjust the database queries based on your specific GLPI setup and plugins
2. The signature implementation will depend on your organization's security requirements
3. Test thoroughly in a development environment before deploying to production

Script from Claude.ai:

<?php
// config.php - Configuration settings
define('GLPI_URL', 'http://your-glpi-server');
define('GLPI_API_TOKEN', 'your-api-token');
define('PDF_TEMPLATE_ID', 123); // ID of your custom PDF template

// Script to monitor approved purchase orders and generate PDFs
require_once 'path/to/glpi/inc/includes.php';

// Initialize session and check permissions
Session::init();
if (!Session::getLoginUserID()) {
    Session::checkLoginUser();
}

// Get approved purchase orders
$query = "
    SELECT t.id as ticket_id, t.name, t.content, 
           u.id as requester_id, u.name as requester_name,
           a.id as approval_id, a.users_id_approver, a.comment
    FROM glpi_tickets t
    JOIN glpi_users u ON t.users_id_recipient = u.id
    JOIN glpi_ticketvalidations a ON t.id = a.tickets_id
    WHERE a.status = " . CommonITILValidation::ACCEPTED . "
    AND t.tags LIKE '%purchase_order%'
    AND t.is_deleted = 0
    AND NOT EXISTS (
        SELECT 1 FROM glpi_documents d
        JOIN glpi_documents_items di ON d.id = di.documents_id
        WHERE di.items_id = t.id
        AND di.itemtype = 'Ticket'
        AND d.name LIKE 'PO-%'
    )
";

$result = $DB->query($query);

while ($data = $DB->fetchAssoc($result)) {
    $ticket_id = $data['ticket_id'];
    $approver_id = $data['users_id_approver'];
    
    // Get approver details
    $approver = new User();
    $approver->getFromDB($approver_id);
    
    // Get order items from the ticket
    $items = getOrderItemsFromTicket($ticket_id);
    
    // Generate purchase order number
    $po_number = 'PO-' . date('Y') . '-' . str_pad($ticket_id, 6, '0', STR_PAD_LEFT);
    
    // Generate PDF using custom template
    $pdf_file = generatePDF($po_number, $data, $approver, $items);
    
    // Attach PDF to the ticket
    attachDocumentToTicket($ticket_id, $pdf_file, $po_number);
    
    // Update ticket status
    updateTicketStatus($ticket_id, 'Processing');
    
    // Notify requester
    NotificationEvent::raiseEvent('purchase_order_approved', new Ticket(), ['id' => $ticket_id]);
}

/**
 * Get order items from ticket
 */
function getOrderItemsFromTicket($ticket_id) {
    global $DB;
    
    // This is a placeholder - you'll need to adapt based on your actual data structure
    $query = "
        SELECT item_name, quantity, unit_price, description
        FROM glpi_plugin_order_items
        WHERE tickets_id = $ticket_id
    ";
    
    $items = [];
    $result = $DB->query($query);
    while ($data = $DB->fetchAssoc($result)) {
        $items[] = $data;
    }
    
    return $items;
}

/**
 * Generate PDF with custom template
 */
function generatePDF($po_number, $ticket_data, $approver, $items) {
    // Load PDF template
    $template = new PluginPdfTemplate();
    $template->getFromDB(PDF_TEMPLATE_ID);
    
    // Initialize PDF generator
    $pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
    
    // Set document information
    $pdf->SetCreator('GLPI');
    $pdf->SetAuthor('GLPI Automated System');
    $pdf->SetTitle('Purchase Order: ' . $po_number);
    
    // Set template content
    $html = $template->getContent();
    
    // Replace placeholders with ticket data
    $html = str_replace('{{PO_NUMBER}}', $po_number, $html);
    $html = str_replace('{{DATE}}', date('Y-m-d'), $html);
    $html = str_replace('{{REQUESTER_NAME}}', $ticket_data['requester_name'], $html);
    $html = str_replace('{{TICKET_ID}}', $ticket_data['ticket_id'], $html);
    $html = str_replace('{{APPROVER_NAME}}', $approver->fields['realname'] . ' ' . $approver->fields['firstname'], $html);
    $html = str_replace('{{APPROVAL_DATE}}', date('Y-m-d H:i:s'), $html);
    
    // Add digital signature
    // Fetch approver's signature from database or generate one
    $signature_img = getApproverSignature($approver->getID());
    $html = str_replace('{{SIGNATURE}}', '<img src="' . $signature_img . '" style="height: 50px;" />', $html);
    
    // Add items table
    $items_html = '<table border="1" cellpadding="5"><tr><th>Item</th><th>Qty</th><th>Unit Price</th><th>Total</th></tr>';
    $total = 0;
    foreach ($items as $item) {
        $item_total = $item['quantity'] * $item['unit_price'];
        $total += $item_total;
        $items_html .= '<tr>
            <td>' . htmlspecialchars($item['item_name']) . '</td>
            <td>' . $item['quantity'] . '</td>
            <td>$' . number_format($item['unit_price'], 2) . '</td>
            <td>$' . number_format($item_total, 2) . '</td>
        </tr>';
    }
    $items_html .= '<tr><td colspan="3" align="right"><strong>Total:</strong></td><td>$' . number_format($total, 2) . '</td></tr></table>';
    $html = str_replace('{{ITEMS_TABLE}}', $items_html, $html);
    
    // Output PDF
    $pdf->AddPage();
    $pdf->writeHTML($html, true, false, true, false, '');
    
    // Save to file
    $file_path = GLPITMPDIR . '/' . $po_number . '.pdf';
    $pdf->Output($file_path, 'F');
    
    return $file_path;
}

/**
 * Get approver's signature image
 */
function getApproverSignature($approver_id) {
    // Placeholder - you'll need to implement based on how signatures are stored
    // Options:
    // 1. Pre-stored signature images
    // 2. Generated signature based on name
    // 3. Signature capture system
    
    // For this example, we'll assume signatures are stored as images
    $signature_path = '/path/to/signatures/' . $approver_id . '.png';
    
    if (file_exists($signature_path)) {
        return $signature_path;
    } else {
        // Generate a basic text signature as fallback
        return generateTextSignature($approver_id);
    }
}

/**
 * Generate a text-based signature image if no image is available
 */
function generateTextSignature($approver_id) {
    // Get approver name
    $approver = new User();
    $approver->getFromDB($approver_id);
    $name = $approver->fields['realname'] . ' ' . $approver->fields['firstname'];
    
    // Create image
    $img = imagecreatetruecolor(300, 80);
    $bg = imagecolorallocate($img, 255, 255, 255);
    $text_color = imagecolorallocate($img, 0, 0, 0);
    
    // Fill background
    imagefilledrectangle($img, 0, 0, 300, 80, $bg);
    
    // Add text
    $font = 5; // Built-in font
    imagestring($img, $font, 10, 30, "Approved by: " . $name, $text_color);
    
    // Save image
    $file_path = GLPITMPDIR . '/signature_' . $approver_id . '.png';
    imagepng($img, $file_path);
    imagedestroy($img);
    
    return $file_path;
}

/**
 * Attach document to ticket
 */
function attachDocumentToTicket($ticket_id, $file_path, $po_number) {
    $doc = new Document();
    $doc_item = new Document_Item();
    
    $doc_id = $doc->add([
        'name' => $po_number,
        'filename' => basename($file_path),
        'filepath' => $file_path,
        'documentcategories_id' => 0, // Set appropriate category
        'mime' => 'application/pdf',
        'date_mod' => $_SESSION['glpi_currenttime'],
        'users_id' => Session::getLoginUserID(),
        'entities_id' => $_SESSION['glpiactive_entity']
    ]);
    
    if ($doc_id) {
        $doc_item->add([
            'documents_id' => $doc_id,
            'itemtype' => 'Ticket',
            'items_id' => $ticket_id
        ]);
    }
}

/**
 * Update ticket status
 */
function updateTicketStatus($ticket_id, $status) {
    $ticket = new Ticket();
    $ticket->getFromDB($ticket_id);
    
    // Map status string to ID
    $status_map = [
        'New' => 1,
        'Processing' => 2,
        'Resolved' => 5,
        'Closed' => 6
    ];
    
    $ticket->update([
        'id' => $ticket_id,
        'status' => $status_map[$status] ?? 2
    ]);
}

Last edited by eLBruto (2025-02-25 12:25:51)


eLBruto
GLPI version 10.0.17 , Server : Ubuntu LTS 24.04
Total beginner.

Offline

#2 2025-02-25 11:52:15

cconard96
Moderator
Registered: 2018-07-31
Posts: 3,285
Website

Re: [SOLVED]GLPI Order Purchase Orders though tickets

"I have lost faith in ChatGPT and attempted to set this up with Claude.ai"

No AI is going to give you good information.

"I'm posting here because unfortunately for GLPI it doesn't have the Test Environment -> Production Evirnoment feature to be able to test something out before deployment"

Usually people have a separate installation of GLPI for testing. I personally wouldn't trust any software that claims to manage a test and production environment in the same installation.


"Script from Claude.ai:"

This is nonsense in a several ways, even without knowing much about the plugins it claims to work with.
- There is no "tags" column in the ticket table
- There is no "users_id_approver" column in the ticket validation table
- There is no "comment" column in the ticket validation table
- There is no "item_name", "quantity", "unit_price", "description", or "tickets_id" columns in the order plugin's order_item table
- No checks to avoid sending notifications for the same tickets over and over
- Triggers a notification event that doesn't exist in GLPI or the plugins
- There is no "PDF Generation plugin". There is a "PDF" plugin, but it doesn't allow for custom templates like this claims.

There are probably a lot more issues, but I'm not spending the time to review everything. I also haven't done a review for security, but you shouldn't trust an AI will ensure data is properly sanitized and give you code that is secure to avoid SQL injection or other types of vulnerabiltiies.

You will be far, far better off relying on the real people that are trained GLPI professionals and official partners to try to get your custom requirements implemented.
https://glpi-project.org/partners/

Alternatively, you could research GLPI and its plugin ecosystem for yourself and, if still needed, learn about creating a custom GLPI plugin yourself.
Some resources to get started:
GLPI User Documentation - https://glpi-user-documentation.readthe … fr/latest/
GLPI Developer Documentation - https://glpi-developer-documentation.re … en/master/
GLPI Plugin Catalog - https://plugins.glpi-project.org/


GLPI Collaborator and Plugin Developer.
My non-English comments are automated translations. Sorry for any confusion that causes.
Mes commentaires non anglais sont des traductions automatiques. Désolé pour toute confusion qui cause.
Mis comentarios que no están en inglés son traducciones automáticas. Perdón por cualquier confusión que cause.

Offline

#3 2025-02-25 12:25:24

eLBruto
Member
Registered: 2025-01-16
Posts: 23

Re: [SOLVED]GLPI Order Purchase Orders though tickets

That's all I needed to hear ! Thank you Conrad and sorry for posting this but I thought I'd rather ask before I do something really stupid.


eLBruto
GLPI version 10.0.17 , Server : Ubuntu LTS 24.04
Total beginner.

Offline

#4 2025-02-25 13:11:08

cconard96
Moderator
Registered: 2018-07-31
Posts: 3,285
Website

Re: [SOLVED]GLPI Order Purchase Orders though tickets

No worries. There is nothing wrong with asking.


GLPI Collaborator and Plugin Developer.
My non-English comments are automated translations. Sorry for any confusion that causes.
Mes commentaires non anglais sont des traductions automatiques. Désolé pour toute confusion qui cause.
Mis comentarios que no están en inglés son traducciones automáticas. Perdón por cualquier confusión que cause.

Offline

Board footer

Powered by FluxBB