From ee9b3e0d0c8f20590616287a017d7fe802fc7796 Mon Sep 17 00:00:00 2001 From: Dhawal Limbuwala Date: Tue, 18 Jul 2017 17:59:38 +0200 Subject: [PATCH] [IMP] delivery: notification email for shippings When an order is shipped, a notification email is sent to the customer. If there is a tracking URL, it is included in the email. (and also a bit of refactoring) --- addons/delivery/__manifest__.py | 1 + addons/delivery/data/mail_template_data.xml | 89 +++++++++++++++++++ addons/delivery/models/delivery_carrier.py | 12 +-- addons/delivery/models/delivery_grid.py | 8 +- addons/delivery/models/stock_picking.py | 35 +++++++- addons/delivery/views/delivery_view.xml | 3 + addons/delivery/views/report_deliveryslip.xml | 4 + .../views/website_sale_delivery_templates.xml | 6 +- 8 files changed, 141 insertions(+), 17 deletions(-) create mode 100644 addons/delivery/data/mail_template_data.xml diff --git a/addons/delivery/__manifest__.py b/addons/delivery/__manifest__.py index 51350fba523..736da783817 100644 --- a/addons/delivery/__manifest__.py +++ b/addons/delivery/__manifest__.py @@ -21,6 +21,7 @@ invoices from picking, the system is able to add and compute the shipping line. 'views/partner_view.xml', 'views/product_template_view.xml', 'data/delivery_data.xml', + 'data/mail_template_data.xml', 'views/report_shipping.xml', 'views/report_deliveryslip.xml', 'views/sale_config_settings_views.xml', diff --git a/addons/delivery/data/mail_template_data.xml b/addons/delivery/data/mail_template_data.xml new file mode 100644 index 00000000000..7f06198d9a9 --- /dev/null +++ b/addons/delivery/data/mail_template_data.xml @@ -0,0 +1,89 @@ + + + + + Delivery: Send by Email + ${object.company_id.name} Delivery Order (Ref ${object.name or 'n/a' }) + ${object.partner_id.id} + + + ${(object.name or '').replace('/','_')} + ${object.partner_id.lang} + +

Dear ${object.partner_id.name},

+

We are glad to inform you that your order has been shipped.

+

+%if object.carrier_tracking_ref: + Your tracking reference: + %if object.carrier_tracking_url: + ${object.carrier_tracking_ref}. + %else: + ${object.carrier_tracking_ref}. + %endif +%endif +

+

Find your delivery order attached for more details.

+

Thank you,

+
+
+ + + Delivery: Custom Notification Email + ${object.subject} + + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+ ${object.record_name} + + ${user.company_id.name} +
+
+ + + + +
${object.body | safe}
+
+ + + + + +
${user.company_id.name}
${user.company_id.phone or ''}
+ % if user.company_id.email: + ${user.company_id.email}
+ % endif + % if user.company_id.website: + ${user.company_id.website} + % endif +
+
Powered by Odoo.
+
+
+
+
diff --git a/addons/delivery/models/delivery_carrier.py b/addons/delivery/models/delivery_carrier.py index eb07767df26..2f9cff280e8 100644 --- a/addons/delivery/models/delivery_carrier.py +++ b/addons/delivery/models/delivery_carrier.py @@ -136,15 +136,15 @@ class DeliveryCarrier(models.Model): if hasattr(self, '%s_send_shipping' % self.delivery_type): return getattr(self, '%s_send_shipping' % self.delivery_type)(pickings) - def get_tracking_link(self, pickings): + def get_tracking_link(self, picking): ''' Ask the tracking link to the service provider - :param pickings: A recordset of pickings - :return list: A list of string URLs, containing the tracking links for every picking + :param picking: record of stock.picking + :return str: an URL containing the tracking link or False ''' self.ensure_one() if hasattr(self, '%s_get_tracking_link' % self.delivery_type): - return getattr(self, '%s_get_tracking_link' % self.delivery_type)(pickings) + return getattr(self, '%s_get_tracking_link' % self.delivery_type)(picking) def cancel_shipment(self, pickings): ''' Cancel a shipment @@ -183,8 +183,8 @@ class DeliveryCarrier(models.Model): 'tracking_number': False}] return res - def fixed_get_tracking_link(self, pickings): - raise NotImplementedError() + def fixed_get_tracking_link(self, picking): + return False def fixed_cancel_shipment(self, pickings): raise NotImplementedError() diff --git a/addons/delivery/models/delivery_grid.py b/addons/delivery/models/delivery_grid.py index d19d7840075..49678160fec 100644 --- a/addons/delivery/models/delivery_grid.py +++ b/addons/delivery/models/delivery_grid.py @@ -104,12 +104,12 @@ class ProviderGrid(models.Model): carrier = self._match_address(p.partner_id) if not carrier: raise ValidationError(_('Error: no matching grid.')) - res = res + [{'exact_price': p.carrier_id._get_price_available(p.sale_id), # TODO cleanme + res = res + [{'exact_price': p.carrier_id._get_price_available(p.sale_id) if p.sale_id else 0.0, # TODO cleanme 'tracking_number': False}] return res - def base_on_rule__get_tracking_link(self, pickings): - raise NotImplementedError() + def base_on_rule_get_tracking_link(self, picking): + return False - def base_on_rule__cancel_shipment(self, pickings): + def base_on_rule_cancel_shipment(self, pickings): raise NotImplementedError() diff --git a/addons/delivery/models/stock_picking.py b/addons/delivery/models/stock_picking.py index 37a845d937e..6fb25a5b43a 100644 --- a/addons/delivery/models/stock_picking.py +++ b/addons/delivery/models/stock_picking.py @@ -84,12 +84,18 @@ class StockPicking(models.Model): volume = fields.Float(copy=False) weight = fields.Float(compute='_cal_weight', digits=dp.get_precision('Stock Weight'), store=True) carrier_tracking_ref = fields.Char(string='Tracking Reference', copy=False) + carrier_tracking_url = fields.Char(string='Tracking URL', compute='_compute_carrier_tracking_url') number_of_packages = fields.Integer(string='Number of Packages', copy=False) weight_uom_id = fields.Many2one('product.uom', string='Unit of Measure', required=True, readonly="1", help="Unit of measurement for Weight", default=_default_uom) package_ids = fields.Many2many('stock.quant.package', compute='_compute_packages', string='Packages') weight_bulk = fields.Float('Bulk Weight', compute='_compute_bulk_weight') shipping_weight = fields.Float("Weight for Shipping", compute='_compute_shipping_weight') + @api.depends('carrier_id', 'carrier_tracking_ref') + def _compute_carrier_tracking_url(self): + for picking in self: + picking.carrier_tracking_url = picking.carrier_id.get_tracking_link(picking) if picking.carrier_id and picking.carrier_tracking_ref else False + @api.depends('product_id', 'move_lines') def _cal_weight(self): for picking in self: @@ -128,6 +134,29 @@ class StockPicking(models.Model): else: return self._put_in_pack() + @api.multi + def action_send_confirmation_email(self): + self.ensure_one() + delivery_template_id = self.env.ref('delivery.mail_template_data_delivery_confirmation').id + compose_form_id = self.env.ref('mail.email_compose_message_wizard_form').id + ctx = dict( + default_composition_mode='comment', + default_res_id=self.id, + default_model='stock.picking', + default_use_template=bool(delivery_template_id), + default_template_id=delivery_template_id, + custom_layout='delivery.mail_template_data_delivery_notification' + ) + return { + 'type': 'ir.actions.act_window', + 'view_type': 'form', + 'view_mode': 'form', + 'res_model': 'mail.compose.message', + 'view_id': compose_form_id, + 'target': 'new', + 'context': ctx, + } + @api.multi def send_to_shipper(self): self.ensure_one() @@ -148,15 +177,13 @@ class StockPicking(models.Model): @api.multi def open_website_url(self): self.ensure_one() - if self.carrier_id.get_tracking_link(self): - url = self.carrier_id.get_tracking_link(self)[0] - else: + if not self.carrier_tracking_url: raise UserError(_("Your delivery method has no redirect on courier provider's website to track this order.")) client_action = {'type': 'ir.actions.act_url', 'name': "Shipment Tracking Page", 'target': 'new', - 'url': url, + 'url': self.carrier_tracking_url, } return client_action diff --git a/addons/delivery/views/delivery_view.xml b/addons/delivery/views/delivery_view.xml index 83494f7ebfe..54b4ccc325e 100644 --- a/addons/delivery/views/delivery_view.xml +++ b/addons/delivery/views/delivery_view.xml @@ -227,6 +227,9 @@