Skip to content
Snippets Groups Projects
Commit cadd65bc authored by William Henrotin's avatar William Henrotin Committed by Simon Lejeune
Browse files

[IMP] sale_stock: use popover instead of dialog


Commit fff2a30a introduces a dialog to show quantities on hand directly
on sale order line.

This commit replace the dialog by a bootstrap popover

Task 2058670

closes odoo/odoo#36213

Signed-off-by: default avatarSimon Lejeune (sle) <sle@openerp.com>
parent 31764a98
No related branches found
No related tags found
No related merge requests found
......@@ -6,9 +6,9 @@ var QWeb = core.qweb;
var Widget = require('web.Widget');
var Context = require('web.Context');
var Dialog = require('web.Dialog');
var data_manager = require('web.data_manager');
var widget_registry = require('web.widget_registry');
var config = require('web.config');
var _t = core._t;
var time = require('web.time');
......@@ -29,58 +29,77 @@ var QtyAtDateWidget = Widget.extend({
this._super(parent);
},
start: function () {
var self = this;
return this._super.apply(this, arguments).then(function () {
self._setPopOver();
});
},
//--------------------------------------------------------------------------
// Handlers
// Private
//--------------------------------------------------------------------------
_onClickButton: function (ev) {
ev.stopPropagation();
/**
* Set a bootstrap popover on the current QtyAtDate widget that display available
* quantity.
*/
_setPopOver: function () {
var self = this;
if (!this.data.scheduled_date) {
return;
}
this.data.delivery_date = this.data.scheduled_date.clone().add(this.getSession().getTZOffset(this.data.scheduled_date), 'minutes').format(time.getLangDateFormat());
// The grid view need a specific date format that could be different than
// the user one.
this.data.delivery_date_grid = this.data.scheduled_date.clone().add(this.getSession().getTZOffset(this.data.scheduled_date), 'minutes').format('YYYY-MM-DD');
var $content = $(QWeb.render('sale_stock.QtyDetailDialog', {
this.data.debug = config.isDebug();
var $content = $(QWeb.render('sale_stock.QtyDetailPopOver', {
data: this.data,
}));
this.dialog = new Dialog(this, {
size: 'medium',
title: _.str.sprintf(_t('%s Availability'), self.data.product_id.data.display_name),
$content: $content,
buttons: [{
text: _t('Close'),
classes: 'btn-primary',
close: true,
}],
});
this.dialog.opened().then(function () {
var $forecastButton = self.dialog.$('.action_open_forecast');
$forecastButton.on('click', function(ev) {
ev.stopPropagation();
data_manager.load_action('stock.report_stock_quantity_action').then(function (action) {
// Change action context to choose a specific date and product(s)
// As grid_anchor is set to now() by default in the data, we need
// to load the action first, change the context then launch it via do_action
// additional_context cannot replace a context value, only add new
//
// in case of kit product, the forecast view show the kit's components
self._rpc({
model: 'product.product',
method: 'get_components',
args: [[self.data.product_id.data.id]]
}).then(function (res) {
var additional_context = {};
additional_context.grid_anchor = self.data.delivery_date_grid;
additional_context.search_default_warehouse_id = [self.data.warehouse_id.data.id]
action.context = new Context(action.context, additional_context);
action.domain = [
['product_id', 'in', res]
];
self.do_action(action);
});
var $forecastButton = $content.find('.action_open_forecast');
$forecastButton.on('click', function(ev) {
ev.stopPropagation();
data_manager.load_action('stock.report_stock_quantity_action').then(function (action) {
// Change action context to choose a specific date and product(s)
// As grid_anchor is set to now() by default in the data, we need
// to load the action first, change the context then launch it via do_action
// additional_context cannot replace a context value, only add new
//
// in case of kit product, the forecast view show the kit's components
self._rpc({
model: 'product.product',
method: 'get_components',
args: [[self.data.product_id.data.id]]
}).then(function (res) {
var additional_context = {};
additional_context.grid_anchor = self.data.delivery_date_grid;
additional_context.search_default_warehouse_id = [self.data.warehouse_id.data.id];
action.context = new Context(action.context, additional_context);
action.domain = [
['product_id', 'in', res]
];
self.do_action(action);
});
});
});
this.dialog.open();
var options = {
content: $content,
html: true,
placement: 'left',
title: _t('Availability'),
trigger: 'focus',
delay: {'show': 0, 'hide': 100 },
};
this.$el.popover(options);
},
//--------------------------------------------------------------------------
// Handlers
//--------------------------------------------------------------------------
_onClickButton: function () {
// We add the property special click on the widget link.
// This hack allows us to trigger the popover (see _setPopOver) without
// triggering the _onRowClicked that opens the order line form view.
this.$el.find('.fa-info-circle').prop('special_click', true);
},
});
......
<templates>
<div t-name="sale_stock.qtyAtDate">
<div t-att-class="!widget.data.id ? 'd-none' : ''">
<div t-att-class="!widget.data.product_id ? 'd-none' : ''">
<t t-if="widget.data.virtual_available_at_date &lt; widget.data.qty_to_deliver and !widget.data.is_mto">
<a class="fa fa-info-circle text-danger"/>
<a tabindex="0" class="fa fa-info-circle text-danger"/>
</t>
<t t-else="">
<a class="fa fa-info-circle text-primary"/>
<a tabindex="0" class="fa fa-info-circle text-primary"/>
</t>
</div>
</div>
<div t-name="sale_stock.QtyDetailDialog">
<div class="container my-2">
<div class="row">
<div class="col-6">
<div class="row mt-2">
<div class="col-6"><h5><b>Delivery Date</b></h5></div>
<div class="col-6"><span t-esc="data.delivery_date"/></div>
</div>
<div t-if="!data.is_mto" class="row mt-2">
<div class="col-6"><h5 class="mb-0"><b>Forecasted Stock</b></h5><small>On delivery date</small></div>
<div class="col-6"><t t-esc='data.virtual_available_at_date'/>
<label class="mb-0"><t t-esc='data.product_uom.data.display_name'/></label></div>
</div>
<div t-if="!data.is_mto" class="row mt-3">
<div class="col-12">
<button class="text-left btn btn-link p-0 action_open_forecast"
type="button">
<i class="fa fa-fw o_button_icon fa-arrow-right mr-1"></i>
View Detailed Forecast
</button>
</div>
</div>
</div>
<div t-if="!data.is_mto" class="col-6 text-muted">
<div class="row mt-2">
<div class="col-6"><p class="mb-0"><b>Stock On Hand</b></p></div>
<div class="col-6"><t t-esc='data.qty_available_today'/>
<label class="mb-0"><t t-esc='data.product_uom.data.display_name'/></label></div>
</div>
<div class="row mt-2">
<div class="col-6"><p class="mb-0"><b>Stock Available </b></p><small>On Hand - Reserved</small></div>
<div class="col-6"><t t-esc='data.free_qty_today'/>
<label class="mb-0"><t t-esc='data.product_uom.data.display_name'/></label></div>
</div>
</div>
<div t-else="" class="col-6">
<div class="row mt-2">
<div t-name="sale_stock.QtyDetailPopOver">
<table>
<tbody>
<tr>
<td><strong>Expected Delivery</strong></td>
<td class="oe-right"><span t-esc="data.delivery_date"/></td>
</tr>
<t t-if="!data.is_mto">
<tr>
<td><strong>Forecasted Stock</strong></td>
<td><t t-esc='data.virtual_available_at_date'/>
<t t-esc='data.product_uom.data.display_name'/></td>
</tr>
<t t-if="data.debug">
<tr>
<td><strong>Stock On Hand</strong></td>
<td><t t-esc='data.qty_available_today'/>
<t t-esc='data.product_uom.data.display_name'/></td>
</tr>
<tr>
<td><strong>Stock Available</strong><br /><small>On Hand - Reserved</small></td>
<td><t t-esc='data.free_qty_today'/>
<t t-esc='data.product_uom.data.display_name'/></td>
</tr>
</t>
</t>
<t t-else="">
<tr>
<p>This product is replenished on demand.</p>
</div>
</div>
</div>
</div>
</tr>
</t>
</tbody>
</table>
<button t-if="!data.is_mto" class="text-left btn btn-link action_open_forecast"
type="button">
<i class="fa fa-fw o_button_icon fa-arrow-right"></i>
View Detailed Forecast
</button>
</div>
</templates>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment