Test Setup Failed
Push — master ( d00a46...d73e35 )
by
unknown
03:25
created

  B

Complexity

Conditions 3
Paths 3

Size

Total Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
nc 3
dl 0
loc 25
rs 8.8571
c 0
b 0
f 0
nop 0

1 Function

Rating   Name   Duplication   Size   Complexity  
A product-quantity-editable-view.js ➔ ... ➔ _.bind 0 3 1
1
define(function(require) {
2
    'use strict';
3
4
    var ProductQuantityEditableView;
5
    var BaseView = require('oroui/js/app/views/base/view');
6
    var ApiAccessor = require('oroui/js/tools/api-accessor');
7
    var mediator = require('oroui/js/mediator');
8
    var tools = require('oroui/js/tools');
9
    var $ = require('jquery');
10
    var _ = require('underscore');
11
    var __ = require('orotranslation/js/translator');
12
13
    ProductQuantityEditableView = BaseView.extend({
14
        options: {
15
            quantityFieldName: 'quantity',
16
            unitFieldName: 'unit',
17
            dataKey: null,
18
            enable: false,
19
            save_api_accessor: {
20
                http_method: 'PUT'
21
            },
22
            messages: {
23
                success: __('oro.form.inlineEditing.successMessage'),
24
                processingMessage: __('oro.form.inlineEditing.saving_progress'),
25
                preventWindowUnload: __('oro.form.inlineEditing.inline_edits')
26
            },
27
            elements: {
28
                saveButton: '',
29
                quantity: '[name$="[quantity]"]',
30
                unit: '[name$="[unit]"]'
31
            },
32
            validation: {
33
                showErrorsHandler: null,
34
                rules: {
35
                    quantity: {
36
                        NotBlank: {
37
                            message: 'oro.product.validation.quantity.required'
38
                        },
39
                        OpenRange: {
40
                            min: 0,
41
                            minMessage: 'oro.product.validation.quantity.greaterThanZero'
42
                        }
43
                    },
44
                    unit: {
45
                        NotBlank: {
46
                            message: 'oro.product.validation.unit.required'
47
                        }
48
                    }
49
                }
50
            }
51
        },
52
53
        /**
54
         * @constructor
55
         * @param {Object} options
56
         */
57
        initialize: function(options) {
58
            options = $.extend(true, {}, this.options, options);
59
            if (!options.enable) {
60
                return;
61
            }
62
            this._isSaving = false;
63
64
            this.messages = options.messages;
65
            this.dataKey = options.dataKey;
66
            this.quantityFieldName = options.quantityFieldName;
67
            this.unitFieldName = options.unitFieldName;
68
            this.triggerData = options.triggerData || null;
69
            this.initElements(options);
70
71
            this.saveModelState();
72
73
            this.saveApiAccessor = new ApiAccessor(options.save_api_accessor);
74
        },
75
76
        initElements: function(options) {
77
            this.elements = {};
78
            _.each(options.elements, function(selector, key) {
79
                this.elements[key] = selector ? this.$el.find(selector) : null;
80
            }, this);
81
82
            this.elements.unit.prop('disabled', false);
83
84
            if (!this.elements.unit.find(':selected').is(':disabled')) {
85
                this.enableQuantity();
86
            }
87
88
            this.initValidator(options);
89
            if (this.deferredInit) {
90
                this.deferredInit.done(_.bind(this.initListeners, this));
91
            } else {
92
                this.initListeners();
93
            }
94
95
            this._bindEvents();
96
            this.disableOptions();
97
        },
98
99
        _bindEvents: function() {
100
            this.elements.unit.on('change.' + this.cid, _.bind(function() {
101
                mediator.trigger('unitChanged');
102
            }, this));
103
104
            mediator.on('unitChanged', this.disableOptions, this);
105
        },
106
107
        disableOptions: function() {
108
            this.elements.unit.find('option').prop('disabled', false);
109
110
            this.$el.siblings().each(_.bind(function(index, el) {
111
                var value = $(el).find('[name="unit"]').val();
112
                this.elements.unit
113
                    .find('[value="' + value + '"]')
114
                    .prop('disabled', true);
115
            }, this));
116
        },
117
118
        enableAccept: function() {
119
            this.elements.saveButton.prop('disabled', false);
120
        },
121
122
        enableQuantity: function() {
123
            this.elements.quantity.prop('disabled', false);
124
        },
125
126
        initValidator: function(options) {
127
            var $form = this.$el.find('form');
128
            var validationRules = {};
129
            validationRules[this.elements.quantity.attr('name')] = options.validation.rules.quantity;
130
            validationRules[this.elements.unit.attr('name')] = options.validation.rules.unit;
131
132
            var validationOptions = {
133
                rules: validationRules
134
            };
135
136
            if (options.validation.showErrorsHandler) {
137
                var waitors = [];
138
                waitors.push(tools.loadModuleAndReplace(options.validation, 'showErrorsHandler').then(
139
                    _.bind(function() {
140
                        validationOptions.showErrors = options.validation.showErrorsHandler;
141
                        this.updateValidation($form, validationOptions);
142
                    }, this)
143
                ));
144
                this.deferredInit = $.when.apply($, waitors);
145
            } else {
146
                this.updateValidation($form, validationOptions);
147
            }
148
        },
149
150
        updateValidation: function($form, options) {
151
            this.validator = $form.validate();
152
153
            if (_.isObject(options)) {
154
                var settings = this.validator.settings;
155
                $.extend(true, settings, options);
156
            }
157
        },
158
159
        initListeners: function() {
160
            var changeAction = this.onViewChange;
161
            if (this.elements.saveButton) {
162
                this.elements.saveButton.on('click', _.bind(this.onViewChange, this));
163
                changeAction = this.enableAccept;
164
            }
165
            this.$el.on('change', this.elements.quantity, _.bind(changeAction, this));
166
            this.$el.on('change', this.elements.unit, _.bind(changeAction, this));
167
        },
168
169
        saveModelState: function() {
170
            this.oldModelState = this.getValue();
171
        },
172
173
        restoreSavedState: function() {
174
            this.elements.quantity.val(this.oldModelState.quantity).change();
175
            this.elements.unit.val(this.oldModelState.unit).change();
176
        },
177
178
        onViewChange: function(e) {
179
            if (!this.isValid()) {
180
                return;
181
            }
182
183
            if (this.triggerData) {
184
                this.triggerData.event = e;
185
            }
186
            this.enableQuantity();
187
            this.saveChanges();
188
        },
189
190
        getValue: function() {
191
            return {
192
                quantity: this.elements.quantity.val(),
193
                unit: this.elements.unit.val()
194
            };
195
        },
196
197
        isChanged: function() {
198
            var modelData = this.getValue();
199
            for (var key in modelData) {
200
                if (modelData.hasOwnProperty(key) && this.oldModelState[key] !== modelData[key]) {
201
                    return true;
202
                }
203
            }
204
205
            return false;
206
        },
207
208
        isValid: function() {
209
            return this.validator.form();
210
        },
211
212
        requireSave: function() {
213
            return !this._isSaving &&
214
                this.isChanged() &&
215
                this.isValid();
216
        },
217
218
        saveChanges: function() {
219
            if (!this.requireSave()) {
220
                return false;
221
            }
222
223
            this._isSaving = true;
224
            var modelData = this.getValue();
225
            var serverUpdateData = {};
226
            if (this.dataKey) {
227
                serverUpdateData[this.dataKey] = modelData;
228
            } else {
229
                serverUpdateData = modelData;
230
            }
231
232
            var savePromise = this.saveApiAccessor.send(modelData, serverUpdateData, {}, {
233
                processingMessage: this.messages.processingMessage,
234
                preventWindowUnload: this.messages.preventWindowUnload
235
            });
236
            savePromise
237
                .done(_.bind(this.onSaveSuccess, this))
238
                .fail(_.bind(this.onSaveError, this))
239
                .always(_.bind(function() {
240
                    this._isSaving = false;
241
                }, this));
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
242
        },
243
244
        onSaveSuccess: function(response) {
0 ignored issues
show
Unused Code introduced by
The parameter response is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
245
            this.saveModelState();
246
            this.restoreSavedState();
247
248
            var value = _.extend({}, this.triggerData || {}, {
249
                value: this.getValue()
250
            });
251
            this.trigger('product:quantity-unit:update', value);
252
            mediator.trigger('product:quantity-unit:update', value);
253
254
            mediator.execute('showFlashMessage', 'success', this.messages.success);
255
        },
256
257
        onSaveError: function(jqXHR) {
258
            var errorCode = 'responseJSON' in jqXHR ? jqXHR.responseJSON.code : jqXHR.status;
259
260
            this.restoreSavedState();
261
262
            var errors = [];
263
            switch (errorCode) {
264
                case 400:
265
                    var jqXHRerrors = jqXHR.responseJSON.errors.children;
266
                    for (var i in jqXHRerrors) {
267
                        if (jqXHRerrors.hasOwnProperty(i) && jqXHRerrors[i].errors) {
268
                            errors.push.apply(errors, _.values(jqXHRerrors[i].errors));
269
                        }
270
                    }
271
                    if (!errors.length) {
272
                        errors.push(__('oro.ui.unexpected_error'));
273
                    }
274
                    break;
275
                case 403:
276
                    errors.push(__('You do not have permission to perform this action.'));
277
                    break;
278
                default:
279
                    errors.push(__('oro.ui.unexpected_error'));
280
            }
281
282
            _.each(errors, function(value) {
283
                mediator.execute('showFlashMessage', 'error', value);
284
            });
285
        },
286
287
        dispose: function() {
288
            if (this.disposed) {
289
                return;
290
            }
291
292
            mediator.off('unitChanged', this.disableOptions, this);
293
            this.elements.unit.off('change.' + this.cid);
294
295
            ProductQuantityEditableView.__super__.dispose.call(this);
296
        }
297
    });
298
299
    return ProductQuantityEditableView;
300
});
301