diff --git a/addons/account/account_bank_statement.py b/addons/account/account_bank_statement.py index 8e79376aa87..4422537007f 100644 --- a/addons/account/account_bank_statement.py +++ b/addons/account/account_bank_statement.py @@ -486,6 +486,19 @@ class account_bank_statement(osv.osv): default['move_line_ids'] = [] return super(account_bank_statement, self).copy(cr, uid, id, default, context=context) + def button_journal_entries(self, cr, uid, ids, context=None): + ctx = (context or {}).copy() + ctx['journal_id'] = self.browse(cr, uid, ids[0], context=context).journal_id.id + return { + 'view_type':'form', + 'view_mode':'tree', + 'res_model':'account.move.line', + 'view_id':False, + 'type':'ir.actions.act_window', + 'domain':[('statement_id','in',ids)], + 'context':ctx, + } + account_bank_statement() class account_bank_statement_line(osv.osv): diff --git a/addons/account/account_invoice.py b/addons/account/account_invoice.py index b37118c3baa..3e86c4963b7 100644 --- a/addons/account/account_invoice.py +++ b/addons/account/account_invoice.py @@ -402,6 +402,7 @@ class account_invoice(osv.osv): 'default_res_id': ids[0], 'default_use_template': True, 'default_template_id': template_id, + 'default_composition_mode': 'comment', }) return { 'view_type': 'form', @@ -431,7 +432,7 @@ class account_invoice(osv.osv): if t['state'] in ('draft', 'cancel') and t['internal_number']== False: unlink_ids.append(t['id']) else: - raise osv.except_osv(_('Invalid Action!'), _('You cannot delete an invoice which is open or paid. You should refund it instead.')) + raise osv.except_osv(_('Invalid Action!'), _('You can not delete an invoice which is not cancelled. You should refund it instead.')) osv.osv.unlink(self, cr, uid, unlink_ids, context=context) return True diff --git a/addons/account/account_invoice_view.xml b/addons/account/account_invoice_view.xml index 4feb97c2f5f..d3697b13ea9 100644 --- a/addons/account/account_invoice_view.xml +++ b/addons/account/account_invoice_view.xml @@ -436,7 +436,7 @@
The accounting features are fully integrated with other OpenERP applications to automate all your processes: creation of customer invoices, control of supplier invoices, point-of-sale integration, automated follow-ups, etc.
]]>You can track customer payments easily and automate follow-ups. You get an overview of the discussion with your customers on each invoice for easier traceability. For advanced accounting features, you should install the "Accounting and Finance" module.
]]>- Click to define a new customer segmentation. + Click to define a new customer segmentation.
Create specific categories which you can assign to your
contacts to better manage your interactions with them. The
@@ -425,7 +424,7 @@
+ parent="base.menu_base_config"/>
@@ -466,11 +465,11 @@
Admin\n' - _body_html2 = 'I am angry !\n
Admin\n' + _body_html1 = 'Fans of Pigs, unite !\n
Admin
\n' + _body_html2 = 'I am angry !\nAdmin
\n' _attachments = [ {'name': 'First', 'datas_fname': 'first.txt', 'datas': base64.b64encode('My first attachment')}, {'name': 'Second', 'datas_fname': 'second.txt', 'datas': base64.b64encode('My second attachment')} @@ -63,11 +63,16 @@ class test_message_compose(test_mail.TestMailMockups): # Create template on mail.group, with attachments group_model_id = self.registry('ir.model').search(cr, uid, [('model', '=', 'mail.group')])[0] email_template = self.registry('email.template') - email_template_id = email_template.create(cr, uid, {'model_id': group_model_id, - 'name': 'Pigs Template', 'subject': '${object.name}', - 'body_html': '${object.description}', 'user_signature': True, + email_template_id = email_template.create(cr, uid, { + 'model_id': group_model_id, + 'name': 'Pigs Template', + 'subject': '${object.name}', + 'body_html': '${object.description}', + 'user_signature': True, 'attachment_ids': [(0, 0, _attachments[0]), (0, 0, _attachments[1])], - 'email_to': 'b@b.b c@c.c', 'email_cc': 'd@d.d'}) + 'email_to': 'b@b.b c@c.c', + 'email_cc': 'd@d.d' + }) # ---------------------------------------- # CASE1: comment and save as template @@ -76,9 +81,9 @@ class test_message_compose(test_mail.TestMailMockups): # 1. Comment on pigs compose_id = mail_compose.create(cr, uid, {'subject': 'Forget me subject', 'body': 'Dummy body
'}, - {'default_composition_mode': 'comment', 'default_model': 'mail.group', + {'default_composition_mode': 'comment', + 'default_model': 'mail.group', 'default_res_id': self.group_pigs_id, - 'default_template_id': email_template_id, 'active_ids': [self.group_pigs_id, self.group_bird_id]}) compose = mail_compose.browse(cr, uid, compose_id) @@ -97,8 +102,10 @@ class test_message_compose(test_mail.TestMailMockups): # 1. Comment on pigs compose_id = mail_compose.create(cr, uid, {'subject': 'Forget me subject', 'body': 'Dummy body'}, - {'default_composition_mode': 'comment', 'default_model': 'mail.group', + {'default_composition_mode': 'comment', + 'default_model': 'mail.group', 'default_res_id': self.group_pigs_id, + 'default_use_template': False, 'default_template_id': email_template_id, 'active_ids': [self.group_pigs_id, self.group_bird_id]}) compose = mail_compose.browse(cr, uid, compose_id) @@ -135,8 +142,10 @@ class test_message_compose(test_mail.TestMailMockups): # 1. Mass_mail on pigs and bird, with a default_partner_ids set to check he is correctly added compose_id = mail_compose.create(cr, uid, {'subject': 'Forget me subject', 'body': 'Dummy body'}, - {'default_composition_mode': 'mass_mail', 'default_model': 'mail.group', + {'default_composition_mode': 'mass_mail', + 'default_model': 'mail.group', 'default_res_id': self.group_pigs_id, + 'default_use_template': False, 'default_template_id': email_template_id, 'default_partner_ids': [p_a_id], 'active_ids': [self.group_pigs_id, self.group_bird_id]}) @@ -170,3 +179,26 @@ class test_message_compose(test_mail.TestMailMockups): partner_ids = self.res_partner.search(cr, uid, [('email', 'in', ['b@b.b', 'c@c.c', 'd@d.d'])]) self.assertEqual(set(message_pigs_pids), set(partner_ids), 'mail.message on pigs incorrect number of notified_partner_ids') self.assertEqual(set(message_bird_pids), set(partner_ids), 'mail.message on bird notified_partner_ids incorrect') + + # ---------------------------------------- + # CASE4: test newly introduced email_recipients field + # ---------------------------------------- + + # get already-created partners back + p_b_id = self.res_partner.search(cr, uid, [('email', '=', 'b@b.b')])[0] + p_c_id = self.res_partner.search(cr, uid, [('email', '=', 'c@c.c')])[0] + p_d_id = self.res_partner.search(cr, uid, [('email', '=', 'd@d.d')])[0] + # modify template: use email_recipients, use template and email address in email_to to test all features together + user_model_id = self.registry('ir.model').search(cr, uid, [('model', '=', 'res.users')])[0] + email_template.write(cr, uid, [email_template_id], { + 'model_id': user_model_id, + 'body_html': '${object.login}', + 'email_to': '${object.email} c@c', + 'email_recipients': '%i,%i' % (p_b_id, p_c_id), + 'email_cc': 'd@d', + }) + # patner by email + partner by id (no double) + send_to = [p_a_id, p_b_id, p_c_id, p_d_id] + # Generate messsage with default email and partner on template + mail_value = mail_compose.generate_email_for_composer(cr, uid, email_template_id, uid) + self.assertEqual(set(mail_value['partner_ids']), set(send_to), 'mail.message partner_ids list created by template is incorrect') diff --git a/addons/email_template/wizard/email_template_preview_view.xml b/addons/email_template/wizard/email_template_preview_view.xml index f91535a17a5..8dd4bc92ba7 100644 --- a/addons/email_template/wizard/email_template_preview_view.xml +++ b/addons/email_template/wizard/email_template_preview_view.xml @@ -17,6 +17,7 @@
diff --git a/addons/fleet/static/src/img/icon.png b/addons/fleet/static/src/img/icon.png
index 3db7ae9fa49..5b41e43c5bd 100644
Binary files a/addons/fleet/static/src/img/icon.png and b/addons/fleet/static/src/img/icon.png differ
diff --git a/addons/hr/hr.py b/addons/hr/hr.py
index d57fcf49ab2..5f3a5653307 100644
--- a/addons/hr/hr.py
+++ b/addons/hr/hr.py
@@ -158,6 +158,8 @@ class hr_employee(osv.osv):
return self.write(cr, uid, [id], {'image': tools.image_resize_image_big(value)}, context=context)
_columns = {
+ #we need a related field in order to be able to sort the employee by name
+ 'name_related': fields.related('resource_id', 'name', type='char', string='Name', readonly=True, store=True),
'country_id': fields.many2one('res.country', 'Nationality'),
'birthday': fields.date("Date of Birth"),
'ssnid': fields.char('SSN No', size=32, help='Social Security Number'),
@@ -207,6 +209,8 @@ class hr_employee(osv.osv):
'last_login': fields.related('user_id', 'date', type='datetime', string='Latest Connection', readonly=1),
}
+ _order='name_related'
+
def create(self, cr, uid, data, context=None):
employee_id = super(hr_employee, self).create(cr, uid, data, context=context)
try:
diff --git a/addons/hr/hr_data.xml b/addons/hr/hr_data.xml
index 514cf1f80f6..25c882f2201 100644
--- a/addons/hr/hr_data.xml
+++ b/addons/hr/hr_data.xml
@@ -6,11 +6,11 @@
More HR features are available via extra applications: Recruitment Process (manage job positions and recruitment), Timesheet Validation (record timesheets and attendance), +Leave Management (keep track of employee leaves), Expense Management (manage employee expenses), Employee Appraisals (organize employee surveys, where employees evaluate their subordinates or their manager).
]]>This feature is also linked to analytic accounting and compatible with timesheet invoices, so you will be able to automatically re-invoice project-related expenses to your customers.
]]>Once validated, they are visible in the employee's calendar. HR officers can define leave types and allocate leaves to employees and employee categories.
]]>You can automatically receive job application though an email gateway, see the Human Resources settings.
]]>+The top menu bar contains all applications you installed. You can use the Settings menu to install more applications, activate others features or give access to new users.
+To setup your preferences (name, email signature, avatar), click on the top right corner.
]]>Admin\n' - _mail_bodyalt1 = 'Pigs rules\nAdmin' + _mail_body1 = 'Pigs rules\n
Admin
Admin\n') + _mail_body2 = html_sanitize('Pigs rules\n
Admin
Bert Tartopoils\n', 'sent_email body incorrect') + self.assertEqual(sent_email['body'], _mail_body1 + '\nBert Tartopoils\n', 'sent_email body incorrect') # the html2plaintext uses etree or beautiful soup, so the result may be slighly different # depending if you have installed beautiful soup. self.assertIn(sent_email['body_alternative'], _mail_bodyalt1 + '\nBert Tartopoils\n', 'sent_email body_alternative is incorrect') @@ -495,7 +463,8 @@ class test_mail(TestMailMockups): # 1. Comment group_pigs with body_text and subject compose_id = mail_compose.create(cr, uid, {'subject': _subject, 'body_text': _body_text, 'partner_ids': [(4, p_c_id), (4, p_d_id)]}, - {'default_composition_mode': 'comment', 'default_model': 'mail.group', 'default_res_id': self.group_pigs_id}) + {'default_composition_mode': 'comment', 'default_model': 'mail.group', 'default_res_id': self.group_pigs_id, + 'default_content_subtype': 'plaintext'}) compose = mail_compose.browse(cr, uid, compose_id) # Test: mail.compose.message: composition_mode, model, res_id self.assertEqual(compose.composition_mode, 'comment', 'mail.compose.message incorrect composition_mode') diff --git a/addons/mail/tests/test_mail_access_rights.py b/addons/mail/tests/test_mail_access_rights.py index 7b90e07b9b5..ec08d257efe 100644 --- a/addons/mail/tests/test_mail_access_rights.py +++ b/addons/mail/tests/test_mail_access_rights.py @@ -19,11 +19,11 @@ # ############################################################################## -from openerp.addons.mail.tests import test_mail +from openerp.addons.mail.tests import test_mail_mockup from osv.orm import except_orm -class test_mail_access_rights(test_mail.TestMailMockups): +class test_mail_access_rights(test_mail_mockup.TestMailMockups): def setUp(self): super(test_mail_access_rights, self).setUp() diff --git a/addons/mail/tests/test_mail_mockup.py b/addons/mail/tests/test_mail_mockup.py new file mode 100644 index 00000000000..cba04a0c6b3 --- /dev/null +++ b/addons/mail/tests/test_mail_mockup.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Business Applications +# Copyright (c) 2012-TODAY OpenERP S.A.
+This application supports complete integration and production scheduling for stockable goods, consumables, and services.
+From the Manufacturing Settings, you can choose to compute production schedules periodically or just-in-time.
]]>\n" +" Click to add a personal note.\n" +"
\n" +" Use notes to organize personal tasks or notes. All\n" +" notes are private; no one else will be able to see them. " +"However\n" +" you can share some notes with other people by inviting " +"followers\n" +" on the note. (Useful for meeting minutes, especially if\n" +" you activate the pad feature for collaborative writings).\n" +"
\n" +" You can customize how you process your notes/tasks by adding,\n" +" removing or modifying columns.\n" +"
\n" +" " +msgstr "" +"\n" +" Clique para adicionar nota pessoal.\n" +"
\n" +" Use notas para organizar tarefas ou notas pessoais. Todas\n" +" notas são privadas; ninguém mais é capaz de vê-las. Contudo\n" +" você pode compartilhar algumas notas com outras pessoas " +"convidando seguidores\n" +" na nota. (Útil para atas de reunião, especialmente se\n" +" você ativar o recurso \"PAD\" para textos colaborativos).\n" +"
\n" +" Você pode customizar a forma como você processa suas " +"notas/tarefas adicionando,\n" +" removendo ou modificando colunas.\n" +"
\n" +" " + +#. module: note +#: view:note.note:0 +msgid "kanban note" +msgstr "nota kanban" + +#. module: note +#: model:note.stage,name:note.demo_note_stage_01 +#: model:note.stage,name:note.note_stage_01 +msgid "Today" +msgstr "Hoje" + +#. module: note +#: model:ir.model,name:note.model_res_users +msgid "Users" +msgstr "Usuários" + +#. module: note +#: view:note.note:0 +msgid "í" +msgstr "í" + +#. module: note +#: view:note.stage:0 +msgid "Stage of Notes" +msgstr "Estágios das Notas" + +#. module: note +#: field:note.note,message_unread:0 +msgid "Unread Messages" +msgstr "Mensagens não lidas" + +#. module: note +#: field:note.note,current_partner_id:0 +msgid "unknown" +msgstr "desconhecido" + +#. module: note +#: view:note.note:0 +msgid "By sticky note Category" +msgstr "" + +#. module: note +#: help:note.note,message_unread:0 +msgid "If checked new messages require your attention." +msgstr "Se marcado novas mensagens requerem sua atenção" + +#. module: note +#: field:note.stage,name:0 +msgid "Stage Name" +msgstr "Nome do Estágio" + +#. module: note +#: field:note.note,message_is_follower:0 +msgid "Is a Follower" +msgstr "É um seguidor" + +#. module: note +#: view:note.note:0 +msgid "title" +msgstr "título" + +#. module: note +#: model:note.stage,name:note.demo_note_stage_02 +#: model:note.stage,name:note.note_stage_02 +msgid "Tomorrow" +msgstr "Amanhã" + +#. module: note +#: view:note.note:0 +#: field:note.note,open:0 +msgid "Active" +msgstr "Ativo" + +#. module: note +#: help:note.stage,user_id:0 +msgid "Owner of the note stage." +msgstr "Proprietário do estágio da nota." + +#. module: note +#: model:ir.ui.menu,name:note.menu_notes_stage +msgid "Categories" +msgstr "Categorias" + +#. module: note +#: field:note.note,message_comment_ids:0 +#: help:note.note,message_comment_ids:0 +msgid "Comments and emails" +msgstr "Comentários e emails" + +#. module: note +#: field:note.tag,name:0 +msgid "Tag Name" +msgstr "Nome da Tag" + +#. module: note +#: field:note.note,message_ids:0 +msgid "Messages" +msgstr "Mensagens" + +#. module: note +#: view:base.config.settings:0 +#: model:ir.actions.act_window,name:note.action_note_note +#: model:ir.ui.menu,name:note.menu_note_notes +#: view:note.note:0 +#: model:note.stage,name:note.note_stage_04 +msgid "Notes" +msgstr "Notas" + +#. module: note +#: model:note.stage,name:note.demo_note_stage_03 +#: model:note.stage,name:note.note_stage_03 +msgid "Later" +msgstr "Mais tarde" + +#. module: note +#: model:ir.model,name:note.model_note_stage +msgid "Note Stage" +msgstr "Estágio da Nota" + +#. module: note +#: view:note.note:0 +msgid "dropdown menu" +msgstr "dropdown menu" + +#. module: note +#: model:note.stage,name:note.demo_note_stage_04 +msgid "Morning" +msgstr "Manhã" + +#. module: note +#: help:note.stage,sequence:0 +msgid "Used to order the note stages" +msgstr "Usado para ordenar os estágios das notas" + +#. module: note +#: view:note.note:0 +msgid "W" +msgstr "W" + +#. module: note +#: field:note.note,stage_ids:0 +msgid "Stages of Users" +msgstr "Estágios de Usuários" + +#. module: note +#: field:note.note,name:0 +msgid "Note Summary" +msgstr "Resumo da Nota" + +#. module: note +#: model:ir.actions.act_window,name:note.action_note_stage +#: view:note.note:0 +msgid "Stages" +msgstr "Estágios" + +#. module: note +#: help:note.note,message_ids:0 +msgid "Messages and communication history" +msgstr "Histórico de mensagens e comunicação" + +#. module: note +#: view:note.note:0 +msgid "Delete" +msgstr "Excluir" + +#. module: note +#: field:note.note,color:0 +msgid "Color Index" +msgstr "Índice de Cores" + +#. module: note +#: field:note.note,sequence:0 +#: field:note.stage,sequence:0 +msgid "Sequence" +msgstr "Sequencia" + +#. module: note +#: field:note.note,tag_ids:0 +msgid "Tags" +msgstr "Tags" + +#. module: note +#: view:note.note:0 +msgid "Archive" +msgstr "Arquivo" + +#. module: note +#: field:base.config.settings,module_note_pad:0 +msgid "Use collaborative pads (etherpad)" +msgstr "Usar pads colaborativos (etherpad)" + +#. module: note +#: help:note.note,message_summary:0 +msgid "" +"Holds the Chatter summary (number of messages, ...). This summary is " +"directly in html format in order to be inserted in kanban views." +msgstr "" + +#. module: note +#: field:base.config.settings,group_note_fancy:0 +msgid "Use fancy layouts for notes" +msgstr "Usar leiautes fantasia para notas" + +#. module: note +#: field:note.stage,user_id:0 +msgid "Owner" +msgstr "Proprietário" + +#. module: note +#: constraint:res.users:0 +msgid "The chosen company is not in the allowed companies for this user" +msgstr "" +"A empresa escolhida não está entre as empresas habilitadas para este usuário" + +#. module: note +#: view:note.note:0 +#: field:note.note,stage_id:0 +msgid "Stage" +msgstr "Estágio" + +#. module: note +#: field:note.note,date_done:0 +msgid "Date done" +msgstr "Data de conclusão" + +#. module: note +#: field:note.stage,fold:0 +msgid "Folded by Default" +msgstr "Dobrado por Padrão" diff --git a/addons/note/note.py b/addons/note/note.py index fe5eca5efd7..9e1a9187095 100644 --- a/addons/note/note.py +++ b/addons/note/note.py @@ -20,9 +20,7 @@ ############################################################################## from openerp.osv import osv, fields -from tools.translate import _ -import re -from openerp.tools.misc import html2plaintext +from openerp.tools import html2plaintext class note_stage(osv.osv): """ Category of Note """ diff --git a/addons/note/security/ir.rule.xml b/addons/note/security/ir.rule.xml index 1195314cc9e..b0c79561355 100644 --- a/addons/note/security/ir.rule.xml +++ b/addons/note/security/ir.rule.xml @@ -6,6 +6,10 @@If you install the PoS proxy you will be able to interface OpenERP with retail hardware: barcode scanners, printers, cash registers, weighing machines, credit card payment terminals.
]]>Log in our portal at: %s
It is a great pleasure to announce you the creation of our portal by writing this first news! As you may have seen, a new discussion group is now present under your 'My groups' menu: Company's News. We will post news about the company and its employees in this discussion group. Moreover, we will be able to communicate with our partners that are given the opportunity to join us in our portal.
+A new era of communication has begun! Feel free to post your feelings about our portal by replying on this message!
]]>You can manage todo lists on tasks by installing the Todo Lists application, supporting the Getting Things Done (GTD) methodology.
+You can also manage issues/bugs in projects by installing the "Issue Tracker" application.
]]>+This application supports the Getting Things Done (GTD) methodology, based on David Allen's book.
]]>+You can record issues, assign them to a responsible person, and keep track of their status as they evolve over time.
+Access all issues from the top Project menu, and access the issues of a specific project via the projects gallery view.
]]>You can also manage purchase requisitions, see also the Purchase Settings.
]]>If you need to manage your sales pipeline (leads, opportunities, phonecalls), the CRM application may be useful. Use the Settings menu to install it.
]]>