1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import logging
from odoo import api, fields, models
_logger = logging.getLogger(__name__)
class SaleOrder(models.Model):
_inherit = 'sale.order'
amount_delivery = fields.Monetary(
compute='_compute_amount_delivery',
string='Delivery Amount',
help="The amount without tax.", store=True, tracking=True)
def _compute_website_order_line(self):
super(SaleOrder, self)._compute_website_order_line()
for order in self:
order.website_order_line = order.website_order_line.filtered(lambda l: not l.is_delivery)
@api.depends('order_line.price_unit', 'order_line.tax_id', 'order_line.discount', 'order_line.product_uom_qty')
def _compute_amount_delivery(self):
for order in self:
if self.env.user.has_group('account.group_show_line_subtotals_tax_excluded'):
order.amount_delivery = sum(order.order_line.filtered('is_delivery').mapped('price_subtotal'))
else:
order.amount_delivery = sum(order.order_line.filtered('is_delivery').mapped('price_total'))
def _check_carrier_quotation(self, force_carrier_id=None):
self.ensure_one()
DeliveryCarrier = self.env['delivery.carrier']
if self.only_services:
self.write({'carrier_id': None})
self._remove_delivery_line()
return True
else:
self = self.with_company(self.company_id)
# attempt to use partner's preferred carrier
if not force_carrier_id and self.partner_shipping_id.property_delivery_carrier_id:
force_carrier_id = self.partner_shipping_id.property_delivery_carrier_id.id
carrier = force_carrier_id and DeliveryCarrier.browse(force_carrier_id) or self.carrier_id
available_carriers = self._get_delivery_methods()
if carrier:
if carrier not in available_carriers:
carrier = DeliveryCarrier
else:
# set the forced carrier at the beginning of the list to be verfied first below
available_carriers -= carrier
available_carriers = carrier + available_carriers
if force_carrier_id or not carrier or carrier not in available_carriers:
for delivery in available_carriers:
verified_carrier = delivery._match_address(self.partner_shipping_id)
if verified_carrier:
carrier = delivery
break
self.write({'carrier_id': carrier.id})
self._remove_delivery_line()
if carrier:
res = carrier.rate_shipment(self)
if res.get('success'):
self.set_delivery_line(carrier, res['price'])
self.delivery_rating_success = True
self.delivery_message = res['warning_message']
else:
self.set_delivery_line(carrier, 0.0)
self.delivery_rating_success = False
self.delivery_message = res['error_message']
return bool(carrier)
def _get_delivery_methods(self):
address = self.partner_shipping_id
# searching on website_published will also search for available website (_search method on computed field)
return self.env['delivery.carrier'].sudo().search([('website_published', '=', True)]).available_carriers(address)
def _cart_update(self, product_id=None, line_id=None, add_qty=0, set_qty=0, **kwargs):
""" Override to update carrier quotation if quantity changed """
self._remove_delivery_line()
# When you update a cart, it is not enouf to remove the "delivery cost" line
# The carrier might also be invalid, eg: if you bought things that are too heavy
# -> this may cause a bug if you go to the checkout screen, choose a carrier,
# then update your cart (the cart becomes uneditable)
self.write({'carrier_id': False})
values = super(SaleOrder, self)._cart_update(product_id, line_id, add_qty, set_qty, **kwargs)
return values
|