diff --git a/addons/account_asset/models/account_invoice.py b/addons/account_asset/models/account_invoice.py index 91e6336d23c..105354f6509 100644 --- a/addons/account_asset/models/account_invoice.py +++ b/addons/account_asset/models/account_invoice.py @@ -20,7 +20,13 @@ class AccountInvoice(models.Model): asset_ids = self.env['account.asset.asset'].sudo().search([('invoice_id', '=', inv.id), ('company_id', '=', inv.company_id.id)]) if asset_ids: asset_ids.write({'active': False}) - inv.invoice_line_ids.asset_create() + context = dict(self.env.context) + # Within the context of an invoice, + # this default value is for the type of the invoice, not the type of the asset. + # This has to be cleaned from the context before creating the asset, + # otherwise it tries to create the asset with the type of the invoice. + context.pop('default_type', None) + inv.invoice_line_ids.with_context(context).asset_create() return result diff --git a/addons/auth_ldap/models/res_company_ldap.py b/addons/auth_ldap/models/res_company_ldap.py index 649cfb7bdf0..dfc9070a2e9 100644 --- a/addons/auth_ldap/models/res_company_ldap.py +++ b/addons/auth_ldap/models/res_company_ldap.py @@ -100,7 +100,7 @@ class CompanyLDAP(models.Model): _logger.warning('Could not format LDAP filter. Your filter should contain one \'%s\'.') return False try: - results = self.query(conf, filter) + results = self.query(conf, tools.ustr(filter)) # Get rid of (None, attrs) for searchResultReference replies results = [i for i in results if i[0]] diff --git a/addons/l10n_be/i18n_extra/nl_BE.po b/addons/l10n_be/i18n_extra/nl_BE.po index 4516f76832a..d40cd32f598 100644 --- a/addons/l10n_be/i18n_extra/nl_BE.po +++ b/addons/l10n_be/i18n_extra/nl_BE.po @@ -701,7 +701,7 @@ msgstr "R.S.Z. 4de kwartaal" #. module: l10n_be #: model:account.account.template,name:l10n_be.a4540 msgid "ONSS. Arriérés" -msgstr "" +msgstr "Achterstallige bijdragen RSZ" #. module: l10n_be #: model:account.account.template,name:l10n_be.a4553 @@ -879,7 +879,7 @@ msgstr "Waardeverminderingen op voorraden" #. module: l10n_be #: model:account.fiscal.position.template,name:l10n_be.fiscal_position_template_4 msgid "Régime Cocontractant" -msgstr "" +msgstr "Medecontractant" #. module: l10n_be #: model:account.fiscal.position.template,name:l10n_be.fiscal_position_template_2 diff --git a/addons/mail/models/mail_thread.py b/addons/mail/models/mail_thread.py index 6af6a2206f4..71c196cd693 100644 --- a/addons/mail/models/mail_thread.py +++ b/addons/mail/models/mail_thread.py @@ -441,11 +441,14 @@ class MailThread(models.AbstractModel): - a set of updated column names - a list of changes (initial value, new value, column name, column info) """ self.ensure_one() - changes = set() + changes = set() # contains always and onchange tracked fields that changed + displays = set() # contains always tracked field that did not change but displayed for information tracking_value_ids = [] + display_values_ids = [] # generate tracked_values data structure: {'col_name': {col_info, new_value, old_value}} for col_name, col_info in tracked_fields.items(): + track_visibility = getattr(self._fields[col_name], 'track_visibility', 'onchange') initial_value = initial[col_name] new_value = getattr(self, col_name) @@ -456,6 +459,16 @@ class MailThread(models.AbstractModel): if col_name in tracked_fields: changes.add(col_name) + # 'always' tracked fields in separate variable; added if other changes + elif new_value == initial_value and track_visibility == 'always' and col_name in tracked_fields: + tracking = self.env['mail.tracking.value'].create_tracking_values(initial_value, initial_value, col_name, col_info) + if tracking: + display_values_ids.append([0, 0, tracking]) + displays.add(col_name) + + if changes and displays: + tracking_value_ids = display_values_ids + tracking_value_ids + return changes, tracking_value_ids @api.multi diff --git a/addons/mail/models/mail_tracking_value.py b/addons/mail/models/mail_tracking_value.py index ce8bdc7ec48..da38a678d06 100644 --- a/addons/mail/models/mail_tracking_value.py +++ b/addons/mail/models/mail_tracking_value.py @@ -10,6 +10,7 @@ class MailTracking(models.Model): _name = 'mail.tracking.value' _description = 'Mail Tracking Value' + # TDE CLEANME: why not a m2o to ir model field ? field = fields.Char('Changed Field', required=True, readonly=1) field_desc = fields.Char('Field Description', required=True, readonly=1) field_type = fields.Char('Field Type') diff --git a/addons/mail/static/src/js/chat_manager.js b/addons/mail/static/src/js/chat_manager.js index 90fbb6ed801..0b7b37ec49f 100644 --- a/addons/mail/static/src/js/chat_manager.js +++ b/addons/mail/static/src/js/chat_manager.js @@ -128,7 +128,8 @@ function make_message (data) { subtype_description: data.subtype_description, is_author: data.author_id && data.author_id[0] === session.partner_id, is_note: data.is_note, - is_system_notification: data.message_type === 'notification' && data.model === 'mail.channel', + is_system_notification: (data.message_type === 'notification' && data.model === 'mail.channel') + || data.info === 'transient_message', attachment_ids: data.attachment_ids || [], subject: data.subject, email_from: data.email_from, diff --git a/addons/mail/static/src/xml/thread.xml b/addons/mail/static/src/xml/thread.xml index 47e84e38f60..b5ed0081d74 100644 --- a/addons/mail/static/src/xml/thread.xml +++ b/addons/mail/static/src/xml/thread.xml @@ -154,9 +154,11 @@ : - + - + + + diff --git a/addons/mail/tests/test_message_track.py b/addons/mail/tests/test_message_track.py index 77204336e0d..e97b840cda4 100644 --- a/addons/mail/tests/test_message_track.py +++ b/addons/mail/tests/test_message_track.py @@ -122,10 +122,10 @@ class TestTracking(TestMail): self.assertEqual(len(self.group_pigs.message_ids), 3) last_msg = self.group_pigs.message_ids[0] self.assertEqual(last_msg.subtype_id, mt_group_public_set) - self.assertEqual(len(last_msg.tracking_value_ids), 2) - self.assertEqual(set(last_msg.tracking_value_ids.mapped('field')), set(['group_public_id', 'public'])) - self.assertEqual(set(last_msg.tracking_value_ids.mapped('field_desc')), set(['Authorized Group', 'Privacy'])) - self.assertEqual(set(last_msg.tracking_value_ids.mapped('old_value_char')), set([group_user.name_get()[0][1], 'Invited people only'])) - self.assertEqual(set(last_msg.tracking_value_ids.mapped('new_value_char')), set([group_system.name_get()[0][1], 'Everyone'])) + self.assertEqual(len(last_msg.tracking_value_ids), 3) + self.assertEqual(set(last_msg.tracking_value_ids.mapped('field')), set(['group_public_id', 'public', 'name'])) + self.assertEqual(set(last_msg.tracking_value_ids.mapped('field_desc')), set(['Authorized Group', 'Privacy', 'Name'])) + self.assertEqual(set(last_msg.tracking_value_ids.mapped('old_value_char')), set([group_user.name_get()[0][1], 'Invited people only', 'supername'])) + self.assertEqual(set(last_msg.tracking_value_ids.mapped('new_value_char')), set([group_system.name_get()[0][1], 'Everyone', 'supername'])) self.assertEqual(set(last_msg.tracking_value_ids.mapped('old_value_integer')), set([0, group_user.id])) self.assertEqual(set(last_msg.tracking_value_ids.mapped('new_value_integer')), set([0, group_system.id])) diff --git a/addons/maintenance/data/maintenance_data.xml b/addons/maintenance/data/maintenance_data.xml index cc4174756ca..051b72c05e0 100644 --- a/addons/maintenance/data/maintenance_data.xml +++ b/addons/maintenance/data/maintenance_data.xml @@ -69,30 +69,8 @@ category_id - - - Computers - - - - Software - - - - Printers - - - Internal Maintenance - - - Metrology - - - - Subcontractor - diff --git a/addons/maintenance/data/maintenance_demo.xml b/addons/maintenance/data/maintenance_demo.xml index 1abdeb31c83..a5bc8bb02e9 100644 --- a/addons/maintenance/data/maintenance_demo.xml +++ b/addons/maintenance/data/maintenance_demo.xml @@ -2,7 +2,28 @@ + + + + Metrology + + + Subcontractor + + + + Computers + + + + Software + + + + Printers + + Monitors diff --git a/addons/mass_mailing/controllers/main.py b/addons/mass_mailing/controllers/main.py index 40a8207648d..cd73918224e 100644 --- a/addons/mass_mailing/controllers/main.py +++ b/addons/mass_mailing/controllers/main.py @@ -3,7 +3,7 @@ import werkzeug -from odoo import http +from odoo import http, _ from odoo.http import request diff --git a/addons/mrp/__manifest__.py b/addons/mrp/__manifest__.py index 78b3a6e6c03..a69d9582136 100644 --- a/addons/mrp/__manifest__.py +++ b/addons/mrp/__manifest__.py @@ -66,6 +66,7 @@ Dashboard / Reports for MRP will include: 'demo': [ 'data/mrp_demo.xml', 'data/mrp_lot_demo.yml'], + 'qweb': ['static/src/xml/mrp.xml'], 'test': [], 'application': True, } diff --git a/addons/mrp/data/mrp_demo.xml b/addons/mrp/data/mrp_demo.xml index 70da69628f8..787eb2eaea9 100644 --- a/addons/mrp/data/mrp_demo.xml +++ b/addons/mrp/data/mrp_demo.xml @@ -90,7 +90,7 @@ Manual Assembly 60 5 - + @@ -99,7 +99,7 @@ Long time assembly 180 15 - + @@ -108,7 +108,7 @@ Testing 60 10 - + @@ -117,7 +117,7 @@ Packing 30 5 - + @@ -126,7 +126,7 @@ 120 5 Manual Assembly - + @@ -135,7 +135,7 @@ 120 10 Cutting - + @@ -144,7 +144,7 @@ 120 15 Drilling - + @@ -153,7 +153,7 @@ 120 20 Assembly - + diff --git a/addons/mrp/static/img/assebly-worksheet.jpg b/addons/mrp/static/img/assebly-worksheet.jpg deleted file mode 100644 index 8d2e4b65440..00000000000 Binary files a/addons/mrp/static/img/assebly-worksheet.jpg and /dev/null differ diff --git a/addons/mrp/static/img/assebly-worksheet.pdf b/addons/mrp/static/img/assebly-worksheet.pdf new file mode 100644 index 00000000000..c5975da4a5d Binary files /dev/null and b/addons/mrp/static/img/assebly-worksheet.pdf differ diff --git a/addons/mrp/static/img/cutting-worksheet.jpg b/addons/mrp/static/img/cutting-worksheet.jpg deleted file mode 100644 index 3ecc631c4a6..00000000000 Binary files a/addons/mrp/static/img/cutting-worksheet.jpg and /dev/null differ diff --git a/addons/mrp/static/img/cutting-worksheet.pdf b/addons/mrp/static/img/cutting-worksheet.pdf new file mode 100644 index 00000000000..a6bbd4ebe39 Binary files /dev/null and b/addons/mrp/static/img/cutting-worksheet.pdf differ diff --git a/addons/mrp/static/img/drill-worksheet.jpg b/addons/mrp/static/img/drill-worksheet.jpg deleted file mode 100644 index 27c62c2b894..00000000000 Binary files a/addons/mrp/static/img/drill-worksheet.jpg and /dev/null differ diff --git a/addons/mrp/static/img/drill-worksheet.pdf b/addons/mrp/static/img/drill-worksheet.pdf new file mode 100644 index 00000000000..86d58a6cd2f Binary files /dev/null and b/addons/mrp/static/img/drill-worksheet.pdf differ diff --git a/addons/mrp/static/src/js/mrp.js b/addons/mrp/static/src/js/mrp.js index 1f1a42f1950..3c94517173c 100644 --- a/addons/mrp/static/src/js/mrp.js +++ b/addons/mrp/static/src/js/mrp.js @@ -5,6 +5,8 @@ var core = require('web.core'); var common = require('web.form_common'); var Model = require('web.Model'); var time = require('web.time'); +var utils = require('web.utils'); +var FieldBinaryFile = core.form_widget_registry.get('binary'); var _t = core._t; @@ -72,6 +74,74 @@ var TimeCounter = common.AbstractField.extend(common.ReinitializeFieldMixin, { }, }); -core.form_widget_registry.add('bullet_state', SetBulletStatus) - .add('mrp_time_counter', TimeCounter); +var FieldPdfViewer = FieldBinaryFile.extend({ + template: 'FieldPdfViewer', + init: function(){ + this._super.apply(this, arguments); + this.PDFViewerApplication = false; + }, + get_uri: function(){ + var query_obj = { + model: this.view.dataset.model, + field: this.name, + id: this.view.datarecord.id + }; + var query_string = $.param(query_obj); + var url = encodeURIComponent('/web/image?' + query_string); + var viewer_url = '/web/static/lib/pdfjs/web/viewer.html?file='; + return viewer_url + url; + }, + on_file_change: function(ev) { + this._super.apply(this, arguments); + if(this.PDFViewerApplication){ + var files = ev.target.files; + if (!files || files.length === 0) { + return; + } + var file = files[0]; + // TOCheck: is there requirement to fallback on FileReader if browser don't support URL + this.PDFViewerApplication.open(URL.createObjectURL(file), 0); + } + }, + render_value: function() { + var $pdf_viewer = this.$('.o_form_pdf_controls').children().add(this.$('.o_pdfview_iframe')), + $select_upload_el = this.$('.o_select_file_button').first(), + $iFrame = this.$('.o_pdfview_iframe'), + value = this.get('value'), + self = this; + + var bin_size = utils.is_bin_size(value); + $iFrame.on('load', function(){ + self.PDFViewerApplication = this.contentWindow.window.PDFViewerApplication; + self.disable_buttons(this); + }); + if (this.get("effective_readonly")) { + if (value) { + this.$el.off('click'); // off click event(on_save_as) of FieldBinaryFile + $iFrame.attr('src', this.get_uri()); + } + } else { + if (value) { + $pdf_viewer.removeClass('o_hidden'); + $select_upload_el.addClass('o_hidden'); + if(bin_size){ + $iFrame.attr('src', this.get_uri()); + } + } else { + $pdf_viewer.addClass('o_hidden'); + $select_upload_el.removeClass('o_hidden'); + } + } + }, + disable_buttons: function(iframe){ + if (this.get("effective_readonly")){ + $(iframe).contents().find('button#download').hide(); + } + $(iframe).contents().find('button#openFile').hide(); + } + +}); +core.form_widget_registry.add('bullet_state', SetBulletStatus) + .add('mrp_time_counter', TimeCounter) + .add('pdf_viewer', FieldPdfViewer); }); diff --git a/addons/mrp/static/src/less/mrp.less b/addons/mrp/static/src/less/mrp.less new file mode 100644 index 00000000000..e6acf64b9fc --- /dev/null +++ b/addons/mrp/static/src/less/mrp.less @@ -0,0 +1,8 @@ +.o_form_view { + .o_form_field_pdfviewer { + width: 100%; + height: 450px; + border: 0; + margin-top: 10px; + } +} diff --git a/addons/mrp/static/src/xml/mrp.xml b/addons/mrp/static/src/xml/mrp.xml new file mode 100644 index 00000000000..7f86a6a20dd --- /dev/null +++ b/addons/mrp/static/src/xml/mrp.xml @@ -0,0 +1,23 @@ + + + +
+
+ Uploading... + + + +
+