diff --git a/addons/account/account.py b/addons/account/account.py index df623f32174..21a5ce992d7 100644 --- a/addons/account/account.py +++ b/addons/account/account.py @@ -1416,14 +1416,17 @@ class account_move(osv.osv): l[2]['period_id'] = default_period context['period_id'] = default_period - if 'line_id' in vals: + if vals.get('line_id', False): c = context.copy() c['novalidate'] = True c['period_id'] = vals['period_id'] if 'period_id' in vals else self._get_period(cr, uid, context) c['journal_id'] = vals['journal_id'] if 'date' in vals: c['date'] = vals['date'] result = super(account_move, self).create(cr, uid, vals, c) - self.validate(cr, uid, [result], context) + tmp = self.validate(cr, uid, [result], context) + journal = self.pool.get('account.journal').browse(cr, uid, vals['journal_id'], context) + if journal.entry_posted and tmp: + self.button_validate(cr,uid, [result], context) else: result = super(account_move, self).create(cr, uid, vals, context) return result diff --git a/addons/account/account_invoice_view.xml b/addons/account/account_invoice_view.xml index d56fe27759c..1b7bd658faf 100644 --- a/addons/account/account_invoice_view.xml +++ b/addons/account/account_invoice_view.xml @@ -349,6 +349,7 @@ + diff --git a/addons/account/account_move_line.py b/addons/account/account_move_line.py index 7f5fa9707c1..0fc9d9e2227 100644 --- a/addons/account/account_move_line.py +++ b/addons/account/account_move_line.py @@ -1283,7 +1283,7 @@ class account_move_line(osv.osv): self.create(cr, uid, data, context) del vals['account_tax_id'] - if check and ((not context.get('no_store_function')) or journal.entry_posted): + if check and not context.get('novalidate') and ((not context.get('no_store_function')) or journal.entry_posted): tmp = move_obj.validate(cr, uid, [vals['move_id']], context) if journal.entry_posted and tmp: move_obj.button_validate(cr,uid, [vals['move_id']], context) diff --git a/addons/account/test/account_test_users.yml b/addons/account/test/account_test_users.yml index 143e8bb5473..c0002ac8b67 100644 --- a/addons/account/test/account_test_users.yml +++ b/addons/account/test/account_test_users.yml @@ -1,7 +1,7 @@ - Create a user as 'Accountant' - - !record {model: res.users, id: res_users_account_user}: + !record {model: res.users, id: res_users_account_user, view: False}: company_id: base.main_company name: Accountant login: acc @@ -17,7 +17,7 @@ - Create a user as 'Financial Manager' - - !record {model: res.users, id: res_users_account_manager}: + !record {model: res.users, id: res_users_account_manager, view: False}: company_id: base.main_company name: Financial Manager login: fm diff --git a/addons/account/wizard/account_report_partner_ledger_view.xml b/addons/account/wizard/account_report_partner_ledger_view.xml index 34c5d55e4c1..61b57f87d7e 100644 --- a/addons/account/wizard/account_report_partner_ledger_view.xml +++ b/addons/account/wizard/account_report_partner_ledger_view.xml @@ -15,7 +15,7 @@ - + diff --git a/addons/web_shortcuts/i18n/da.po b/addons/account_accountant/i18n/es_AR.po similarity index 50% rename from addons/web_shortcuts/i18n/da.po rename to addons/account_accountant/i18n/es_AR.po index 3cbeed065b5..0e2684b0431 100644 --- a/addons/web_shortcuts/i18n/da.po +++ b/addons/account_accountant/i18n/es_AR.po @@ -1,4 +1,4 @@ -# Danish translation for openobject-addons +# Spanish (Argentina) translation for openobject-addons # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the openobject-addons package. # FIRST AUTHOR , 2013. @@ -7,19 +7,17 @@ msgid "" msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME \n" -"POT-Creation-Date: 2012-12-21 17:06+0000\n" -"PO-Revision-Date: 2013-09-15 20:22+0000\n" +"POT-Creation-Date: 2012-12-21 17:04+0000\n" +"PO-Revision-Date: 2013-10-07 21:16+0000\n" "Last-Translator: FULL NAME \n" -"Language-Team: Danish \n" +"Language-Team: Spanish (Argentina) \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2013-09-16 05:42+0000\n" -"X-Generator: Launchpad (build 16761)\n" +"X-Launchpad-Export-Date: 2013-10-08 05:42+0000\n" +"X-Generator: Launchpad (build 16799)\n" -#. module: web_shortcuts -#. openerp-web -#: code:addons/web_shortcuts/static/src/xml/web_shortcuts.xml:21 -#, python-format -msgid "Add / Remove Shortcut..." -msgstr "Tilføj/fjern genvej ..." +#. module: account_accountant +#: model:ir.actions.client,name:account_accountant.action_client_account_menu +msgid "Open Accounting Menu" +msgstr "" diff --git a/addons/account_analytic_analysis/account_analytic_analysis.py b/addons/account_analytic_analysis/account_analytic_analysis.py index 7b21a4f1855..65d87ca3086 100644 --- a/addons/account_analytic_analysis/account_analytic_analysis.py +++ b/addons/account_analytic_analysis/account_analytic_analysis.py @@ -655,7 +655,7 @@ class account_analytic_account(osv.osv): if not contract.partner_id: raise osv.except_osv(_('No Customer Defined!'),_("You must first select a Customer for Contract %s!") % contract.name ) - fpos = contract.partner_id.property_account_position.id or False + fpos = contract.partner_id.property_account_position or False journal_ids = journal_obj.search(cr, uid, [('type', '=','sale'),('company_id', '=', contract.company_id.id or False)], limit=1) if not journal_ids: raise osv.except_osv(_('Error!'), @@ -673,7 +673,7 @@ class account_analytic_account(osv.osv): 'journal_id': len(journal_ids) and journal_ids[0] or False, 'date_invoice': contract.recurring_next_date, 'origin': contract.name, - 'fiscal_position': fpos, + 'fiscal_position': fpos and fpos.id, 'payment_term': partner_payment_term, 'company_id': contract.company_id.id or False, } @@ -687,7 +687,7 @@ class account_analytic_account(osv.osv): account_id = res.categ_id.property_account_income_categ.id account_id = fpos_obj.map_account(cr, uid, fpos, account_id) - taxes = res.taxes_id and res.taxes_id or False + taxes = res.taxes_id or False tax_id = fpos_obj.map_tax(cr, uid, fpos, taxes) invoice_line_vals = { diff --git a/addons/web_shortcuts/i18n/el.po b/addons/account_cancel/i18n/et.po similarity index 52% rename from addons/web_shortcuts/i18n/el.po rename to addons/account_cancel/i18n/et.po index d8ee859a736..440850791a7 100644 --- a/addons/web_shortcuts/i18n/el.po +++ b/addons/account_cancel/i18n/et.po @@ -1,4 +1,4 @@ -# Greek translation for openobject-addons +# Estonian translation for openobject-addons # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the openobject-addons package. # FIRST AUTHOR , 2013. @@ -7,19 +7,17 @@ msgid "" msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME \n" -"POT-Creation-Date: 2012-12-21 17:06+0000\n" -"PO-Revision-Date: 2013-09-30 20:14+0000\n" +"POT-Creation-Date: 2012-12-21 17:05+0000\n" +"PO-Revision-Date: 2013-10-09 14:39+0000\n" "Last-Translator: FULL NAME \n" -"Language-Team: Greek \n" +"Language-Team: Estonian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2013-10-01 05:18+0000\n" -"X-Generator: Launchpad (build 16774)\n" +"X-Launchpad-Export-Date: 2013-10-10 04:41+0000\n" +"X-Generator: Launchpad (build 16799)\n" -#. module: web_shortcuts -#. openerp-web -#: code:addons/web_shortcuts/static/src/xml/web_shortcuts.xml:21 -#, python-format -msgid "Add / Remove Shortcut..." +#. module: account_cancel +#: view:account.invoice:0 +msgid "Cancel" msgstr "" diff --git a/addons/account_voucher/test/account_voucher_users.yml b/addons/account_voucher/test/account_voucher_users.yml index c96645f0190..cb822ae4cef 100644 --- a/addons/account_voucher/test/account_voucher_users.yml +++ b/addons/account_voucher/test/account_voucher_users.yml @@ -1,7 +1,7 @@ - Create a user as 'Accountant for account voucher' - - !record {model: res.users, id: res_users_account_voucher_user}: + !record {model: res.users, id: res_users_account_voucher_user, view: False}: company_id: base.main_company name: Voucher Accountant login: vacc @@ -17,7 +17,7 @@ - Create a user as 'Financial Manager for account voucher' - - !record {model: res.users, id: res_users_account_voucher_manager}: + !record {model: res.users, id: res_users_account_voucher_manager, view: False}: company_id: base.main_company name: Financial Manager for voucher login: fmv diff --git a/addons/auth_crypt/i18n/et.po b/addons/auth_crypt/i18n/et.po index a634e17faa5..cbe529a053d 100644 --- a/addons/auth_crypt/i18n/et.po +++ b/addons/auth_crypt/i18n/et.po @@ -1,30 +1,28 @@ # Estonian translation for openobject-addons -# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 +# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the openobject-addons package. -# FIRST AUTHOR , 2011. +# FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME \n" -"POT-Creation-Date: 2012-12-03 16:03+0000\n" -"PO-Revision-Date: 2011-10-10 19:33+0000\n" -"Last-Translator: Aare Vesi \n" +"POT-Creation-Date: 2012-12-21 17:05+0000\n" +"PO-Revision-Date: 2013-10-09 14:40+0000\n" +"Last-Translator: FULL NAME \n" "Language-Team: Estonian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-12-04 05:53+0000\n" -"X-Generator: Launchpad (build 16335)\n" +"X-Launchpad-Export-Date: 2013-10-10 04:41+0000\n" +"X-Generator: Launchpad (build 16799)\n" -#. module: base_crypt -#: model:ir.model,name:base_crypt.model_res_users +#. module: auth_crypt +#: field:res.users,password_crypt:0 +msgid "Encrypted Password" +msgstr "Krüpteeritud Parool" + +#. module: auth_crypt +#: model:ir.model,name:auth_crypt.model_res_users msgid "Users" -msgstr "" - -#, python-format -#~ msgid "Error" -#~ msgstr "Viga" - -#~ msgid "res.users" -#~ msgstr "res.users" +msgstr "Kasutajad" diff --git a/addons/auth_oauth_signup/i18n/et.po b/addons/auth_oauth_signup/i18n/et.po new file mode 100644 index 00000000000..2d159250cff --- /dev/null +++ b/addons/auth_oauth_signup/i18n/et.po @@ -0,0 +1,23 @@ +# Estonian translation for openobject-addons +# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-12-21 17:05+0000\n" +"PO-Revision-Date: 2013-10-09 14:34+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Estonian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2013-10-10 04:41+0000\n" +"X-Generator: Launchpad (build 16799)\n" + +#. module: auth_oauth_signup +#: model:ir.model,name:auth_oauth_signup.model_res_users +msgid "Users" +msgstr "Kasutajad" diff --git a/addons/base_calendar/base_calendar.py b/addons/base_calendar/base_calendar.py index d4cd1e083b4..397bd193757 100644 --- a/addons/base_calendar/base_calendar.py +++ b/addons/base_calendar/base_calendar.py @@ -114,19 +114,6 @@ def real_id2base_calendar_id(real_id, recurrent_date): return '%d-%s' % (real_id, recurrent_date) return real_id -def _links_get(self, cr, uid, context=None): - """ - Get request link. - @param cr: the current row, from the database cursor - @param uid: the current user's ID for security checks - @param context: a standard dictionary for contextual values - @return: list of dictionary which contain object and name and id - """ - obj = self.pool.get('res.request.link') - ids = obj.search(cr, uid, []) - res = obj.read(cr, uid, ids, ['object', 'name'], context=context) - return [(r['object'], r['name']) for r in res] - html_invitation = """ @@ -307,19 +294,6 @@ class calendar_attendee(osv.osv): return result - def _links_get(self, cr, uid, context=None): - """ - Get request link for ref field in calendar attendee. - @param cr: the current row, from the database cursor - @param uid: the current user's id for security checks - @param context: A standard dictionary for contextual values - @return: list of dictionary which contain object and name and id - """ - obj = self.pool.get('res.request.link') - ids = obj.search(cr, uid, []) - res = obj.read(cr, uid, ids, ['object', 'name'], context=context) - return [(r['object'], r['name']) for r in res] - def _lang_get(self, cr, uid, context=None): """ Get language for language selection field. @@ -385,7 +359,7 @@ property or property parameter."), 'event_end_date': fields.function(_compute_data, \ string='Event End Date', type="datetime", \ multi='event_end_date'), - 'ref': fields.reference('Event Ref', selection=_links_get, size=128), + 'ref': fields.reference('Event Ref', selection=openerp.addons.base.res.res_request.referencable_models, size=128), 'availability': fields.selection([('free', 'Free'), ('busy', 'Busy')], 'Free/Busy', readonly="True"), } _defaults = { @@ -1208,20 +1182,44 @@ rule or repeating pattern of time to exclude from the recurring rule."), new_rrule_str = ';'.join(new_rrule_str) rdates = get_recurrent_dates(str(new_rrule_str), exdate, event_date, data['exrule']) for r_date in rdates: - ok = True + # fix domain evaluation + # step 1: check date and replace expression by True or False, replace other expressions by True + # step 2: evaluation of & and | + # check if there are one False + pile = [] for arg in domain: - if arg[0] in ('date', 'date_deadline'): - if (arg[1]=='='): - ok = ok and r_date.strftime('%Y-%m-%d')==arg[2] - if (arg[1]=='>'): - ok = ok and r_date.strftime('%Y-%m-%d')>arg[2] - if (arg[1]=='<'): - ok = ok and r_date.strftime('%Y-%m-%d')='): - ok = ok and r_date.strftime('%Y-%m-%d')>=arg[2] - if (arg[1]=='<='): - ok = ok and r_date.strftime('%Y-%m-%d')<=arg[2] - if not ok: + if str(arg[0]) in (str('date'), str('date_deadline')): + if (arg[1] == '='): + ok = r_date.strftime('%Y-%m-%d')==arg[2] + if (arg[1] == '>'): + ok = r_date.strftime('%Y-%m-%d')>arg[2] + if (arg[1] == '<'): + ok = r_date.strftime('%Y-%m-%d')='): + ok = r_date.strftime('%Y-%m-%d')>=arg[2] + if (arg[1] == '<='): + ok = r_date.strftime('%Y-%m-%d')<=arg[2] + pile.append(ok) + elif str(arg) == str('&') or str(arg) == str('|'): + pile.append(arg) + else: + pile.append(True) + pile.reverse() + new_pile = [] + for item in pile: + if not isinstance(item, basestring): + res = item + elif str(item) == str('&'): + first = new_pile.pop() + second = new_pile.pop() + res = first and second + elif str(item) == str('|'): + first = new_pile.pop() + second = new_pile.pop() + res = first or second + new_pile.append(res) + + if [True for item in new_pile if not item]: continue idval = real_id2base_calendar_id(data['id'], r_date.strftime("%Y-%m-%d %H:%M:%S")) result.append(idval) @@ -1346,18 +1344,17 @@ rule or repeating pattern of time to exclude from the recurring rule."), for arg in args: new_arg = arg - if arg[0] in ('date', unicode('date'), 'date_deadline', unicode('date_deadline')): + if arg[0] in ('date_deadline', unicode('date_deadline')): if context.get('virtual_id', True): - new_args += ['|','&',('recurrency','=',1),('recurrent_id_date', arg[1], arg[2])] + new_args += ['|','&',('recurrency','=',1),('end_date', arg[1], arg[2])] elif arg[0] == "id": new_id = get_real_ids(arg[2]) new_arg = (arg[0], arg[1], new_id) new_args.append(new_arg) - #offset, limit and count must be treated separately as we may need to deal with virtual ids res = super(calendar_event, self).search(cr, uid, new_args, offset=0, limit=0, order=order, context=context, count=False) if context.get('virtual_id', True): - res = self.get_recurrent_ids(cr, uid, res, new_args, limit, context=context) + res = self.get_recurrent_ids(cr, uid, res, args, limit, context=context) if count: return len(res) elif limit: @@ -1436,6 +1433,14 @@ rule or repeating pattern of time to exclude from the recurring rule."), vals['vtimezone'] = vals['vtimezone'][40:] res = super(calendar_event, self).write(cr, uid, ids, vals, context=context) + + # set end_date for calendar searching + if vals.get('recurrency', True) and vals.get('end_type', 'count') in ('count', unicode('count')) and \ + (vals.get('rrule_type') or vals.get('count') or vals.get('date') or vals.get('date_deadline')): + for data in self.read(cr, uid, ids, ['date', 'date_deadline', 'recurrency', 'rrule_type', 'count', 'end_type'], context=context): + end_date = self._set_recurrency_end_date(data, context=context) + super(calendar_event, self).write(cr, uid, [data['id']], {'end_date': end_date}, context=context) + if vals.get('partner_ids', False): self.create_attendees(cr, uid, ids, context) @@ -1554,6 +1559,21 @@ rule or repeating pattern of time to exclude from the recurring rule."), self.unlink_events(cr, uid, ids, context=context) return res + def _set_recurrency_end_date(self, data, context=None): + end_date = data.get('end_date') + if data.get('recurrency') and data.get('end_type') in ('count', unicode('count')): + data_date_deadline = datetime.strptime(data.get('date_deadline'), '%Y-%m-%d %H:%M:%S') + if data.get('rrule_type') in ('daily', unicode('count')): + rel_date = relativedelta(days=data.get('count')+1) + elif data.get('rrule_type') in ('weekly', unicode('weekly')): + rel_date = relativedelta(days=(data.get('count')+1)*7) + elif data.get('rrule_type') in ('monthly', unicode('monthly')): + rel_date = relativedelta(months=data.get('count')+1) + elif data.get('rrule_type') in ('yearly', unicode('yearly')): + rel_date = relativedelta(years=data.get('count')+1) + end_date = data_date_deadline + rel_date + return end_date + def create(self, cr, uid, vals, context=None): if context is None: context = {} @@ -1561,7 +1581,9 @@ rule or repeating pattern of time to exclude from the recurring rule."), if vals.get('vtimezone', '') and vals.get('vtimezone', '').startswith('/freeassociation.sourceforge.net/tzfile/'): vals['vtimezone'] = vals['vtimezone'][40:] + vals['end_date'] = self._set_recurrency_end_date(vals, context=context) res = super(calendar_event, self).create(cr, uid, vals, context) + alarm_obj = self.pool.get('res.alarm') alarm_obj.do_alarm_create(cr, uid, [res], self._name, 'date', context=context) self.create_attendees(cr, uid, [res], context) diff --git a/addons/base_report_designer/i18n/hi.po b/addons/base_report_designer/i18n/hi.po new file mode 100644 index 00000000000..660f5e3d429 --- /dev/null +++ b/addons/base_report_designer/i18n/hi.po @@ -0,0 +1,185 @@ +# Hindi translation for openobject-addons +# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-12-21 17:05+0000\n" +"PO-Revision-Date: 2013-10-09 05:55+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Hindi \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2013-10-10 04:41+0000\n" +"X-Generator: Launchpad (build 16799)\n" + +#. module: base_report_designer +#: model:ir.model,name:base_report_designer.model_base_report_sxw +msgid "base.report.sxw" +msgstr "base.report.sxw" + +#. module: base_report_designer +#: view:base_report_designer.installer:0 +msgid "OpenERP Report Designer Configuration" +msgstr "" + +#. module: base_report_designer +#: view:base_report_designer.installer:0 +msgid "" +"This plug-in allows you to create/modify OpenERP Reports into OpenOffice " +"Writer." +msgstr "" + +#. module: base_report_designer +#: view:base.report.sxw:0 +msgid "Upload the modified report" +msgstr "" + +#. module: base_report_designer +#: view:base.report.file.sxw:0 +msgid "The .SXW report" +msgstr "" + +#. module: base_report_designer +#: model:ir.model,name:base_report_designer.model_base_report_designer_installer +msgid "base_report_designer.installer" +msgstr "" + +#. module: base_report_designer +#: model:ir.model,name:base_report_designer.model_base_report_rml_save +msgid "base.report.rml.save" +msgstr "" + +#. module: base_report_designer +#: view:base_report_designer.installer:0 +msgid "Configure" +msgstr "" + +#. module: base_report_designer +#: view:base_report_designer.installer:0 +msgid "title" +msgstr "" + +#. module: base_report_designer +#: field:base.report.file.sxw,report_id:0 +#: field:base.report.sxw,report_id:0 +msgid "Report" +msgstr "" + +#. module: base_report_designer +#: view:base.report.rml.save:0 +msgid "The RML Report" +msgstr "" + +#. module: base_report_designer +#: model:ir.ui.menu,name:base_report_designer.menu_action_report_designer_wizard +msgid "Report Designer" +msgstr "" + +#. module: base_report_designer +#: field:base_report_designer.installer,name:0 +msgid "File name" +msgstr "" + +#. module: base_report_designer +#: view:base.report.file.sxw:0 +#: view:base.report.sxw:0 +msgid "Get a report" +msgstr "" + +#. module: base_report_designer +#: view:base_report_designer.installer:0 +#: model:ir.actions.act_window,name:base_report_designer.action_report_designer_wizard +msgid "OpenERP Report Designer" +msgstr "" + +#. module: base_report_designer +#: view:base.report.sxw:0 +msgid "Continue" +msgstr "" + +#. module: base_report_designer +#: field:base.report.rml.save,file_rml:0 +msgid "Save As" +msgstr "" + +#. module: base_report_designer +#: help:base_report_designer.installer,plugin_file:0 +msgid "" +"OpenObject Report Designer plug-in file. Save as this file and install this " +"plug-in in OpenOffice." +msgstr "" + +#. module: base_report_designer +#: view:base.report.rml.save:0 +msgid "Save RML FIle" +msgstr "" + +#. module: base_report_designer +#: field:base.report.file.sxw,file_sxw:0 +#: field:base.report.file.sxw,file_sxw_upload:0 +msgid "Your .SXW file" +msgstr "" + +#. module: base_report_designer +#: view:base_report_designer.installer:0 +msgid "Installation and Configuration Steps" +msgstr "" + +#. module: base_report_designer +#: field:base_report_designer.installer,description:0 +msgid "Description" +msgstr "" + +#. module: base_report_designer +#: view:base.report.file.sxw:0 +msgid "" +"This is the template of your requested report.\n" +"Save it as a .SXW file and open it with OpenOffice.\n" +"Don't forget to install the OpenERP SA OpenOffice package to modify it.\n" +"Once it is modified, re-upload it in OpenERP using this wizard." +msgstr "" + +#. module: base_report_designer +#: model:ir.actions.act_window,name:base_report_designer.action_view_base_report_sxw +msgid "Base Report sxw" +msgstr "" + +#. module: base_report_designer +#: model:ir.model,name:base_report_designer.model_base_report_file_sxw +msgid "base.report.file.sxw" +msgstr "" + +#. module: base_report_designer +#: field:base_report_designer.installer,plugin_file:0 +msgid "OpenObject Report Designer Plug-in" +msgstr "" + +#. module: base_report_designer +#: model:ir.actions.act_window,name:base_report_designer.action_report_designer_installer +msgid "OpenERP Report Designer Installation" +msgstr "" + +#. module: base_report_designer +#: view:base.report.sxw:0 +msgid "Cancel" +msgstr "" + +#. module: base_report_designer +#: view:base.report.sxw:0 +msgid "or" +msgstr "" + +#. module: base_report_designer +#: model:ir.model,name:base_report_designer.model_ir_actions_report_xml +msgid "ir.actions.report.xml" +msgstr "" + +#. module: base_report_designer +#: view:base.report.sxw:0 +msgid "Select your report" +msgstr "" diff --git a/addons/base_setup/res_config.py b/addons/base_setup/res_config.py index 9a5309d5c54..b059584d2db 100644 --- a/addons/base_setup/res_config.py +++ b/addons/base_setup/res_config.py @@ -20,10 +20,16 @@ ############################################################################## from openerp.osv import fields, osv +import re +from openerp.report.render.rml2pdf import customfonts class base_config_settings(osv.osv_memory): _name = 'base.config.settings' _inherit = 'res.config.settings' + + def _get_font(self, cr, uid, context=None): + return sorted(customfonts.RegisterCustomFonts()) + _columns = { 'module_multi_company': fields.boolean('Manage multiple companies', help='Work in multi-company environments, with appropriate security access between companies.\n' @@ -38,8 +44,13 @@ class base_config_settings(osv.osv_memory): 'module_base_import': fields.boolean("Allow users to import data from CSV files"), 'module_google_drive': fields.boolean('Attach Google documents to any record', help="""This installs the module google_docs."""), + 'font': fields.selection(_get_font, "Select Font", help="Set the font into the report header, will be used for every RML report of the user company"), } - + + _defaults= { + 'font': lambda self,cr,uid,c: self.pool.get('res.users').browse(cr, uid, uid, c).company_id.font or 'Helvetica', + } + def open_company(self, cr, uid, ids, context=None): user = self.pool.get('res.users').browse(cr, uid, uid, context) return { @@ -52,6 +63,20 @@ class base_config_settings(osv.osv_memory): 'target': 'current', } + def _change_header(self, header,font): + """ Replace default fontname use in header and setfont tag """ + + default_para = re.sub('fontName.?=.?".*"', 'fontName="%s"'% font,header) + return re.sub('("%s"\g<3>'% font,default_para) + + def set_base_defaults(self, cr, uid, ids, context=None): + ir_model_data = self.pool.get('ir.model.data') + wizard = self.browse(cr, uid, ids)[0] + if wizard.font: + user = self.pool.get('res.users').browse(cr, uid, uid, context) + user.company_id.write({'font':wizard.font,'rml_header': self._change_header(user.company_id.rml_header,wizard.font), 'rml_header2': self._change_header(user.company_id.rml_header2,wizard.font), 'rml_header3': self._change_header(user.company_id.rml_header3,wizard.font)}) + return {} + # Preferences wizard for Sales & CRM. # It is defined here because it is inherited independently in modules sale, crm, # plugin_outlook and plugin_thunderbird. @@ -80,4 +105,4 @@ class sale_config_settings(osv.osv_memory): help='Get access to statistics with your mass mailing, manage campaigns.'), } -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file diff --git a/addons/base_setup/res_config_view.xml b/addons/base_setup/res_config_view.xml index b0d7c90c7a0..e0434480a37 100644 --- a/addons/base_setup/res_config_view.xml +++ b/addons/base_setup/res_config_view.xml @@ -90,6 +90,14 @@ + + diff --git a/addons/claim_from_delivery/i18n/et.po b/addons/claim_from_delivery/i18n/et.po new file mode 100644 index 00000000000..312e096ffde --- /dev/null +++ b/addons/claim_from_delivery/i18n/et.po @@ -0,0 +1,33 @@ +# Estonian translation for openobject-addons +# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-12-21 17:05+0000\n" +"PO-Revision-Date: 2013-10-09 14:42+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Estonian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2013-10-10 04:41+0000\n" +"X-Generator: Launchpad (build 16799)\n" + +#. module: claim_from_delivery +#: view:stock.picking.out:0 +msgid "Claims" +msgstr "Nõuded" + +#. module: claim_from_delivery +#: model:res.request.link,name:claim_from_delivery.request_link_claim_from_delivery +msgid "Delivery Order" +msgstr "Tarnetellimus" + +#. module: claim_from_delivery +#: model:ir.actions.act_window,name:claim_from_delivery.action_claim_from_delivery +msgid "Claim From Delivery" +msgstr "" diff --git a/addons/crm/crm.py b/addons/crm/crm.py index 932fa998d0a..98581b91666 100644 --- a/addons/crm/crm.py +++ b/addons/crm/crm.py @@ -19,6 +19,7 @@ # ############################################################################## +import calendar from datetime import date, datetime from dateutil import relativedelta @@ -117,9 +118,9 @@ class crm_case_section(osv.osv): """ month_begin = date.today().replace(day=1) section_result = [{ - 'value': 0, - 'tooltip': (month_begin + relativedelta.relativedelta(months=-i)).strftime('%B'), - } for i in range(self._period_number - 1, -1, -1)] + 'value': 0, + 'tooltip': (month_begin + relativedelta.relativedelta(months=-i)).strftime('%B'), + } for i in range(self._period_number - 1, -1, -1)] group_obj = obj.read_group(cr, uid, domain, read_fields, groupby_field, context=context) for group in group_obj: group_begin_date = datetime.strptime(group['__domain'][0][2], tools.DEFAULT_SERVER_DATE_FORMAT) @@ -135,12 +136,14 @@ class crm_case_section(osv.osv): obj = self.pool.get('crm.lead') res = dict.fromkeys(ids, False) month_begin = date.today().replace(day=1) - groupby_begin = (month_begin + relativedelta.relativedelta(months=-4)).strftime(tools.DEFAULT_SERVER_DATE_FORMAT) + date_begin = month_begin - relativedelta.relativedelta(months=self._period_number - 1) + date_end = month_begin.replace(day=calendar.monthrange(month_begin.year, month_begin.month)[1]) + date_domain = [('create_date', '>=', date_begin.strftime(tools.DEFAULT_SERVER_DATE_FORMAT)), ('create_date', '<=', date_end.strftime(tools.DEFAULT_SERVER_DATE_FORMAT))] for id in ids: res[id] = dict() - lead_domain = [('type', '=', 'lead'), ('section_id', '=', id), ('create_date', '>=', groupby_begin)] + lead_domain = date_domain + [('type', '=', 'lead'), ('section_id', '=', id)] res[id]['monthly_open_leads'] = self.__get_bar_values(cr, uid, obj, lead_domain, ['create_date'], 'create_date_count', 'create_date', context=context) - opp_domain = [('type', '=', 'opportunity'), ('section_id', '=', id), ('create_date', '>=', groupby_begin)] + opp_domain = date_domain + [('type', '=', 'opportunity'), ('section_id', '=', id)] res[id]['monthly_planned_revenue'] = self.__get_bar_values(cr, uid, obj, opp_domain, ['planned_revenue', 'create_date'], 'planned_revenue', 'create_date', context=context) return res @@ -255,13 +258,6 @@ class crm_case_resource_type(osv.osv): 'section_id': fields.many2one('crm.case.section', 'Sales Team'), } -def _links_get(self, cr, uid, context=None): - """Gets links value for reference field""" - obj = self.pool.get('res.request.link') - ids = obj.search(cr, uid, []) - res = obj.read(cr, uid, ids, ['object', 'name'], context) - return [(r['object'], r['name']) for r in res] - class crm_payment_mode(osv.osv): """ Payment Mode for Fund """ _name = "crm.payment.mode" diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py index d4c54001606..7449a6f7650 100644 --- a/addons/crm/crm_lead.py +++ b/addons/crm/crm_lead.py @@ -23,6 +23,7 @@ import crm from datetime import datetime from operator import itemgetter +import openerp from openerp import SUPERUSER_ID from openerp import tools from openerp.addons.base.res.res_partner import format_address @@ -258,8 +259,8 @@ class crm_lead(format_address, osv.osv): # Only used for type opportunity 'probability': fields.float('Success Rate (%)', group_operator="avg"), 'planned_revenue': fields.float('Expected Revenue', track_visibility='always'), - 'ref': fields.reference('Reference', selection=crm._links_get, size=128), - 'ref2': fields.reference('Reference 2', selection=crm._links_get, size=128), + 'ref': fields.reference('Reference', selection=openerp.addons.base.res.res_request.referencable_models), + 'ref2': fields.reference('Reference 2', selection=openerp.addons.base.res.res_request.referencable_models), 'phone': fields.char("Phone", size=64), 'date_deadline': fields.date('Expected Closing', help="Estimate of the date on which the opportunity will be won."), 'date_action': fields.date('Next Action Date', select=True), diff --git a/addons/crm/test/crm_access_group_users.yml b/addons/crm/test/crm_access_group_users.yml index 51cf52c0abc..ffde96a18f3 100644 --- a/addons/crm/test/crm_access_group_users.yml +++ b/addons/crm/test/crm_access_group_users.yml @@ -1,7 +1,7 @@ - Create a user as 'Crm Salesmanager' - - !record {model: res.users, id: crm_res_users_salesmanager}: + !record {model: res.users, id: crm_res_users_salesmanager, view: False}: company_id: base.main_company name: Crm Sales manager login: csm @@ -16,7 +16,7 @@ - Create a user as 'Crm Salesman' - - !record {model: res.users, id: crm_res_users_salesman}: + !record {model: res.users, id: crm_res_users_salesman, view: False}: company_id: base.main_company name: Crm Salesman login: csu diff --git a/addons/crm/wizard/crm_lead_to_opportunity.py b/addons/crm/wizard/crm_lead_to_opportunity.py index d954e0486cc..48097944ec4 100644 --- a/addons/crm/wizard/crm_lead_to_opportunity.py +++ b/addons/crm/wizard/crm_lead_to_opportunity.py @@ -63,7 +63,7 @@ class crm_lead2opportunity_partner(osv.osv_memory): for id in ids: tomerge.add(id) if email: - ids = lead_obj.search(cr, uid, [('email_from', 'ilike', email[0]), ('probability', '<', '100')]) + ids = lead_obj.search(cr, uid, [('email_from', '=ilike', email[0]), ('probability', '<', '100')]) for id in ids: tomerge.add(id) diff --git a/addons/crm_claim/crm_claim.py b/addons/crm_claim/crm_claim.py index a3b09c272f6..1b9cb0b0c50 100644 --- a/addons/crm_claim/crm_claim.py +++ b/addons/crm_claim/crm_claim.py @@ -19,6 +19,7 @@ # ############################################################################## +import openerp from openerp.addons.crm import crm from openerp.osv import fields, osv from openerp import tools @@ -83,7 +84,7 @@ class crm_claim(osv.osv): 'date_deadline': fields.date('Deadline'), 'date_closed': fields.datetime('Closed', readonly=True), 'date': fields.datetime('Claim Date', select=True), - 'ref' : fields.reference('Reference', selection=crm._links_get, size=128), + 'ref': fields.reference('Reference', selection=openerp.addons.base.res.res_request.referencable_models), 'categ_id': fields.many2one('crm.case.categ', 'Category', \ domain="[('section_id','=',section_id),\ ('object_id.model', '=', 'crm.claim')]"), diff --git a/addons/crm_helpdesk/crm_helpdesk.py b/addons/crm_helpdesk/crm_helpdesk.py index 80a86c87c7c..5f84d45f974 100644 --- a/addons/crm_helpdesk/crm_helpdesk.py +++ b/addons/crm_helpdesk/crm_helpdesk.py @@ -19,6 +19,7 @@ # ############################################################################## +import openerp from openerp.addons.crm import crm from openerp.osv import fields, osv from openerp import tools @@ -53,8 +54,8 @@ class crm_helpdesk(osv.osv): 'email_cc': fields.text('Watchers Emails', size=252 , help="These email addresses will be added to the CC field of all inbound and outbound emails for this record before being sent. Separate multiple email addresses with a comma"), 'email_from': fields.char('Email', size=128, help="Destination email for email gateway"), 'date': fields.datetime('Date'), - 'ref' : fields.reference('Reference', selection=crm._links_get, size=128), - 'ref2' : fields.reference('Reference 2', selection=crm._links_get, size=128), + 'ref': fields.reference('Reference', selection=openerp.addons.base.res.res_request.referencable_models), + 'ref2': fields.reference('Reference 2', selection=openerp.addons.base.res.res_request.referencable_models), 'channel_id': fields.many2one('crm.case.channel', 'Channel', help="Communication channel."), 'planned_revenue': fields.float('Planned Revenue'), 'planned_cost': fields.float('Planned Costs'), diff --git a/addons/crm_todo/i18n/et.po b/addons/crm_todo/i18n/et.po new file mode 100644 index 00000000000..4e08132360c --- /dev/null +++ b/addons/crm_todo/i18n/et.po @@ -0,0 +1,85 @@ +# Estonian translation for openobject-addons +# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-12-21 17:05+0000\n" +"PO-Revision-Date: 2013-10-09 15:39+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Estonian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2013-10-10 04:41+0000\n" +"X-Generator: Launchpad (build 16799)\n" + +#. module: crm_todo +#: model:ir.model,name:crm_todo.model_project_task +msgid "Task" +msgstr "Ülesanne" + +#. module: crm_todo +#: view:crm.lead:0 +msgid "Timebox" +msgstr "Ajalahter" + +#. module: crm_todo +#: view:crm.lead:0 +msgid "Lead" +msgstr "" + +#. module: crm_todo +#: view:crm.lead:0 +msgid "For cancelling the task" +msgstr "Ülesande katkestamiseks" + +#. module: crm_todo +#: view:crm.lead:0 +msgid "Next" +msgstr "Järgmine" + +#. module: crm_todo +#: model:ir.actions.act_window,name:crm_todo.crm_todo_action +#: model:ir.ui.menu,name:crm_todo.menu_crm_todo +msgid "My Tasks" +msgstr "Minu ülesanded" + +#. module: crm_todo +#: view:crm.lead:0 +#: field:crm.lead,task_ids:0 +msgid "Tasks" +msgstr "Ülesanded" + +#. module: crm_todo +#: view:crm.lead:0 +msgid "Done" +msgstr "Valmis" + +#. module: crm_todo +#: view:crm.lead:0 +msgid "Cancel" +msgstr "Katkesta" + +#. module: crm_todo +#: model:ir.model,name:crm_todo.model_crm_lead +msgid "Lead/Opportunity" +msgstr "" + +#. module: crm_todo +#: field:project.task,lead_id:0 +msgid "Lead / Opportunity" +msgstr "" + +#. module: crm_todo +#: view:crm.lead:0 +msgid "For changing to done state" +msgstr "" + +#. module: crm_todo +#: view:crm.lead:0 +msgid "Previous" +msgstr "Eelmine" diff --git a/addons/email_template/ir_actions.py b/addons/email_template/ir_actions.py index bd860785da4..ae2395e3b81 100644 --- a/addons/email_template/ir_actions.py +++ b/addons/email_template/ir_actions.py @@ -33,48 +33,45 @@ class actions_server(osv.Model): return res _columns = { - 'email_from': fields.char('From', - help="Sender address; define the template to see its value. If not set, the default " - "value will be the author's email alias if configured, or email address."), - 'email_to': fields.char('To (Emails)', - help="Comma-separated recipient addresses; define the template to see its value"), - 'partner_to': fields.char('To (Partners)', - help="Comma-separated ids of recipient partners; define the template to see its value"), - 'subject': fields.char('Subject', - help="Email subject; define the template to see its value"), - 'body_html': fields.text('Body', - help="Rich-text/HTML version of the message; define the template to see its value"), - 'template_id': fields.many2one('email.template', 'Email Template', ondelete='set null', - help="Define the email template to use for the email to send.") + 'email_from': fields.related( + 'template_id', 'email_from', type='char', + readonly=True, string='From' + ), + 'email_to': fields.related( + 'template_id', 'email_to', type='char', + readonly=True, string='To (Emails)' + ), + 'partner_to': fields.related( + 'template_id', 'partner_to', type='char', + readonly=True, string='To (Partners)' + ), + 'subject': fields.related( + 'template_id', 'subject', type='char', + readonly=True, string='Subject' + ), + 'body_html': fields.related( + 'template_id', 'body_html', type='text', + readonly=True, string='Body' + ), + 'template_id': fields.many2one( + 'email.template', 'Email Template', ondelete='set null', + domain="[('model_id', '=', model_id)]", + ), } def on_change_template_id(self, cr, uid, ids, template_id, context=None): """ Render the raw template in the server action fields. """ + fields = ['subject', 'body_html', 'email_from', 'email_to', 'partner_to'] if template_id: - fields = ['subject', 'body_html', 'email_from', 'email_to', 'partner_to', 'email_cc', 'reply_to', 'attachment_ids'] template_values = self.pool.get('email.template').read(cr, uid, template_id, fields, context) values = dict((field, template_values[field]) for field in fields if template_values.get(field)) if not values.get('email_from'): return {'warning': {'title': 'Incomplete template', 'message': 'Your template should define email_from'}, 'value': values} else: - values = self.default_get(cr, uid, ['subject', 'body_html', 'email_from', 'email_to', 'partner_to'], context=context) + values = dict.fromkeys(fields, False) return {'value': values} - def create(self, cr, uid, values, context=None): - if values.get('template_id'): - fields = ['subject', 'body_html', 'email_from', 'email_to', 'partner_to', 'email_cc', 'reply_to', 'attachment_ids'] - template_values = self.pool.get('email.template').read(cr, uid, values.get('template_id'), fields, context) - values.update(dict((field, template_values[field]) for field in fields if template_values.get(field))) - return super(actions_server, self).create(cr, uid, values, context=context) - - def write(self, cr, uid, ids, values, context=None): - if values.get('template_id'): - fields = ['subject', 'body_html', 'email_from', 'email_to', 'partner_to', 'email_cc', 'reply_to', 'attachment_ids'] - template_values = self.pool.get('email.template').read(cr, uid, values.get('template_id'), fields, context) - values.update(dict((field, template_values[field]) for field in fields if template_values.get(field))) - return super(actions_server, self).write(cr, uid, ids, values, context=context) - def run_action_email(self, cr, uid, action, eval_context=None, context=None): if not action.template_id or not context.get('active_id'): return False diff --git a/addons/email_template/ir_actions_view.xml b/addons/email_template/ir_actions_view.xml index fae9c364312..8f5875257aa 100644 --- a/addons/email_template/ir_actions_view.xml +++ b/addons/email_template/ir_actions_view.xml @@ -16,7 +16,6 @@

Choose a template to display its values. diff --git a/addons/event/test/ui/event_users.yml b/addons/event/test/ui/event_users.yml index cda4ebda750..1f4d7a56035 100644 --- a/addons/event/test/ui/event_users.yml +++ b/addons/event/test/ui/event_users.yml @@ -1,7 +1,7 @@ - Create a user as 'Event manager' - - !record {model: res.users, id: res_users_eventmanager}: + !record {model: res.users, id: res_users_eventmanager, view: False}: company_id: base.main_company name: Event manager login: em @@ -16,7 +16,7 @@ - Create a user as 'Event user' - - !record {model: res.users, id: res_users_eventuser}: + !record {model: res.users, id: res_users_eventuser, view: False}: company_id: base.main_company name: User login: eu diff --git a/addons/hr/hr.py b/addons/hr/hr.py index d19f1f7de8b..bf58fdd76f8 100644 --- a/addons/hr/hr.py +++ b/addons/hr/hr.py @@ -346,26 +346,9 @@ class res_users(osv.osv): _name = 'res.users' _inherit = 'res.users' - def create(self, cr, uid, data, context=None): - user_id = super(res_users, self).create(cr, uid, data, context=context) - - # add shortcut unless 'noshortcut' is True in context - if not(context and context.get('noshortcut', False)): - data_obj = self.pool.get('ir.model.data') - try: - data_id = data_obj._get_id(cr, uid, 'hr', 'ir_ui_view_sc_employee') - view_id = data_obj.browse(cr, uid, data_id, context=context).res_id - self.pool.get('ir.ui.view_sc').copy(cr, uid, view_id, default = { - 'user_id': user_id}, context=context) - except: - # Tolerate a missing shortcut. See product/product.py for similar code. - _logger.debug('Skipped meetings shortcut for user "%s".', data.get('name',' - - Employees - ir.ui.menu - - - - hr.employee.tree diff --git a/addons/hr/test/hr_users.yml b/addons/hr/test/hr_users.yml index 115924d5c1c..e69c5ad5cb0 100644 --- a/addons/hr/test/hr_users.yml +++ b/addons/hr/test/hr_users.yml @@ -1,7 +1,7 @@ - Create a user as 'HR Manager' - - !record {model: res.users, id: res_users_hr_manager}: + !record {model: res.users, id: res_users_hr_manager, view: False}: company_id: base.main_company name: HR manager login: hrm @@ -15,7 +15,7 @@ - Create a user as 'HR Officer' - - !record {model: res.users, id: res_users_hr_officer}: + !record {model: res.users, id: res_users_hr_officer, view: False}: company_id: base.main_company name: HR Officer login: hro @@ -29,7 +29,7 @@ - Create a user as 'Employee' - - !record {model: res.users, id: res_users_employee}: + !record {model: res.users, id: res_users_employee, view: False}: company_id: base.main_company name: Employee login: emp diff --git a/addons/hr_attendance/test/attendance_process.yml b/addons/hr_attendance/test/attendance_process.yml index 814f0ee9b8a..e8e97d57ee9 100644 --- a/addons/hr_attendance/test/attendance_process.yml +++ b/addons/hr_attendance/test/attendance_process.yml @@ -1,7 +1,7 @@ - Create a user as 'HR Attendance Officer' - - !record {model: res.users, id: res_users_attendance_officer}: + !record {model: res.users, id: res_users_attendance_officer, view: False}: company_id: base.main_company name: HR Officer login: ao diff --git a/addons/hr_recruitment/test/recruitment_process.yml b/addons/hr_recruitment/test/recruitment_process.yml index 50637281a70..8588e5c96e8 100644 --- a/addons/hr_recruitment/test/recruitment_process.yml +++ b/addons/hr_recruitment/test/recruitment_process.yml @@ -1,7 +1,7 @@ - Create a user as 'HR Recruitment Officer' - - !record {model: res.users, id: res_users_hr_recruitment_officer}: + !record {model: res.users, id: res_users_hr_recruitment_officer, view: False}: company_id: base.main_company name: HR Recruitment Officer login: hrro diff --git a/addons/hr_timesheet/test/hr_timesheet_users.yml b/addons/hr_timesheet/test/hr_timesheet_users.yml index cb59f77df69..09731a16cf9 100644 --- a/addons/hr_timesheet/test/hr_timesheet_users.yml +++ b/addons/hr_timesheet/test/hr_timesheet_users.yml @@ -1,7 +1,7 @@ - Create a user as 'HR timesheet Manager' - - !record {model: res.users, id: res_hr_timesheet_manager}: + !record {model: res.users, id: res_hr_timesheet_manager, view: False}: company_id: base.main_company name: HR timesheet manager login: hrtm @@ -15,7 +15,7 @@ - Create a user as 'HR timesheet Officer' - - !record {model: res.users, id: res_hr_timesheet_officer}: + !record {model: res.users, id: res_hr_timesheet_officer, view: False}: company_id: base.main_company name: HR timesheet Officer login: hrto @@ -29,7 +29,7 @@ - Create a user as 'Timesheet Employee' - - !record {model: res.users, id: res_hr_timesheet_employee}: + !record {model: res.users, id: res_hr_timesheet_employee, view: False}: company_id: base.main_company name: Timesheet Employee login: empt diff --git a/addons/hr_timesheet/wizard/hr_timesheet_sign_in_out.py b/addons/hr_timesheet/wizard/hr_timesheet_sign_in_out.py index 87425b9cb3f..3b73920cf7d 100644 --- a/addons/hr_timesheet/wizard/hr_timesheet_sign_in_out.py +++ b/addons/hr_timesheet/wizard/hr_timesheet_sign_in_out.py @@ -133,7 +133,7 @@ class hr_si_project(osv.osv_memory): def check_state(self, cr, uid, ids, context=None): obj_model = self.pool.get('ir.model.data') - emp_id = self.default_get(cr, uid, context)['emp_id'] + emp_id = self.default_get(cr, uid, ['emp_id'], context)['emp_id'] # get the latest action (sign_in or out) for this employee cr.execute('select action from hr_attendance where employee_id=%s and action in (\'sign_in\',\'sign_out\') order by name desc limit 1', (emp_id,)) res = (cr.fetchone() or ('sign_out',))[0] diff --git a/addons/hr_timesheet_sheet/hr_timesheet_sheet.py b/addons/hr_timesheet_sheet/hr_timesheet_sheet.py index 70f94a4f57e..9226787e908 100644 --- a/addons/hr_timesheet_sheet/hr_timesheet_sheet.py +++ b/addons/hr_timesheet_sheet/hr_timesheet_sheet.py @@ -458,7 +458,7 @@ class hr_timesheet_sheet_sheet_day(osv.osv): THEN (SUM(total_attendance) + CASE WHEN current_date <> name THEN 1440 - ELSE (EXTRACT(hour FROM current_time) * 60) + EXTRACT(minute FROM current_time) + ELSE (EXTRACT(hour FROM current_time AT TIME ZONE 'UTC') * 60) + EXTRACT(minute FROM current_time AT TIME ZONE 'UTC') END ) ELSE SUM(total_attendance) diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index 35a6adfaaea..226c5700248 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -1218,7 +1218,7 @@ openerp.mail = function (session) { init: function (parent, datasets, options) { var self = this; this._super(parent, options); - this.MailWidget = parent.__proto__ == mail.Widget.prototype ? parent : false; + this.MailWidget = parent instanceof mail.Widget ? parent : false; this.domain = options.domain || []; this.context = _.extend(options.context || {}); diff --git a/addons/mail/static/src/js/suggestions.js b/addons/mail/static/src/js/suggestions.js index 52f9bc8be21..47a5bcf625c 100644 --- a/addons/mail/static/src/js/suggestions.js +++ b/addons/mail/static/src/js/suggestions.js @@ -49,7 +49,7 @@ openerp.mail.suggestions = function(session, mail) { join_group: function (event) { var self = this; var group_id = parseInt($(event.currentTarget).attr('id'), 10); - return this.mail_group.call('message_subscribe_users', [[group_id],[this.session.uid]]).then(function(res) { + return this.mail_group.call('message_subscribe_users', [[group_id], [this.session.uid]]).then(function(res) { self.fetch_suggested_groups(); }); }, diff --git a/addons/mass_mailing/mass_mailing.py b/addons/mass_mailing/mass_mailing.py index ad59a918203..4f59994d4a6 100644 --- a/addons/mass_mailing/mass_mailing.py +++ b/addons/mass_mailing/mass_mailing.py @@ -194,10 +194,13 @@ class MassMailing(osv.Model): } for id in ids: res[id] = {} - date_begin = self.browse(cr, uid, id, context=context).date - domain = [('mass_mailing_id', '=', id), ('opened', '>=', date_begin)] + date_begin = datetime.strptime(self.browse(cr, uid, id, context=context).date, tools.DEFAULT_SERVER_DATETIME_FORMAT) + date_end = date_begin + relativedelta.relativedelta(days=self._period_number - 1) + date_begin_str = date_begin.strftime(tools.DEFAULT_SERVER_DATETIME_FORMAT) + date_end_str = date_end.strftime(tools.DEFAULT_SERVER_DATETIME_FORMAT) + domain = [('mass_mailing_id', '=', id), ('opened', '>=', date_begin_str), ('opened', '<=', date_end_str)] res[id]['opened_monthly'] = self.__get_bar_values(cr, uid, id, obj, domain, ['opened'], 'opened_count', 'opened', context=context) - domain = [('mass_mailing_id', '=', id), ('replied', '>=', date_begin)] + domain = [('mass_mailing_id', '=', id), ('replied', '>=', date_begin_str), ('replied', '<=', date_end_str)] res[id]['replied_monthly'] = self.__get_bar_values(cr, uid, id, obj, domain, ['replied'], 'replied_count', 'replied', context=context) return res diff --git a/addons/mrp/__openerp__.py b/addons/mrp/__openerp__.py index 5f5ded337a7..99afd01707a 100644 --- a/addons/mrp/__openerp__.py +++ b/addons/mrp/__openerp__.py @@ -77,6 +77,7 @@ Dashboard / Reports for MRP will include: #TODO: This yml tests are needed to be completely reviewed again because the product wood panel is removed in product demo as it does not suit for new demo context of computer and consultant company # so the ymls are too complex to change at this stage 'test': [ + 'test/bom_with_service_type_product.yml', 'test/mrp_users.yml', 'test/order_demo.yml', 'test/order_process.yml', diff --git a/addons/mrp/mrp.py b/addons/mrp/mrp.py index e4efc9a4779..1d0a0c98d48 100644 --- a/addons/mrp/mrp.py +++ b/addons/mrp/mrp.py @@ -292,8 +292,10 @@ class mrp_bom(osv.osv): """ if properties is None: properties = [] - cr.execute('select id from mrp_bom where product_id=%s and bom_id is null order by sequence', (product_id,)) - ids = map(lambda x: x[0], cr.fetchall()) + domain = [('product_id', '=', product_id), ('bom_id', '=', False), + '|', ('date_start', '=', False), ('date_start', '<=', time.strftime(DEFAULT_SERVER_DATETIME_FORMAT)), + '|', ('date_stop', '=', False), ('date_stop', '>=', time.strftime(DEFAULT_SERVER_DATETIME_FORMAT))] + ids = self.search(cr, uid, domain) max_prop = 0 result = False for bom in self.pool.get('mrp.bom').browse(cr, uid, ids): @@ -601,12 +603,12 @@ class mrp_production(osv.osv): """ self.write(cr, uid, ids, {'state': 'picking_except'}) return True - - def action_compute(self, cr, uid, ids, properties=None, context=None): - """ Computes bills of material of a product. - @param properties: List containing dictionaries of properties. - @return: No. of products. + + def _action_compute_lines(self, cr, uid, ids, properties=None, context=None): + """ Compute product_lines and workcenter_lines from BoM structure + @return: product_lines """ + if properties is None: properties = [] results = [] @@ -614,13 +616,15 @@ class mrp_production(osv.osv): uom_obj = self.pool.get('product.uom') prod_line_obj = self.pool.get('mrp.production.product.line') workcenter_line_obj = self.pool.get('mrp.production.workcenter.line') - for production in self.browse(cr, uid, ids): - - p_ids = prod_line_obj.search(cr, SUPERUSER_ID, [('production_id', '=', production.id)], context=context) - prod_line_obj.unlink(cr, SUPERUSER_ID, p_ids, context=context) - w_ids = workcenter_line_obj.search(cr, SUPERUSER_ID, [('production_id', '=', production.id)], context=context) - workcenter_line_obj.unlink(cr, SUPERUSER_ID, w_ids, context=context) + for production in self.browse(cr, uid, ids, context=context): + #unlink product_lines + prod_line_obj.unlink(cr, SUPERUSER_ID, [line.id for line in production.product_lines], context=context) + + #unlink workcenter_lines + workcenter_line_obj.unlink(cr, SUPERUSER_ID, [line.id for line in production.workcenter_lines], context=context) + + # search BoM structure and route bom_point = production.bom_id bom_id = production.bom_id.id if not bom_point: @@ -629,20 +633,33 @@ class mrp_production(osv.osv): bom_point = bom_obj.browse(cr, uid, bom_id) routing_id = bom_point.routing_id.id or False self.write(cr, uid, [production.id], {'bom_id': bom_id, 'routing_id': routing_id}) - + if not bom_id: raise osv.except_osv(_('Error!'), _("Cannot find a bill of material for this product.")) + + # get components and workcenter_lines from BoM structure factor = uom_obj._compute_qty(cr, uid, production.product_uom.id, production.product_qty, bom_point.product_uom.id) res = bom_obj._bom_explode(cr, uid, bom_point, factor / bom_point.product_qty, properties, routing_id=production.routing_id.id) - results = res[0] - results2 = res[1] + results = res[0] # product_lines + results2 = res[1] # workcenter_lines + + # reset product_lines in production order for line in results: line['production_id'] = production.id prod_line_obj.create(cr, uid, line) + + #reset workcenter_lines in production order for line in results2: line['production_id'] = production.id workcenter_line_obj.create(cr, uid, line) - return len(results) + return results + + def action_compute(self, cr, uid, ids, properties=None, context=None): + """ Computes bills of material of a product. + @param properties: List containing dictionaries of properties. + @return: No. of products. + """ + return len(self._action_compute_lines(cr, uid, ids, properties=properties, context=context)) def action_cancel(self, cr, uid, ids, context=None): """ Cancels the production order and related stock moves. @@ -669,8 +686,12 @@ class mrp_production(osv.osv): move_obj = self.pool.get('stock.move') self.write(cr, uid, ids, {'state': 'ready'}) - for (production_id,name) in self.name_get(cr, uid, ids): - production = self.browse(cr, uid, production_id) + for production in self.browse(cr, uid, ids, context=context): + if not production.move_created_ids: + produce_move_id = self._make_production_produce_line(cr, uid, production, context=context) + for scheduled in production.product_lines: + self._make_production_line_procurement(cr, uid, scheduled, False, context=context) + if production.move_prod_id and production.move_prod_id.location_id.id != production.location_dest_id.id: move_obj.write(cr, uid, [production.move_prod_id.id], {'location_id': production.location_dest_id.id}) @@ -722,6 +743,10 @@ class mrp_production(osv.osv): stock_mov_obj = self.pool.get('stock.move') production = self.browse(cr, uid, production_id, context=context) + if not production.move_lines and production.state == 'ready': + # trigger workflow if not products to consume (eg: services) + self.signal_button_produce(cr, uid, [production_id]) + produced_qty = 0 for produced_product in production.move_created_ids2: if (produced_product.scrapped) or (produced_product.product_id.id != production.product_id.id): @@ -784,9 +809,9 @@ class mrp_production(osv.osv): subproduct_factor = self._get_subproduct_factor(cr, uid, production.id, produce_product.id, context=context) rest_qty = (subproduct_factor * production.product_qty) - produced_qty - if rest_qty < production_qty: + if rest_qty < (subproduct_factor * production_qty): prod_name = produce_product.product_id.name_get()[0][1] - raise osv.except_osv(_('Warning!'), _('You are going to produce total %s quantities of "%s".\nBut you can only produce up to total %s quantities.') % (production_qty, prod_name, rest_qty)) + raise osv.except_osv(_('Warning!'), _('You are going to produce total %s quantities of "%s".\nBut you can only produce up to total %s quantities.') % ((subproduct_factor * production_qty), prod_name, rest_qty)) if rest_qty > 0 : stock_mov_obj.action_consume(cr, uid, [produce_product.id], (subproduct_factor * production_qty), context=context) @@ -861,13 +886,19 @@ class mrp_production(osv.osv): """ res = True for production in self.browse(cr, uid, ids): - if not production.product_lines: - if not self.action_compute(cr, uid, [production.id]): - res = False + boms = self._action_compute_lines(cr, uid, [production.id]) + res = False + for bom in boms: + product = self.pool.get('product.product').browse(cr, uid, bom['product_id']) + if product.type in ('product', 'consu'): + res = True return res def _get_auto_picking(self, cr, uid, production): return True + + def _hook_create_post_procurement(self, cr, uid, production, procurement_id, context=None): + return True def _make_production_line_procurement(self, cr, uid, production_line, shipment_move_id, context=None): procurement_order = self.pool.get('procurement.order') @@ -1015,11 +1046,13 @@ class mrp_production(osv.osv): for line in production.product_lines: consume_move_id = self._make_production_consume_line(cr, uid, line, produce_move_id, source_location_id=source_location_id, context=context) - shipment_move_id = self._make_production_internal_shipment_line(cr, uid, line, shipment_id, consume_move_id,\ + if shipment_id: + shipment_move_id = self._make_production_internal_shipment_line(cr, uid, line, shipment_id, consume_move_id,\ destination_location_id=source_location_id, context=context) - self._make_production_line_procurement(cr, uid, line, shipment_move_id, context=context) + self._make_production_line_procurement(cr, uid, line, shipment_move_id, context=context) - self.pool.get('stock.picking').signal_button_confirm(cr, uid, [shipment_id]) + if shipment_id: + self.pool.get('stock.picking').signal_button_confirm(cr, uid, [shipment_id]) production.write({'state':'confirmed'}, context=context) return shipment_id diff --git a/addons/mrp/test/bom_with_service_type_product.yml b/addons/mrp/test/bom_with_service_type_product.yml new file mode 100644 index 00000000000..dc434cabf73 --- /dev/null +++ b/addons/mrp/test/bom_with_service_type_product.yml @@ -0,0 +1,134 @@ +- + I create Bill of Materials with one service type product and one consumable product. +- + !record {model: mrp.bom, id: mrp_bom_test1}: + company_id: base.main_company + name: PC Assemble SC234 + product_id: product.product_product_3 + product_qty: 1.0 + type: normal + bom_lines: + - company_id: base.main_company + name: On Site Assistance + product_id: product.product_product_2 + product_qty: 1.0 + - company_id: base.main_company + name: GrapWorks Software + product_id: product.product_product_44 + product_qty: 1.0 +- + I make the production order using BoM having one service type product and one consumable product. +- + !record {model: mrp.production, id: mrp_production_servicetype_mo1}: + product_id: product.product_product_5 + product_qty: 1.0 + bom_id: mrp_bom_test1 + date_planned: !eval time.strftime('%Y-%m-%d %H:%M:%S') +- + I compute the data of production order. +- + !python {model: mrp.production}: | + self.action_compute(cr, uid, [ref("mrp_production_servicetype_mo1")], {"lang": "en_US", "tz": False, "search_default_Current": 1, + "active_model": "ir.ui.menu", "active_ids": [ref("mrp.menu_mrp_production_action")], + "active_id": ref("mrp.menu_mrp_production_action"), }) +- + I confirm the production order. +- + !workflow {model: mrp.production, action: button_confirm, ref: mrp_production_servicetype_mo1} +- + I confirm the Consume Products. +- + !python {model: mrp.production}: | + order = self.browse(cr, uid, ref("mrp_production_servicetype_mo1")) + assert order.state == 'confirmed', "Production order should be confirmed." + for move_line in order.move_lines: + move_line.action_consume(move_line.product_qty) +- + I processed the Product Entirely. +- + !python {model: mrp.production}: | + order = self.browse(cr, uid, ref("mrp_production_servicetype_mo1")) + assert order.state == 'in_production', 'Production order should be in production State.' + for move_created in order.move_created_ids: + move_created.action_done() +- + I produce product. +- + !python {model: mrp.product.produce}: | + context.update({'active_id': ref('mrp_production_servicetype_mo1')}) +- + !record {model: mrp.product.produce, id: mrp_product_produce_1}: + mode: 'consume_produce' +- + !python {model: mrp.product.produce}: | + self.do_produce(cr, uid, [ref('mrp_product_produce_1')], context=context) +- + I check production order after produced. +- + !python {model: mrp.production}: | + order = self.browse(cr, uid, ref("mrp_production_servicetype_mo1")) + assert order.state == 'done', "Production order should be closed." +- + I create Bill of Materials with two service type products. +- + !record {model: mrp.bom, id: mrp_bom_test_2}: + company_id: base.main_company + name: PC Assemble SC234 + product_id: product.product_product_3 + product_qty: 1.0 + type: normal + bom_lines: + - company_id: base.main_company + name: On Site Monitoring + product_id: product.product_product_1 + product_qty: 1.0 + - company_id: base.main_company + name: On Site Assistance + product_id: product.product_product_2 + product_qty: 1.0 +- + I make the production order using BoM having two service type products. +- + !record {model: mrp.production, id: mrp_production_servicetype_2}: + product_id: product.product_product_5 + product_qty: 1.0 + bom_id: mrp_bom_test_2 + date_planned: !eval time.strftime('%Y-%m-%d %H:%M:%S') +- + I compute the data of production order. +- + !python {model: mrp.production}: | + self.action_compute(cr, uid, [ref("mrp_production_servicetype_2")], {"lang": "en_US", "tz": False, "search_default_Current": 1, + "active_model": "ir.ui.menu", "active_ids": [ref("mrp.menu_mrp_production_action")], + "active_id": ref("mrp.menu_mrp_production_action"), }) +- + I confirm the production order. +- + !workflow {model: mrp.production, action: button_confirm, ref: mrp_production_servicetype_2} +- + Now I start production. +- + !workflow {model: mrp.production, action: button_produce, ref: mrp_production_servicetype_2} +- + I check that production order in production state after start production. +- + !python {model: mrp.production}: | + order = self.browse(cr, uid, ref("mrp_production_servicetype_2")) + assert order.state == 'in_production', 'Production order should be in production State.' +- + I produce product. +- + !python {model: mrp.product.produce}: | + context.update({'active_id': ref('mrp_production_servicetype_2')}) +- + !record {model: mrp.product.produce, id: mrp_product_produce_2}: + mode: 'consume_produce' +- + !python {model: mrp.product.produce}: | + self.do_produce(cr, uid, [ref('mrp_product_produce_2')], context=context) +- + I check production order after produced. +- + !python {model: mrp.production}: | + order = self.browse(cr, uid, ref("mrp_production_servicetype_2")) + assert order.state == 'done', "Production order should be closed." diff --git a/addons/mrp/test/mrp_users.yml b/addons/mrp/test/mrp_users.yml index 05c4889cf28..8f89207a47d 100644 --- a/addons/mrp/test/mrp_users.yml +++ b/addons/mrp/test/mrp_users.yml @@ -1,7 +1,7 @@ - Create a user as 'MRP Manager' - - !record {model: res.users, id: res_users_mrp_manager}: + !record {model: res.users, id: res_users_mrp_manager, view: False}: company_id: base.main_company name: MRP Manager login: mam @@ -17,7 +17,7 @@ - Create a user as 'MRP User' - - !record {model: res.users, id: res_users_mrp_user}: + !record {model: res.users, id: res_users_mrp_user, view: False}: company_id: base.main_company name: MRP User login: mau diff --git a/addons/mrp_operations/mrp_operations_view.xml b/addons/mrp_operations/mrp_operations_view.xml index f2d1a84b40a..9b8587349bc 100644 --- a/addons/mrp_operations/mrp_operations_view.xml +++ b/addons/mrp_operations/mrp_operations_view.xml @@ -9,7 +9,7 @@

-