[ADD] barcodes: onchange-like mechanism to react to scans in form view
For a model to use it, it must : - Inherit barcodes.barcode_events_mixin and override on_barcode_scanned(self, barcode) - Add <field name=barcode_scanned widget=barcode_handler/> to each form view that should listen to barcode events and trigger on_barcode_scanned. The method on_barcode_scanned works just like an onchange.
This commit is contained in:
@@ -1 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import barcodes
|
||||
|
||||
import models
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import barcode_events_mixin
|
||||
@@ -0,0 +1,24 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from openerp import models, fields, api
|
||||
|
||||
class BarcodeEventsMixin(models.AbstractModel):
|
||||
""" Mixin class for objects reacting when a barcode is scanned in their form views
|
||||
which contains `<field name="_barcode_scanned" widget="barcode_handler"/>`.
|
||||
Models using this mixin must implement the method on_barcode_scanned. It works
|
||||
like an onchange and receives the scanned barcode in parameter.
|
||||
"""
|
||||
|
||||
_name = 'barcodes.barcode_events_mixin'
|
||||
|
||||
_barcode_scanned = fields.Char("Barcode Scanned", help="Value of the last barcode scanned.", store=False)
|
||||
|
||||
@api.onchange('_barcode_scanned')
|
||||
def _on_barcode_scanned(self):
|
||||
barcode = self._barcode_scanned
|
||||
if barcode:
|
||||
self._barcode_scanned = ""
|
||||
return self.on_barcode_scanned(barcode)
|
||||
|
||||
def on_barcode_scanned(self, barcode):
|
||||
raise NotImplementedError("In order to use barcodes.barcode_events_mixin, method on_barcode_scanned must be implemented")
|
||||
@@ -0,0 +1,79 @@
|
||||
odoo.define('barcodes.FormViewBarcodeHandler', function(require) {
|
||||
"use strict";
|
||||
|
||||
var core = require('web.core');
|
||||
var utils = require('web.utils');
|
||||
var common = require('web.form_common');
|
||||
|
||||
var _t = core._t;
|
||||
|
||||
var FormViewBarcodeHandler = common.AbstractField.extend({
|
||||
|
||||
start: function() {
|
||||
this._super();
|
||||
this.form_view = this.field_manager;
|
||||
core.bus.on('barcode_scanned', this, this.on_barcode_scanned);
|
||||
// Hardcoded barcode actions
|
||||
this.map_barcode_method = {
|
||||
'O-CMD.NEW': _.bind(this.form_view.on_button_new, this.form_view),
|
||||
'O-CMD.CANCEL': _.bind(this.form_view.on_button_cancel, this.form_view),
|
||||
// FIXME: on_button_save shouldn't mix view and model concerns (it expects to be used as onclick handler)
|
||||
'O-CMD.SAVE': _.bind(this.form_view.on_button_save, this.form_view, {target: $('.o_cp_buttons .o_form_button_save')}),
|
||||
};
|
||||
// Old design pager actions
|
||||
if (this.form_view.execute_pager_action) {
|
||||
this.map_barcode_method['O-CMD.PAGER-PREV'] = _.bind(this.form_view.execute_pager_action, this.form_view, 'previous');
|
||||
this.map_barcode_method['O-CMD.PAGER-NEXT'] = _.bind(this.form_view.execute_pager_action, this.form_view, 'next');
|
||||
// New design pager actions
|
||||
} else if (this.form_view.pager) {
|
||||
this.map_barcode_method['O-CMD.PAGER-PREV'] = _.bind(this.form_view.pager.previous, this.form_view.pager);
|
||||
this.map_barcode_method['O-CMD.PAGER-NEXT'] = _.bind(this.form_view.pager.next, this.form_view.pager);
|
||||
}
|
||||
},
|
||||
|
||||
// Let subclasses add custom behaviour before onchange
|
||||
// Return false in order to proceed with the onchange, anything else to prevent it.
|
||||
pre_onchange_hook: function(barcode) {
|
||||
return false;
|
||||
},
|
||||
|
||||
on_barcode_scanned: function(barcode) {
|
||||
var self = this;
|
||||
// Execute a harcoded action
|
||||
var action = this.map_barcode_method[barcode];
|
||||
if (typeof action === "function")
|
||||
return $.when(action());
|
||||
// Warn the user if form view is not editable
|
||||
else if (this.form_view.get('actual_mode') === 'view')
|
||||
this.do_warn(_t('Error : Document not editable'), _t('To modify this document, please first start edition.'));
|
||||
else {
|
||||
// Call hook method possibly implemented by subclass
|
||||
$.when(this.pre_onchange_hook(barcode)).then(function(result) {
|
||||
if (result !== false) {
|
||||
return result;
|
||||
} else {
|
||||
// Wait for hypothetical ongoing onchange to finish
|
||||
self.form_view.onchanges_mutex.exec(function() {
|
||||
// A real onchange is triggered when a value actually changes (which can correspond
|
||||
// to a widget's blur event per example). Commit the value of fields before
|
||||
// programmatically triggering an onchange to be consistent with this.
|
||||
var mutex_commit_value = new utils.Mutex();
|
||||
_.each(self.form_view.fields, function(field) {
|
||||
mutex_commit_value.exec(_.bind(field.commit_value, field));
|
||||
});
|
||||
return mutex_commit_value.def.then(function(){
|
||||
// Trigger the barcode onchange
|
||||
self.set_value(barcode);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
core.form_widget_registry.add('barcode_handler', FormViewBarcodeHandler);
|
||||
|
||||
return FormViewBarcodeHandler;
|
||||
|
||||
});
|
||||
@@ -6,6 +6,7 @@
|
||||
<xpath expr="." position="inside">
|
||||
<script type="text/javascript" src="/barcodes/static/src/js/barcode_parser.js"></script>
|
||||
<script type="text/javascript" src="/barcodes/static/src/js/barcode_events.js"></script>
|
||||
<script type="text/javascript" src="/barcodes/static/src/js/form_view_barcode_handler.js"></script>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user