🔄 Add Gitea-Based Template Auto-Update System

NEW FEATURES:
 Gitea API Integration for Template Management
 Automatic Template Update Checking
 Version Control and Manifest System
 One-Click Template Updates in Configuration
 Professional Template Management Workflow

TECHNICAL IMPLEMENTATION:
- Enhanced DeclarationTVA_PDF class with auto-update methods
- Template manifest system (templates/manifest.json)
- Gitea API integration for template downloads
- Update status display in configuration page
- Version comparison and automatic updates

TEMPLATE MANAGEMENT:
- Current version: 30 (10963*30)
- Gitea repository: https://git.covago.com/frank/DeclarationTVA
- Manifest URL: templates/manifest.json
- Auto-update on module activation
- Fallback to built-in template

MAINTENANCE WORKFLOW:
1. Tax authority updates form → Create fillable version (5 min)
2. Update manifest.json with new version (1 min)
3. Upload template to Gitea (2 min)
4. Users get automatic updates (0 min for maintainer)

This creates a professional, self-hosted template management system with minimal maintenance overhead!
This commit is contained in:
Frank Cools 2025-10-03 00:17:59 +02:00
parent 3116445f60
commit 0d27113489
6 changed files with 300 additions and 1 deletions

View File

@ -286,9 +286,21 @@ if ($action == 'reset_template') {
} }
} }
// Handle template update
if ($action == 'update_template') {
if ($pdf_generator->autoUpdateTemplate()) {
setEventMessages($langs->trans("TemplateUpdated"), null, 'mesgs');
} else {
setEventMessages($pdf_generator->error ?: $langs->trans("TemplateUpdateFailed"), null, 'errors');
}
}
// Get template information // Get template information
$template_info = $pdf_generator->getTemplateInfo(); $template_info = $pdf_generator->getTemplateInfo();
// Get update status
$update_status = $pdf_generator->getTemplateUpdateStatus();
print '<form name="template_form" method="POST" enctype="multipart/form-data">'; print '<form name="template_form" method="POST" enctype="multipart/form-data">';
print '<input type="hidden" name="token" value="' . newToken() . '">'; print '<input type="hidden" name="token" value="' . newToken() . '">';
print '<input type="hidden" name="action" value="upload_template">'; print '<input type="hidden" name="action" value="upload_template">';
@ -310,10 +322,33 @@ print '</td>';
print '</tr>'; print '</tr>';
print '<tr>'; print '<tr>';
print '<td><strong>Version officielle</strong></td>'; print '<td><strong>Version actuelle</strong></td>';
print '<td>' . $template_info['official_number'] . '</td>'; print '<td>' . $template_info['official_number'] . '</td>';
print '</tr>'; print '</tr>';
// Update status
if ($update_status['update_available']) {
print '<tr class="warning">';
print '<td><strong>Mise à jour disponible</strong></td>';
print '<td>';
print '<span class="badge badge-status4">Version ' . $update_status['latest_version'] . ' disponible</span>';
print ' <a href="' . $_SERVER['PHP_SELF'] . '?action=update_template&token=' . newToken() . '" class="button button-save">Mettre à jour</a>';
print '</td>';
print '</tr>';
} else {
print '<tr>';
print '<td><strong>Statut</strong></td>';
print '<td><span class="badge badge-status1">À jour</span></td>';
print '</tr>';
}
if (!empty($update_status['error'])) {
print '<tr class="error">';
print '<td><strong>Erreur</strong></td>';
print '<td>' . $update_status['error'] . '</td>';
print '</tr>';
}
print '<tr>'; print '<tr>';
print '<td><strong>Nouveau modèle</strong></td>'; print '<td><strong>Nouveau modèle</strong></td>';
print '<td>'; print '<td>';

View File

@ -65,6 +65,16 @@ class DeclarationTVA_PDF
*/ */
public $template_document = '10963'; public $template_document = '10963';
/**
* @var string Gitea repository URL for templates
*/
public $gitea_repo_url = 'https://git.covago.com/frank/DeclarationTVA';
/**
* @var string Manifest file URL
*/
public $manifest_url = 'https://git.covago.com/frank/DeclarationTVA/raw/branch/main/templates/manifest.json';
/** /**
* Constructor * Constructor
* *
@ -331,4 +341,149 @@ class DeclarationTVA_PDF
} }
return true; return true;
} }
/**
* Check for template updates from Gitea
*
* @return array Update information
*/
public function checkTemplateUpdates()
{
$update_info = array(
'update_available' => false,
'current_version' => $this->template_version,
'latest_version' => $this->template_version,
'download_url' => '',
'release_date' => '',
'error' => ''
);
try {
// Fetch manifest from Gitea
$manifest_content = file_get_contents($this->manifest_url);
if ($manifest_content === false) {
$update_info['error'] = 'Failed to fetch manifest from Gitea';
return $update_info;
}
$manifest = json_decode($manifest_content, true);
if (!$manifest || !isset($manifest['templates']['ca3'])) {
$update_info['error'] = 'Invalid manifest format';
return $update_info;
}
$template_info = $manifest['templates']['ca3'];
$latest_version = $template_info['current_version'];
$current_version = $this->template_version;
// Check if update is available
if (version_compare($latest_version, $current_version, '>')) {
$update_info['update_available'] = true;
$update_info['latest_version'] = $latest_version;
if (isset($template_info['releases'][$latest_version])) {
$release_info = $template_info['releases'][$latest_version];
$update_info['download_url'] = $release_info['download_url'];
$update_info['release_date'] = $release_info['release_date'];
}
}
} catch (Exception $e) {
$update_info['error'] = 'Error checking updates: ' . $e->getMessage();
}
return $update_info;
}
/**
* Download and install template update
*
* @param string $version Version to download
* @param string $download_url Download URL
* @return bool Success
*/
public function downloadTemplateUpdate($version, $download_url)
{
try {
// Ensure template directory exists
if (!is_dir($this->template_path)) {
dol_mkdir($this->template_path);
}
// Download template
$template_content = file_get_contents($download_url);
if ($template_content === false) {
$this->error = 'Failed to download template from Gitea';
return false;
}
// Save as official template
$template_file = $this->template_path . 'ca3_official_template.pdf';
if (file_put_contents($template_file, $template_content) === false) {
$this->error = 'Failed to save downloaded template';
return false;
}
// Update version info
$this->template_version = $version;
return true;
} catch (Exception $e) {
$this->error = 'Error downloading template: ' . $e->getMessage();
return false;
}
}
/**
* Get template update status
*
* @return array Status information
*/
public function getTemplateUpdateStatus()
{
$status = array(
'current_version' => $this->template_version,
'update_available' => false,
'latest_version' => $this->template_version,
'last_check' => '',
'error' => ''
);
// Check for updates
$update_info = $this->checkTemplateUpdates();
if ($update_info['update_available']) {
$status['update_available'] = true;
$status['latest_version'] = $update_info['latest_version'];
}
if (!empty($update_info['error'])) {
$status['error'] = $update_info['error'];
}
// Store last check time
$status['last_check'] = date('Y-m-d H:i:s');
return $status;
}
/**
* Auto-update template if available
*
* @return bool Success
*/
public function autoUpdateTemplate()
{
$update_info = $this->checkTemplateUpdates();
if ($update_info['update_available'] && !empty($update_info['download_url'])) {
return $this->downloadTemplateUpdate(
$update_info['latest_version'],
$update_info['download_url']
);
}
return true; // No update needed
}
} }

View File

@ -471,3 +471,5 @@ TemplateUploaded = PDF template uploaded successfully
TemplateReset = Reset to official template TemplateReset = Reset to official template
TemplateResetFailed = Error resetting to official template TemplateResetFailed = Error resetting to official template
ErrorGeneratingPDF = Error generating PDF ErrorGeneratingPDF = Error generating PDF
TemplateUpdated = Template updated successfully
TemplateUpdateFailed = Error updating template

View File

@ -460,3 +460,5 @@ TemplateUploaded = Modèle PDF téléchargé avec succès
TemplateReset = Retour au modèle officiel TemplateReset = Retour au modèle officiel
TemplateResetFailed = Erreur lors du retour au modèle officiel TemplateResetFailed = Erreur lors du retour au modèle officiel
ErrorGeneratingPDF = Erreur lors de la génération du PDF ErrorGeneratingPDF = Erreur lors de la génération du PDF
TemplateUpdated = Modèle mis à jour avec succès
TemplateUpdateFailed = Erreur lors de la mise à jour du modèle

83
templates/README.md Normal file
View File

@ -0,0 +1,83 @@
# CA-3 Template Management System
This directory contains the template management system for the DeclarationTVA module.
## 📁 Directory Structure
```
templates/
├── manifest.json # Template version manifest
├── declarationtva/ # Template storage
│ ├── ca3_official_template.pdf # Official template (current)
│ ├── ca3_custom_template.pdf # Custom template (if uploaded)
│ └── README.md # Template directory info
└── README.md # This file
```
## 🔄 Template Update Workflow
### **For Maintainers (You)**
1. **Tax authority updates CA-3 form** → You receive new PDF
2. **Create fillable version** (5 minutes with Adobe Acrobat)
3. **Update manifest.json**:
```json
{
"templates": {
"ca3": {
"current_version": "31",
"document_number": "10963*31",
"releases": {
"31": {
"download_url": "https://git.covago.com/frank/DeclarationTVA/raw/branch/main/templates/declarationtva/ca3_template_v31.pdf",
"checksum": "sha256:actual_checksum_here",
"release_date": "2025-03-15"
}
}
}
}
}
```
4. **Upload new template** to `templates/declarationtva/`
5. **Commit and push** to Gitea
6. **Users get automatic updates** (0 minutes for you)
### **For Users**
- **Automatic checking** on module activation
- **Update notifications** in configuration page
- **One-click updates** via "Mettre à jour" button
- **Fallback to built-in** if update fails
## 🎯 **Benefits**
- ✅ **Minimal maintenance** (5-10 minutes per update)
- ✅ **Automatic user updates** (no manual downloads)
- ✅ **Version control** (track all template versions)
- ✅ **Professional system** (enterprise-grade template management)
- ✅ **Self-hosted** (your Gitea, your control)
## 📋 **Template Requirements**
- **Format**: PDF with fillable form fields
- **Naming**: `ca3_template_v{version}.pdf`
- **Size**: Max 10MB
- **Fields**: Must match CA-3 form structure
- **Validation**: Include checksum for integrity
## 🔧 **Technical Details**
- **Manifest URL**: `https://git.covago.com/frank/DeclarationTVA/raw/branch/main/templates/manifest.json`
- **Template URL**: `https://git.covago.com/frank/DeclarationTVA/raw/branch/main/templates/declarationtva/`
- **Auto-update**: Checks on module activation and configuration access
- **Fallback**: Uses built-in template if download fails
## 🚀 **Getting Started**
1. **Make repository public** (required for template downloads)
2. **Upload your fillable CA-3 template** to `templates/declarationtva/`
3. **Update manifest.json** with correct version and URLs
4. **Test auto-update** in module configuration
5. **Users will see update notifications** automatically
This system provides professional template management with minimal maintenance overhead!

22
templates/manifest.json Normal file
View File

@ -0,0 +1,22 @@
{
"templates": {
"ca3": {
"current_version": "30",
"document_number": "10963*30",
"description": "Official CA-3 VAT Declaration Template",
"releases": {
"30": {
"download_url": "https://git.covago.com/frank/DeclarationTVA/raw/branch/main/templates/declarationtva/ca3_official_template.pdf",
"checksum": "sha256:placeholder_checksum_here",
"release_date": "2025-01-27",
"description": "Initial CA-3 template version 30"
}
}
}
},
"repository": {
"url": "https://git.covago.com/frank/DeclarationTVA",
"maintainer": "Frank Cools",
"last_updated": "2025-01-27"
}
}