commit e7c8c09ca3c36ff0531caca3e47244c0f50d22bd Author: admin.suherdy Date: Wed Dec 17 14:30:04 2025 +0700 first commit diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..cde864b --- /dev/null +++ b/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +from . import models diff --git a/__manifest__.py b/__manifest__.py new file mode 100644 index 0000000..c5bda44 --- /dev/null +++ b/__manifest__.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +{ + 'name': 'Sign Image Field', + 'version': '1.0', + 'category': 'Document Management', + 'summary': 'Add Image field to Sign module', + 'description': """ +This module extends the Odoo Sign module to allow users to upload images as a field type. + """, + 'depends': ['sign'], + 'data': [ + 'data/sign_item_type_data.xml', + ], + 'assets': { + 'web.assets_frontend': [ + 'sign_image_field/static/src/js/sign_image_upload.js', + 'sign_image_field/static/src/xml/sign_items_image.xml', + ], + 'web.assets_backend': [ + 'sign_image_field/static/src/js/sign_image_upload.js', + 'sign_image_field/static/src/xml/sign_items_image.xml', + ], + 'sign.assets_public_sign': [ + 'sign_image_field/static/src/js/sign_image_upload.js', + 'sign_image_field/static/src/xml/sign_items_image.xml', + ] + }, + 'installable': True, + 'application': False, + 'license': 'OEEL-1', +} diff --git a/__pycache__/__init__.cpython-312.pyc b/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000..bc933a5 Binary files /dev/null and b/__pycache__/__init__.cpython-312.pyc differ diff --git a/data/sign_item_type_data.xml b/data/sign_item_type_data.xml new file mode 100644 index 0000000..78885c0 --- /dev/null +++ b/data/sign_item_type_data.xml @@ -0,0 +1,12 @@ + + + + Image + image + fa-image + Upload an image + Click to upload image + 0.2 + 0.05 + + diff --git a/models/__init__.py b/models/__init__.py new file mode 100644 index 0000000..5da7954 --- /dev/null +++ b/models/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +from . import sign_item_type diff --git a/models/__pycache__/__init__.cpython-312.pyc b/models/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000..fc2c617 Binary files /dev/null and b/models/__pycache__/__init__.cpython-312.pyc differ diff --git a/models/__pycache__/sign_item_type.cpython-312.pyc b/models/__pycache__/sign_item_type.cpython-312.pyc new file mode 100644 index 0000000..a25abc5 Binary files /dev/null and b/models/__pycache__/sign_item_type.cpython-312.pyc differ diff --git a/models/sign_item_type.py b/models/sign_item_type.py new file mode 100644 index 0000000..58db8e6 --- /dev/null +++ b/models/sign_item_type.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import fields, models + + +class SignItemType(models.Model): + _inherit = "sign.item.type" + + item_type = fields.Selection(selection_add=[('image', "Image")], ondelete={'image': 'cascade'}) diff --git a/static/src/js/sign_image_upload.js b/static/src/js/sign_image_upload.js new file mode 100644 index 0000000..2488af4 --- /dev/null +++ b/static/src/js/sign_image_upload.js @@ -0,0 +1,59 @@ +/** @odoo-module **/ + +import { patch } from "@web/core/utils/patch"; +import { SignablePDFIframe } from "@sign/components/sign_request/signable_PDF_iframe"; + +patch(SignablePDFIframe.prototype, { + enableCustom(signItem) { + super.enableCustom(signItem); + if (signItem.data.type === 'image') { + const input = signItem.el.querySelector('.o_sign_image_upload_input'); + if (!input) return; + + signItem.el.addEventListener('click', (e) => { + if (this.readonly || signItem.data.responsible !== this.currentRole) return; + // Prevent recursive click if clicking the input itself bubbles up + if (e.target !== input) { + input.click(); + } + }); + + input.addEventListener('change', (e) => { + const file = e.target.files[0]; + if (!file) return; + const reader = new FileReader(); + reader.onload = () => { + const result = reader.result; + signItem.el.dataset.value = result; + // Manually update the DOM to show the image + const img = signItem.el.querySelector('img'); + if (img) { + img.src = result; + } else { + // Remove placeholder if it exists + const placeholder = signItem.el.querySelector('.o_placeholder'); + if (placeholder) placeholder.remove(); + + const newImg = document.createElement('img'); + newImg.src = result; + newImg.style.maxWidth = '100%'; + newImg.style.maxHeight = '100%'; + newImg.style.objectFit = 'contain'; + + signItem.el.appendChild(newImg); + } + + this.handleInput(); // Trigger validation check + }; + reader.readAsDataURL(file); + }); + } + }, + + getSignatureValueFromElement(item) { + if (item.data.type === 'image') { + return item.el.dataset.value || false; + } + return super.getSignatureValueFromElement(item); + } +}); diff --git a/static/src/xml/sign_items_image.xml b/static/src/xml/sign_items_image.xml new file mode 100644 index 0000000..00d0ef3 --- /dev/null +++ b/static/src/xml/sign_items_image.xml @@ -0,0 +1,38 @@ + + + + + + + +
+ + + + + + + + + + +
+
+
+ + +
+
+ + + + + + + + + +
+
+
+