diff --git a/addons/account/account_bank_statement.py b/addons/account/account_bank_statement.py index 095d461ff3b..2dc7f96768f 100644 --- a/addons/account/account_bank_statement.py +++ b/addons/account/account_bank_statement.py @@ -304,7 +304,7 @@ class account_bank_statement(osv.osv): 'date': st_line.date, 'ref': st_line.ref, 'move_id': move_id, - 'partner_id': partner_id, + 'partner_id': par_id, 'account_id': acc_id, 'credit': credit, 'debit': debit, diff --git a/addons/account/account_view.xml b/addons/account/account_view.xml index d1b19910365..20aa198c63f 100644 --- a/addons/account/account_view.xml +++ b/addons/account/account_view.xml @@ -252,16 +252,6 @@ - - account.treasury.graph - account.account - - - - - - - Accounts account.account @@ -2537,7 +2527,7 @@ action = pool.get('res.config').next(cr, uid, [], context)
diff --git a/addons/account/board_account_view.xml b/addons/account/board_account_view.xml index 563c3f5fc6c..abbc81ade2b 100644 --- a/addons/account/board_account_view.xml +++ b/addons/account/board_account_view.xml @@ -12,16 +12,6 @@ [('year','=',time.strftime('%Y'))]
- - Treasury - account.account - form - graph,tree - [('type','=','liquidity')] - {'default_type': 'liquidity'} - - - board.account.form board.board @@ -31,9 +21,6 @@ - - - diff --git a/addons/account/wizard/account_move_journal.py b/addons/account/wizard/account_move_journal.py index 1353efca1f5..d87e4d04a0c 100644 --- a/addons/account/wizard/account_move_journal.py +++ b/addons/account/wizard/account_move_journal.py @@ -92,14 +92,14 @@ class account_move_journal(osv.osv_memory): journal = False if journal_id: - journal = journal_pool.read(cr, uid, [journal_id], ['name'])[0]['name'] + journal = journal_pool.read(cr, uid, journal_id, ['name'], context=context).name journal_string = _("Journal: %s") % tools.ustr(journal) else: journal_string = _("Journal: All") period = False if period_id: - period = period_pool.browse(cr, uid, [period_id], ['name'])[0]['name'] + period = period_pool.browse(cr, uid, period_id, context=context).name period_string = _("Period: %s") % tools.ustr(period) open_string = _("Open") diff --git a/addons/anonymization/anonymization.py b/addons/anonymization/anonymization.py index 47e168a12b8..6b6db168a4f 100644 --- a/addons/anonymization/anonymization.py +++ b/addons/anonymization/anonymization.py @@ -64,11 +64,13 @@ class ir_model_fields_anonymization(osv.osv): state = 'anonymized' # all fields are anonymized else: state = 'unstable' # fields are mixed: this should be fixed + return state def _check_write(self, cr, uid, context=None): # check that the field is created from the menu and not from an database update # otherwise the database update can crash: + if context.get('manual'): global_state = self._get_global_state(cr, uid, context=context) if global_state == 'anonymized': @@ -100,12 +102,16 @@ class ir_model_fields_anonymization(osv.osv): # check field state: all should be clear before we can add a new field to anonymize: self._check_write(cr, uid, context=context) + global_state = self._get_global_state(cr, uid, context=context) + if 'field_name' in vals and vals['field_name'] and 'model_name' in vals and vals['model_name']: vals['model_id'], vals['field_id'] = self._get_model_and_field_ids(cr, uid, vals, context=context) # check not existing fields: if not vals.get('field_id'): vals['state'] = 'not_existing' + else: + vals['state'] = global_state res = super(ir_model_fields_anonymization, self).create(cr, uid, vals, context=context) @@ -340,8 +346,9 @@ class ir_model_fields_anonymize_wizard(osv.osv_memory): # remove the placeholer: eview.remove(placeholder) else: - # unstable ? - raise + msg = "The database anonymization is currently in an unstable state. Some fields are anonymized," + \ + " while some fields are not anonymized. You should try to solve this problem before trying to do anything else." + raise osv.except_osv('Error !', msg) res['arch'] = etree.tostring(eview) diff --git a/addons/auth_signup/auth_signup_data.xml b/addons/auth_signup/auth_signup_data.xml index 4a6bf9ae4b9..39b62148494 100644 --- a/addons/auth_signup/auth_signup_data.xml +++ b/addons/auth_signup/auth_signup_data.xml @@ -13,7 +13,7 @@ - + auth_signup.template_user_id diff --git a/addons/base_calendar/__openerp__.py b/addons/base_calendar/__openerp__.py index 48ec05e2e92..b1afacfbd01 100644 --- a/addons/base_calendar/__openerp__.py +++ b/addons/base_calendar/__openerp__.py @@ -20,7 +20,7 @@ ############################################################################## { - 'name': 'Calendar Layer', + 'name': 'Calendar', 'version': '1.0', 'depends': ['base', 'base_status', 'mail', 'base_action_rule'], 'description': """ @@ -51,6 +51,7 @@ If you need to manage your meetings, you should install the CRM module. ], 'test' : ['test/base_calendar_test.yml'], 'installable': True, + 'application': True, 'auto_install': False, 'certificate': '00694071962960352821', 'images': ['images/base_calendar1.jpeg','images/base_calendar2.jpeg','images/base_calendar3.jpeg','images/base_calendar4.jpeg',], diff --git a/addons/base_calendar/base_calendar.py b/addons/base_calendar/base_calendar.py index a6d5f6859af..85199d09c60 100644 --- a/addons/base_calendar/base_calendar.py +++ b/addons/base_calendar/base_calendar.py @@ -1431,7 +1431,10 @@ rule or repeating pattern of time to exclude from the recurring rule."), if r['class']=='private': for f in r.keys(): if f not in ('id','date','date_deadline','duration','user_id','state'): - r[f] = False + if isinstance(r[f], list): + r[f] = [] + else: + r[f] = False if f=='name': r[f] = _('Busy') diff --git a/addons/base_calendar/base_calendar_view.xml b/addons/base_calendar/base_calendar_view.xml index 89066ce74bb..d374c2e6d88 100644 --- a/addons/base_calendar/base_calendar_view.xml +++ b/addons/base_calendar/base_calendar_view.xml @@ -418,7 +418,7 @@ ir.actions.act_window calendar.event form - tree,form,calendar + calendar,tree,form @@ -428,5 +428,6 @@ name="Events" parent="base.menu_calendar_configuration" sequence="15" action="action_view_event"/> + diff --git a/addons/base_calendar/crm_meeting.py b/addons/base_calendar/crm_meeting.py index e1c66148ae7..0ee23ed1d0f 100644 --- a/addons/base_calendar/crm_meeting.py +++ b/addons/base_calendar/crm_meeting.py @@ -53,7 +53,7 @@ class crm_meeting(base_state, osv.Model): 'partner_ids': fields.many2many('res.partner', 'crm_meeting_partner_rel', 'meeting_id','partner_id', string='Attendees', states={'done': [('readonly', True)]}), 'state': fields.selection( - [('draft', 'Unconfirmed'), ('open', 'Confirmed'), ('cancel', 'Cancelled'), ('done', 'Done')], + [('draft', 'Unconfirmed'), ('open', 'Confirmed')], string='Status', size=16, readonly=True), # Meeting fields 'name': fields.char('Meeting Subject', size=128, required=True, states={'done': [('readonly', True)]}), @@ -66,6 +66,11 @@ class crm_meeting(base_state, osv.Model): 'state': 'open', } + def copy(self, cr, uid, id, default=None, context=None): + default = default or {} + default['attendee_ids'] = False + return super(crm_meeting, self).copy(cr, uid, id, default, context) + # ---------------------------------------- # OpenChatter # ---------------------------------------- diff --git a/addons/base_calendar/crm_meeting_view.xml b/addons/base_calendar/crm_meeting_view.xml index 928f8d94d5c..b963de68130 100644 --- a/addons/base_calendar/crm_meeting_view.xml +++ b/addons/base_calendar/crm_meeting_view.xml @@ -69,9 +69,7 @@ crm.meeting
-
- -
+
diff --git a/addons/base_calendar/i18n/mk.po b/addons/base_calendar/i18n/mk.po new file mode 100644 index 00000000000..2f873ab5446 --- /dev/null +++ b/addons/base_calendar/i18n/mk.po @@ -0,0 +1,1520 @@ +# Macedonian translation for openobject-addons +# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-02-08 00:36+0000\n" +"PO-Revision-Date: 2012-09-17 15:05+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Macedonian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2012-09-18 04:48+0000\n" +"X-Generator: Launchpad (build 15966)\n" + +#. module: base_calendar +#: view:calendar.attendee:0 +msgid "Invitation Type" +msgstr "" + +#. module: base_calendar +#: selection:calendar.alarm,trigger_related:0 +#: selection:res.alarm,trigger_related:0 +msgid "The event starts" +msgstr "" + +#. module: base_calendar +#: view:calendar.attendee:0 +msgid "Declined Invitations" +msgstr "" + +#. module: base_calendar +#: help:calendar.event,exdate:0 +#: help:calendar.todo,exdate:0 +msgid "" +"This property defines the list of date/time exceptions for a recurring " +"calendar component." +msgstr "" + +#. module: base_calendar +#: constraint:res.users:0 +msgid "The chosen company is not in the allowed companies for this user" +msgstr "" + +#. module: base_calendar +#: field:calendar.event,we:0 +#: field:calendar.todo,we:0 +msgid "Wed" +msgstr "" + +#. module: base_calendar +#: selection:calendar.event,rrule_type:0 +#: selection:calendar.todo,rrule_type:0 +msgid "Monthly" +msgstr "" + +#. module: base_calendar +#: selection:calendar.attendee,cutype:0 +msgid "Unknown" +msgstr "" + +#. module: base_calendar +#: view:calendar.attendee:0 +msgid "Invited User" +msgstr "" + +#. module: base_calendar +#: view:calendar.attendee:0 +msgid "Invitation" +msgstr "" + +#. module: base_calendar +#: help:calendar.event,recurrency:0 +#: help:calendar.todo,recurrency:0 +msgid "Recurrent Meeting" +msgstr "" + +#. module: base_calendar +#: model:ir.actions.act_window,name:base_calendar.action_res_alarm_view +#: model:ir.ui.menu,name:base_calendar.menu_crm_meeting_avail_alarm +msgid "Alarms" +msgstr "" + +#. module: base_calendar +#: selection:calendar.event,week_list:0 +#: selection:calendar.todo,week_list:0 +msgid "Sunday" +msgstr "" + +#. module: base_calendar +#: view:calendar.attendee:0 +#: field:calendar.attendee,role:0 +msgid "Role" +msgstr "" + +#. module: base_calendar +#: view:calendar.attendee:0 +#: view:calendar.event:0 +msgid "Invitation details" +msgstr "" + +#. module: base_calendar +#: selection:calendar.event,byday:0 +#: selection:calendar.todo,byday:0 +msgid "Fourth" +msgstr "" + +#. module: base_calendar +#: code:addons/base_calendar/base_calendar.py:1006 +#, python-format +msgid "Count cannot be negative" +msgstr "" + +#. module: base_calendar +#: field:calendar.event,day:0 +#: selection:calendar.event,select1:0 +#: field:calendar.todo,day:0 +#: selection:calendar.todo,select1:0 +msgid "Date of month" +msgstr "" + +#. module: base_calendar +#: selection:calendar.event,class:0 +#: selection:calendar.todo,class:0 +msgid "Public" +msgstr "" + +#. module: base_calendar +#: view:calendar.event:0 +msgid " " +msgstr "" + +#. module: base_calendar +#: selection:calendar.event,month_list:0 +#: selection:calendar.todo,month_list:0 +msgid "March" +msgstr "" + +#. module: base_calendar +#: code:addons/base_calendar/base_calendar.py:418 +#: code:addons/base_calendar/base_calendar.py:1411 +#, python-format +msgid "Warning !" +msgstr "" + +#. module: base_calendar +#: field:calendar.event,rrule_type:0 +#: field:calendar.todo,rrule_type:0 +msgid "Recurrency" +msgstr "" + +#. module: base_calendar +#: selection:calendar.event,week_list:0 +#: selection:calendar.todo,week_list:0 +msgid "Friday" +msgstr "" + +#. module: base_calendar +#: field:calendar.event,allday:0 +#: field:calendar.todo,allday:0 +msgid "All Day" +msgstr "" + +#. module: base_calendar +#: field:calendar.event,select1:0 +#: field:calendar.todo,select1:0 +msgid "Option" +msgstr "" + +#. module: base_calendar +#: selection:calendar.attendee,availability:0 +#: selection:calendar.event,show_as:0 +#: selection:calendar.todo,show_as:0 +#: selection:res.users,availability:0 +msgid "Free" +msgstr "" + +#. module: base_calendar +#: help:calendar.attendee,rsvp:0 +msgid "Indicats whether the favor of a reply is requested" +msgstr "" + +#. module: base_calendar +#: field:calendar.alarm,alarm_id:0 +msgid "Basic Alarm" +msgstr "" + +#. module: base_calendar +#: help:calendar.attendee,delegated_to:0 +msgid "The users that the original request was delegated to" +msgstr "" + +#. module: base_calendar +#: field:calendar.attendee,ref:0 +msgid "Event Ref" +msgstr "" + +#. module: base_calendar +#: view:calendar.event:0 +msgid "Show Time as" +msgstr "" + +#. module: base_calendar +#: field:calendar.event,tu:0 +#: field:calendar.todo,tu:0 +msgid "Tue" +msgstr "" + +#. module: base_calendar +#: selection:calendar.event,byday:0 +#: selection:calendar.todo,byday:0 +msgid "Third" +msgstr "" + +#. module: base_calendar +#: selection:calendar.event,rrule_type:0 +#: selection:calendar.todo,rrule_type:0 +msgid "Yearly" +msgstr "" + +#. module: base_calendar +#: selection:calendar.event,byday:0 +#: selection:calendar.todo,byday:0 +msgid "Last" +msgstr "" + +#. module: base_calendar +#: selection:calendar.attendee,cutype:0 +msgid "Room" +msgstr "" + +#. module: base_calendar +#: view:calendar.attendee:0 +msgid "Accepted Invitations" +msgstr "" + +#. module: base_calendar +#: selection:calendar.alarm,trigger_interval:0 +#: selection:res.alarm,trigger_interval:0 +msgid "Days" +msgstr "" + +#. module: base_calendar +#: code:addons/base_calendar/base_calendar.py:1194 +#: code:addons/base_calendar/wizard/base_calendar_invite_attendee.py:96 +#: code:addons/base_calendar/wizard/base_calendar_invite_attendee.py:143 +#, python-format +msgid "Error!" +msgstr "" + +#. module: base_calendar +#: selection:calendar.attendee,role:0 +msgid "Chair Person" +msgstr "" + +#. module: base_calendar +#: selection:calendar.alarm,action:0 +msgid "Procedure" +msgstr "" + +#. module: base_calendar +#: code:addons/base_calendar/base_calendar.py:1004 +#, python-format +msgid "Interval cannot be negative" +msgstr "" + +#. module: base_calendar +#: selection:calendar.event,state:0 +#: selection:calendar.todo,state:0 +msgid "Cancelled" +msgstr "" + +#. module: base_calendar +#: code:addons/base_calendar/wizard/base_calendar_invite_attendee.py:143 +#, python-format +msgid "%s must have an email address to send mail" +msgstr "" + +#. module: base_calendar +#: selection:calendar.alarm,trigger_interval:0 +#: selection:res.alarm,trigger_interval:0 +msgid "Minutes" +msgstr "" + +#. module: base_calendar +#: selection:calendar.alarm,action:0 +msgid "Display" +msgstr "" + +#. module: base_calendar +#: view:calendar.attendee:0 +msgid "Invitation type" +msgstr "" + +#. module: base_calendar +#: help:calendar.attendee,state:0 +msgid "Status of the attendee's participation" +msgstr "" + +#. module: base_calendar +#: selection:calendar.alarm,trigger_related:0 +#: selection:res.alarm,trigger_related:0 +msgid "The event ends" +msgstr "" + +#. module: base_calendar +#: view:calendar.attendee:0 +#: view:calendar.event:0 +msgid "Group By..." +msgstr "" + +#. module: base_calendar +#: help:base_calendar.invite.attendee,email:0 +msgid "Provide external email address who will receive this invitation." +msgstr "" + +#. module: base_calendar +#: help:calendar.attendee,partner_id:0 +msgid "Partner related to contact" +msgstr "" + +#. module: base_calendar +#: help:calendar.attendee,cutype:0 +msgid "Specify the type of Invitation" +msgstr "" + +#. module: base_calendar +#: field:calendar.alarm,event_end_date:0 +#: field:calendar.attendee,event_end_date:0 +msgid "Event End Date" +msgstr "" + +#. module: base_calendar +#: selection:calendar.attendee,role:0 +msgid "Optional Participation" +msgstr "" + +#. module: base_calendar +#: field:calendar.event,date_deadline:0 +#: field:calendar.todo,date_deadline:0 +msgid "Deadline" +msgstr "" + +#. module: base_calendar +#: code:addons/base_calendar/base_calendar.py:389 +#: code:addons/base_calendar/base_calendar.py:1004 +#: code:addons/base_calendar/base_calendar.py:1006 +#, python-format +msgid "Warning!" +msgstr "" + +#. module: base_calendar +#: help:calendar.event,active:0 +#: help:calendar.todo,active:0 +msgid "" +"If the active field is set to true, it will allow you to hide the " +"event alarm information without removing it." +msgstr "" + +#. module: base_calendar +#: field:base_calendar.invite.attendee,partner_id:0 +#: view:calendar.attendee:0 +#: field:calendar.attendee,partner_id:0 +msgid "Partner" +msgstr "" + +#. module: base_calendar +#: field:calendar.event,organizer:0 +#: field:calendar.event,organizer_id:0 +#: field:calendar.todo,organizer:0 +#: field:calendar.todo,organizer_id:0 +msgid "Organizer" +msgstr "" + +#. module: base_calendar +#: view:calendar.attendee:0 +#: view:calendar.event:0 +#: field:calendar.event,user_id:0 +#: field:calendar.todo,user_id:0 +msgid "Responsible" +msgstr "" + +#. module: base_calendar +#: view:calendar.event:0 +#: model:res.request.link,name:base_calendar.request_link_meeting +msgid "Event" +msgstr "" + +#. module: base_calendar +#: selection:calendar.alarm,trigger_occurs:0 +#: selection:res.alarm,trigger_occurs:0 +msgid "Before" +msgstr "" + +#. module: base_calendar +#: view:calendar.event:0 +#: selection:calendar.event,state:0 +#: selection:calendar.todo,state:0 +msgid "Confirmed" +msgstr "" + +#. module: base_calendar +#: field:calendar.alarm,attendee_ids:0 +#: field:calendar.event,attendee_ids:0 +#: field:calendar.todo,attendee_ids:0 +msgid "Attendees" +msgstr "" + +#. module: base_calendar +#: code:addons/base_calendar/base_calendar.py:1411 +#, python-format +msgid "Group by date not supported, use the calendar view instead" +msgstr "" + +#. module: base_calendar +#: view:calendar.event:0 +msgid "Confirm" +msgstr "" + +#. module: base_calendar +#: model:ir.model,name:base_calendar.model_calendar_todo +msgid "Calendar Task" +msgstr "" + +#. module: base_calendar +#: field:calendar.event,su:0 +#: field:calendar.todo,su:0 +msgid "Sun" +msgstr "" + +#. module: base_calendar +#: field:calendar.attendee,cutype:0 +msgid "Invite Type" +msgstr "" + +#. module: base_calendar +#: view:res.alarm:0 +msgid "Reminder details" +msgstr "" + +#. module: base_calendar +#: field:calendar.attendee,parent_ids:0 +msgid "Delegrated From" +msgstr "" + +#. module: base_calendar +#: selection:calendar.event,select1:0 +#: selection:calendar.todo,select1:0 +msgid "Day of month" +msgstr "" + +#. module: base_calendar +#: view:calendar.event:0 +#: field:calendar.event,location:0 +#: field:calendar.todo,location:0 +msgid "Location" +msgstr "" + +#. module: base_calendar +#: selection:calendar.event,class:0 +#: selection:calendar.todo,class:0 +msgid "Public for Employees" +msgstr "" + +#. module: base_calendar +#: field:base_calendar.invite.attendee,send_mail:0 +msgid "Send mail?" +msgstr "" + +#. module: base_calendar +#: field:base_calendar.invite.attendee,email:0 +#: selection:calendar.alarm,action:0 +#: field:calendar.attendee,email:0 +msgid "Email" +msgstr "" + +#. module: base_calendar +#: view:calendar.attendee:0 +msgid "Event Detail" +msgstr "" + +#. module: base_calendar +#: selection:calendar.alarm,state:0 +msgid "Run" +msgstr "" + +#. module: base_calendar +#: field:calendar.event,exdate:0 +#: field:calendar.todo,exdate:0 +msgid "Exception Date/Times" +msgstr "" + +#. module: base_calendar +#: field:calendar.event,end_date:0 +#: field:calendar.todo,end_date:0 +msgid "Repeat Until" +msgstr "" + +#. module: base_calendar +#: model:ir.actions.act_window,help:base_calendar.action_res_alarm_view +msgid "" +"Create specific calendar alarms that may be assigned to calendar events or " +"meetings." +msgstr "" + +#. module: base_calendar +#: field:calendar.event,show_as:0 +#: field:calendar.todo,show_as:0 +msgid "Show as" +msgstr "" + +#. module: base_calendar +#: view:calendar.event:0 +msgid "Visibility" +msgstr "" + +#. module: base_calendar +#: field:calendar.attendee,rsvp:0 +msgid "Required Reply?" +msgstr "" + +#. module: base_calendar +#: field:calendar.event,base_calendar_url:0 +#: field:calendar.todo,base_calendar_url:0 +msgid "Caldav URL" +msgstr "" + +#. module: base_calendar +#: field:calendar.event,recurrent_uid:0 +#: field:calendar.todo,recurrent_uid:0 +msgid "Recurrent ID" +msgstr "" + +#. module: base_calendar +#: selection:calendar.event,month_list:0 +#: selection:calendar.todo,month_list:0 +msgid "July" +msgstr "" + +#. module: base_calendar +#: view:calendar.attendee:0 +#: selection:calendar.attendee,state:0 +msgid "Accepted" +msgstr "" + +#. module: base_calendar +#: field:calendar.event,th:0 +#: field:calendar.todo,th:0 +msgid "Thu" +msgstr "" + +#. module: base_calendar +#: field:calendar.attendee,child_ids:0 +msgid "Delegrated To" +msgstr "" + +#. module: base_calendar +#: view:calendar.event:0 +msgid "To" +msgstr "" + +#. module: base_calendar +#: view:calendar.attendee:0 +msgid "Required Reply" +msgstr "" + +#. module: base_calendar +#: selection:calendar.attendee,role:0 +msgid "Participation required" +msgstr "" + +#. module: base_calendar +#: field:calendar.event,create_date:0 +#: field:calendar.todo,create_date:0 +msgid "Created" +msgstr "" + +#. module: base_calendar +#: sql_constraint:ir.model:0 +msgid "Each model must be unique!" +msgstr "" + +#. module: base_calendar +#: selection:calendar.event,rrule_type:0 +#: selection:calendar.todo,rrule_type:0 +msgid "Daily" +msgstr "" + +#. module: base_calendar +#: field:calendar.event,class:0 +#: field:calendar.todo,class:0 +msgid "Mark as" +msgstr "" + +#. module: base_calendar +#: view:calendar.attendee:0 +#: field:calendar.attendee,partner_address_id:0 +msgid "Contact" +msgstr "" + +#. module: base_calendar +#: help:calendar.event,rrule_type:0 +#: help:calendar.todo,rrule_type:0 +msgid "Let the event automatically repeat at that interval" +msgstr "" + +#. module: base_calendar +#: view:calendar.attendee:0 +#: view:calendar.event:0 +msgid "Delegate" +msgstr "" + +#. module: base_calendar +#: view:base_calendar.invite.attendee:0 +#: selection:base_calendar.invite.attendee,type:0 +msgid "Partner Contacts" +msgstr "" + +#. module: base_calendar +#: selection:calendar.event,byday:0 +#: selection:calendar.todo,byday:0 +msgid "First" +msgstr "" + +#. module: base_calendar +#: view:calendar.event:0 +msgid "Privacy" +msgstr "" + +#. module: base_calendar +#: field:calendar.event,vtimezone:0 +#: field:calendar.todo,vtimezone:0 +msgid "Timezone" +msgstr "" + +#. module: base_calendar +#: view:calendar.event:0 +msgid "Subject" +msgstr "" + +#. module: base_calendar +#: selection:calendar.attendee,state:0 +msgid "Needs Action" +msgstr "" + +#. module: base_calendar +#: selection:calendar.event,month_list:0 +#: selection:calendar.todo,month_list:0 +msgid "September" +msgstr "" + +#. module: base_calendar +#: selection:calendar.event,month_list:0 +#: selection:calendar.todo,month_list:0 +msgid "December" +msgstr "" + +#. module: base_calendar +#: help:base_calendar.invite.attendee,send_mail:0 +msgid "Check this if you want to send an Email to Invited Person" +msgstr "" + +#. module: base_calendar +#: view:calendar.event:0 +msgid "Availability" +msgstr "" + +#. module: base_calendar +#: selection:calendar.attendee,cutype:0 +msgid "Individual" +msgstr "" + +#. module: base_calendar +#: help:calendar.event,count:0 +#: help:calendar.todo,count:0 +msgid "Repeat x times" +msgstr "" + +#. module: base_calendar +#: field:calendar.alarm,user_id:0 +msgid "Owner" +msgstr "" + +#. module: base_calendar +#: view:calendar.attendee:0 +msgid "Delegation Info" +msgstr "" + +#. module: base_calendar +#: view:calendar.event:0 +msgid "Start Date" +msgstr "" + +#. module: base_calendar +#: field:calendar.attendee,cn:0 +msgid "Common name" +msgstr "" + +#. module: base_calendar +#: view:calendar.attendee:0 +#: selection:calendar.attendee,state:0 +msgid "Declined" +msgstr "" + +#. module: base_calendar +#: view:calendar.attendee:0 +msgid "My Role" +msgstr "" + +#. module: base_calendar +#: view:calendar.event:0 +msgid "My Events" +msgstr "" + +#. module: base_calendar +#: view:calendar.attendee:0 +#: view:calendar.event:0 +msgid "Decline" +msgstr "" + +#. module: base_calendar +#: selection:calendar.attendee,cutype:0 +msgid "Group" +msgstr "" + +#. module: base_calendar +#: selection:calendar.event,class:0 +#: selection:calendar.todo,class:0 +msgid "Private" +msgstr "" + +#. module: base_calendar +#: field:base_calendar.invite.attendee,contact_ids:0 +msgid "Contacts" +msgstr "" + +#. module: base_calendar +#: model:ir.model,name:base_calendar.model_res_alarm +msgid "Basic Alarm Information" +msgstr "" + +#. module: base_calendar +#: field:calendar.event,fr:0 +#: field:calendar.todo,fr:0 +msgid "Fri" +msgstr "" + +#. module: base_calendar +#: selection:calendar.alarm,trigger_interval:0 +#: selection:res.alarm,trigger_interval:0 +msgid "Hours" +msgstr "" + +#. module: base_calendar +#: view:calendar.attendee:0 +#: view:calendar.event:0 +msgid "Invitation Detail" +msgstr "" + +#. module: base_calendar +#: field:calendar.attendee,member:0 +msgid "Member" +msgstr "" + +#. module: base_calendar +#: view:calendar.event:0 +msgid "From" +msgstr "" + +#. module: base_calendar +#: field:calendar.event,rrule:0 +#: field:calendar.todo,rrule:0 +msgid "Recurrent Rule" +msgstr "" + +#. module: base_calendar +#: selection:calendar.alarm,state:0 +msgid "Draft" +msgstr "" + +#. module: base_calendar +#: field:calendar.alarm,attach:0 +msgid "Attachment" +msgstr "" + +#. module: base_calendar +#: view:calendar.attendee:0 +msgid "Invitation From" +msgstr "" + +#. module: base_calendar +#: view:calendar.event:0 +msgid "End of Recurrency" +msgstr "" + +#. module: base_calendar +#: view:calendar.event:0 +msgid "Reminder" +msgstr "" + +#. module: base_calendar +#: view:calendar.event:0 +#: model:ir.actions.act_window,name:base_calendar.action_view_event +#: model:ir.ui.menu,name:base_calendar.menu_events +msgid "Events" +msgstr "" + +#. module: base_calendar +#: model:ir.actions.act_window,name:base_calendar.action_view_calendar_invite_attendee_wizard +#: model:ir.model,name:base_calendar.model_base_calendar_invite_attendee +msgid "Invite Attendees" +msgstr "" + +#. module: base_calendar +#: help:calendar.attendee,email:0 +msgid "Email of Invited Person" +msgstr "" + +#. module: base_calendar +#: field:calendar.alarm,repeat:0 +#: field:calendar.event,count:0 +#: field:calendar.todo,count:0 +#: field:res.alarm,repeat:0 +msgid "Repeat" +msgstr "" + +#. module: base_calendar +#: help:calendar.attendee,dir:0 +msgid "" +"Reference to the URIthat points to the directory information corresponding " +"to the attendee." +msgstr "" + +#. module: base_calendar +#: selection:calendar.event,month_list:0 +#: selection:calendar.todo,month_list:0 +msgid "August" +msgstr "" + +#. module: base_calendar +#: selection:calendar.event,week_list:0 +#: selection:calendar.todo,week_list:0 +msgid "Monday" +msgstr "" + +#. module: base_calendar +#: model:ir.model,name:base_calendar.model_ir_model +msgid "Models" +msgstr "" + +#. module: base_calendar +#: selection:calendar.event,month_list:0 +#: selection:calendar.todo,month_list:0 +msgid "June" +msgstr "" + +#. module: base_calendar +#: field:calendar.alarm,event_date:0 +#: field:calendar.attendee,event_date:0 +#: view:calendar.event:0 +msgid "Event Date" +msgstr "" + +#. module: base_calendar +#: selection:calendar.event,end_type:0 +#: selection:calendar.todo,end_type:0 +msgid "Number of repetitions" +msgstr "" + +#. module: base_calendar +#: view:calendar.event:0 +msgid "The" +msgstr "" + +#. module: base_calendar +#: view:calendar.attendee:0 +#: field:calendar.attendee,delegated_from:0 +msgid "Delegated From" +msgstr "" + +#. module: base_calendar +#: field:calendar.attendee,user_id:0 +msgid "User" +msgstr "" + +#. module: base_calendar +#: view:calendar.event:0 +#: field:calendar.event,date:0 +msgid "Date" +msgstr "" + +#. module: base_calendar +#: selection:calendar.event,month_list:0 +#: selection:calendar.todo,month_list:0 +msgid "November" +msgstr "" + +#. module: base_calendar +#: help:calendar.attendee,member:0 +msgid "Indicate the groups that the attendee belongs to" +msgstr "" + +#. module: base_calendar +#: view:base_calendar.invite.attendee:0 +msgid "Data" +msgstr "" + +#. module: base_calendar +#: field:calendar.event,end_type:0 +#: field:calendar.todo,end_type:0 +msgid "Recurrence termination" +msgstr "" + +#. module: base_calendar +#: field:calendar.event,mo:0 +#: field:calendar.todo,mo:0 +msgid "Mon" +msgstr "" + +#. module: base_calendar +#: view:calendar.attendee:0 +msgid "Invitations To Review" +msgstr "" + +#. module: base_calendar +#: selection:calendar.event,month_list:0 +#: selection:calendar.todo,month_list:0 +msgid "October" +msgstr "" + +#. module: base_calendar +#: view:calendar.attendee:0 +#: view:calendar.event:0 +msgid "Uncertain" +msgstr "" + +#. module: base_calendar +#: field:calendar.attendee,language:0 +msgid "Language" +msgstr "" + +#. module: base_calendar +#: field:calendar.alarm,trigger_occurs:0 +#: field:res.alarm,trigger_occurs:0 +msgid "Triggers" +msgstr "" + +#. module: base_calendar +#: selection:calendar.event,month_list:0 +#: selection:calendar.todo,month_list:0 +msgid "January" +msgstr "" + +#. module: base_calendar +#: view:calendar.attendee:0 +msgid "Delegated Invitations" +msgstr "" + +#. module: base_calendar +#: field:calendar.alarm,trigger_interval:0 +#: field:res.alarm,trigger_interval:0 +msgid "Interval" +msgstr "" + +#. module: base_calendar +#: selection:calendar.event,week_list:0 +#: selection:calendar.todo,week_list:0 +msgid "Wednesday" +msgstr "" + +#. module: base_calendar +#: field:calendar.alarm,name:0 +#: view:calendar.event:0 +msgid "Summary" +msgstr "" + +#. module: base_calendar +#: field:calendar.alarm,active:0 +#: field:calendar.event,active:0 +#: field:calendar.todo,active:0 +#: field:res.alarm,active:0 +msgid "Active" +msgstr "" + +#. module: base_calendar +#: code:addons/base_calendar/base_calendar.py:389 +#, python-format +msgid "You cannot duplicate a calendar attendee." +msgstr "" + +#. module: base_calendar +#: view:calendar.event:0 +msgid "Choose day in the month where repeat the meeting" +msgstr "" + +#. module: base_calendar +#: field:calendar.alarm,action:0 +msgid "Action" +msgstr "" + +#. module: base_calendar +#: help:base_calendar.invite.attendee,type:0 +msgid "Select whom you want to Invite" +msgstr "" + +#. module: base_calendar +#: help:calendar.alarm,duration:0 +#: help:res.alarm,duration:0 +msgid "" +"Duration' and 'Repeat' are both optional, but if one occurs, so MUST the " +"other" +msgstr "" + +#. module: base_calendar +#: view:calendar.attendee:0 +msgid "Required to Join" +msgstr "" + +#. module: base_calendar +#: help:calendar.attendee,role:0 +msgid "Participation role for the calendar user" +msgstr "" + +#. module: base_calendar +#: view:calendar.attendee:0 +#: field:calendar.attendee,delegated_to:0 +msgid "Delegated To" +msgstr "" + +#. module: base_calendar +#: help:calendar.alarm,action:0 +msgid "Defines the action to be invoked when an alarm is triggered" +msgstr "" + +#. module: base_calendar +#: selection:calendar.event,end_type:0 +#: selection:calendar.todo,end_type:0 +msgid "End date" +msgstr "" + +#. module: base_calendar +#: view:calendar.event:0 +msgid "Search Events" +msgstr "" + +#. module: base_calendar +#: view:calendar.event:0 +msgid "Recurrency Option" +msgstr "" + +#. module: base_calendar +#: selection:calendar.event,rrule_type:0 +#: selection:calendar.todo,rrule_type:0 +msgid "Weekly" +msgstr "" + +#. module: base_calendar +#: help:calendar.alarm,active:0 +#: help:res.alarm,active:0 +msgid "" +"If the active field is set to true, it will allow you to hide the event " +"alarm information without removing it." +msgstr "" + +#. module: base_calendar +#: field:calendar.event,recurrent_id:0 +#: field:calendar.todo,recurrent_id:0 +msgid "Recurrent ID date" +msgstr "" + +#. module: base_calendar +#: sql_constraint:res.users:0 +msgid "You can not have two users with the same login !" +msgstr "" + +#. module: base_calendar +#: field:calendar.alarm,state:0 +#: view:calendar.attendee:0 +#: field:calendar.attendee,state:0 +#: view:calendar.event:0 +#: field:calendar.event,state:0 +#: field:calendar.todo,state:0 +msgid "State" +msgstr "" + +#. module: base_calendar +#: view:res.alarm:0 +msgid "Reminder Details" +msgstr "" + +#. module: base_calendar +#: view:calendar.attendee:0 +msgid "To Review" +msgstr "" + +#. module: base_calendar +#: selection:calendar.alarm,state:0 +msgid "Done" +msgstr "" + +#. module: base_calendar +#: help:calendar.event,interval:0 +#: help:calendar.todo,interval:0 +msgid "Repeat every (Days/Week/Month/Year)" +msgstr "" + +#. module: base_calendar +#: view:base_calendar.invite.attendee:0 +#: field:base_calendar.invite.attendee,user_ids:0 +msgid "Users" +msgstr "" + +#. module: base_calendar +#: view:base_calendar.invite.attendee:0 +#: view:calendar.event:0 +msgid "Cancel" +msgstr "" + +#. module: base_calendar +#: model:ir.model,name:base_calendar.model_res_users +msgid "res.users" +msgstr "" + +#. module: base_calendar +#: selection:calendar.event,week_list:0 +#: selection:calendar.todo,week_list:0 +msgid "Tuesday" +msgstr "" + +#. module: base_calendar +#: help:calendar.alarm,description:0 +msgid "" +"Provides a more complete description of the " +"calendar component, than that provided by the " +"\"SUMMARY\" property" +msgstr "" + +#. module: base_calendar +#: view:calendar.event:0 +msgid "Responsible User" +msgstr "" + +#. module: base_calendar +#: code:addons/base_calendar/base_calendar.py:1466 +#: selection:calendar.attendee,availability:0 +#: selection:calendar.event,show_as:0 +#: selection:calendar.todo,show_as:0 +#: selection:res.users,availability:0 +#, python-format +msgid "Busy" +msgstr "" + +#. module: base_calendar +#: model:ir.model,name:base_calendar.model_calendar_event +msgid "Calendar Event" +msgstr "" + +#. module: base_calendar +#: selection:calendar.attendee,state:0 +#: selection:calendar.event,state:0 +#: selection:calendar.todo,state:0 +msgid "Tentative" +msgstr "" + +#. module: base_calendar +#: field:calendar.event,interval:0 +#: field:calendar.todo,interval:0 +msgid "Repeat every" +msgstr "" + +#. module: base_calendar +#: field:calendar.event,recurrency:0 +#: field:calendar.todo,recurrency:0 +msgid "Recurrent" +msgstr "" + +#. module: base_calendar +#: help:calendar.event,location:0 +#: help:calendar.todo,location:0 +msgid "Location of Event" +msgstr "" + +#. module: base_calendar +#: model:ir.actions.act_window,name:base_calendar.action_view_attendee_form +#: model:ir.ui.menu,name:base_calendar.menu_attendee_invitations +msgid "Event Invitations" +msgstr "" + +#. module: base_calendar +#: selection:calendar.event,week_list:0 +#: selection:calendar.todo,week_list:0 +msgid "Thursday" +msgstr "" + +#. module: base_calendar +#: field:calendar.event,exrule:0 +#: field:calendar.todo,exrule:0 +msgid "Exception Rule" +msgstr "" + +#. module: base_calendar +#: help:calendar.attendee,language:0 +msgid "" +"To specify the language for text values in aproperty or property parameter." +msgstr "" + +#. module: base_calendar +#: view:calendar.event:0 +msgid "Details" +msgstr "" + +#. module: base_calendar +#: help:calendar.event,exrule:0 +#: help:calendar.todo,exrule:0 +msgid "" +"Defines a rule or repeating pattern of time to exclude from the recurring " +"rule." +msgstr "" + +#. module: base_calendar +#: field:calendar.event,month_list:0 +#: field:calendar.todo,month_list:0 +msgid "Month" +msgstr "" + +#. module: base_calendar +#: view:base_calendar.invite.attendee:0 +#: view:calendar.event:0 +msgid "Invite People" +msgstr "" + +#. module: base_calendar +#: view:calendar.event:0 +msgid "Confirmed Events" +msgstr "" + +#. module: base_calendar +#: field:calendar.attendee,dir:0 +msgid "URI Reference" +msgstr "" + +#. module: base_calendar +#: field:calendar.alarm,description:0 +#: view:calendar.event:0 +#: field:calendar.event,description:0 +#: field:calendar.event,name:0 +#: field:calendar.todo,description:0 +#: field:calendar.todo,name:0 +msgid "Description" +msgstr "" + +#. module: base_calendar +#: selection:calendar.event,month_list:0 +#: selection:calendar.todo,month_list:0 +msgid "May" +msgstr "" + +#. module: base_calendar +#: field:base_calendar.invite.attendee,type:0 +#: view:calendar.attendee:0 +msgid "Type" +msgstr "" + +#. module: base_calendar +#: view:calendar.attendee:0 +msgid "Search Invitations" +msgstr "" + +#. module: base_calendar +#: selection:calendar.alarm,trigger_occurs:0 +#: selection:res.alarm,trigger_occurs:0 +msgid "After" +msgstr "" + +#. module: base_calendar +#: selection:calendar.alarm,state:0 +msgid "Stop" +msgstr "" + +#. module: base_calendar +#: model:ir.model,name:base_calendar.model_ir_values +msgid "ir.values" +msgstr "" + +#. module: base_calendar +#: model:ir.model,name:base_calendar.model_ir_attachment +msgid "ir.attachment" +msgstr "" + +#. module: base_calendar +#: view:calendar.attendee:0 +#: selection:calendar.attendee,state:0 +msgid "Delegated" +msgstr "" + +#. module: base_calendar +#: field:calendar.event,sa:0 +#: field:calendar.todo,sa:0 +msgid "Sat" +msgstr "" + +#. module: base_calendar +#: view:calendar.event:0 +msgid "Choose day where repeat the meeting" +msgstr "" + +#. module: base_calendar +#: field:calendar.alarm,trigger_related:0 +#: field:res.alarm,trigger_related:0 +msgid "Related to" +msgstr "" + +#. module: base_calendar +#: help:calendar.attendee,sent_by:0 +msgid "Specify the user that is acting on behalf of the calendar user" +msgstr "" + +#. module: base_calendar +#: view:calendar.event:0 +msgid "End Date" +msgstr "" + +#. module: base_calendar +#: selection:calendar.event,month_list:0 +#: selection:calendar.todo,month_list:0 +msgid "February" +msgstr "" + +#. module: base_calendar +#: selection:calendar.attendee,cutype:0 +msgid "Resource" +msgstr "" + +#. module: base_calendar +#: field:res.alarm,name:0 +msgid "Name" +msgstr "" + +#. module: base_calendar +#: model:ir.model,name:base_calendar.model_calendar_alarm +msgid "Event alarm information" +msgstr "" + +#. module: base_calendar +#: help:calendar.alarm,name:0 +msgid "" +"Contains the text to be used as the message subject for " +"email or contains the text to be used for display" +msgstr "" + +#. module: base_calendar +#: field:calendar.event,alarm_id:0 +#: field:calendar.event,base_calendar_alarm_id:0 +#: field:calendar.todo,alarm_id:0 +#: field:calendar.todo,base_calendar_alarm_id:0 +msgid "Alarm" +msgstr "" + +#. module: base_calendar +#: field:calendar.attendee,sent_by_uid:0 +msgid "Sent By User" +msgstr "" + +#. module: base_calendar +#: selection:calendar.event,month_list:0 +#: selection:calendar.todo,month_list:0 +msgid "April" +msgstr "" + +#. module: base_calendar +#: view:calendar.event:0 +msgid "Recurrency period" +msgstr "" + +#. module: base_calendar +#: field:calendar.event,week_list:0 +#: field:calendar.todo,week_list:0 +msgid "Weekday" +msgstr "" + +#. module: base_calendar +#: field:calendar.event,byday:0 +#: field:calendar.todo,byday:0 +msgid "By day" +msgstr "" + +#. module: base_calendar +#: field:calendar.alarm,model_id:0 +msgid "Model" +msgstr "" + +#. module: base_calendar +#: selection:calendar.alarm,action:0 +msgid "Audio" +msgstr "" + +#. module: base_calendar +#: field:calendar.event,id:0 +#: field:calendar.todo,id:0 +msgid "ID" +msgstr "" + +#. module: base_calendar +#: selection:calendar.attendee,role:0 +msgid "For information Purpose" +msgstr "" + +#. module: base_calendar +#: view:base_calendar.invite.attendee:0 +msgid "Invite" +msgstr "" + +#. module: base_calendar +#: model:ir.model,name:base_calendar.model_calendar_attendee +msgid "Attendee information" +msgstr "" + +#. module: base_calendar +#: field:calendar.alarm,res_id:0 +msgid "Resource ID" +msgstr "" + +#. module: base_calendar +#: code:addons/base_calendar/base_calendar.py:418 +#, python-format +msgid "Couldn't Invite because date is not specified!" +msgstr "" + +#. module: base_calendar +#: field:calendar.attendee,sent_by:0 +msgid "Sent By" +msgstr "" + +#. module: base_calendar +#: field:calendar.event,sequence:0 +#: field:calendar.todo,sequence:0 +msgid "Sequence" +msgstr "" + +#. module: base_calendar +#: help:calendar.event,alarm_id:0 +#: help:calendar.todo,alarm_id:0 +msgid "Set an alarm at this time, before the event occurs" +msgstr "" + +#. module: base_calendar +#: selection:base_calendar.invite.attendee,type:0 +msgid "Internal User" +msgstr "" + +#. module: base_calendar +#: view:calendar.attendee:0 +#: view:calendar.event:0 +msgid "Accept" +msgstr "" + +#. module: base_calendar +#: selection:calendar.event,week_list:0 +#: selection:calendar.todo,week_list:0 +msgid "Saturday" +msgstr "" + +#. module: base_calendar +#: view:calendar.attendee:0 +msgid "Invitation To" +msgstr "" + +#. module: base_calendar +#: selection:calendar.event,byday:0 +#: selection:calendar.todo,byday:0 +msgid "Second" +msgstr "" + +#. module: base_calendar +#: field:calendar.attendee,availability:0 +#: field:res.users,availability:0 +msgid "Free/Busy" +msgstr "" + +#. module: base_calendar +#: field:calendar.alarm,duration:0 +#: field:calendar.alarm,trigger_duration:0 +#: field:calendar.event,duration:0 +#: field:calendar.todo,date:0 +#: field:calendar.todo,duration:0 +#: field:res.alarm,duration:0 +#: field:res.alarm,trigger_duration:0 +msgid "Duration" +msgstr "" + +#. module: base_calendar +#: selection:base_calendar.invite.attendee,type:0 +msgid "External Email" +msgstr "" + +#. module: base_calendar +#: field:calendar.alarm,trigger_date:0 +msgid "Trigger Date" +msgstr "" + +#. module: base_calendar +#: help:calendar.alarm,attach:0 +msgid "" +"* Points to a sound resource, which is rendered when the " +"alarm is triggered for audio,\n" +" * File which is intended to be sent as message " +"attachments for email,\n" +" * Points to a procedure resource, which is invoked when " +" the alarm is triggered for procedure." +msgstr "" + +#. module: base_calendar +#: selection:calendar.event,byday:0 +#: selection:calendar.todo,byday:0 +msgid "Fifth" +msgstr "" diff --git a/addons/base_calendar/static/src/img/icon.png b/addons/base_calendar/static/src/img/icon.png new file mode 100644 index 00000000000..f612cd9ea4b Binary files /dev/null and b/addons/base_calendar/static/src/img/icon.png differ diff --git a/addons/base_setup/res_partner_view.xml b/addons/base_setup/res_partner_view.xml index 5e54c0b8629..15b80151831 100644 --- a/addons/base_setup/res_partner_view.xml +++ b/addons/base_setup/res_partner_view.xml @@ -9,14 +9,11 @@ - - - - + + - diff --git a/addons/base_status/base_stage.py b/addons/base_status/base_stage.py index 529e70fdb49..9db3ece7d8b 100644 --- a/addons/base_status/base_stage.py +++ b/addons/base_status/base_stage.py @@ -69,7 +69,7 @@ class base_stage(object): return False return uid - def onchange_partner_address_id(self, cr, uid, ids, add, email=False): + def onchange_partner_address_id(self, cr, uid, ids, add, email=False, context=None): """ This function returns value of partner email based on Partner Address :param add: Id of Partner's address :param email: Partner's email ID @@ -77,10 +77,20 @@ class base_stage(object): data = {'value': {'email_from': False, 'phone':False}} if add: address = self.pool.get('res.partner').browse(cr, uid, add) - data['value'] = {'email_from': address and address.email or False , - 'phone': address and address.phone or False} - if 'phone' not in self._columns: - del data['value']['phone'] + data['value'] = {'partner_name': address and address.name or False, + 'email_from': address and address.email or False, + 'phone': address and address.phone or False, + 'street': address and address.street or False, + 'street2': address and address.street2 or False, + 'city': address and address.city or False, + 'state_id': address.state_id and address.state_id.id or False, + 'zip': address and address.zip or False, + 'country_id': address.country_id and address.country_id.id or False, + } + fields = self.fields_get(cr, uid, context=context or {}) + for key in data['value'].keys(): + if key not in fields: + del data['value'][key] return data def onchange_partner_id(self, cr, uid, ids, part, email=False): diff --git a/addons/board/static/src/css/dashboard.css b/addons/board/static/src/css/dashboard.css index ed66e338c81..f2bbcd07071 100644 --- a/addons/board/static/src/css/dashboard.css +++ b/addons/board/static/src/css/dashboard.css @@ -1,3 +1,36 @@ +.openerp .oe_dashboard_layout_1 .oe_dashboard_column.index_0 { + width: 100%; +} +.openerp .oe_dashboard_layout_1 .oe_dashboard_column.index_1, .openerp .oe_dashboard_layout_1 .oe_dashboard_column.index_2 { + display: none; +} +.openerp .oe_dashboard_layout_1-1 .oe_dashboard_column { + width: 50%; +} +.openerp .oe_dashboard_layout_1-1 .oe_dashboard_column.index_2 { + display: none; +} +.openerp .oe_dashboard_layout_1-1-1 .oe_dashboard_column { + width: 33%; +} +.openerp .oe_dashboard_layout_2-1 .oe_dashboard_column.index_0 { + width: 70%; +} +.openerp .oe_dashboard_layout_2-1 .oe_dashboard_column.index_1 { + width: 30%; +} +.openerp .oe_dashboard_layout_2-1 .oe_dashboard_column.index_2 { + display: none; +} +.openerp .oe_dashboard_layout_1-2 .oe_dashboard_column.index_0 { + width: 30%; +} +.openerp .oe_dashboard_layout_1-2 .oe_dashboard_column.index_1 { + width: 70%; +} +.openerp .oe_dashboard_layout_1-2 .oe_dashboard_column.index_2 { + display: none; +} .openerp .oe_dashboard_layout_selector ul { white-space: nowrap; } diff --git a/addons/board/static/src/css/dashboard.sass b/addons/board/static/src/css/dashboard.sass index 32f0e3b4f3a..122b6dc232c 100644 --- a/addons/board/static/src/css/dashboard.sass +++ b/addons/board/static/src/css/dashboard.sass @@ -9,6 +9,31 @@ box-shadow: $bsval .openerp + .oe_dashboard_layout_1 .oe_dashboard_column + &.index_0 + width: 100% + &.index_1, &.index_2 + display: none + .oe_dashboard_layout_1-1 .oe_dashboard_column + width: 50% + &.index_2 + display: none + .oe_dashboard_layout_1-1-1 .oe_dashboard_column + width: 33% + .oe_dashboard_layout_2-1 .oe_dashboard_column + &.index_0 + width: 70% + &.index_1 + width: 30% + &.index_2 + display: none + .oe_dashboard_layout_1-2 .oe_dashboard_column + &.index_0 + width: 30% + &.index_1 + width: 70% + &.index_2 + display: none .oe_dashboard_layout_selector ul white-space: nowrap @@ -98,3 +123,4 @@ > tbody tr:nth-child(odd) background: transparent + diff --git a/addons/board/static/src/js/dashboard.js b/addons/board/static/src/js/dashboard.js index 9c37924144d..43d7ca76d39 100644 --- a/addons/board/static/src/js/dashboard.js +++ b/addons/board/static/src/js/dashboard.js @@ -24,6 +24,10 @@ instance.web.form.DashBoard = instance.web.form.FormWidget.extend({ scroll: false }).bind('sortstop', self.do_save_dashboard); + var old_title = this.__parentedParent.get('title'); + this.__parentedParent.on_record_loaded.add_last(function(){ + self.__parentedParent.set({ 'title' : old_title}); + }); // Events this.$el.find('.oe_dashboard_link_reset').click(this.on_reset); this.$el.find('.oe_dashboard_link_change_layout').click(this.on_change_layout); @@ -165,8 +169,6 @@ instance.web.form.DashBoard = instance.web.form.FormWidget.extend({ this.rpc('/web/view/add_custom', { view_id: this.view.fields_view.view_id, arch: arch - }, function() { - self.$el.find('.oe_dashboard_link_reset').show(); }); }, on_load_action: function(result, index, action_attrs) { diff --git a/addons/board/static/src/xml/board.xml b/addons/board/static/src/xml/board.xml index e13fa707776..03ede793036 100644 --- a/addons/board/static/src/xml/board.xml +++ b/addons/board/static/src/xml/board.xml @@ -1,7 +1,7 @@ diff --git a/addons/mail/tests/test_mail.py b/addons/mail/tests/test_mail.py index 1fab5dd1732..57a59e2595f 100644 --- a/addons/mail/tests/test_mail.py +++ b/addons/mail/tests/test_mail.py @@ -647,3 +647,33 @@ class test_mail(TestMailMockups): msg1.refresh() self.assertEqual(5, len(group_pigs.message_ids), 'group should contain 5 messages') self.assertEqual(2, len(msg1.child_ids), 'msg1 should have 2 children now') + + def test_60_vote(self): + """ Test designed for the vote/unvote feature. """ + cr, uid = self.cr, self.uid + group_pigs = self.mail_group.browse(cr, uid, self.group_pigs_id) + user_admin = self.res_users.browse(cr, uid, uid) + msg1 = group_pigs.message_post(body='My Body', subject='1') + msg1 = self.mail_message.browse(cr, uid, msg1) + + # Create user Bert Tartopoils + user_bert_id = self.res_users.create(cr, uid, {'name': 'Bert', 'login': 'bert'}) + user_bert = self.res_users.browse(cr, uid, user_bert_id) + + # Test: msg1 and msg2 have void vote_user_ids + self.assertFalse(msg1.vote_user_ids, 'newly created message msg1 has not void vote_user_ids') + # Do: Admin vote for msg1 + self.mail_message.vote_toggle(cr, uid, [msg1.id]) + msg1.refresh() + # Test: msg1 has Admin as voter + self.assertEqual(set(msg1.vote_user_ids), set([user_admin]), 'after voting, Admin is not the voter') + # Do: Bert vote for msg1 + self.mail_message.vote_toggle(cr, uid, [msg1.id], [user_bert_id]) + msg1.refresh() + # Test: msg1 has Admin and Bert as voters + self.assertEqual(set(msg1.vote_user_ids), set([user_admin, user_bert]), 'after voting, Admin and Bert are not the voters') + # Do: Admin unvote for msg1 + self.mail_message.vote_toggle(cr, uid, [msg1.id]) + msg1.refresh() + # Test: msg1 has Bert as voter + self.assertEqual(set(msg1.vote_user_ids), set([user_bert]), 'after unvoting for Admin, Bert is not the voter') diff --git a/addons/mrp/board_manufacturing_view.xml b/addons/mrp/board_manufacturing_view.xml index cae1fea07dc..6bd07c2648b 100644 --- a/addons/mrp/board_manufacturing_view.xml +++ b/addons/mrp/board_manufacturing_view.xml @@ -30,7 +30,8 @@ icon="terp-graph" id="menu_board_manufacturing" parent="base.menu_reporting_dashboard" - sequence="30"/> + sequence="30" + groups="group_mrp_manager"/> diff --git a/addons/mrp/mrp_view.xml b/addons/mrp/mrp_view.xml index ec66b5692c0..d05893cf778 100644 --- a/addons/mrp/mrp_view.xml +++ b/addons/mrp/mrp_view.xml @@ -956,9 +956,16 @@ product.product - - + + False + +

+ When you sell this product, OpenERP will trigger a manufacturing + order using the bill of materials assigned to this product. + The delivery order will be ready once the production is done. +

+
diff --git a/addons/note/__openerp__.py b/addons/note/__openerp__.py index 7d6cac5b85b..2c6134e5e3a 100644 --- a/addons/note/__openerp__.py +++ b/addons/note/__openerp__.py @@ -20,7 +20,7 @@ ############################################################################## { - 'name': 'Memos', + 'name': 'Notes', 'version': '1.0', 'category': 'Tools', 'description': """ @@ -28,12 +28,12 @@ This module allows users to create their own notes inside OpenERP ================================================================= Use notes to write meeting minutes, organize ideas, organize personnal todo -lists, etc. Each user manages his own personnal memos. Notes are available to +lists, etc. Each user manages his own personnal Notes. Notes are available to their authors only, but they can share notes to others users so that several people can work on the same note in real time. It's very efficient to share meeting minutes. -Memos can be found in the 'Home' menu. +Notes can be found in the 'Home' menu. """, 'author': 'OpenERP SA', 'website': 'http://openerp.com', diff --git a/addons/note/note.py b/addons/note/note.py index 65848ed7828..fb3f0cee853 100644 --- a/addons/note/note.py +++ b/addons/note/note.py @@ -22,6 +22,7 @@ from openerp.osv import osv, fields from tools.translate import _ import re +from openerp.tools.misc import html2plaintext class note_stage(osv.osv): """ Category of Note """ @@ -62,26 +63,24 @@ class note_note(osv.osv): def _get_note_first_line(self, cr, uid, ids, name="", args={}, context=None): res = {} for note in self.browse(cr, uid, ids, context=context): - text_note = (note.memo or '').strip().split('\n')[0] - text_note = re.sub(r'(\S?)(|<[/]?p>|<[/]?div>|)[\s\S]*',r'\1',text_note) - text_note = re.sub(r'<[^>]+>','',text_note) - res[note.id] = text_note + res[note.id] = (note.memo and html2plaintext(note.memo) or "").strip().replace('*','').split("\n")[0] + return res #unactivate a sticky note and record the date def onclick_note_is_done(self, cr, uid, ids, context=None): - self.write(cr, uid, ids, { 'active' : False, 'date_done' : fields.date.today() }) + self.write(cr, uid, ids, { 'open' : False, 'date_done' : fields.date.today() }) self.message_post(cr, uid, ids[0], body='Note is done.', subject=False, type='notification', parent_id=False, attachments=None, context=context) return False #activate a note def onclick_note_not_done(self, cr, uid, ids, context=None): - self.write(cr, uid, ids, {'active' : True}) + self.write(cr, uid, ids, {'open' : True}) self.message_post(cr, uid, ids[0], body='Note has been activated.', subject=False, type='notification', parent_id=False, attachments=None, context=context) return False - + #used for undisplay the follower if it's the current user def _get_my_current_partner(self, cr, uid, ids, name, args, context=None): user = self.pool.get('res.users').browse(cr, uid, uid, context=context) @@ -96,7 +95,8 @@ class note_note(osv.osv): def _set_stage_per_user(self, cr, uid, id, name, value, args=None, context=None): note = self.browse(cr, uid, id, context=context) if not value: return False - return self.write(cr, uid, [id], {'stage_ids': [(4, value)]}, context=context) + stage_ids = [value] + [stage.id for stage in note.stage_ids if stage.user_id.id != uid ] + return self.write(cr, uid, [id], {'stage_ids': [(6, 0, stage_ids)]}, context=context) def _get_stage_per_user(self, cr, uid, ids, name, args, context=None): result = dict.fromkeys(ids, False) @@ -119,14 +119,14 @@ class note_note(osv.osv): type='many2one', relation='note.stage'), 'stage_ids': fields.many2many('note.stage','note_stage_rel','note_id','stage_id','Stages of Users'), - 'active': fields.boolean('Active'), + 'open': fields.boolean('Active'), 'date_done': fields.date('Date done'), 'color': fields.integer('Color Index'), 'tag_ids' : fields.many2many('note.tag','note_tags_rel','note_id','tag_id','Tags'), 'current_partner_id' : fields.function(_get_my_current_partner), } _defaults = { - 'active' : 1, + 'open' : 1, 'stage_id' : _get_default_stage_id, } _order = 'sequence' diff --git a/addons/note/note_demo.xml b/addons/note/note_demo.xml index 82601f903c0..16fa5a3f66b 100644 --- a/addons/note/note_demo.xml +++ b/addons/note/note_demo.xml @@ -28,7 +28,7 @@ Customer report #349872 - Customer report #349872

* Calendar app in Home
* The base_calendar module should create a menu in Home, like described above.
* This module should become a main application (in the first screen at installation) @@ -40,7 +40,7 @@
- Call Fabien

* Followed by the telephone conversation and mail about D.544.3 ]]>
@@ -48,21 +48,21 @@
- Call Marc

]]>
- Project N.947.5

]]>
- Shop for family dinner
* stuffed turkey
* wine ]]> @@ -71,7 +71,7 @@
- Idea to develop

* Create a module note_pad it transforms the html editable memo text field into widget='pad', similar to project_pad depends on 'memo' and 'pad' modules ]]> @@ -80,7 +80,7 @@
- Read some documentation about OpenERP before diving into the code

* Open ERP: a modern approach to integrated business management
* Open ERP for Retail and Industrial Management ]]> @@ -89,7 +89,7 @@
- New computer specs

* Motherboard according to processor
* Processor @@ -111,7 +111,7 @@
- Read those books

* Open ERP: a modern approach to integrated business management
* Open ERP for Retail and Industrial Management ]]> @@ -120,7 +120,7 @@
- Read some documentation about OpenERP before diving into the code

* Open ERP: a modern approach to integrated business management
* Open ERP for Retail and Industrial Management ]]> @@ -129,7 +129,7 @@
- Read some documentation about OpenERP before diving into the code

* Open ERP: a modern approach to integrated business management
* Open ERP for Retail and Industrial Management ]]> @@ -138,14 +138,5 @@ 7
- -
* Open ERP: a modern approach to integrated business management -
* Open ERP for Retail and Industrial Management - ]]> -
- -
- diff --git a/addons/note/note_view.xml b/addons/note/note_view.xml index 1166e687750..8d943dde44d 100644 --- a/addons/note/note_view.xml +++ b/addons/note/note_view.xml @@ -1,9 +1,6 @@ - - - note.stage.form @@ -39,8 +36,6 @@ [('user_id','=',uid)] - - note.note.kanban @@ -51,7 +46,7 @@ - + @@ -65,8 +60,8 @@
- W - è + W + è @@ -78,13 +73,12 @@
- -
+
-
+
@@ -105,7 +99,7 @@ - + @@ -119,12 +113,10 @@
+
- - - @@ -139,9 +131,8 @@ - - - + + @@ -185,10 +176,11 @@ form kanban,tree,form - {'search_default_active_true':True} + {'search_default_open_true':True} - + + diff --git a/addons/note/security/ir.rule.xml b/addons/note/security/ir.rule.xml index 3d2f0d242f6..1195314cc9e 100644 --- a/addons/note/security/ir.rule.xml +++ b/addons/note/security/ir.rule.xml @@ -1,12 +1,19 @@ - - Only followers can access a sticky notes - - ['|',('message_follower_ids','=',False),('message_follower_ids','=',user.partner_id.id)] - - + + Only followers can access a sticky notes + + [('message_follower_ids','=',user.partner_id.id)] + + + + + Each user have his stage name + + ['|',('user_id','=',False),('user_id','=',user.id)] + + diff --git a/addons/note_pad/note_pad.py b/addons/note_pad/note_pad.py index 9864f0ae14f..d0c18a9f986 100644 --- a/addons/note_pad/note_pad.py +++ b/addons/note_pad/note_pad.py @@ -31,11 +31,5 @@ class note_pad_note(osv.osv): _pad_fields = ['note_pad'] _columns = { - 'note_pad_url': fields.char('Pad Url', - pad_content_field='memo', - size=250 ), - } - - #_defaults = { - # 'note_pad_url': lambda self, cr, uid, context: self.pad_generate_url(cr, uid, context), - #} + 'note_pad_url': fields.char('Pad Url', pad_content_field='memo'), + } \ No newline at end of file diff --git a/addons/pad/pad.py b/addons/pad/pad.py index d21ccd42d16..48ac940ccfa 100644 --- a/addons/pad/pad.py +++ b/addons/pad/pad.py @@ -21,7 +21,7 @@ class pad_common(osv.osv_memory): s = string.ascii_uppercase + string.digits salt = ''.join([s[random.randint(0, len(s) - 1)] for i in range(10)]) # contruct the url - url = '%s/p/%s-%s-%s' % (pad_server, cr.dbname, self._name, salt) + url = '%s/p/%s-%s-%s' % (pad_server, cr.dbname.replace('_','-'), self._name, salt) return url def pad_get_content(self, cr, uid, url, context=None): @@ -35,22 +35,21 @@ class pad_common(osv.osv_memory): # TODO # reverse engineer protocol to be setHtml without using the api key - # override read and copy to generate url and store the content if empty - - def default_get(self, cr, uid, fields, context=None): - data = super(pad_common, self).default_get(cr, uid, fields, context) - for k in fields: - field = self._all_columns[k].column - if hasattr(field,'pad_content_field'): - data[k] = self.pad_generate_url(cr, uid, context=context) - return data def write(self, cr, uid, ids, vals, context=None): + self._set_pad_value(cr, uid, vals, context) + return super(pad_common, self).write(cr, uid, ids, vals, context=context) + + def create(self, cr, uid, vals, context=None): + self._set_pad_value(cr, uid, vals, context) + return super(pad_common, self).create(cr, uid, vals, context=context) + + # Set the pad content in vals + def _set_pad_value(self, cr, uid, vals, context=None): for k,v in vals.items(): field = self._all_columns[k].column if hasattr(field,'pad_content_field'): - vals[field.pad_content_field] = self.pad_get_content(cr, uid, v, context=context) - return super(pad_common, self).write(cr, uid, ids, vals, context=context) + vals[field.pad_content_field] = self.pad_get_content(cr, uid, v, context=context) def copy(self, cr, uid, id, default=None, context=None): if not default: diff --git a/addons/pad/static/src/js/pad.js b/addons/pad/static/src/js/pad.js index 511400bcede..b7c13ba1b89 100644 --- a/addons/pad/static/src/js/pad.js +++ b/addons/pad/static/src/js/pad.js @@ -16,8 +16,15 @@ instance.web.form.FieldPad = instance.web.form.AbstractField.extend({ var self = this; var _super = self._super; _super.apply(self,[val]); + if (val === false || val === "") { + self.field_manager.dataset.call('pad_generate_url').then(function(r) { + _super.apply(self,[r]); + self.render_value(); + }); + } else { + self.render_value(); + } this._dirty_flag = true; - self.render_value(); }, render_value: function() { console.log("display"); diff --git a/addons/plugin_thunderbird/i18n/is.po b/addons/plugin_thunderbird/i18n/is.po new file mode 100644 index 00000000000..cc846bc56d8 --- /dev/null +++ b/addons/plugin_thunderbird/i18n/is.po @@ -0,0 +1,109 @@ +# Icelandic translation for openobject-addons +# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-02-09 00:36+0000\n" +"PO-Revision-Date: 2012-09-19 10:08+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Icelandic \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2012-09-20 04:43+0000\n" +"X-Generator: Launchpad (build 15985)\n" + +#. module: plugin_thunderbird +#: field:plugin_thunderbird.installer,pdf_file:0 +msgid "Installation Manual" +msgstr "Uppsetningarhandbók" + +#. module: plugin_thunderbird +#: field:plugin_thunderbird.installer,description:0 +msgid "Description" +msgstr "Lýsing" + +#. module: plugin_thunderbird +#: view:plugin_thunderbird.installer:0 +msgid "title" +msgstr "titill" + +#. module: plugin_thunderbird +#: model:ir.model,name:plugin_thunderbird.model_plugin_thunderbird_installer +msgid "plugin_thunderbird.installer" +msgstr "plugin_thunderbird.installer" + +#. module: plugin_thunderbird +#: field:plugin_thunderbird.installer,config_logo:0 +msgid "Image" +msgstr "Mynd" + +#. module: plugin_thunderbird +#: field:plugin_thunderbird.installer,plugin_file:0 +#: field:plugin_thunderbird.installer,thunderbird:0 +msgid "Thunderbird Plug-in" +msgstr "Thunderbird viðbót" + +#. module: plugin_thunderbird +#: view:plugin_thunderbird.installer:0 +msgid "" +"This plug-in allows you to link your email to OpenERP's documents. You can " +"attach it to any existing one in OpenERP or create a new one." +msgstr "" + +#. module: plugin_thunderbird +#: help:plugin_thunderbird.installer,thunderbird:0 +msgid "" +"Allows you to select an object that you would like to add to your email and " +"its attachments." +msgstr "" +"Gerir þér kleift að velja hlut sem þú vilt bæta við póstinn og viðhengi hans." + +#. module: plugin_thunderbird +#: help:plugin_thunderbird.installer,pdf_file:0 +msgid "The documentation file :- how to install Thunderbird Plug-in." +msgstr "Handbókin :- hvernig á að setja inn Thunderbird viðbót." + +#. module: plugin_thunderbird +#: view:plugin_thunderbird.installer:0 +msgid "_Close" +msgstr "_Loka" + +#. module: plugin_thunderbird +#: view:plugin_thunderbird.installer:0 +msgid "Installation and Configuration Steps" +msgstr "" + +#. module: plugin_thunderbird +#: field:plugin_thunderbird.installer,name:0 +#: field:plugin_thunderbird.installer,pdf_name:0 +msgid "File name" +msgstr "Skrárheiti" + +#. module: plugin_thunderbird +#: help:plugin_thunderbird.installer,plugin_file:0 +msgid "" +"Thunderbird plug-in file. Save as this file and install this plug-in in " +"thunderbird." +msgstr "" +"Skrá með Thunderbird viðbót. Vistaðu skrána og settu viðbótina inn í " +"Thunderbird." + +#. module: plugin_thunderbird +#: model:ir.actions.act_window,name:plugin_thunderbird.action_thunderbird_installer +#: model:ir.ui.menu,name:plugin_thunderbird.menu_base_config_plugins_thunderbird +#: view:plugin_thunderbird.installer:0 +msgid "Install Thunderbird Plug-In" +msgstr "Setja inn Thunderbird viðbót" + +#~ msgid "" +#~ "This plug-in allows you to link your e-mail to OpenERP's documents. You can " +#~ "attach it to any existing one in OpenERP or create a new one." +#~ msgstr "" +#~ "Þessi viðbót gerir þér kleift að tengja tölvupóst við OpenERP skjöl. Þú " +#~ "getur viðhengt póstinn við skjöl sem þegar eru til í OpenERP eða búið til " +#~ "nýtt." diff --git a/addons/point_of_sale/point_of_sale.py b/addons/point_of_sale/point_of_sale.py index 95b54b6baed..590718b48f0 100644 --- a/addons/point_of_sale/point_of_sale.py +++ b/addons/point_of_sale/point_of_sale.py @@ -314,9 +314,13 @@ class pos_session(osv.osv): # define some cash journal if no payment method exists if not pos_config.journal_ids: - cashids = self.pool.get('account.journal').search(cr, uid, [('journal_user', '=', True), ('type','=','cash')], context=context) + journal_proxy = self.pool.get('account.journal') + cashids = journal_proxy.search(cr, uid, [('journal_user', '=', True), ('type','=','cash')], context=context) if not cashids: - cashids = self.pool.get('account.journal').search(cr, uid, [('journal_user','=',True)], context=context) + cashids = journal_proxy.search(cr, uid, [('type', '=', 'cash')], context=context) + if not cashids: + cashids = journal_proxy.search(cr, uid, [('journal_user','=',True)], context=context) + jobj.write(cr, uid, [pos_config.id], {'journal_ids': [(6,0, cashids)]}) diff --git a/addons/point_of_sale/point_of_sale_view.xml b/addons/point_of_sale/point_of_sale_view.xml index 80abb5444db..9c92145ed89 100644 --- a/addons/point_of_sale/point_of_sale_view.xml +++ b/addons/point_of_sale/point_of_sale_view.xml @@ -896,8 +896,8 @@ - - + @@ -906,7 +906,8 @@ - + @@ -916,7 +917,7 @@ -
+
@@ -933,7 +934,7 @@
- + @@ -1035,7 +1036,7 @@ - + diff --git a/addons/portal/mail_mail.py b/addons/portal/mail_mail.py index 72c8469c042..a41c28f15e2 100644 --- a/addons/portal/mail_mail.py +++ b/addons/portal/mail_mail.py @@ -43,7 +43,7 @@ class mail_mail_portal(osv.Model): :param partner: browse_record of the specific recipient partner """ if partner: - portal_ref = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'portal', 'portal') + portal_ref = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'portal', 'group_portal') portal_id = portal_ref and portal_ref[1] or False url = self._generate_signin_url(cr, uid, partner.id, portal_id, 1234, context=context) body = tools.append_content_to_html(mail.body_html, url) diff --git a/addons/portal/portal.py b/addons/portal/portal.py index 3672d87cf30..13cde80f849 100644 --- a/addons/portal/portal.py +++ b/addons/portal/portal.py @@ -20,196 +20,14 @@ ############################################################################## from osv import osv, fields -from tools.translate import _ - class portal(osv.osv): + """ A portal is simply a group of users with the flag 'is_portal' set to True. + The flag 'is_portal' makes a user group usable as a portal. """ - A portal is a group of users with specific menu, widgets, and typically - restricted access rights. - """ - _name = 'res.portal' - _description = 'Portal' - _inherits = {'res.groups': 'group_id'} - + _inherit = 'res.groups' _columns = { - 'group_id': fields.many2one('res.groups', required=True, ondelete='cascade', - string='Group', - help='The group corresponding to this portal'), - 'url': fields.char('URL', - help="The url where portal users can connect to the server"), - 'home_action_id': fields.many2one('ir.actions.actions', - string='Home Action', - help="if set, replaces the standard home action (first screen after loggin) for the portal's users"), - 'menu_action_id': fields.many2one('ir.actions.act_window', readonly=True, - # ISSUE: 'ondelete' constraints do not seem effective on this field... - string='Menu Action', - help="If set, replaces the standard menu for the portal's users"), - 'parent_menu_id': fields.many2one('ir.ui.menu', ondelete='restrict', - string='Parent Menu', - help='The menu action opens the submenus of this menu item'), - 'widget_ids': fields.one2many('res.portal.widget', 'portal_id', - string='Widgets', - help='Widgets assigned to portal users'), + 'is_portal': fields.boolean('Portal', help="If checked, this group is usable as a portal."), } - def copy(self, cr, uid, id, values, context=None): - """ override copy(): menu_action_id must be different """ - values['menu_action_id'] = None - return super(portal, self).copy(cr, uid, id, values, context) - - def create(self, cr, uid, values, context=None): - """ extend create() to assign the portal menu to users """ - if context is None: - context = {} - - # create portal (admin should not be included) - context['noadmin'] = True - portal_id = super(portal, self).create(cr, uid, values, context) - - # assign menu action and widgets to users - if values.get('users') or values.get('menu_action_id'): - self._assign_menu(cr, uid, [portal_id], context) - if values.get('users') or values.get('widget_ids'): - self._assign_widgets(cr, uid, [portal_id], context) - - return portal_id - - def write(self, cr, uid, ids, values, context=None): - """ extend write() to reflect changes on users """ - # first apply portal changes - super(portal, self).write(cr, uid, ids, values, context) - - # assign menu action and widgets to users - if values.get('users') or values.get('menu_action_id'): - self._assign_menu(cr, uid, ids, context) - if values.get('users') or values.get('widget_ids'): - self._assign_widgets(cr, uid, ids, context) - - # if parent_menu_id has changed, apply the change on menu_action_id - if 'parent_menu_id' in values: - act_window_obj = self.pool.get('ir.actions.act_window') - portals = self.browse(cr, uid, ids, context) - action_ids = [p.menu_action_id.id for p in portals if p.menu_action_id] - if action_ids: - action_values = {'domain': [('parent_id', '=', values['parent_menu_id'])]} - act_window_obj.write(cr, uid, action_ids, action_values, context) - - return True - - def _assign_menu(self, cr, uid, ids, context=None): - """ assign portal_menu_settings to users of portals (ids) """ - user_obj = self.pool.get('res.users') - for p in self.browse(cr, uid, ids, context): - # user menu action = portal menu action if set in portal - if p.menu_action_id: - user_ids = [u.id for u in p.users if u.id != 1] - user_values = {'menu_id': p.menu_action_id.id} - user_obj.write(cr, uid, user_ids, user_values, context) - - def _assign_widgets(self, cr, uid, ids, context=None): - """ assign portal widgets to users of portals (ids) """ - widget_user_obj = self.pool.get('res.widget.user') - for p in self.browse(cr, uid, ids, context): - for w in p.widget_ids: - values = {'sequence': w.sequence, 'widget_id': w.widget_id.id} - for u in p.users: - if u.id == 1: continue - values['user_id'] = u.id - widget_user_obj.create(cr, uid, values, context) - - def _res_xml_id(self, cr, uid, module, xml_id): - """ return the resource id associated to the given xml_id """ - data_obj = self.pool.get('ir.model.data') - data_id = data_obj._get_id(cr, uid, module, xml_id) - return data_obj.browse(cr, uid, data_id).res_id - -portal() - - - -class portal_override_menu(osv.osv): - """ - Extend res.portal with a boolean field 'Override Users Menu', that - triggers the creation or removal of menu_action_id - """ - _name = 'res.portal' - _inherit = 'res.portal' - - def _get_override_menu(self, cr, uid, ids, field_name, arg, context=None): - assert field_name == 'override_menu' - result = {} - for p in self.browse(cr, uid, ids, context): - result[p.id] = bool(p.menu_action_id) - return result - - def _set_override_menu(self, cr, uid, id, field_name, field_value, arg, context=None): - assert field_name == 'override_menu' - if field_value: - self.create_menu_action(cr, uid, id, context) - else: - self.write(cr, uid, [id], {'menu_action_id': False}, context) - - def create_menu_action(self, cr, uid, id, context=None): - """ create, if necessary, a menu action that opens the menu items below - parent_menu_id """ - p = self.browse(cr, uid, id, context) - if not p.menu_action_id: - actions_obj = self.pool.get('ir.actions.act_window') - parent_id = p.parent_menu_id.id if p.parent_menu_id else False - action_values = { - 'name': _('%s Menu') % p.name, - 'type': 'ir.actions.act_window', - 'usage': 'menu', - 'res_model': 'ir.ui.menu', - 'view_type': 'tree', - 'view_id': self._res_xml_id(cr, uid, 'base', 'view_menu'), - 'domain': [('parent_id', '=', parent_id)], - } - action_id = actions_obj.create(cr, uid, action_values, context) - self.write(cr, uid, [id], {'menu_action_id': action_id}, context) - - _columns = { - 'override_menu': fields.function( - _get_override_menu, fnct_inv=_set_override_menu, - type='boolean', string='Override Menu Action of Users', - help='Enable this option to override the Menu Action of portal users'), - } - -portal_override_menu() - - - -class portal_widget(osv.osv): - """ - Similar to res.widget.user (res_widget.py), but with a portal instead. - New users in a portal are assigned the portal's widgets. - """ - _name='res.portal.widget' - _description = 'Portal Widgets' - _order = 'sequence' - _columns = { - 'sequence': fields.integer('Sequence'), - 'portal_id': fields.many2one('res.portal', select=1, ondelete='cascade', - string='Portal'), - 'widget_id': fields.many2one('res.widget', required=True, ondelete='cascade', - string='Widget'), - } - - def create(self, cr, uid, values, context=None): - domain = [('portal_id', '=', values.get('portal_id')), - ('widget_id', '=', values.get('widget_id'))] - existing = self.search(cr, uid, domain, context=context) - if existing: - res = existing[0] - else: - res = super(portal_widget, self).create(cr, uid, values, context=context) - return res - -portal_widget() - - - - -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/portal/portal_data.xml b/addons/portal/portal_data.xml index eb06ca656d6..a980552a854 100644 --- a/addons/portal/portal_data.xml +++ b/addons/portal/portal_data.xml @@ -2,14 +2,6 @@ - - Portal - - - - - - Company's news diff --git a/addons/portal/portal_demo.xml b/addons/portal/portal_demo.xml index 1ace02f3d7d..f4ba8fe2192 100644 --- a/addons/portal/portal_demo.xml +++ b/addons/portal/portal_demo.xml @@ -13,7 +13,7 @@ - + diff --git a/addons/portal/portal_view.xml b/addons/portal/portal_view.xml index fd15a842405..16e8a86b27e 100644 --- a/addons/portal/portal_view.xml +++ b/addons/portal/portal_view.xml @@ -5,7 +5,7 @@ @@ -21,71 +21,31 @@ - - - Portal List - res.portal + + + Group Search + res.groups + - - - + + + + + - - + + Portal Form - res.portal + res.groups - - - - - - - - - - - - - - - - - - - - - + + + - - - Portals - res.portal - form - tree,form - - {'form_view_ref': 'portal.portal_form_view'} - -

- Click to create a new portal. -

- A portal helps defining specific views and rules for a group of - users (the portal group). A portal menu, widgets and specific - groups may be assigned to the portal's users. -

-
-
- - - - -
diff --git a/addons/portal/security/ir.model.access.csv b/addons/portal/security/ir.model.access.csv index 56b3ae5f269..2d7a17e0016 100644 --- a/addons/portal/security/ir.model.access.csv +++ b/addons/portal/security/ir.model.access.csv @@ -1,12 +1,8 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_all,access.portal.all,model_res_portal,,1,0,0,0 -access_widget_all,access.portal.widget.all,model_res_portal_widget,,1,0,0,0 -access_manager,access.portal.manager,model_res_portal,group_portal_manager,1,1,1,1 -access_widget_manager,access.portal.widget.manager,model_res_portal_widget,group_portal_manager,1,1,1,1 -access_mail_message,mail.message,mail.model_mail_message,group_portal_member,1,0,1,1 -access_mail_message_all,mail.message.all,mail.model_mail_message,group_portal_member,1,0,0,0 -access_mail_thread,mail.thread,mail.model_mail_thread,group_portal_member,1,0,0,0 -access_mail_followers,mail.followers,mail.model_mail_followers,group_portal_member,1,0,1,1 -access_mail_notification,mail.notification,mail.model_mail_notification,group_portal_member,1,0,1,0 -access_mail_group,mail.group,mail.model_mail_group,group_portal_member,1,0,0,0 -access_mail_alias,mail.alias,mail.model_mail_alias,group_portal_member,1,0,0,0 +access_mail_message,mail.message,mail.model_mail_message,group_portal,1,0,1,1 +access_mail_message_all,mail.message.all,mail.model_mail_message,group_portal,1,0,0,0 +access_mail_thread,mail.thread,mail.model_mail_thread,group_portal,1,0,0,0 +access_mail_followers,mail.followers,mail.model_mail_followers,group_portal,1,0,1,1 +access_mail_notification,mail.notification,mail.model_mail_notification,group_portal,1,0,1,0 +access_mail_group,mail.group,mail.model_mail_group,group_portal,1,0,0,0 +access_mail_alias,mail.alias,mail.model_mail_alias,group_portal,1,0,0,0 diff --git a/addons/portal/security/portal_security.xml b/addons/portal/security/portal_security.xml index 4a493204d67..ee0af785599 100644 --- a/addons/portal/security/portal_security.xml +++ b/addons/portal/security/portal_security.xml @@ -2,31 +2,14 @@ - - - Portal Member - Portal members can access information through the portal menu. Also, they are chrooted in this specific menu. - - - + + Portal - - 25 - - - - - Officer - Portal officers can create new portal users with the portal wizard. - - - - - Manager - Portal managers have access to the portal definitions, and can easily configure the users, access rights and menus of portal users. - - - + Portal members have specific access rights (such as record rules and restricted menus). + They usually do not belong to the usual OpenERP groups. + + + diff --git a/addons/portal/tests/test_portal.py b/addons/portal/tests/test_portal.py index 2c301228859..5e992fa06ea 100644 --- a/addons/portal/tests/test_portal.py +++ b/addons/portal/tests/test_portal.py @@ -42,7 +42,7 @@ class test_portal(test_mail.TestMailMockups): user_admin = self.res_users.browse(cr, uid, uid) self.mail_invite = self.registry('mail.wizard.invite') base_url = self.registry('ir.config_parameter').get_param(cr, uid, 'web.base.url', default='') - portal_ref = self.registry('ir.model.data').get_object_reference(cr, uid, 'portal', 'portal') + portal_ref = self.registry('ir.model.data').get_object_reference(cr, uid, 'portal', 'group_portal') portal_id = portal_ref and portal_ref[1] or False # 0 - Admin diff --git a/addons/portal/wizard/portal_wizard.py b/addons/portal/wizard/portal_wizard.py index 85f6566eba6..3cc706c2129 100644 --- a/addons/portal/wizard/portal_wizard.py +++ b/addons/portal/wizard/portal_wizard.py @@ -23,33 +23,43 @@ import logging import random from osv import osv, fields -from tools.misc import email_re from tools.translate import _ +from tools.misc import email_re +from openerp import SUPERUSER_ID from base.res.res_partner import _lang_get _logger = logging.getLogger(__name__) - -# welcome email sent to new portal users (note that calling tools.translate._ -# has no effect except exporting those strings for translation) +# welcome/goodbye email sent to portal users +# (note that calling '_' has no effect except exporting those strings for translation) WELCOME_EMAIL_SUBJECT = _("Your OpenERP account at %(company)s") WELCOME_EMAIL_BODY = _("""Dear %(name)s, -You have been created an OpenERP account at %(url)s. +You have been given access to %(portal)s at %(url)s. Your login account data is: Database: %(db)s User: %(login)s Password: %(password)s -%(message)s +%(welcome_message)s -- OpenERP - Open Source Business Applications http://www.openerp.com """) -ROOT_UID = 1 +GOODBYE_EMAIL_SUBJECT = _("Your OpenERP account at %(company)s") +GOODBYE_EMAIL_BODY = _("""Dear %(name)s, + +Your access to %(portal)s has been withdrawn. + +%(goodbye_message)s + +-- +OpenERP - Open Source Business Applications +http://www.openerp.com +""") # character sets for passwords, excluding 0, O, o, 1, I, l _PASSU = 'ABCDEFGHIJKLMNPQRSTUVWXYZ' @@ -71,169 +81,173 @@ def extract_email(email): class wizard(osv.osv_memory): """ - A wizard to create portal users from instances of 'res.partner'. The purpose - is to provide an OpenERP database access to customers or suppliers. + A wizard to manage the creation/removal of portal users. """ - _name = 'res.portal.wizard' - _description = 'Portal Wizard' - + _name = 'portal.wizard' + _description = 'Portal Access Management' + _columns = { - 'portal_id': fields.many2one('res.portal', required=True, - string='Portal', - help="The portal in which new users must be added"), - 'user_ids': fields.one2many('res.portal.wizard.user', 'wizard_id', - string='Users'), - 'message': fields.text(string='Invitation message', - help="This text is included in the welcome email sent to the users"), + 'portal_id': fields.many2one('res.groups', domain=[('is_portal', '=', True)], required=True, + string='Portal', help="The portal that users can be added in or removed from."), + 'user_ids': fields.one2many('portal.wizard.user', 'wizard_id', string='Users'), + 'welcome_message': fields.text(string='Invitation Message', + help="This text is included in the email sent to new users of the portal."), + 'goodbye_message': fields.text(string='Withdrawal Message', + help="This text is included in the email sent to users withdrawn from the portal."), } - def _default_user_ids(self, cr, uid, context): - """ determine default user_ids from the active records """ - def create_user_from_address(address): - if isinstance(address, int): - res_partner_obj = self.pool.get('res.partner') - address = res_partner_obj.browse(cr, uid, address, context=context) - lang = address.id and address.lang or 'en_US' - partner_id = address.id - - else: - lang = address.parent_id and address.parent_id.lang or 'en_US' - partner_id = address.parent_id and address.parent_id.id - - return{ - 'name': address.name, - 'email': extract_email(address.email), - 'lang': lang, - 'partner_id': partner_id, - } - - user_ids = [] - if context.get('active_model') == 'res.partner': - partner_obj = self.pool.get('res.partner') - partner_ids = context.get('active_ids', []) - partners = partner_obj.browse(cr, uid, partner_ids, context) - for p in partners: - # add one user per contact, or one user if no contact - if p.child_ids: - user_ids.extend(map(create_user_from_address, p.child_ids)) - elif p.is_company == False and p.customer == True: - user_ids.extend(map(create_user_from_address, [p.id])) - else: - user_ids.append({'lang': p.lang or 'en_US', 'parent_id': p.id}) - - return user_ids + def _default_portal(self, cr, uid, context): + portal_ids = self.pool.get('res.groups').search(cr, uid, [('is_portal', '=', True)]) + return portal_ids and portal_ids[0] or False _defaults = { - 'user_ids': _default_user_ids + 'portal_id': _default_portal, } - def action_create(self, cr, uid, ids, context=None): - """ create new users in portal(s), and notify them by email """ - # we copy the context to change the language for translating emails - context0 = context or {} - context0['noshortcut'] = True # prevent shortcut creation - context = context0.copy() - - user_obj = self.pool.get('res.users') - user = user_obj.browse(cr, ROOT_UID, uid, context0) - if not user.email: - raise osv.except_osv(_('Email required'), - _('You must have an email address in your User Preferences' - ' to send emails.')) - - portal_obj = self.pool.get('res.portal') - for wiz in self.browse(cr, uid, ids, context): - # determine existing users - login_cond = [('login', 'in', [u.email for u in wiz.user_ids])] - existing_uids = user_obj.search(cr, ROOT_UID, login_cond) - existing_users = user_obj.browse(cr, ROOT_UID, existing_uids) - existing_logins = [u.login for u in existing_users] - - # create new users in portal (skip existing logins) - new_users_data = [ { - 'name': u.name, - 'login': u.email, - 'password': random_password(), - 'email': u.email, - 'lang': u.lang, - 'share': True, - 'action_id': wiz.portal_id.home_action_id and wiz.portal_id.home_action_id.id or False, - 'partner_id': u.partner_id and u.partner_id.id, - 'groups_id': [(6, 0, [])], - } for u in wiz.user_ids if u.email not in existing_logins ] - portal_obj.write(cr, ROOT_UID, [wiz.portal_id.id], - {'users': [(0, 0, data) for data in new_users_data]}, context0) - - # send email to all users (translated in their language) - data = { - 'company': user.company_id.name, - 'message': wiz.message or "", - 'url': wiz.portal_id.url or _("(missing url)"), - 'db': cr.dbname, - } - mail_mail_obj = self.pool.get('mail.mail') - dest_uids = user_obj.search(cr, ROOT_UID, login_cond) - dest_users = user_obj.browse(cr, ROOT_UID, dest_uids) - for dest_user in dest_users: - context['lang'] = dest_user.lang - data['login'] = dest_user.login - data['password'] = dest_user.password - data['name'] = dest_user.name - - email_from = user.email - email_to = dest_user.email - subject = _(WELCOME_EMAIL_SUBJECT) % data - body = _(WELCOME_EMAIL_BODY) % data - mail_id = mail_mail_obj.create(cr, uid, { - 'email_from': email_from , - 'email_to': email_to, - 'subject': subject, - 'state': 'outgoing', - 'body_html': '
%s
' % body}, context=context) - + def onchange_portal_id(self, cr, uid, ids, portal_id, context=None): + # for each partner, determine corresponding portal.wizard.user records + res_partner = self.pool.get('res.partner') + partner_ids = context and context.get('active_ids') or [] + contact_ids = set() + user_changes = [] + for partner in res_partner.browse(cr, SUPERUSER_ID, partner_ids, context): + for contact in (partner.child_ids or [partner]): + # make sure that each contact appears at most once in the list + if contact.id not in contact_ids: + contact_ids.add(contact.id) + in_portal = False + if contact.user_ids: + in_portal = portal_id in [g.id for g in contact.user_ids[0].groups_id] + user_changes.append((0, 0, { + 'partner_id': contact.id, + 'email': contact.email, + 'in_portal': in_portal, + })) + return {'value': {'user_ids': user_changes}} + + def action_apply(self, cr, uid, ids, context=None): + wizard = self.browse(cr, uid, ids[0], context) + portal_user_ids = [user.id for user in wizard.user_ids] + self.pool.get('portal.wizard.user').action_apply(cr, uid, portal_user_ids, context) return {'type': 'ir.actions.act_window_close'} -wizard() - - - class wizard_user(osv.osv_memory): """ A model to configure users in the portal wizard. """ - _name = 'res.portal.wizard.user' + _name = 'portal.wizard.user' _description = 'Portal User Config' _columns = { - 'wizard_id': fields.many2one('res.portal.wizard', required=True, - string='Wizard'), - 'name': fields.char(size=64, required=True, - string='User Name', - help="The user's real name"), - 'email': fields.char(size=64, required=True, - string='Email', - help="Will be used as user login. " - "Also necessary to send the account information to new users"), - 'lang': fields.selection(_lang_get, required=True, - string='Language', - help="The language for the user's user interface"), - 'partner_id': fields.many2one('res.partner', - string='Partner'), + 'wizard_id': fields.many2one('portal.wizard', string='Wizard', required=True), + 'partner_id': fields.many2one('res.partner', string='Contact', required=True, readonly=True), + 'email': fields.char(size=240, string='Email'), + 'in_portal': fields.boolean('In Portal'), } - def _check_email(self, cr, uid, ids): - """ check syntax of email address """ - for wuser in self.browse(cr, uid, ids): - if not email_re.match(wuser.email): return False - return True + def create(self, cr, uid, values, context=None): + """ overridden to update the partner's email (if necessary) """ + id = super(wizard_user, self).create(cr, uid, values, context) + wuser = self.browse(cr, uid, id, context) + if wuser.partner_id.email != wuser.email: + wuser.partner_id.write({'email': wuser.email}) + return id - _constraints = [ - (_check_email, 'Invalid email address', ['email']), - ] + def action_apply(self, cr, uid, ids, context=None): + res_users = self.pool.get('res.users') + for wizard_user in self.browse(cr, SUPERUSER_ID, ids, context): + portal = wizard_user.wizard_id.portal_id + user = self._retrieve_user(cr, SUPERUSER_ID, wizard_user, context) + if wizard_user.in_portal: + # create a user if necessary, and make sure it is in the portal group + if not user: + user = self._create_user(cr, SUPERUSER_ID, wizard_user, context) + if (not user.active) or (portal not in user.groups_id): + user.write({'active': True, 'groups_id': [(4, portal.id)]}) + wizard_user = self.browse(cr, SUPERUSER_ID, wizard_user.id, context) + self._send_email(cr, uid, wizard_user, context) + else: + # remove the user (if it exists) from the portal group + if user and (portal in user.groups_id): + # if user belongs to portal only, deactivate it + if len(user.groups_id) <= 1: + user.write({'groups_id': [(3, portal.id)], 'active': False}) + else: + user.write({'groups_id': [(3, portal.id)]}) + wizard_user = self.browse(cr, SUPERUSER_ID, wizard_user.id, context) + self._send_email(cr, uid, wizard_user, context) -wizard_user() + def _retrieve_user(self, cr, uid, wizard_user, context=None): + """ retrieve the (possibly inactive) user corresponding to wizard_user.partner_id + @param wizard_user: browse record of model portal.wizard.user + @return: browse record of model res.users + """ + if wizard_user.partner_id.user_ids: + return wizard_user.partner_id.user_ids[0] + # the user may be inactive, search for it + res_users = self.pool.get('res.users') + domain = [('partner_id', '=', wizard_user.partner_id.id), ('active', '=', False)] + user_ids = res_users.search(cr, uid, domain) + return user_ids and res_users.browse(cr, uid, user_ids[0], context) or False + def _create_user(self, cr, uid, wizard_user, context=None): + """ create a new user for wizard_user.partner_id + @param wizard_user: browse record of model portal.wizard.user + @return: browse record of model res.users + """ + res_users = self.pool.get('res.users') + create_context = dict(context or {}, noshortcut=True) # to prevent shortcut creation + values = { + 'login': extract_email(wizard_user.email), + 'password': random_password(), + 'partner_id': wizard_user.partner_id.id, + 'groups_id': [(6, 0, [])], + 'share': True, + } + user_id = res_users.create(cr, uid, values, context=create_context) + return res_users.browse(cr, uid, user_id, context) + def _send_email(self, cr, uid, wizard_user, context=None): + """ send notification email to a new/former portal user + @param wizard_user: browse record of model portal.wizard.user + @return: the id of the created mail.mail record + """ + this_context = context + this_user = self.pool.get('res.users').browse(cr, SUPERUSER_ID, uid, context) + if not this_user.email: + raise osv.except_osv(_('Email required'), + _('You must have an email address in your User Preferences to send emails.')) + # determine subject and body in the portal user's language + url = self.pool.get('ir.config_parameter').get_param(cr, SUPERUSER_ID, 'web.base.url', context=this_context) + user = self._retrieve_user(cr, SUPERUSER_ID, wizard_user, context) + context = dict(this_context or {}, lang=user.lang) + data = { + 'company': this_user.company_id.name, + 'portal': wizard_user.wizard_id.portal_id.name, + 'welcome_message': wizard_user.wizard_id.welcome_message or "", + 'goodbye_message': wizard_user.wizard_id.goodbye_message or "", + 'url': url or _("(missing url)"), + 'db': cr.dbname, + 'login': user.login, + 'password': user.password, + 'name': user.name + } + if wizard_user.in_portal: + subject = _(WELCOME_EMAIL_SUBJECT) % data + body = _(WELCOME_EMAIL_BODY) % data + else: + subject = _(GOODBYE_EMAIL_SUBJECT) % data + body = _(GOODBYE_EMAIL_BODY) % data + + mail_mail = self.pool.get('mail.mail') + mail_values = { + 'email_from': this_user.email, + 'email_to': user.email, + 'subject': subject, + 'body_html': '
%s
' % body, + 'state': 'outgoing', + } + return mail_mail.create(cr, uid, mail_values, context=this_context) # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/portal/wizard/portal_wizard_view.xml b/addons/portal/wizard/portal_wizard_view.xml index f3cd5c98bb4..c8e3f30b128 100644 --- a/addons/portal/wizard/portal_wizard_view.xml +++ b/addons/portal/wizard/portal_wizard_view.xml @@ -3,28 +3,34 @@ + groups="base.group_partner_manager"/> - Add Portal Access - res.portal.wizard + Portal Access Management + portal.wizard -
- - + + + +
+ Select which contacts should belong to the portal in the list below. + The email address of each selected contact must be valid and unique. + If necessary, you can fix any contact's email address directly in the list. +
-
diff --git a/addons/portal/wizard/share_wizard.py b/addons/portal/wizard/share_wizard.py index ca950a61b08..b1b6e980dec 100644 --- a/addons/portal/wizard/share_wizard.py +++ b/addons/portal/wizard/share_wizard.py @@ -44,9 +44,6 @@ class share_wizard_portal(osv.TransientModel): 'group_ids': fields.many2many('res.groups', 'share_wizard_res_group_rel', 'share_id', 'group_id', 'Existing groups', domain=[('share', '=', False)]), } - def is_portal_manager(self, cr, uid, context=None): - return self.has_group(cr, uid, module='portal', group_xml_id='group_portal_manager', context=context) - def _check_preconditions(self, cr, uid, wizard_data, context=None): if wizard_data.user_type == 'existing': self._assert(wizard_data.user_ids, @@ -122,16 +119,14 @@ class share_wizard_portal(osv.TransientModel): # alter the rules of the groups so they can see the shared data if wizard_data.group_ids: # get the list of portals and the related groups to install their menus. - Portals = self.pool.get('res.portal') - all_portals = Portals.browse(cr, UID_ROOT, Portals.search(cr, UID_ROOT, [])) #no context! - all_portal_group_ids = [p.group_id.id for p in all_portals] + res_groups = self.pool.get('res.groups') + all_portal_group_ids = res_groups.search(cr, UID_ROOT, [('is_portal', '=', True)]) # populate result lines with the users of each group and # setup the menu for portal groups for group in wizard_data.group_ids: if group.id in all_portal_group_ids: - portal = all_portals[all_portal_group_ids.index(group.id)] - self._create_shared_data_menu(cr, uid, wizard_data, portal, context=context) + self._create_shared_data_menu(cr, uid, wizard_data, group.id, context=context) for user in group.users: new_line = {'user_id': user.id, diff --git a/addons/portal/wizard/share_wizard_view.xml b/addons/portal/wizard/share_wizard_view.xml index 72ae857eaaf..065a7aa317e 100644 --- a/addons/portal/wizard/share_wizard_view.xml +++ b/addons/portal/wizard/share_wizard_view.xml @@ -36,12 +36,12 @@ - + - - + + diff --git a/addons/portal_claim/security/ir.model.access.csv b/addons/portal_claim/security/ir.model.access.csv index 554c66cc998..ab2a2f66770 100644 --- a/addons/portal_claim/security/ir.model.access.csv +++ b/addons/portal_claim/security/ir.model.access.csv @@ -1,3 +1,3 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_crm_claim,crm.claim,crm_claim.model_crm_claim,portal.group_portal_member,1,0,0,0 -access_crm_claim_stage,crm.claim.stage,crm_claim.model_crm_claim_stage,portal.group_portal_member,1,0,0,0 +access_crm_claim,crm.claim,crm_claim.model_crm_claim,portal.group_portal,1,0,0,0 +access_crm_claim_stage,crm.claim.stage,crm_claim.model_crm_claim_stage,portal.group_portal,1,0,0,0 diff --git a/addons/portal_claim/security/portal_security.xml b/addons/portal_claim/security/portal_security.xml index e902bd043ad..9fc47c4cfb0 100644 --- a/addons/portal_claim/security/portal_security.xml +++ b/addons/portal_claim/security/portal_security.xml @@ -6,7 +6,7 @@ Portal Personal Claims [('partner_id','child_of',user.partner_id.id)] - + diff --git a/addons/portal_event/security/ir.model.access.csv b/addons/portal_event/security/ir.model.access.csv index b418acbb9c4..7418b08bb4b 100644 --- a/addons/portal_event/security/ir.model.access.csv +++ b/addons/portal_event/security/ir.model.access.csv @@ -1,3 +1,3 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_event,event,event.model_event_event,portal.group_portal_member,1,0,0,0 -access_registration,registration,event.model_event_registration,portal.group_portal_member,1,0,0,0 +access_event,event,event.model_event_event,portal.group_portal,1,0,0,0 +access_registration,registration,event.model_event_registration,portal.group_portal,1,0,0,0 diff --git a/addons/portal_event/security/portal_security.xml b/addons/portal_event/security/portal_security.xml index 6a3ed0ac786..74b2372c147 100644 --- a/addons/portal_event/security/portal_security.xml +++ b/addons/portal_event/security/portal_security.xml @@ -6,14 +6,14 @@ Portal Visible Events [('visibility', '=', 'public')] - + Portal Personal Registrations [('partner_id','child_of',user.partner_id.id)] - + diff --git a/addons/portal_hr_employees/security/ir.model.access.csv b/addons/portal_hr_employees/security/ir.model.access.csv index 6131f49d749..d18aeb90e1c 100644 --- a/addons/portal_hr_employees/security/ir.model.access.csv +++ b/addons/portal_hr_employees/security/ir.model.access.csv @@ -1,6 +1,6 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_hr_employee_user,hr.employee user,hr.model_hr_employee,portal.group_portal_member,1,0,0,0 -access_res_partner,res.partner,base.model_res_partner,portal.group_portal_member,1,0,0,0 -access_res_partner_address,res.partner_address,base.model_res_partner_address,portal.group_portal_member,1,0,0,0 -access_res_partner_category,res.partner_category,base.model_res_partner_category,portal.group_portal_member,1,0,0,0 -access_res_partner_title,res.partner_title,base.model_res_partner_title,portal.group_portal_member,1,0,0,0 +access_hr_employee_user,hr.employee user,hr.model_hr_employee,portal.group_portal,1,0,0,0 +access_res_partner,res.partner,base.model_res_partner,portal.group_portal,1,0,0,0 +access_res_partner_address,res.partner_address,base.model_res_partner_address,portal.group_portal,1,0,0,0 +access_res_partner_category,res.partner_category,base.model_res_partner_category,portal.group_portal,1,0,0,0 +access_res_partner_title,res.partner_title,base.model_res_partner_title,portal.group_portal,1,0,0,0 diff --git a/addons/portal_project/security/ir.model.access.csv b/addons/portal_project/security/ir.model.access.csv index dceca5ba8bb..85463868ee1 100644 --- a/addons/portal_project/security/ir.model.access.csv +++ b/addons/portal_project/security/ir.model.access.csv @@ -1,5 +1,5 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_task,tasks,project.model_project_task,portal.group_portal_member,1,0,0,0 -access_task_type,task_type,project.model_project_task_type,portal.group_portal_member,1,0,0,0 -access_task_work,task_work,project.model_project_task_work,portal.group_portal_member,1,0,0,0 -access_project_category,project_category,project.model_project_category,portal.group_portal_member,1,0,0,0 +access_task,tasks,project.model_project_task,portal.group_portal,1,0,0,0 +access_task_type,task_type,project.model_project_task_type,portal.group_portal,1,0,0,0 +access_task_work,task_work,project.model_project_task_work,portal.group_portal,1,0,0,0 +access_project_category,project_category,project.model_project_category,portal.group_portal,1,0,0,0 diff --git a/addons/portal_project/security/portal_security.xml b/addons/portal_project/security/portal_security.xml index b995c79bbbc..b9d37cec099 100644 --- a/addons/portal_project/security/portal_security.xml +++ b/addons/portal_project/security/portal_security.xml @@ -6,7 +6,7 @@ Portal Personal Task [('partner_id','child_of',user.partner_id.id)] - + diff --git a/addons/portal_project_issue/portal_project_issue_view.xml b/addons/portal_project_issue/portal_project_issue_view.xml index 5d0b4ce081e..1030dedbdf8 100644 --- a/addons/portal_project_issue/portal_project_issue_view.xml +++ b/addons/portal_project_issue/portal_project_issue_view.xml @@ -27,6 +27,7 @@ +
Creation: diff --git a/addons/portal_project_issue/security/ir.model.access.csv b/addons/portal_project_issue/security/ir.model.access.csv index 5257f9b6d02..80a38366b51 100644 --- a/addons/portal_project_issue/security/ir.model.access.csv +++ b/addons/portal_project_issue/security/ir.model.access.csv @@ -1,3 +1,3 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_issues,project_issue,project_issue.model_project_issue,portal.group_portal_member,1,0,0,0 -access_case_section,crm_case_section,crm.model_crm_case_section,portal.group_portal_member,1,0,0,0 +access_issues,project_issue,project_issue.model_project_issue,portal.group_portal,1,0,0,0 +access_case_section,crm_case_section,crm.model_crm_case_section,portal.group_portal,1,0,0,0 diff --git a/addons/portal_project_issue/security/portal_security.xml b/addons/portal_project_issue/security/portal_security.xml index 4ef8da5e4b6..358b5e6a0ad 100644 --- a/addons/portal_project_issue/security/portal_security.xml +++ b/addons/portal_project_issue/security/portal_security.xml @@ -6,7 +6,7 @@ Portal Personal Issues [('partner_id','child_of',user.partner_id.id)] - + diff --git a/addons/portal_sale/security/ir.model.access.csv b/addons/portal_sale/security/ir.model.access.csv index 32266499af7..751c0b9baff 100644 --- a/addons/portal_sale/security/ir.model.access.csv +++ b/addons/portal_sale/security/ir.model.access.csv @@ -1,33 +1,33 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_sale_order,sale.order,sale.model_sale_order,portal.group_portal_member,1,0,0,0 -access_sale_order_line,sale.order.line,sale.model_sale_order_line,portal.group_portal_member,1,0,0,0 -access_stock_picking,stock.picking,stock.model_stock_picking,portal.group_portal_member,1,0,0,0 -access_stock_picking.out,stock.picking.out,stock.model_stock_picking_out,portal.group_portal_member,1,0,0,0 -access_stock_move,stock.move,stock.model_stock_move,portal.group_portal_member,1,0,0,0 -access_stock_warehouse_orderpoint,stock.warehouse.orderpoint,procurement.model_stock_warehouse_orderpoint,portal.group_portal_member,1,0,0,0 -access_account_invoice,account.invoice,account.model_account_invoice,portal.group_portal_member,1,0,0,0 -access_account_invoice_tax,account.invoice.tax,account.model_account_invoice_tax,portal.group_portal_member,1,0,0,0 -access_account_invoice_line,account.invoice.line,account.model_account_invoice_line,portal.group_portal_member,1,0,0,0 -access_account_journal,account.journal,account.model_account_journal,portal.group_portal_member,1,0,0,0 -access_account_voucher,account.voucher,account_voucher.model_account_voucher,portal.group_portal_member,1,0,0,0 -access_account_voucher_line,account.voucher.line,account_voucher.model_account_voucher_line,portal.group_portal_member,1,0,0,0 -access_account_move,account.move,account.model_account_move,portal.group_portal_member,1,0,0,0 -access_account_move_line,account.move.line,account.model_account_move_line,portal.group_portal_member,1,0,0,0 -access_account_move_reconcile,account.move.reconcile,account.model_account_move_reconcile,portal.group_portal_member,1,0,0,0 -access_account_fiscalyear,account.sequence.fiscalyear,account.model_account_sequence_fiscalyear,portal.group_portal_member,1,0,0,0 -access_sale_shop,sale.shop,sale.model_sale_shop,portal.group_portal_member,1,0,0,0 -access_product_list,product.pricelist,product.model_product_pricelist,portal.group_portal_member,1,0,0,0 -access_product,product.product,product.model_product_product,portal.group_portal_member,1,0,0,0 -access_res_partner,res.partner,base.model_res_partner,portal.group_portal_member,1,0,0,0 -access_product_uom,product.uom,product.model_product_uom,portal.group_portal_member,1,0,0,0 -access_account_tax,account.tax,account.model_account_tax,portal.group_portal_member,1,0,0,0 -access_mrp_property,mrp.property,procurement.model_mrp_property,portal.group_portal_member,1,0,0,0 -access_product_template,product.template,product.model_product_template,portal.group_portal_member,1,0,0,0 -access_stock_warehouse,stock.warehouse,stock.model_stock_warehouse,portal.group_portal_member,1,0,0,0 -access_stock_location,stock.location,stock.model_stock_location,portal.group_portal_member,1,0,0,0 -access_account_fiscalyear,account.fiscalyear,account.model_account_fiscalyear,portal.group_portal_member,1,0,0,0 -access_res_partner_category,res.partner.category,base.model_res_partner_category,portal.group_portal_member,1,0,0,0 -access_product_supplierinfo,product.supplierinfo,product.model_product_supplierinfo,portal.group_portal_member,1,0,0,0 -access_product_packaging,product.packaging,product.model_product_packaging,portal.group_portal_member,1,0,0,0 -access_account_period,account.period,account.model_account_period,portal.group_portal_member,1,0,0,0 -access_account_account,account.account,account.model_account_account,portal.group_portal_member,1,0,0,0 +access_sale_order,sale.order,sale.model_sale_order,portal.group_portal,1,0,0,0 +access_sale_order_line,sale.order.line,sale.model_sale_order_line,portal.group_portal,1,0,0,0 +access_stock_picking,stock.picking,stock.model_stock_picking,portal.group_portal,1,0,0,0 +access_stock_picking.out,stock.picking.out,stock.model_stock_picking_out,portal.group_portal,1,0,0,0 +access_stock_move,stock.move,stock.model_stock_move,portal.group_portal,1,0,0,0 +access_stock_warehouse_orderpoint,stock.warehouse.orderpoint,procurement.model_stock_warehouse_orderpoint,portal.group_portal,1,0,0,0 +access_account_invoice,account.invoice,account.model_account_invoice,portal.group_portal,1,0,0,0 +access_account_invoice_tax,account.invoice.tax,account.model_account_invoice_tax,portal.group_portal,1,0,0,0 +access_account_invoice_line,account.invoice.line,account.model_account_invoice_line,portal.group_portal,1,0,0,0 +access_account_journal,account.journal,account.model_account_journal,portal.group_portal,1,0,0,0 +access_account_voucher,account.voucher,account_voucher.model_account_voucher,portal.group_portal,1,0,0,0 +access_account_voucher_line,account.voucher.line,account_voucher.model_account_voucher_line,portal.group_portal,1,0,0,0 +access_account_move,account.move,account.model_account_move,portal.group_portal,1,0,0,0 +access_account_move_line,account.move.line,account.model_account_move_line,portal.group_portal,1,0,0,0 +access_account_move_reconcile,account.move.reconcile,account.model_account_move_reconcile,portal.group_portal,1,0,0,0 +access_account_fiscalyear,account.sequence.fiscalyear,account.model_account_sequence_fiscalyear,portal.group_portal,1,0,0,0 +access_sale_shop,sale.shop,sale.model_sale_shop,portal.group_portal,1,0,0,0 +access_product_list,product.pricelist,product.model_product_pricelist,portal.group_portal,1,0,0,0 +access_product,product.product,product.model_product_product,portal.group_portal,1,0,0,0 +access_res_partner,res.partner,base.model_res_partner,portal.group_portal,1,0,0,0 +access_product_uom,product.uom,product.model_product_uom,portal.group_portal,1,0,0,0 +access_account_tax,account.tax,account.model_account_tax,portal.group_portal,1,0,0,0 +access_mrp_property,mrp.property,procurement.model_mrp_property,portal.group_portal,1,0,0,0 +access_product_template,product.template,product.model_product_template,portal.group_portal,1,0,0,0 +access_stock_warehouse,stock.warehouse,stock.model_stock_warehouse,portal.group_portal,1,0,0,0 +access_stock_location,stock.location,stock.model_stock_location,portal.group_portal,1,0,0,0 +access_account_fiscalyear,account.fiscalyear,account.model_account_fiscalyear,portal.group_portal,1,0,0,0 +access_res_partner_category,res.partner.category,base.model_res_partner_category,portal.group_portal,1,0,0,0 +access_product_supplierinfo,product.supplierinfo,product.model_product_supplierinfo,portal.group_portal,1,0,0,0 +access_product_packaging,product.packaging,product.model_product_packaging,portal.group_portal,1,0,0,0 +access_account_period,account.period,account.model_account_period,portal.group_portal,1,0,0,0 +access_account_account,account.account,account.model_account_account,portal.group_portal,1,0,0,0 diff --git a/addons/portal_sale/security/portal_security.xml b/addons/portal_sale/security/portal_security.xml index f69fd283db6..8028d5360c4 100644 --- a/addons/portal_sale/security/portal_security.xml +++ b/addons/portal_sale/security/portal_security.xml @@ -7,42 +7,42 @@ Portal Personal Quotations/Sales Orders [('partner_id','child_of',user.partner_id.id)] - + Portal Personal Delivery Orders [('partner_id','child_of',[user.partner_id.id])] - + Portal Personal Delivery Orders Out [('partner_id','child_of',[user.partner_id.id])] - + Portal Personal Account Invoices [('partner_id','child_of',user.partner_id.id)] - + Portal Personal Payments [('partner_id','child_of',user.partner_id.id)] - + Portal Personal Contacts [('id','child_of',user.partner_id.id)] - + diff --git a/addons/procurement/procurement.py b/addons/procurement/procurement.py index ec1dc4b26fb..842f9ec27fa 100644 --- a/addons/procurement/procurement.py +++ b/addons/procurement/procurement.py @@ -554,7 +554,7 @@ class stock_warehouse_orderpoint(osv.osv): 'logic': fields.selection([('max','Order to Max'),('price','Best price (not yet active!)')], 'Reordering Mode', required=True), 'warehouse_id': fields.many2one('stock.warehouse', 'Warehouse', required=True, ondelete="cascade"), 'location_id': fields.many2one('stock.location', 'Location', required=True, ondelete="cascade"), - 'product_id': fields.many2one('product.product', 'Product', required=True, ondelete='cascade', domain=[('type','=','product')]), + 'product_id': fields.many2one('product.product', 'Product', required=True, ondelete='cascade', domain=[('type','!=','service')]), 'product_uom': fields.many2one('product.uom', 'Product Unit of Measure', required=True), 'product_min_qty': fields.float('Minimum Quantity', required=True, help="When the virtual stock goes below the Min Quantity specified for this field, OpenERP generates "\ diff --git a/addons/procurement/procurement_view.xml b/addons/procurement/procurement_view.xml index 432ff13aaa5..bf73b383216 100644 --- a/addons/procurement/procurement_view.xml +++ b/addons/procurement/procurement_view.xml @@ -166,7 +166,11 @@ tree,form {'search_default_perm_exceptions':1} - Procurement Orders represent the need for a certain quantity of products, at a given time, in a given location. Sales Orders are one typical source of Procurement Orders (but these are distinct documents). Depending on the procurement parameters and the product configuration, the procurement engine will attempt to satisfy the need by reserving products from stock, ordering products from a supplier, or passing a manufacturing order, etc. A Procurement Exception occurs when the system cannot find a way to fulfill a procurement. Some exceptions will resolve themselves automatically, but others require manual intervention (those are identified by a specific error message). + +

+ Procurement Orders represent the need for a certain quantity of products, at a given time, in a given location. Sales Orders are one typical source of Procurement Orders (but these are distinct documents). Depending on the procurement parameters and the product configuration, the procurement engine will attempt to satisfy the need by reserving products from stock, ordering products from a supplier, or passing a manufacturing order, etc. A Procurement Exception occurs when the system cannot find a way to fulfill a procurement. Some exceptions will resolve themselves automatically, but others require manual intervention (those are identified by a specific error message). +

+
diff --git a/addons/product/product_view.xml b/addons/product/product_view.xml index 13474351744..d04e6f17fe8 100644 --- a/addons/product/product_view.xml +++ b/addons/product/product_view.xml @@ -106,11 +106,31 @@ + - - + +

+ When you sell this service, nothing special will be trigered + to deliver the customer. +

+

+ When you sell this product, OpenERP will use the available inventory + for the delivery order. +
+ If there are not enough quantities available, the delivery order + will wait for new products. You should create others rules + (orderpoints, manual purchase orders) to fulfill the inventory. +

+

+ When you sell this product, a delivery order will be created. + OpenERP will consider that the required quantities are always + available as it's a consumable (the stock on hand may become negative). +

+
+ +
diff --git a/addons/project_issue/project_issue_view.xml b/addons/project_issue/project_issue_view.xml index fea22c519a8..be7427fe8f4 100644 --- a/addons/project_issue/project_issue_view.xml +++ b/addons/project_issue/project_issue_view.xml @@ -269,9 +269,7 @@
-
- - - - - - - - - - - - - -
- -
+ - + - + @@ -972,7 +874,7 @@ stock.picking.out.tree - stock.picking + stock.picking.out @@ -1002,13 +904,16 @@
+
+ + + + tree + + + + + + + form + + + +