# PyPDF2 Compatibility Patch

## Overview

This patch addresses the PyPDF2 deprecation error that occurs when using PyPDF2 version 3.0.0 or higher with Odoo. The original error was:

```
PyPDF2.errors.DeprecationError: PdfFileWriter is deprecated and was removed in PyPDF2 3.0.0. Use PdfWriter instead.
```

## Problem

In PyPDF2 3.0.0, several classes and methods were deprecated and removed:
- `PdfFileWriter` → `PdfWriter`
- `PdfFileReader` → `PdfReader` 
- `addPage()` → `add_page()`
- `addMetadata()` → `add_metadata()`
- `getNumPages()` → `len(pages)`
- `getPage(n)` → `pages[n]`
- `appendPagesFromReader()` → `append_pages_from_reader()`
- `_addObject()` → `_add_object()`
- `cloneReaderDocumentRoot()` → `clone_reader_document_root()`

## Solution

This patch provides backward compatibility by creating wrapper classes that:
1. Inherit from the new PyPDF2 classes (`PdfWriter`, `PdfReader`)
2. Provide the old method signatures as compatibility methods
3. Gracefully handle both old and new PyPDF2 versions

## Files Modified

### 1. `odoo/tools/pdf.py`
- Added compatibility wrapper classes `PdfFileWriter` and `PdfFileReader`
- Updated import logic to handle both PyPDF2 2.x and 3.x
- Added method aliases for deprecated methods
- Updated `BrandedFileWriter` class to use new API with fallback

### 2. `odoo/addons/base/models/ir_actions_report.py`
- Added compatibility import logic
- Created local compatibility classes with required method aliases
- Added support for `numPages` property and related methods

## Implementation Details

### Critical PyPDF2 3.x Fix - Page Content Copying

In PyPDF2 3.x, `cloneReaderDocumentRoot()` only copies document structure, NOT content pages. This was causing 327-byte PDFs with no actual content. Modules using this method now include explicit page copying:

```python
writer.cloneReaderDocumentRoot(reader)
# Copy all pages from the reader to the writer (required for PyPDF2 3.x)
for page_num in range(reader.getNumPages()):
    page = reader.getPage(page_num)
    writer.addPage(page)
```

### Compatibility Import Pattern
```python
try:
    from PyPDF2 import PdfReader, PdfWriter
    
    # Create compatibility classes
    class PdfFileWriter(PdfWriter):
        def addPage(self, page):
            return self.add_page(page)
        
        def addMetadata(self, metadata):
            return self.add_metadata(metadata)
        
        def _addObject(self, obj):
            return self._add_object(obj)
    
    class PdfFileReader(PdfReader):
        def getNumPages(self):
            return len(self.pages)
        
        def getPage(self, page_num):
            return self.pages[page_num]

except ImportError:
    # Fallback to old API for older PyPDF2 versions
    from PyPDF2 import PdfFileWriter, PdfFileReader
```

### Method Compatibility Mapping
| Old Method (PyPDF2 < 3.0) | New Method (PyPDF2 ≥ 3.0) | Compatibility Method |
|---------------------------|---------------------------|---------------------|
| `PdfFileWriter.addPage()` | `PdfWriter.add_page()` | ✅ Wrapped |
| `PdfFileWriter.addMetadata()` | `PdfWriter.add_metadata()` | ✅ Wrapped |
| `PdfFileWriter._addObject()` | `PdfWriter._add_object()` | ✅ Wrapped |
| `PdfFileReader.getNumPages()` | `len(PdfReader.pages)` | ✅ Wrapped |
| `PdfFileReader.getPage()` | `PdfReader.pages[]` | ✅ Wrapped |
| `PdfFileWriter.appendPagesFromReader()` | `PdfWriter.append_pages_from_reader()` | ✅ Wrapped |
| `PdfFileWriter.cloneReaderDocumentRoot()` | `PdfWriter.clone_reader_document_root()` | ✅ Wrapped |

## Testing

The patch has been tested with:
- PyPDF2 3.0.0+ (new API)
- PyPDF2 2.x (old API via fallback)
- `OdooPdfFileWriter` instantiation
- PDF generation workflows
- Report generation (original error case)

## Branch Information

- **Branch**: `pdfwrite`
- **Based on**: Current main/master branch
- **Type**: Compatibility patch
- **Impact**: Backward compatible - no breaking changes

## Author

- **Developer**: Ernad Husremović (hernad@bring.out.ba)
- **Company**: bring.out.doo Sarajevo
- **Date**: 2025-09-02

## Related Issues

This patch resolves the PyPDF2 deprecation error encountered in:
- Report generation (`/report/pdf/` endpoints)
- PDF merge operations
- PDF attachment handling
- Account EDI PDF operations

## Future Considerations

While this patch provides immediate compatibility, consider:
1. Eventually migrating to the new PyPDF2 API directly
2. Monitoring PyPDF2 changelog for future deprecations
3. Testing with future PyPDF2 versions

## Installation

This patch is automatically applied when using the `pdfwrite` branch. No additional installation steps required.