choose_delivery_carrier.py 3.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. # -*- coding: utf-8 -*-
  2. # Part of Odoo. See LICENSE file for full copyright and licensing details.
  3. from odoo import fields, models, api, _
  4. from odoo.exceptions import UserError
  5. class ChooseDeliveryCarrier(models.TransientModel):
  6. _name = 'choose.delivery.carrier'
  7. _description = 'Delivery Carrier Selection Wizard'
  8. order_id = fields.Many2one('sale.order', required=True, ondelete="cascade")
  9. partner_id = fields.Many2one('res.partner', related='order_id.partner_id', required=True)
  10. carrier_id = fields.Many2one(
  11. 'delivery.carrier',
  12. string="Shipping Method",
  13. required=True,
  14. )
  15. delivery_type = fields.Selection(related='carrier_id.delivery_type')
  16. delivery_price = fields.Float()
  17. display_price = fields.Float(string='Cost', readonly=True)
  18. currency_id = fields.Many2one('res.currency', related='order_id.currency_id')
  19. company_id = fields.Many2one('res.company', related='order_id.company_id')
  20. available_carrier_ids = fields.Many2many("delivery.carrier", compute='_compute_available_carrier', string="Available Carriers")
  21. invoicing_message = fields.Text(compute='_compute_invoicing_message')
  22. delivery_message = fields.Text(readonly=True)
  23. @api.onchange('carrier_id')
  24. def _onchange_carrier_id(self):
  25. self.delivery_message = False
  26. if self.delivery_type in ('fixed', 'base_on_rule'):
  27. vals = self._get_shipment_rate()
  28. if vals.get('error_message'):
  29. return {'error': vals['error_message']}
  30. else:
  31. self.display_price = 0
  32. self.delivery_price = 0
  33. @api.onchange('order_id')
  34. def _onchange_order_id(self):
  35. # fixed and base_on_rule delivery price will computed on each carrier change so no need to recompute here
  36. if self.carrier_id and self.order_id.delivery_set and self.delivery_type not in ('fixed', 'base_on_rule'):
  37. vals = self._get_shipment_rate()
  38. if vals.get('error_message'):
  39. warning = {
  40. 'title': '%s Error' % self.carrier_id.name,
  41. 'message': vals.get('error_message'),
  42. 'type': 'notification',
  43. }
  44. return {'warning': warning}
  45. @api.depends('carrier_id')
  46. def _compute_invoicing_message(self):
  47. self.ensure_one()
  48. if self.carrier_id.invoice_policy == 'real':
  49. self.invoicing_message = _('The shipping price will be set once the delivery is done.')
  50. else:
  51. self.invoicing_message = ""
  52. @api.depends('partner_id')
  53. def _compute_available_carrier(self):
  54. for rec in self:
  55. carriers = self.env['delivery.carrier'].search(['|', ('company_id', '=', False), ('company_id', '=', rec.order_id.company_id.id)])
  56. rec.available_carrier_ids = carriers.available_carriers(rec.order_id.partner_shipping_id) if rec.partner_id else carriers
  57. def _get_shipment_rate(self):
  58. vals = self.carrier_id.rate_shipment(self.order_id)
  59. if vals.get('success'):
  60. self.delivery_message = vals.get('warning_message', False)
  61. self.delivery_price = vals['price']
  62. self.display_price = vals['carrier_price']
  63. return {}
  64. return {'error_message': vals['error_message']}
  65. def update_price(self):
  66. vals = self._get_shipment_rate()
  67. if vals.get('error_message'):
  68. raise UserError(vals.get('error_message'))
  69. return {
  70. 'name': _('Add a shipping method'),
  71. 'type': 'ir.actions.act_window',
  72. 'view_mode': 'form',
  73. 'res_model': 'choose.delivery.carrier',
  74. 'res_id': self.id,
  75. 'target': 'new',
  76. }
  77. def button_confirm(self):
  78. self.order_id.set_delivery_line(self.carrier_id, self.delivery_price)
  79. self.order_id.write({
  80. 'recompute_delivery_price': False,
  81. 'delivery_message': self.delivery_message,
  82. })