2026-01-12 03:00:48 -08:00
|
|
|
//go:build never
|
|
|
|
|
// +build never
|
|
|
|
|
|
2026-01-25 05:30:43 -08:00
|
|
|
package documents
|
2026-01-12 03:00:48 -08:00
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
|
|
|
|
"os"
|
|
|
|
|
"path/filepath"
|
|
|
|
|
|
|
|
|
|
api "github.com/pdfcpu/pdfcpu/pkg/api"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// finalizeWithTerms tries to append the standard Terms & Conditions PDF
|
|
|
|
|
// to the generated document. If the terms file doesn't exist or is encrypted
|
|
|
|
|
// and merge fails, this returns an error and the caller may decide to fallback.
|
|
|
|
|
//
|
|
|
|
|
// outputDir: directory where PDFs live (e.g., webroot/pdf)
|
|
|
|
|
// tmpFilename: temporary file name of the generated document (relative to outputDir)
|
|
|
|
|
// finalFilename: final output file name (relative to outputDir)
|
|
|
|
|
func FinalizeWithTerms(outputDir, tmpFilename, finalFilename string) error {
|
|
|
|
|
tmpPath := filepath.Join(outputDir, tmpFilename)
|
|
|
|
|
finalPath := filepath.Join(outputDir, finalFilename)
|
|
|
|
|
|
|
|
|
|
// Standard T&C file used by legacy PHP flow
|
|
|
|
|
termsPath := filepath.Join(outputDir, "CMC_terms_and_conditions2006_A4.pdf")
|
|
|
|
|
|
|
|
|
|
if _, err := os.Stat(termsPath); err != nil {
|
|
|
|
|
// Terms file missing: just rename tmp to final
|
|
|
|
|
return FallbackFinalize(outputDir, tmpFilename, finalFilename)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Merge tmp (first) + terms (second) into final
|
|
|
|
|
inputs := []string{tmpPath, termsPath}
|
|
|
|
|
if err := api.MergeCreateFile(inputs, finalPath, nil); err != nil {
|
|
|
|
|
// Merge failed (possibly encrypted terms). Return error so caller can fallback
|
|
|
|
|
return fmt.Errorf("pdf merge failed: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Cleanup tmp file on success
|
|
|
|
|
_ = os.Remove(tmpPath)
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// finalizeWithTermsAndExtras is like finalizeWithTerms but allows appending additional PDFs.
|
|
|
|
|
// extras should be absolute or relative to outputDir. Non-existent extras are ignored.
|
|
|
|
|
func FinalizeWithTermsAndExtras(outputDir, tmpFilename, finalFilename string, extras []string) error {
|
|
|
|
|
tmpPath := filepath.Join(outputDir, tmpFilename)
|
|
|
|
|
finalPath := filepath.Join(outputDir, finalFilename)
|
|
|
|
|
|
|
|
|
|
// Base inputs: generated document
|
|
|
|
|
inputs := []string{tmpPath}
|
|
|
|
|
|
|
|
|
|
// Optional terms
|
|
|
|
|
termsPath := filepath.Join(outputDir, "CMC_terms_and_conditions2006_A4.pdf")
|
|
|
|
|
if _, err := os.Stat(termsPath); err == nil {
|
|
|
|
|
inputs = append(inputs, termsPath)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Append any extra files (if they exist)
|
|
|
|
|
for _, p := range extras {
|
|
|
|
|
ap := p
|
|
|
|
|
if !filepath.IsAbs(ap) {
|
|
|
|
|
ap = filepath.Join(outputDir, p)
|
|
|
|
|
}
|
|
|
|
|
if _, err := os.Stat(ap); err == nil {
|
|
|
|
|
inputs = append(inputs, ap)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If we only have the tmp file, just rename
|
|
|
|
|
if len(inputs) == 1 {
|
|
|
|
|
return FallbackFinalize(outputDir, tmpFilename, finalFilename)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if err := api.MergeCreateFile(inputs, finalPath, nil); err != nil {
|
|
|
|
|
return fmt.Errorf("pdf merge failed: %w", err)
|
|
|
|
|
}
|
|
|
|
|
_ = os.Remove(tmpPath)
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// fallbackFinalize renames the tmp file to the final filename, overwriting if needed.
|
|
|
|
|
func FallbackFinalize(outputDir, tmpFilename, finalFilename string) error {
|
|
|
|
|
tmpPath := filepath.Join(outputDir, tmpFilename)
|
|
|
|
|
finalPath := filepath.Join(outputDir, finalFilename)
|
|
|
|
|
|
|
|
|
|
// Remove any existing final file
|
|
|
|
|
_ = os.Remove(finalPath)
|
|
|
|
|
return os.Rename(tmpPath, finalPath)
|
|
|
|
|
}
|