/* =======================================
ATUM ORDERS
======================================= */
import AddItemsPopup from './_add-items-popup';
import AtumOrderItems from './_order-items';
import { Blocker } from '../_blocker';
import DateTimePicker from '../_date-time-picker';
import OrdersBulkActions from './_bulk-actions';
import Tooltip from '../_tooltip';
import Settings from '../../config/_settings';
import { StupidTable } from '../_stupid-table';
import { Switcher } from '../_switcher';
export default class AtumOrders {
$container: JQuery;
$itemsBlocker: JQuery;
areItemsSelectable: boolean;
isEditable: string;
swal: any = window['swal'];
accounting: any = window['accounting'];
constructor(
private settings: Settings,
private tooltip: Tooltip,
private dateTimePicker: DateTimePicker
) {
this.$container = $('#atum_order_items');
this.$itemsBlocker = this.$container.find('.items-blocker');
if (!this.$itemsBlocker.length && typeof this.settings.get('itemBlocker') !== 'undefined') {
$('.atum_order_items_wrapper').before(`
${ this.settings.get('itemBlocker') }
`);
this.$itemsBlocker = this.$container.find('.items-blocker');
}
this.areItemsSelectable = this.settings.get('enableSelectItems');
this.isEditable = $('#atum_order_is_editable').val();
StupidTable.init( $('table.atum_order_items') );
new AtumOrderItems(this.settings, this.$container, this);
new OrdersBulkActions(this.settings, this.$container, this);
new AddItemsPopup(this.settings, this.$container, this, this.tooltip);
this.dateTimePicker.addDateTimePickers( $('.date-picker'), {minDate: false} );
Switcher.doSwitchers();
this.bindEvents();
}
bindEvents() {
// Bind items' events
this.$container
// Qty
.on( 'change', 'input.quantity', (evt: JQueryEventObject) => this.quantityChanged(evt) )
// Subtotal/total
.on( 'keyup change', '.split-input :input', (evt: JQueryEventObject) => {
const $input: JQuery = $(evt.currentTarget),
$subtotal: JQuery = $input.parent().prev().find(':input');
if ( $subtotal && ( $subtotal.val() === '' || $subtotal.is('.match-total') ) ) {
$subtotal.val( $input.val() ).addClass('match-total');
}
})
.on( 'keyup', '.split-input :input', (evt: JQueryEventObject) => {
$(evt.currentTarget).removeClass('match-total');
});
if (this.areItemsSelectable) {
this.$container
.on('click', 'tr.item, tr.fee, tr.shipping', (evt: JQueryEventObject) => this.selectRow(evt))
.on('click', 'tr.item :input, tr.fee :input, tr.shipping :input, tr.item a, tr.fee a, tr.shipping a', (evt: JQueryEventObject) => evt.stopPropagation());
}
// Trigger ATUM order type dependent fields
$('#atum_order_type').change( (evt: JQueryEventObject) => this.toggleExtraFields(evt) ).change();
// Hide/show the blocker section on supplier dropdown changes.
$('.dropdown_supplier').change( (evt: JQueryEventObject) => this.toggleItemsBlocker( $(evt.currentTarget).val() !== null ) ).change();
// Trigger multiple suppliers' dependent fields
$('#multiple_suppliers').change( (evt: JQueryEventObject) => this.toggleSupplierField(evt) ).change();
// Ask for importing the order items after linking an order
$('#wc_order').change( () => this.importOrderItems() );
// Change button page-title-action position
$('.wp-heading-inline').append( $('.page-title-action').show() );
// Footer position
$(window).on('load', () => {
if ( $('.footer-box').hasClass('no-style') ) {
$('#wpfooter').css('position', 'relative').show();
$('#wpcontent').css('min-height', '95vh');
}
});
}
/**
* When the qty is changed, increase or decrease costs
*/
quantityChanged(evt: JQueryEventObject) {
let $input: JQuery = $(evt.currentTarget),
$row: JQuery = $input.closest('tr.item'),
qty: number = $input.val(),
oQty: number = $input.data('qty'),
$lineTotal: JQuery = $row.find('input.line_total'),
$lineSubtotal: JQuery = $row.find('input.line_subtotal');
// Totals
let unitTotal: number = this.accounting.unformat( $lineTotal.data( 'total' ), this.settings.get('mon_decimal_point') ) / oQty;
$lineTotal.val(
parseFloat( this.accounting.formatNumber( unitTotal * qty, this.settings.get('rounding_precision'), '' ) )
.toString()
.replace( '.', this.settings.get('mon_decimal_point') )
);
let unitSubtotal: number = this.accounting.unformat( $lineSubtotal.data( 'subtotal' ),this.settings.get('mon_decimal_point') ) / oQty;
$lineSubtotal.val(
parseFloat( this.accounting.formatNumber( unitSubtotal * qty, this.settings.get('rounding_precision'), '' ) )
.toString()
.replace( '.', this.settings.get('mon_decimal_point') )
);
// Taxes
$row.find('input.line_tax').each( (index: number, elem: Element) => {
let $lineTotalTax: JQuery = $(elem),
taxId: string = $lineTotalTax.data('tax_id'),
unitTotalTax: number = this.accounting.unformat($lineTotalTax.data('total_tax'), this.settings.get('mon_decimal_point')) / oQty,
$lineSubtotalTax: JQuery = $row.find(`input.line_subtotal_tax[data-tax_id="${ taxId }"]`),
unitSubtotalTax: number = this.accounting.unformat($lineSubtotalTax.data('subtotal_tax'), this.settings.get('mon_decimal_point')) / oQty;
if ( 0 < unitTotalTax ) {
$lineTotalTax.val(
parseFloat( this.accounting.formatNumber( unitTotalTax * qty, this.settings.get('rounding_precision'), '' ) )
.toString()
.replace( '.', this.settings.get('mon_decimal_point') )
);
}
if ( 0 < unitSubtotalTax ) {
$lineSubtotalTax.val(
parseFloat( this.accounting.formatNumber( unitSubtotalTax * qty, this.settings.get('rounding_precision'), '' ) )
.toString()
.replace( '.', this.settings.get('mon_decimal_point') )
);
}
});
$input.trigger( 'quantity_changed' );
}
loadItemsTable(data: any, dataType?: string, callback?: Function) {
Blocker.block(this.$container);
dataType = dataType || 'html';
$.ajax({
url : window['ajaxurl'],
data : data,
dataType: dataType,
method : 'POST',
success : (response: any) => {
if ((typeof response === 'object' && response.success === true) || typeof response !== 'object') {
const itemsTable: string = dataType === 'html' ? response : response.data.html;
this.$container.find('.inside').empty().append(itemsTable);
this.tooltip.addTooltips();
StupidTable.init( $('table.atum_order_items') );
}
else if (typeof response === 'object' && response.success === false) {
this.showAlert('error', this.settings.get('error'), response.data.error);
}
Blocker.unblock(this.$container);
if (callback) {
callback();
}
}
});
}
reloadItems(callback?: Function) {
this.loadItemsTable({
atum_order_id: this.settings.get('post_id'),
action : 'atum_order_load_items',
security : this.settings.get('atum_order_item_nonce'),
}, 'html', callback);
}
showAlert(type: string, title: string, message: string) {
this.swal({
title : title,
text : message,
type : type,
confirmButtonText: this.settings.get('ok'),
});
}
selectRow(evt: JQueryEventObject) {
const $row: JQuery = $(evt.currentTarget).is('tr') ? $(evt.currentTarget) : $(evt.currentTarget).closest('tr'),
$table: JQuery = $row.closest('table');
if ($row.is('.selected')) {
$row.removeClass('selected');
}
else {
$row.addClass('selected');
}
const $rows: JQuery = $table.find('tr.selected'),
$editControlsWrapper: JQuery = $('div.atum-order-item-bulk-edit');
if ($rows.length) {
// The Increase/Decrease stock buttons must be only visible when at least one product is selected
const $stockChangeButtons: JQuery = $('.bulk-decrease-stock, .bulk-increase-stock');
if ($('table.atum_order_items').find('tr.item.selected').length) {
$stockChangeButtons.show();
}
else {
$stockChangeButtons.hide();
}
$editControlsWrapper.slideDown();
}
else {
$editControlsWrapper.slideUp();
}
}
toggleExtraFields(evt: JQueryEventObject) {
const $atumOrderType: JQuery = $(evt.currentTarget),
typeValue: string = $atumOrderType.val();
$('[data-dependency]').each( (index: number, elem: Element) => {
const $elem: JQuery = $(elem),
dependency: string[] = $elem.data('dependency').split(':');
if (dependency[0] === $atumOrderType.attr('id')) {
if (dependency[1] === typeValue) {
$elem.fadeIn();
}
else if ($elem.is(':visible')) {
$elem.hide();
}
}
});
}
toggleSupplierField(evt: JQueryEventObject) {
const $checkbox: JQuery = $(evt.currentTarget),
$body: JQuery = $('body'),
$dropdown: JQuery = $('.dropdown_supplier'),
$dropdownWrapper: JQuery = $dropdown.parent();
if ($checkbox.is(':checked')) {
$dropdown.val('').change();
$body.addClass('allow-multiple-suppliers');
this.toggleItemsBlocker();
$dropdownWrapper.slideUp();
}
else {
$body.removeClass('allow-multiple-suppliers');
this.toggleItemsBlocker( $dropdown.val() !== null ); // Only block the items if there is no supplier selected.
$dropdownWrapper.slideDown();
}
}
toggleItemsBlocker(on: boolean = true) {
if (!this.$itemsBlocker.length) {
return;
}
if (on === true) {
this.$itemsBlocker.addClass('unblocked');
}
else {
this.$itemsBlocker.removeClass('unblocked');
}
}
importOrderItems() {
const $wcOrder: JQuery = $('#wc_order'),
orderId: number = $wcOrder.val();
if (!orderId || this.isEditable == 'false') {
return false;
}
this.swal({
text : this.settings.get('import_order_items'),
type : 'warning',
showCancelButton : true,
confirmButtonText: this.settings.get('continue'),
cancelButtonText : this.settings.get('cancel'),
reverseButtons : true,
allowOutsideClick: false,
preConfirm : (): Promise => {
return new Promise( (resolve: Function, reject: Function) => {
this.loadItemsTable({
action : 'atum_order_import_items',
wc_order_id : orderId,
atum_order_id: this.settings.get('post_id'),
security : this.settings.get('import_order_items_nonce'),
}, 'json', resolve);
});
},
}).catch(this.swal.noop);
}
}