diff --git a/addons/edi/static/src/xml/edi_sale_purchase.xml b/addons/edi/static/src/xml/edi_sale_purchase.xml index 698b322606f..8191660c5c9 100644 --- a/addons/edi/static/src/xml/edi_sale_purchase.xml +++ b/addons/edi/static/src/xml/edi_sale_purchase.xml @@ -33,7 +33,12 @@ -

Order :

+ +

Quotation :

+
+ +

Order :

+
@@ -116,7 +121,7 @@ - +

Pay Online

diff --git a/addons/email_template/email_template.py b/addons/email_template/email_template.py index 5c33ea89987..fff9bdc0f1a 100644 --- a/addons/email_template/email_template.py +++ b/addons/email_template/email_template.py @@ -56,8 +56,6 @@ class email_template(osv.osv): :param str model: model name of the document record this mail is related to. :param int res_id: id of the document record this mail is related to. """ - if context is None: - context = {} if not template: return u"" if context is None: context = {} @@ -149,7 +147,7 @@ class email_template(osv.osv): help="Optional preferred server for outgoing mails. If not set, the highest " "priority one will be used."), 'body_text': fields.text('Text Contents', translate=True, help="Plaintext version of the message (placeholders may be used here)"), - 'body_html': fields.text('Rich-Text Contents', translate=True, help="Rich-Text/HTML version of the message (placeholders may be used here)"), + 'body_html': fields.text('Rich-text Contents', translate=True, help="Rich-text/HTML version of the message (placeholders may be used here)"), 'message_id': fields.char('Message-Id', size=256, help="Message-ID SMTP header to use in outgoing messages based on this template. " "Please note that this overrides the 'Resource Tracking' option, " "so if you simply need to track replies to outgoing emails, enable " diff --git a/addons/mail/mail_message.py b/addons/mail/mail_message.py index 091922b5cb9..f86ae29c80f 100644 --- a/addons/mail/mail_message.py +++ b/addons/mail/mail_message.py @@ -121,7 +121,8 @@ class mail_message_common(osv.osv_memory): 'body_html': fields.text('Rich-text Contents', help="Rich-text/HTML version of the message"), 'body': fields.function(get_body, fnct_search = search_body, string='Message Content', type='text', help="Content of the message. This content equals the body_text field for plain-test messages, and body_html for rich-text/HTML messages. This allows having one field if we want to access the content matching the message subtype."), - 'parent_id': fields.many2one('mail.message', 'Parent Message', help="Parent message, used for displaying as threads with hierarchy", select=True, ondelete='set null',), + 'parent_id': fields.many2one('mail.message', 'Parent Message', help="Parent message, used for displaying as threads with hierarchy", + select=True, ondelete='set null',), 'child_ids': fields.one2many('mail.message', 'parent_id', 'Child Messages'), } diff --git a/addons/mail/wizard/mail_compose_message.py b/addons/mail/wizard/mail_compose_message.py index 59554acd57b..dd07cbce9b2 100644 --- a/addons/mail/wizard/mail_compose_message.py +++ b/addons/mail/wizard/mail_compose_message.py @@ -260,6 +260,7 @@ class mail_compose_message(osv.osv_memory): subtype=mail.subtype, headers=headers, context=context)] # in normal mode, we send the email immediately, as the user expects us to (delay should be sufficiently small) mail_message.send(cr, uid, msg_ids, context=context) + return {'type': 'ir.actions.act_window_close'} def render_template(self, cr, uid, template, model, res_id, context=None): diff --git a/addons/sale/edi/sale_order.py b/addons/sale/edi/sale_order.py index badd4c20cd9..d1cbe3a98fa 100644 --- a/addons/sale/edi/sale_order.py +++ b/addons/sale/edi/sale_order.py @@ -60,19 +60,20 @@ SALE_ORDER_EDI_STRUCT = { 'payment_term': True, 'order_policy': True, 'user_id': True, + 'state': True, } class sale_order(osv.osv, EDIMixin): _inherit = 'sale.order' - def action_quotation_sent(self, cr, uid, ids, context=None): + def action_quotation_send(self, cr, uid, ids, context=None): if context is None: context = {} sale_objs = self.browse(cr, uid, ids, context=context) edi_token = self.pool.get('edi.document').export_edi(cr, uid, sale_objs, context = context)[0] web_root_url = self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url') ctx = dict(context, edi_web_url_view=edi.EDI_VIEW_WEB_URL % (web_root_url, cr.dbname, edi_token)) - return super(sale_order, self).action_quotation_sent(cr, uid, ids, context=ctx) + return super(sale_order, self).action_quotation_send(cr, uid, ids, context=ctx) def edi_export(self, cr, uid, records, edi_struct=None, context=None): """Exports a Sale order""" diff --git a/addons/sale/edi/sale_order_action_data.xml b/addons/sale/edi/sale_order_action_data.xml index a92c87de46f..7ff130bd58a 100644 --- a/addons/sale/edi/sale_order_action_data.xml +++ b/addons/sale/edi/sale_order_action_data.xml @@ -2,7 +2,6 @@ - @@ -31,11 +29,9 @@ so users can freely customize/delete them --> - @@ -51,7 +47,7 @@

Hello${object.partner_id.name and ' ' or ''}${object.partner_id.name or ''},

-

Here is your order confirmation for ${object.partner_id.name}:

+

Here is your ${object.state in ('draft', 'sent') and 'quotation' or 'order confirmation'}:

  REFERENCES
@@ -68,12 +64,12 @@

- You can view the order confirmation document, download it and pay online using the following link: + You can view the ${object.state in ('draft', 'sent') and 'quotation' or 'order confirmation'} document, download it and pay online using the following link:

View Order - % if object.order_policy in ('prepaid','manual') and object.company_id.paypal_account: + % if object.order_policy in ('prepaid','manual') and object.company_id.paypal_account and object.state not in ('draft', 'sent'): <% comp_name = quote(object.company_id.name) order_name = quote(object.name) @@ -133,7 +129,7 @@ '%(object.user_id.user_email) or ''} -You can view the order confirmation, download it and even pay online using the following link: +You can view the ${object.state in ('draft', 'sent') and 'quotation' or 'order confirmation'}, download it and even pay online using the following link: ${ctx.get('edi_web_url_view') or 'n/a'} -% if object.order_policy in ('prepaid','manual') and object.company_id.paypal_account: +% if object.order_policy in ('prepaid','manual') and object.company_id.paypal_account and object.state not in ('draft', 'sent'): <% comp_name = quote(object.company_id.name) order_name = quote(object.name) diff --git a/addons/sale/sale.py b/addons/sale/sale.py index 8c2a4021c70..4f69d5391c9 100644 --- a/addons/sale/sale.py +++ b/addons/sale/sale.py @@ -207,8 +207,8 @@ class sale_order(osv.osv): ('sent', 'Quotation Sent'), ('cancel', 'Cancelled'), ('waiting_date', 'Waiting Schedule'), - ('manual', 'Sale to Invoice'), ('progress', 'Sale Order'), + ('manual', 'Sale to Invoice'), ('shipping_except', 'Shipping Exception'), ('invoice_except', 'Invoice Exception'), ('done', 'Done'), @@ -469,13 +469,13 @@ class sale_order(osv.osv): return inv_id def print_quotation(self, cr, uid, ids, context=None): + assert len(ids) == 1, 'This option should only be used for a single id at a time' wf_service = netsvc.LocalService("workflow") - for id in ids: - wf_service.trg_validate(uid, 'sale.order', id, 'quotation_sent', cr) + wf_service.trg_validate(uid, 'sale.order', ids[0], 'quotation_sent', cr) datas = { 'model': 'sale.order', 'ids': ids, - 'form': self.read(cr, uid, ids, context=context)[0], + 'form': self.read(cr, uid, ids[0], context=context), } return {'type': 'ir.actions.report.xml', 'report_name': 'sale.order', 'datas': datas, 'nodestroy': True} @@ -511,66 +511,72 @@ class sale_order(osv.osv): } def action_view_invoice(self, cr, uid, ids, context=None): + ''' + This function returns an action that display existing invoices of given sale order ids. It can either be a in a list or in a form view, if there is only one invoice to show. + ''' mod_obj = self.pool.get('ir.model.data') + result = { + 'name': _('Cutomer Invoice'), + 'view_type': 'form', + 'res_model': 'account.invoice', + 'context': "{'type':'out_invoice', 'journal_type': 'sale'}", + 'type': 'ir.actions.act_window', + 'nodestroy': True, + 'target': 'current', + } + #compute the number of invoices to display inv_ids = [] - result = {} for so in self.browse(cr, uid, ids, context=context): - inv_ids+= [invoice.id for invoice in so.invoice_ids] + inv_ids += [invoice.id for invoice in so.invoice_ids] + #choose the view_mode accordingly if len(inv_ids)>1: res = mod_obj.get_object_reference(cr, uid, 'account', 'invoice_tree') result.update({ - 'view_mode': 'tree,form', - 'res_id': inv_ids or False + 'view_mode': 'tree,form', + 'res_id': inv_ids or False }) else: res = mod_obj.get_object_reference(cr, uid, 'account', 'invoice_form') result.update({ - 'view_mode': 'form', - 'res_id': inv_ids and inv_ids[0] or False, + 'view_mode': 'form', + 'res_id': inv_ids and inv_ids[0] or False, }) - res_id = res and res[1] or False, - result.update({ - 'name': _('Cutomer Invoice'), - 'view_type': 'form', - 'view_id': [res_id], - 'res_model': 'account.invoice', - 'context': "{'type':'out_invoice', 'journal_type': 'sale'}", - 'type': 'ir.actions.act_window', - 'nodestroy': True, - 'target': 'current', - }) + result.update(view_id = res and res[1] or False) return result def action_view_delivery(self, cr, uid, ids, context=None): + ''' + This function returns an action that display existing delivery orders of given sale order ids. It can either be a in a list or in a form view, if there is only one delivery order to show. + ''' mod_obj = self.pool.get('ir.model.data') + result = { + 'name': _('Delivery Order'), + 'view_type': 'form', + 'res_model': 'stock.picking', + 'context': "{'type':'out'}", + 'type': 'ir.actions.act_window', + 'nodestroy': True, + 'target': 'current', + } + #compute the number of delivery orders to display pick_ids = [] - result = {} for so in self.browse(cr, uid, ids, context=context): pick_ids += [picking.id for picking in so.picking_ids] + #choose the view_mode accordingly if len(pick_ids) > 1: res = mod_obj.get_object_reference(cr, uid, 'stock', 'view_picking_out_tree') result.update({ - 'view_mode': 'tree,form', - 'res_id': pick_ids or False + 'view_mode': 'tree,form', + 'res_id': pick_ids or False }) else: res = mod_obj.get_object_reference(cr, uid, 'stock', 'view_picking_out_form') result.update({ - 'view_mode': 'form', - 'res_id': pick_ids and pick_ids[0] or False, + 'view_mode': 'form', + 'res_id': pick_ids and pick_ids[0] or False, }) - res_id = res and res[1] or False, - result.update({ - 'name': _('Delivery Order'), - 'view_type': 'form', - 'view_id': res_id, - 'res_model': 'stock.picking', - 'context': "{'type':'out'}", - 'type': 'ir.actions.act_window', - 'nodestroy': True, - 'target': 'current', - }) + result.update(view_id = res and res[1] or False) return result def action_invoice_create(self, cr, uid, ids, grouped=False, states=['confirmed', 'done', 'exception'], date_inv = False, context=None): @@ -730,7 +736,11 @@ class sale_order(osv.osv): self.confirm_send_note(cr, uid, ids, context) return True - def action_quotation_sent(self, cr, uid, ids, context=None): + def action_quotation_send(self, cr, uid, ids, context=None): + ''' + This function opens a window to compose an email, with the edi sale template message loaded by default + ''' + assert len(ids) == 1, 'This option should only be used for a single id at a time' mod_obj = self.pool.get('ir.model.data') template = mod_obj.get_object_reference(cr, uid, 'sale', 'email_template_edi_sale') template_id = template and template[1] or False @@ -1476,7 +1486,6 @@ class sale_order_line(osv.osv): sale_order_line() class mail_message(osv.osv): - _name = 'mail.message' _inherit = 'mail.message' def _postprocess_sent_message(self, cr, uid, message, context=None): diff --git a/addons/sale/sale_view.xml b/addons/sale/sale_view.xml index 1eba286c744..3259276540d 100644 --- a/addons/sale/sale_view.xml +++ b/addons/sale/sale_view.xml @@ -102,8 +102,8 @@