3
0
Fork 0

web_widget_digital_signature_sale_order was moved in sale workflow https://github.com/OCA/sale-workflow/pull/252

Rename module this module in web_widget_digitized_signature
8.0
archetipo 2015-12-22 17:50:41 +01:00
parent 7f8e41a6e3
commit 59f262c01b
21 changed files with 258 additions and 393 deletions

View File

@ -1,53 +0,0 @@
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
=====================================
Web Digital Signature for sale orders
=====================================
This module adds a signature field to sale order form, so that salesman can let customers sign their quotations.
Usage
=====
Just open a quotation and sign it.
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
:alt: Try me on Runbot
:target: https://runbot.odoo-community.org/runbot/162/8.0
Bug Tracker
===========
Bugs are tracked on `GitHub Issues
<https://github.com/OCA/web/issues>`_. In case of trouble, please
check there if your issue has already been reported. If you spotted it first,
help us smashing it by providing a detailed and welcomed `feedback
<https://github.com/OCA/
web/issues/new?body=module:%20
web_widget_digital_signature_sale_order%0Aversion:%20
8.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Credits
=======
Contributors
------------
* Lorenzo Battistini <lorenzo.battistini@agilebg.com>
Maintainer
----------
.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org
This module is maintained by the OCA.
OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
To contribute to this module, please visit https://odoo-community.org.

View File

@ -1,10 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright 2015 Lorenzo Battistini - Agile Business Group
#
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
#
##############################################################################
from . import models

View File

@ -1,27 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright 2015 Lorenzo Battistini - Agile Business Group
#
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
#
##############################################################################
{
"name": "Web Digital Signature for sale orders",
"version": "8.0.1.0.0",
"author": "Agile Business Group, "
"Odoo Community Association (OCA)",
"category": 'web',
"license": "AGPL-3",
'depends': ['web_widget_digital_signature', 'sale'],
'data': [
'views/sale_order_view.xml'
],
'images': [
'images/so_signature.png',
],
'website': 'http://www.agilebg.com',
'installable': True,
'auto_install': False,
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

View File

@ -1,10 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright 2015 Lorenzo Battistini - Agile Business Group
#
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
#
##############################################################################
from . import sale_order

View File

@ -1,16 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright 2015 Lorenzo Battistini - Agile Business Group
#
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
#
##############################################################################
from openerp import models, fields
class Users(models.Model):
_inherit = 'sale.order'
signature_image = fields.Binary(string='Signature')

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

View File

@ -1,19 +0,0 @@
<?xml version="1.0" ?>
<openerp>
<data>
<record id="view_order_form_signature" model="ir.ui.view">
<field name="name">view_order_form_signature</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_order_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='note']" position="after">
<div class="oe_clear"/>
<label for="signature_image" class="oe_edit_only"/>
<h2><field name="signature_image" widget="signature" width="400" height="100"/></h2>
</xpath>
</field>
</record>
</data>
</openerp>

View File

@ -30,7 +30,7 @@ check there if your issue has already been reported. If you spotted it first,
help us smashing it by providing a detailed and welcomed `feedback help us smashing it by providing a detailed and welcomed `feedback
<https://github.com/OCA/ <https://github.com/OCA/
web/issues/new?body=module:%20 web/issues/new?body=module:%20
web_widget_digital_signature%0Aversion:%20 web_widget_digitized_signature%0Aversion:%20
8.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_. 8.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Credits Credits

View File

@ -12,7 +12,7 @@
############################################################################## ##############################################################################
{ {
"name": "Web Digital Signature", "name": "Web Widget Digitized Signature",
"version": "8.0.1.0.0", "version": "8.0.1.0.0",
"author": "Serpent Consulting Services Pvt. Ltd., " "author": "Serpent Consulting Services Pvt. Ltd., "
"Odoo Community Association (OCA)", "Odoo Community Association (OCA)",

View File

Before

Width:  |  Height:  |  Size: 8.9 KiB

After

Width:  |  Height:  |  Size: 8.9 KiB

View File

@ -1,246 +1,246 @@
(function($) { // Hide scope, no $ conflict (function($) { // Hide scope, no $ conflict
var signatureOverrides = { var signatureOverrides = {
// Global defaults for signature // Global defaults for signature
options: { options: {
background: '#ffffff', // Colour of the background background: '#ffffff', // Colour of the background
color: '#000000', // Colour of the signature color: '#000000', // Colour of the signature
thickness: 2, // Thickness of the lines thickness: 2, // Thickness of the lines
guideline: false, // Add a guide line or not? guideline: false, // Add a guide line or not?
guidelineColor: '#a0a0a0', // Guide line colour guidelineColor: '#a0a0a0', // Guide line colour
guidelineOffset: 50, // Guide line offset from the bottom guidelineOffset: 50, // Guide line offset from the bottom
guidelineIndent: 10, // Guide line indent from the edges guidelineIndent: 10, // Guide line indent from the edges
notAvailable: 'Your browser doesn\'t support signing', // Error message when no canvas notAvailable: 'Your browser doesn\'t support signing', // Error message when no canvas
syncField: null, // Selector for synchronised text field syncField: null, // Selector for synchronised text field
change: null, // Callback when signature changed change: null, // Callback when signature changed
width: 170, width: 170,
height: 50 height: 50
}, },
/* Initialise a new signature area. */ /* Initialise a new signature area. */
_create: function() { _create: function() {
this.element.addClass(this.widgetFullName || this.widgetBaseClass); this.element.addClass(this.widgetFullName || this.widgetBaseClass);
try { try {
this.canvas = $('<canvas width="' + this.options.width + '" height="' + this.canvas = $('<canvas width="' + this.options.width + '" height="' +
this.options.height + '">' + '' + '</canvas>')[0]; this.options.height + '">' + '' + '</canvas>')[0];
this.element.prepend(this.canvas); this.element.prepend(this.canvas);
this.element.find('img').remove(); this.element.find('img').remove();
this.ctx = this.canvas.getContext('2d'); this.ctx = this.canvas.getContext('2d');
} }
catch (e) { catch (e) {
$(this.canvas).remove(); $(this.canvas).remove();
this.resize = true; this.resize = true;
this.canvas = document.createElement('canvas'); this.canvas = document.createElement('canvas');
this.canvas.setAttribute('width', this.element.width()); this.canvas.setAttribute('width', this.element.width());
this.canvas.setAttribute('height', this.element.height()); this.canvas.setAttribute('height', this.element.height());
this.canvas.innerHTML = this.options.notAvailable; this.canvas.innerHTML = this.options.notAvailable;
this.element.append(this.canvas); this.element.append(this.canvas);
if (G_vmlCanvasManager) { // Requires excanvas.js if (G_vmlCanvasManager) { // Requires excanvas.js
G_vmlCanvasManager.initElement(this.canvas); G_vmlCanvasManager.initElement(this.canvas);
} }
this.ctx = this.canvas.getContext('2d'); this.ctx = this.canvas.getContext('2d');
} }
this._refresh(true); this._refresh(true);
this._mouseInit(); this._mouseInit();
}, },
/* Refresh the appearance of the signature area. /* Refresh the appearance of the signature area.
@param init (boolean, internal) true if initialising */ @param init (boolean, internal) true if initialising */
_refresh: function(init) { _refresh: function(init) {
if (this.resize) { if (this.resize) {
var parent = $(this.canvas); var parent = $(this.canvas);
$('div', this.canvas).css({width: parent.width(), height: parent.height()}); $('div', this.canvas).css({width: parent.width(), height: parent.height()});
} }
this.ctx.fillStyle = this.options.background; this.ctx.fillStyle = this.options.background;
this.ctx.strokeStyle = this.options.color; this.ctx.strokeStyle = this.options.color;
this.ctx.lineWidth = this.options.thickness; this.ctx.lineWidth = this.options.thickness;
this.ctx.lineCap = 'round'; this.ctx.lineCap = 'round';
this.ctx.lineJoin = 'round'; this.ctx.lineJoin = 'round';
this.clear(init); this.clear(init);
}, },
/* Clear the signature area. /* Clear the signature area.
@param init (boolean, internal) true if initialising */ @param init (boolean, internal) true if initialising */
clear: function(init) { clear: function(init) {
this.ctx.fillRect(0, 0, this.element.width(), this.element.height()); this.ctx.fillRect(0, 0, this.element.width(), this.element.height());
if (this.options.guideline) { if (this.options.guideline) {
this.ctx.save(); this.ctx.save();
this.ctx.strokeStyle = this.options.guidelineColor; this.ctx.strokeStyle = this.options.guidelineColor;
this.ctx.lineWidth = 1; this.ctx.lineWidth = 1;
this.ctx.beginPath(); this.ctx.beginPath();
this.ctx.moveTo(this.options.guidelineIndent, this.ctx.moveTo(this.options.guidelineIndent,
this.element.height() - this.options.guidelineOffset); this.element.height() - this.options.guidelineOffset);
this.ctx.lineTo(this.element.width() - this.options.guidelineIndent, this.ctx.lineTo(this.element.width() - this.options.guidelineIndent,
this.element.height() - this.options.guidelineOffset); this.element.height() - this.options.guidelineOffset);
this.ctx.stroke(); this.ctx.stroke();
this.ctx.restore(); this.ctx.restore();
} }
this.lines = []; this.lines = [];
if (!init) { if (!init) {
this._changed(); this._changed();
} }
}, },
/* Synchronise changes and trigger change event. /* Synchronise changes and trigger change event.
@param event (Event) the triggering event */ @param event (Event) the triggering event */
_changed: function(event) { _changed: function(event) {
if (this.options.syncField) { if (this.options.syncField) {
$(this.options.syncField).val(this.toJSON()); $(this.options.syncField).val(this.toJSON());
} }
this._trigger('change', event, {}); this._trigger('change', event, {});
}, },
/* Custom options handling. /* Custom options handling.
@param options (object) the new option values */ @param options (object) the new option values */
_setOptions: function(options) { _setOptions: function(options) {
if (this._superApply) { if (this._superApply) {
this._superApply(arguments); // Base widget handling this._superApply(arguments); // Base widget handling
} }
else { else {
$.Widget.prototype._setOptions.apply(this, arguments); // Base widget handling $.Widget.prototype._setOptions.apply(this, arguments); // Base widget handling
} }
this._refresh(); this._refresh();
}, },
/* Determine if dragging can start. /* Determine if dragging can start.
@param event (Event) the triggering mouse event @param event (Event) the triggering mouse event
@return (boolean) true if allowed, false if not */ @return (boolean) true if allowed, false if not */
_mouseCapture: function(event) { _mouseCapture: function(event) {
return !this.options.disabled; return !this.options.disabled;
}, },
/* Start a new line. /* Start a new line.
@param event (Event) the triggering mouse event */ @param event (Event) the triggering mouse event */
_mouseStart: function(event) { _mouseStart: function(event) {
this.offset = this.element.offset(); this.offset = this.element.offset();
this.offset.left -= document.documentElement.scrollLeft || document.body.scrollLeft; this.offset.left -= document.documentElement.scrollLeft || document.body.scrollLeft;
this.offset.top -= document.documentElement.scrollTop || document.body.scrollTop; this.offset.top -= document.documentElement.scrollTop || document.body.scrollTop;
this.lastPoint = [this._round(event.clientX - this.offset.left), this.lastPoint = [this._round(event.clientX - this.offset.left),
this._round(event.clientY - this.offset.top)]; this._round(event.clientY - this.offset.top)];
this.curLine = [this.lastPoint]; this.curLine = [this.lastPoint];
this.lines.push(this.curLine); this.lines.push(this.curLine);
}, },
/* Track the mouse. /* Track the mouse.
@param event (Event) the triggering mouse event */ @param event (Event) the triggering mouse event */
_mouseDrag: function(event) { _mouseDrag: function(event) {
var point = [this._round(event.clientX - this.offset.left), var point = [this._round(event.clientX - this.offset.left),
this._round(event.clientY - this.offset.top)]; this._round(event.clientY - this.offset.top)];
this.curLine.push(point); this.curLine.push(point);
this.ctx.beginPath(); this.ctx.beginPath();
this.ctx.moveTo(this.lastPoint[0], this.lastPoint[1]); this.ctx.moveTo(this.lastPoint[0], this.lastPoint[1]);
this.ctx.lineTo(point[0], point[1]); this.ctx.lineTo(point[0], point[1]);
this.ctx.stroke(); this.ctx.stroke();
this.lastPoint = point; this.lastPoint = point;
}, },
/* End a line. /* End a line.
@param event (Event) the triggering mouse event */ @param event (Event) the triggering mouse event */
_mouseStop: function(event) { _mouseStop: function(event) {
this.lastPoint = null; this.lastPoint = null;
this.curLine = null; this.curLine = null;
this._changed(event); this._changed(event);
}, },
/* Round to two decimal points. /* Round to two decimal points.
@param value (number) the value to round @param value (number) the value to round
@return (number) the rounded value */ @return (number) the rounded value */
_round: function(value) { _round: function(value) {
return Math.round(value * 100) / 100; return Math.round(value * 100) / 100;
}, },
/* Convert the captured lines to JSON text. /* Convert the captured lines to JSON text.
@return (string) the JSON text version of the lines */ @return (string) the JSON text version of the lines */
toJSON: function() { toJSON: function() {
return '{"lines":[' + $.map(this.lines, function(line) { return '{"lines":[' + $.map(this.lines, function(line) {
return '[' + $.map(line, function(point) { return '[' + $.map(line, function(point) {
return '[' + point + ']'; return '[' + point + ']';
}) + ']'; }) + ']';
}) + ']}'; }) + ']}';
}, },
/* Convert the captured lines to SVG text. /* Convert the captured lines to SVG text.
@return (string) the SVG text version of the lines */ @return (string) the SVG text version of the lines */
toSVG: function() { toSVG: function() {
return '<?xml version="1.0"?>\n<!DOCTYPE svg PUBLIC ' + return '<?xml version="1.0"?>\n<!DOCTYPE svg PUBLIC ' +
'"-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n' + '"-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n' +
'<svg xmlns="http://www.w3.org/2000/svg" width="15cm" height="15cm">\n' + '<svg xmlns="http://www.w3.org/2000/svg" width="15cm" height="15cm">\n' +
' <g fill="' + this.options.background + '">\n' + ' <g fill="' + this.options.background + '">\n' +
' <rect x="0" y="0" width="' + this.canvas.width + ' <rect x="0" y="0" width="' + this.canvas.width +
'" height="' + this.canvas.height + '"/>\n' + '" height="' + this.canvas.height + '"/>\n' +
' <g fill="none" stroke="' + this.options.color + '" stroke-width="' + ' <g fill="none" stroke="' + this.options.color + '" stroke-width="' +
this.options.thickness + '">\n'+ this.options.thickness + '">\n'+
$.map(this.lines, function(line) { $.map(this.lines, function(line) {
return ' <polyline points="' + return ' <polyline points="' +
$.map(line, function(point) { return point + ''; }).join(' ') + '"/>\n'; $.map(line, function(point) { return point + ''; }).join(' ') + '"/>\n';
}).join('') + }).join('') +
' </g>\n </g>\n</svg>\n'; ' </g>\n </g>\n</svg>\n';
}, },
/* Draw a signature from its JSON description. /* Draw a signature from its JSON description.
@param sigJSON (object) object with attribute lines @param sigJSON (object) object with attribute lines
being an array of arrays of points or being an array of arrays of points or
(string) text version of the JSON */ (string) text version of the JSON */
draw: function(sigJSON) { draw: function(sigJSON) {
this.clear(true); this.clear(true);
if (typeof sigJSON === 'string') { if (typeof sigJSON === 'string') {
sigJSON = $.parseJSON(sigJSON); sigJSON = $.parseJSON(sigJSON);
} }
this.lines = sigJSON.lines || []; this.lines = sigJSON.lines || [];
var ctx = this.ctx; var ctx = this.ctx;
$.each(this.lines, function() { $.each(this.lines, function() {
ctx.beginPath(); ctx.beginPath();
$.each(this, function(i) { $.each(this, function(i) {
ctx[i === 0 ? 'moveTo' : 'lineTo'](this[0], this[1]); ctx[i === 0 ? 'moveTo' : 'lineTo'](this[0], this[1]);
}); });
ctx.stroke(); ctx.stroke();
}); });
this._changed(); this._changed();
}, },
/* Determine whether or not any drawing has occurred. /* Determine whether or not any drawing has occurred.
@return (boolean) true if not signed, false if signed */ @return (boolean) true if not signed, false if signed */
isEmpty: function() { isEmpty: function() {
return this.lines.length === 0; return this.lines.length === 0;
}, },
/* Remove the signature functionality. */ /* Remove the signature functionality. */
_destroy: function() { _destroy: function() {
this.element.removeClass(this.widgetFullName || this.widgetBaseClass); this.element.removeClass(this.widgetFullName || this.widgetBaseClass);
$(this.canvas).remove(); $(this.canvas).remove();
this.canvas = this.ctx = this.lines = null; this.canvas = this.ctx = this.lines = null;
this._mouseDestroy(); this._mouseDestroy();
} }
}; };
if (!$.Widget.prototype._destroy) { if (!$.Widget.prototype._destroy) {
$.extend(signatureOverrides, { $.extend(signatureOverrides, {
/* Remove the signature functionality. */ /* Remove the signature functionality. */
destroy: function() { destroy: function() {
this._destroy(); this._destroy();
$.Widget.prototype.destroy.call(this); // Base widget handling $.Widget.prototype.destroy.call(this); // Base widget handling
} }
}); });
} }
if($.Widget.prototype._getCreateOptions === $.noop) { if($.Widget.prototype._getCreateOptions === $.noop) {
$.extend(signatureOverrides, { $.extend(signatureOverrides, {
/* Restore the metadata functionality. */ /* Restore the metadata functionality. */
_getCreateOptions: function() { _getCreateOptions: function() {
return $.metadata && $.metadata.get(this.element[0])[this.widgetName]; return $.metadata && $.metadata.get(this.element[0])[this.widgetName];
} }
}); });
} }
/* Signature capture and display. /* Signature capture and display.
Depends on jquery.ui.widget, jquery.ui.mouse. */ Depends on jquery.ui.widget, jquery.ui.mouse. */
$.widget('kbw.signature', $.ui.mouse, signatureOverrides); $.widget('kbw.signature', $.ui.mouse, signatureOverrides);
// Make some things more accessible // Make some things more accessible
$.kbw.signature.options = $.kbw.signature.prototype.options; $.kbw.signature.options = $.kbw.signature.prototype.options;
})(jQuery); })(jQuery);

View File

@ -1,5 +1,5 @@
/* Styles for signature plugin v1.1.0. */ /* Styles for signature plugin v1.1.0. */
.kbw-signature { .kbw-signature {
display: inline-block; display: inline-block;
border: 1px solid #a0a0a0; border: 1px solid #a0a0a0;
} }

View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -2,11 +2,11 @@
<data> <data>
<template id="signature_backend" name="signature assets" inherit_id="web.assets_backend"> <template id="signature_backend" name="signature assets" inherit_id="web.assets_backend">
<xpath expr="." position="inside"> <xpath expr="." position="inside">
<link rel="stylesheet" href="/web_widget_digital_signature/static/src/css/digital.css"/> <link rel="stylesheet" href="/web_widget_digitized_signature/static/src/css/digital.css"/>
<link rel="stylesheet" href="/web_widget_digital_signature/static/src/css/jquery.signature.css"/> <link rel="stylesheet" href="/web_widget_digitized_signature/static/src/css/jquery.signature.css"/>
<script type="text/javascript" src="/web_widget_digital_signature/static/lib/excanvas.js"></script> <script type="text/javascript" src="/web_widget_digitized_signature/static/lib/excanvas.js"></script>
<script type="text/javascript" src="/web_widget_digital_signature/static/lib/jquery.signature.js"></script> <script type="text/javascript" src="/web_widget_digitized_signature/static/lib/jquery.signature.js"></script>
<script type="text/javascript" src="/web_widget_digital_signature/static/src/js/digital_sign.js"></script> <script type="text/javascript" src="/web_widget_digitized_signature/static/src/js/digital_sign.js"></script>
</xpath> </xpath>
</template> </template>
</data> </data>