summaryrefslogtreecommitdiff
path: root/addons/delivery/wizard
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
commit3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch)
treea44932296ef4a9b71d5f010906253d8c53727726 /addons/delivery/wizard
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/delivery/wizard')
-rw-r--r--addons/delivery/wizard/__init__.py5
-rw-r--r--addons/delivery/wizard/choose_delivery_carrier.py94
-rw-r--r--addons/delivery/wizard/choose_delivery_carrier_views.xml39
-rw-r--r--addons/delivery/wizard/choose_delivery_package.py68
-rw-r--r--addons/delivery/wizard/choose_delivery_package_views.xml26
5 files changed, 232 insertions, 0 deletions
diff --git a/addons/delivery/wizard/__init__.py b/addons/delivery/wizard/__init__.py
new file mode 100644
index 00000000..66866584
--- /dev/null
+++ b/addons/delivery/wizard/__init__.py
@@ -0,0 +1,5 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from . import choose_delivery_package
+from . import choose_delivery_carrier
diff --git a/addons/delivery/wizard/choose_delivery_carrier.py b/addons/delivery/wizard/choose_delivery_carrier.py
new file mode 100644
index 00000000..a17e2cde
--- /dev/null
+++ b/addons/delivery/wizard/choose_delivery_carrier.py
@@ -0,0 +1,94 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo import fields, models, api, _
+from odoo.exceptions import UserError
+
+
+class ChooseDeliveryCarrier(models.TransientModel):
+ _name = 'choose.delivery.carrier'
+ _description = 'Delivery Carrier Selection Wizard'
+
+ order_id = fields.Many2one('sale.order', required=True, ondelete="cascade")
+ partner_id = fields.Many2one('res.partner', related='order_id.partner_id', required=True)
+ carrier_id = fields.Many2one(
+ 'delivery.carrier',
+ string="Shipping Method",
+ help="Choose the method to deliver your goods",
+ required=True,
+ )
+ delivery_type = fields.Selection(related='carrier_id.delivery_type')
+ delivery_price = fields.Float()
+ display_price = fields.Float(string='Cost', readonly=True)
+ currency_id = fields.Many2one('res.currency', related='order_id.currency_id')
+ company_id = fields.Many2one('res.company', related='order_id.company_id')
+ available_carrier_ids = fields.Many2many("delivery.carrier", compute='_compute_available_carrier', string="Available Carriers")
+ invoicing_message = fields.Text(compute='_compute_invoicing_message')
+ delivery_message = fields.Text(readonly=True)
+
+ @api.onchange('carrier_id')
+ def _onchange_carrier_id(self):
+ self.delivery_message = False
+ if self.delivery_type in ('fixed', 'base_on_rule'):
+ vals = self._get_shipment_rate()
+ if vals.get('error_message'):
+ return {'error': vals['error_message']}
+ else:
+ self.display_price = 0
+ self.delivery_price = 0
+
+ @api.onchange('order_id')
+ def _onchange_order_id(self):
+ # fixed and base_on_rule delivery price will computed on each carrier change so no need to recompute here
+ if self.carrier_id and self.order_id.delivery_set and self.delivery_type not in ('fixed', 'base_on_rule'):
+ vals = self._get_shipment_rate()
+ if vals.get('error_message'):
+ warning = {
+ 'title': '%s Error' % self.carrier_id.name,
+ 'message': vals.get('error_message'),
+ 'type': 'notification',
+ }
+ return {'warning': warning}
+
+ @api.depends('carrier_id')
+ def _compute_invoicing_message(self):
+ self.ensure_one()
+ if self.carrier_id.invoice_policy == 'real':
+ self.invoicing_message = _('The shipping price will be set once the delivery is done.')
+ else:
+ self.invoicing_message = ""
+
+ @api.depends('partner_id')
+ def _compute_available_carrier(self):
+ for rec in self:
+ carriers = self.env['delivery.carrier'].search(['|', ('company_id', '=', False), ('company_id', '=', rec.order_id.company_id.id)])
+ rec.available_carrier_ids = carriers.available_carriers(rec.order_id.partner_shipping_id) if rec.partner_id else carriers
+
+ def _get_shipment_rate(self):
+ vals = self.carrier_id.rate_shipment(self.order_id)
+ if vals.get('success'):
+ self.delivery_message = vals.get('warning_message', False)
+ self.delivery_price = vals['price']
+ self.display_price = vals['carrier_price']
+ return {}
+ return {'error_message': vals['error_message']}
+
+ def update_price(self):
+ vals = self._get_shipment_rate()
+ if vals.get('error_message'):
+ raise UserError(vals.get('error_message'))
+ return {
+ 'name': _('Add a shipping method'),
+ 'type': 'ir.actions.act_window',
+ 'view_mode': 'form',
+ 'res_model': 'choose.delivery.carrier',
+ 'res_id': self.id,
+ 'target': 'new',
+ }
+
+ def button_confirm(self):
+ self.order_id.set_delivery_line(self.carrier_id, self.delivery_price)
+ self.order_id.write({
+ 'recompute_delivery_price': False,
+ 'delivery_message': self.delivery_message,
+ })
diff --git a/addons/delivery/wizard/choose_delivery_carrier_views.xml b/addons/delivery/wizard/choose_delivery_carrier_views.xml
new file mode 100644
index 00000000..d15fef44
--- /dev/null
+++ b/addons/delivery/wizard/choose_delivery_carrier_views.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+ <record id="choose_delivery_carrier_view_form" model="ir.ui.view">
+ <field name="name">choose.delivery.carrier.form</field>
+ <field name="model">choose.delivery.carrier</field>
+ <field name="arch" type="xml">
+ <form>
+ <field name='available_carrier_ids' invisible="1"/>
+ <group>
+ <group>
+ <field name="carrier_id" domain="[('id', 'in', available_carrier_ids)]"/>
+ <field name="delivery_type" invisible="1"/>
+ <field name="currency_id" invisible="1"/>
+ <field name="order_id" invisible="1"/>
+ <field name='delivery_price' invisible="1"/>
+ <label for="display_price"/>
+ <div class="o_row">
+ <field name='display_price' widget="monetary" options="{'currency_field': 'currency_id'}" attrs="{'invisible': [('carrier_id','=', False)]}"/>
+ <button name="update_price" type="object" attrs="{'invisible': [('delivery_type','in', ('fixed', 'base_on_rule'))]}">
+ <i class="fa fa-arrow-right mr-1"/>Get rate
+ </button>
+ </div>
+ </group>
+ </group>
+ <div role="alert" class="alert alert-warning" attrs="{'invisible': [('invoicing_message', '=', '')]}">
+ <field name="invoicing_message" nolabel="1"/>
+ </div>
+ <div role="alert" class="alert alert-info" attrs="{'invisible': [('delivery_message', '=', False)]}">
+ <field name="delivery_message" nolabel="1"/>
+ </div>
+ <footer>
+ <button name="button_confirm" invisible="not context.get('carrier_recompute')" type="object" string="Update" class="btn-primary"/>
+ <button name="button_confirm" invisible="context.get('carrier_recompute')" type="object" string="Add" class="btn-primary"/>
+ <button string="Discard" special="cancel" class="btn-secondary"/>
+ </footer>
+ </form>
+ </field>
+ </record>
+</odoo>
diff --git a/addons/delivery/wizard/choose_delivery_package.py b/addons/delivery/wizard/choose_delivery_package.py
new file mode 100644
index 00000000..f5299832
--- /dev/null
+++ b/addons/delivery/wizard/choose_delivery_package.py
@@ -0,0 +1,68 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo import api, fields, models, _
+from odoo.tools.float_utils import float_compare
+
+
+class ChooseDeliveryPackage(models.TransientModel):
+ _name = 'choose.delivery.package'
+ _description = 'Delivery Package Selection Wizard'
+
+ @api.model
+ def default_get(self, fields_list):
+ defaults = super().default_get(fields_list)
+ if 'shipping_weight' in fields_list:
+ picking = self.env['stock.picking'].browse(defaults.get('picking_id'))
+ move_line_ids = picking.move_line_ids.filtered(lambda m:
+ float_compare(m.qty_done, 0.0, precision_rounding=m.product_uom_id.rounding) > 0
+ and not m.result_package_id
+ )
+ total_weight = 0.0
+ for ml in move_line_ids:
+ qty = ml.product_uom_id._compute_quantity(ml.qty_done, ml.product_id.uom_id)
+ total_weight += qty * ml.product_id.weight
+ defaults['shipping_weight'] = total_weight
+ return defaults
+
+ picking_id = fields.Many2one('stock.picking', 'Picking')
+ delivery_packaging_id = fields.Many2one('product.packaging', 'Delivery Packaging', check_company=True)
+ shipping_weight = fields.Float('Shipping Weight')
+ weight_uom_name = fields.Char(string='Weight unit of measure label', compute='_compute_weight_uom_name')
+ company_id = fields.Many2one(related='picking_id.company_id')
+
+ @api.depends('delivery_packaging_id')
+ def _compute_weight_uom_name(self):
+ weight_uom_id = self.env['product.template']._get_weight_uom_id_from_ir_config_parameter()
+ for package in self:
+ package.weight_uom_name = weight_uom_id.name
+
+ @api.onchange('delivery_packaging_id', 'shipping_weight')
+ def _onchange_packaging_weight(self):
+ if self.delivery_packaging_id.max_weight and self.shipping_weight > self.delivery_packaging_id.max_weight:
+ warning_mess = {
+ 'title': _('Package too heavy!'),
+ 'message': _('The weight of your package is higher than the maximum weight authorized for this package type. Please choose another package type.')
+ }
+ return {'warning': warning_mess}
+
+ def action_put_in_pack(self):
+ picking_move_lines = self.picking_id.move_line_ids
+ if not self.picking_id.picking_type_id.show_reserved and not self.env.context.get('barcode_view'):
+ picking_move_lines = self.picking_id.move_line_nosuggest_ids
+
+ move_line_ids = picking_move_lines.filtered(lambda ml:
+ float_compare(ml.qty_done, 0.0, precision_rounding=ml.product_uom_id.rounding) > 0
+ and not ml.result_package_id
+ )
+ if not move_line_ids:
+ move_line_ids = picking_move_lines.filtered(lambda ml: float_compare(ml.product_uom_qty, 0.0,
+ precision_rounding=ml.product_uom_id.rounding) > 0 and float_compare(ml.qty_done, 0.0,
+ precision_rounding=ml.product_uom_id.rounding) == 0)
+
+ delivery_package = self.picking_id._put_in_pack(move_line_ids)
+ # write shipping weight and product_packaging on 'stock_quant_package' if needed
+ if self.delivery_packaging_id:
+ delivery_package.packaging_id = self.delivery_packaging_id
+ if self.shipping_weight:
+ delivery_package.shipping_weight = self.shipping_weight
diff --git a/addons/delivery/wizard/choose_delivery_package_views.xml b/addons/delivery/wizard/choose_delivery_package_views.xml
new file mode 100644
index 00000000..5346ca84
--- /dev/null
+++ b/addons/delivery/wizard/choose_delivery_package_views.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+ <record id="choose_delivery_package_view_form" model="ir.ui.view">
+ <field name="name">choose.delivery.package.form</field>
+ <field name="model">choose.delivery.package</field>
+ <field name="arch" type="xml">
+ <form string="Package">
+ <field name="picking_id" invisible="1"/>
+ <group>
+ <field name="delivery_packaging_id" domain="[('package_carrier_type', '=', context.get('current_package_carrier_type', 'none'))]"
+ context="{'form_view_ref':'delivery.product_packaging_delivery_form'}"/>
+ <label for="shipping_weight" attrs="{'invisible': [('delivery_packaging_id', '=', False)]}"/>
+ <div class="o_row" attrs="{'invisible': [('delivery_packaging_id', '=', False)]}" name="package_weight">
+ <field name="shipping_weight"/>
+ <field name="weight_uom_name"/>
+ </div>
+ </group>
+ <footer>
+ <button name="action_put_in_pack" type="object" string="Save" class="btn-primary"/>
+ <button string="Discard" special="cancel" class="btn-secondary"/>
+ </footer>
+ </form>
+ </field>
+ </record>
+
+</odoo>