[FIX] delivery: invoice actual shipping cost

Since commit 78cc0b95f4, there was no more
way to invoice the actual price of a shipping (after the transfer).

In order to make that available again, we introduce a new field on the
sale order. This field automatically detects whether a sale order
contains a "delivery" line or not, at sale order confirmation
(action_confirm).

When the delivery order is processed, the actual shipping cost is thus
repercuted on the sale order if and only if the shipping price was not
"forced" at the sale order confirmation.

(and a few refactoring to avoid copy-pasting code lines)
This commit is contained in:
Richard Mathot
2015-09-28 17:25:44 +02:00
parent bb78aecc29
commit 7ac04d409e
2 changed files with 47 additions and 27 deletions
+38 -27
View File
@@ -10,6 +10,7 @@ class SaleOrder(models.Model):
delivery_price = fields.Float(string='Estimated Delivery Price', compute='_compute_delivery_price', store=True)
carrier_id = fields.Many2one("delivery.carrier", string="Delivery Method", help="Fill this field if you plan to invoice the shipping based on picking.")
invoice_shipping_on_delivery = fields.Boolean(string="Invoice Shipping on Delivery")
@api.depends('carrier_id', 'partner_id', 'order_line')
def _compute_delivery_price(self):
@@ -28,6 +29,13 @@ class SaleOrder(models.Model):
if self.partner_id:
self.carrier_id = self.partner_id.property_delivery_carrier_id
@api.multi
def action_confirm(self):
res = super(SaleOrder, self).action_confirm()
for so in self:
self.invoice_shipping_on_delivery = all([not line.is_delivery for line in so.order_line])
return res
@api.multi
def _delivery_unset(self):
self.env['sale.order.line'].search([('order_id', 'in', self.ids), ('is_delivery', '=', True)]).unlink()
@@ -35,8 +43,6 @@ class SaleOrder(models.Model):
@api.multi
def delivery_set(self):
SaleOrderLine = self.env['sale.order.line']
# Remove delivery products from the sale order
self._delivery_unset()
@@ -58,35 +64,40 @@ class SaleOrder(models.Model):
if order.company_id.currency_id.id != order.pricelist_id.currency_id.id:
price_unit = order.company_id.currency_id.with_context(date=order.date_order).compute(price_unit, order.pricelist_id.currency_id)
account_id = carrier.product_id.property_account_income_id.id
if not account_id:
account_id = carrier.product_id.categ_id.property_account_income_categ_id.id
# Apply fiscal position
taxes = carrier.product_id.taxes_id.filtered(lambda t: t.company_id.id == order.company_id.id)
taxes_ids = taxes.ids
if order.partner_id and order.fiscal_position_id:
account_id = order.fiscal_position_id.map_account(account_id)
taxes_ids = order.fiscal_position_id.map_tax(taxes).ids
# Create the sale order line
values = {
'order_id': order.id,
'name': carrier.name,
'product_uom_qty': 1,
'product_uom': carrier.product_id.uom_id.id,
'product_id': carrier.product_id.id,
'price_unit': price_unit,
'tax_id': [(6, 0, taxes_ids)],
'is_delivery': True,
}
if order.order_line:
values['sequence'] = order.order_line[-1].sequence + 1
SaleOrderLine.create(values)
order._create_delivery_line(carrier, price_unit)
else:
raise UserError(_('No carrier set for this order.'))
def _create_delivery_line(self, carrier, price_unit):
SaleOrderLine = self.env['sale.order.line']
account_id = carrier.product_id.property_account_income_id.id
if not account_id:
account_id = carrier.product_id.categ_id.property_account_income_categ_id.id
# Apply fiscal position
taxes = carrier.product_id.taxes_id.filtered(lambda t: t.company_id.id == self.company_id.id)
taxes_ids = taxes.ids
if self.partner_id and self.fiscal_position_id:
account_id = self.fiscal_position_id.map_account(account_id)
taxes_ids = self.fiscal_position_id.map_tax(taxes).ids
# Create the sale order line
values = {
'order_id': self.id,
'name': carrier.name,
'product_uom_qty': 1,
'product_uom': carrier.product_id.uom_id.id,
'product_id': carrier.product_id.id,
'price_unit': price_unit,
'tax_id': [(6, 0, taxes_ids)],
'is_delivery': True,
}
if self.order_line:
values['sequence'] = self.order_line[-1].sequence + 1
SaleOrderLine.create(values)
class SaleOrderLine(models.Model):
_inherit = 'sale.order.line'
+9
View File
@@ -75,6 +75,8 @@ class StockPicking(models.Model):
if self.carrier_id and self.carrier_id.delivery_type not in ['fixed', 'base_on_rule'] and self.carrier_id.shipping_enabled:
self.send_to_shipper()
self._add_delivery_cost_to_so()
return res
@api.multi
@@ -86,6 +88,13 @@ class StockPicking(models.Model):
msg = _("Shipment sent to carrier %s for expedition with tracking number %s") % (self.carrier_id.name, self.carrier_tracking_ref)
self.message_post(body=msg)
@api.multi
def _add_delivery_cost_to_so(self):
self.ensure_one()
sale_order = self.sale_id
if sale_order.invoice_shipping_on_delivery:
sale_order._create_delivery_line(self.carrier_id, self.carrier_price)
@api.multi
def open_website_url(self):
self.ensure_one()