[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:
@@ -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'
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user