From 6173dd21415ab441caaf4404bf812ce2413e29f0 Mon Sep 17 00:00:00 2001 From: Parth Choksi Date: Mon, 15 Jul 2019 10:42:37 +0000 Subject: [PATCH] [IMP] delivery, sale: improvements in recomputing of shipping cost MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The "Recompute shipping cost" button will now reopen the wizard to be able to change carrier. When adding to the order, it will replace the current shipping cost. Relabelled the "Recompute shipping cost" to “Update Shipping Cost” and moved it to the right. Shipping method field will have radio widget and cost will be editable in the wizard. Also, it was not allowed to delete a delivery line when the order was confirmed ('sale' state). So here, as we want to allow user to change the carrier even after the order is confirmed, we have allowed delivery line to be deleted so that new line is added in place of that. task-2033229 --- addons/delivery/models/sale_order.py | 41 ++++++++-------- addons/delivery/views/delivery_view.xml | 10 ++-- .../wizard/choose_delivery_carrier.py | 47 ++++++++++++------- .../wizard/choose_delivery_carrier_views.xml | 27 ++++++----- addons/sale/models/sale.py | 19 +++++--- 5 files changed, 87 insertions(+), 57 deletions(-) diff --git a/addons/delivery/models/sale_order.py b/addons/delivery/models/sale_order.py index 02c6bf605b3..fa6401f54c7 100644 --- a/addons/delivery/models/sale_order.py +++ b/addons/delivery/models/sale_order.py @@ -51,8 +51,14 @@ class SaleOrder(models.Model): def action_open_delivery_wizard(self): view_id = self.env.ref('delivery.choose_delivery_carrier_view_form').id + if self.env.context.get('carrier_recompute'): + name = _('Update shipping cost') + carrier = self.carrier_id + else: + name = _('Add a shipping method') + carrier = self.partner_id.property_delivery_carrier_id return { - 'name': _('Add a shipping method'), + 'name': name, 'type': 'ir.actions.act_window', 'view_mode': 'form', 'res_model': 'choose.delivery.carrier', @@ -61,27 +67,10 @@ class SaleOrder(models.Model): 'target': 'new', 'context': { 'default_order_id': self.id, - 'default_carrier_id': self.partner_id.property_delivery_carrier_id.id, + 'default_carrier_id': carrier.id, } } - def recompute_delivery_cost(self): - self.ensure_one() - delivery_line = self.order_line.filtered('is_delivery')[:1] - res = self.carrier_id.rate_shipment(self) - if res.get('success'): - self.delivery_message = res.get('warning_message', False) - else: - raise UserError(res['error_message']) - delivery_line.name = self.carrier_id.with_context(lang=self.partner_id.lang).name - if self.carrier_id.invoice_policy == 'real': - delivery_line.name += _(' (Estimated Cost: %s )') % self._format_currency_amount(res['price']) - else: - delivery_line.price_unit = res['price'] - if self.carrier_id.free_over and self._compute_amount_total_without_delivery() >= res['price']: - delivery_line.name += '\nFree Shipping' - self.recompute_delivery_price = False - def _create_delivery_line(self, carrier, price_unit, price_unit_in_description=False): SaleOrderLine = self.env['sale.order.line'] if self.partner_id: @@ -163,3 +152,17 @@ class SaleOrderLine(models.Model): def _is_delivery(self): self.ensure_one() return self.is_delivery + + # override to allow deletion of delivery line in a confirmed order + def _check_line_unlink(self): + """ + Extend the allowed deletion policy of SO lines. + + Lines that are delivery lines can be deleted from a confirmed order. + + :rtype: recordset sale.order.line + :returns: set of lines that cannot be deleted + """ + + undeletable_lines = super()._check_line_unlink() + return undeletable_lines.filtered(lambda line: not line.is_delivery) diff --git a/addons/delivery/views/delivery_view.xml b/addons/delivery/views/delivery_view.xml index 211603bc6b0..ac0ef7071a7 100644 --- a/addons/delivery/views/delivery_view.xml +++ b/addons/delivery/views/delivery_view.xml @@ -331,15 +331,17 @@ attrs="{'invisible': ['|', '|',('is_all_service', '=', True), ('order_line', '=', []), ('delivery_set', '=', True)]}" /> + + - @@ -25,7 +29,8 @@ diff --git a/addons/sale/models/sale.py b/addons/sale/models/sale.py index 8145d8166bf..60f4cfad5fc 100644 --- a/addons/sale/models/sale.py +++ b/addons/sale/models/sale.py @@ -478,12 +478,6 @@ class SaleOrder(models.Model): } return invoice_vals - def print_quotation(self): - self.filtered(lambda s: s.state == 'draft').write({'state': 'sent'}) - - return self.env.ref('sale.action_report_saleorder')\ - .with_context({'discard_logo_check': True}).report_action(self) - def action_view_invoice(self): invoices = self.mapped('invoice_ids') action = self.env.ref('account.action_move_out_invoice_type').read()[0] @@ -1456,8 +1450,19 @@ class SaleOrderLine(models.Model): ]) return super(SaleOrderLine, self)._name_search(name, args=args, operator=operator, limit=limit, name_get_uid=name_get_uid) + def _check_line_unlink(self): + """ + Check wether a line can be deleted or not. + + Lines cannot be deleted if the order is confirmed; downpayment + lines who have not yet been invoiced bypass that exception. + :rtype: recordset sale.order.line + :returns: set of lines that cannot be deleted + """ + return self.filtered(lambda line: line.state in ('sale', 'done') and (line.invoice_lines or not line.is_downpayment)) + def unlink(self): - if self.filtered(lambda line: line.state in ('sale', 'done') and (line.invoice_lines or not line.is_downpayment)): + if self._check_line_unlink(): raise UserError(_('You can not remove an order line once the sales order is confirmed.\nYou should rather set the quantity to 0.')) return super(SaleOrderLine, self).unlink()