[IMP] sale_stock: use popover instead of dialog
Commit fff2a30 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: Simon Lejeune (sle) <sle@openerp.com>
This commit is contained in:
committed by
Simon Lejeune
parent
31764a984a
commit
cadd65bcb4
@@ -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);
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Handlers
|
||||
//--------------------------------------------------------------------------
|
||||
_onClickButton: function (ev) {
|
||||
ev.stopPropagation();
|
||||
start: function () {
|
||||
var self = this;
|
||||
return this._super.apply(this, arguments).then(function () {
|
||||
self._setPopOver();
|
||||
});
|
||||
},
|
||||
//--------------------------------------------------------------------------
|
||||
// Private
|
||||
//--------------------------------------------------------------------------
|
||||
/**
|
||||
* 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);
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -1,55 +1,52 @@
|
||||
<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 < 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>
|
||||
|
||||
Reference in New Issue
Block a user