Kali ini om Gee ingin berbagi cerita pada sobat coders yang berawal dari permintaan customer untuk mencari solusi terbaik dari pembuatan signature di invoice yang harus mewakili beberapa kantor cabang dan beberapa financial manager yang beranggung jawab dalam tanda tangan digital pada setiap invoice.
Oke langsung aja kita mulai bahas yuk, pertama-tama kita identifikasikan masalah:
- Lingkungan Multi-Company
Perusahaan memiliki beberapa entitas anak cabang di Odoo, di mana masing-masing entitas wajib menggunakan stempel resmi yang berbeda. - Pergantian Manajemen (Turnover Finance Manager)
Hari ini transaksi disetujui oleh Finance Manager A, bulan depan posisi tersebut digantikan oleh Manager B. Jika tanda tangan dipanggil secara live dari master user saat cetak PDF, atau di-hardcode di XML, developer harus selalu mengedit codingan atau views setiap kali ada pergantian personel. - Integritas Audit & Historis Dokumen
Invoice yang di-post 6 bulan lalu oleh Manager A harus tetap menampilkan tanda tangan Manager A saat dicetak ulang hari ini, meskipun posisi Finance Manager saat ini sudah dipegang oleh Manager B.
Dengan kondisi itu tentu penanganan nya memang agak sedikit "Tricky" alias bagaimana harus kita menginherit modul base yang ada tanpa mengganggu proses operasional yang sudah ada. Arsitektur yang ideal adalah mengunci hasil penggabungan (combined signature) secara permanen pada record account.move tepat di detik invoice di-post, tanpa perlu lagi menyentuh source code saat terjadi dinamika tim.
Arsitektur & Alur Kerja Backend (Pillow + Odoo 16)

Proses pemuatan gambar gabungan mengandalkan pustaka Pillow (PIL) yang dieksekusi melalui override method action_post pada model account.move.
- Penambahan field image di res.partner / res.users sebagai signature image dan field image di res.company sebagi stempel image
- Triggering Saat Post: Gambar gabungan hanya diproses saat transaksi disetujui (action_post). Dokumen draft tidak menyimpan overhead pemrosesan data biner, dan begitu di-post, hasilnya terkunci permanen di invoice tersebut.
- Pengambilan Data Dynamic & Aman: Sistem membaca signature milik user yang sedang melakukan aksi/post (self.invoice_user_id / self.env.user) dan gcs_signature dari perusahaan penerbit. Menggunakan getattr() untuk mencegah AttributeError jika salah satu field gambar belum diisi.
- Isolasi Multi-Company Safe: Mengakses data stempel perusahaan melalui self.company_id.sudo(), bukan self.env.company. Langkah ini menjamin gambar stempel yang diambil selalu sesuai dengan perusahaan transaksi, bukan tergantung perusahaan aktif di session browser user.
Komposisi & Visual Layouting dengan Pillow
Proses manipulasi kanvas transparan RGBA dilakukan melalui empat langkah utama:
- Decoding Base64: Mengonversi string Base64 dari field signature (res.users) dan gcs_signature (res.company) ke objek gambar RGBA Pillow.
- Resizing & Scaling: Mengatur ulang skala stempel (misalnya 200x200 px) menggunakan Resampling.LANCZOS agar ketajaman gambar tetap terjaga.
- Canvas Positioning:
- Tanda tangan diletakkan di sisi kiri kanvas (X=0, Y=30)
- Stempel ditempelkan pada koordinat kanan (stamp_x, Y=0) yang sedikit menimpa area tanda tangan untuk memberikan efek overlay stempel basah yang realistis.
- Encoding Back: Hasil gabungan dikonversi kembali ke format PNG Base64 dan disimpan ke field combined_signature
Keunggulan Pendekatan Ini untuk Long-Term Maintenance
- Zero Code Modification on Turnover: Saat ada pergantian Finance Manager, admin cukup mengunggah file tanda tangan baru di profile user master yang baru. Tidak ada deployment ulang atau modifikasi kode XML/Python.
- PDF Rendering Konsisten: Mengeliminasi keterbatasan CSS position: absolute pada engine wkhtmltopdf yang sering kali tidak stabil antar-versi OS server.
- Single Source of Truth: Berkas gambar gabungan tersimpan permanen sebagai attachment invoice, sehingga siap dikirimkan via API, WhatsApp Gateway, atau Lampiran Email tanpa perlu merender ulang template QWeb.
Oke sobat coders, demikian paparan singkat pengejawantahan solusi dari kebutuhan client yang sederhana tapi ever lasting karena sebagai programmer kita harus mempunyai jiwa visioner kedepan agar hasil coding kita bisa digunakan terus menjadi manfaat bagi partner/customer
Semoga pendekatan teknis ini memberikan pencerahan dan menghemat waktu debugging Sobat Coders saat menggarap kustomisasi laporan invoice di Odoo 16. Selamat mencoba, dan happy coding!