Files
drmaterac.pl/iadmin/themes/new-theme/js/product-page/product-bulk-combinations.js
2025-03-21 20:24:43 +01:00

303 lines
9.9 KiB
JavaScript

/**
* Combination bulk actions management
*/
export default function () {
const bulkForm = $('#bulk-combinations-container');
const deleteCombinationsBtn = $('#delete-combinations');
const applyChangesBtn = $('#apply-on-combinations');
const syncedCollection = $('[data-uniqid]');
const finalPrice = $('#form_step2_price');
const finalPriceIT = $('#form_step2_price_ttc');
const finalPriceBasics = $('#form_step1_price_shortcut');
const finalPriceBasicsIT = $('#form_step1_price_ttc_shortcut');
const ecotaxTI = $('#form_step2_ecotax');
return {
init: function init() {
const that = this;
// stop propagation on buttons
deleteCombinationsBtn.on('click', (event) => {
event.preventDefault();
that.deleteCombinations();
});
applyChangesBtn.on('click', (event) => {
event.preventDefault();
that.applyChangesOnCombinations()
.hideForm()
.resetForm()
.unselectCombinations()
.submitUpdate();
});
/* if final price change with user interaction, combinations should be impacted */
finalPrice.on('blur', () => {
this.syncToPricingTab();
});
finalPriceIT.on('blur', () => {
this.syncToPricingTab();
});
/* if we use final price shortcuts, also combinations should be impacted */
finalPriceBasics.on('blur', () => {
this.syncToPricingTab();
});
finalPriceBasicsIT.on('blur', () => {
this.syncToPricingTab();
});
ecotaxTI.on('blur', () => {
this.syncToPricingTab();
});
syncedCollection.on('DOMSubtreeModified', (event) => {
const uniqid = event.target.getAttribute('data-uniqid');
const newValue = event.target.innerText;
const spans = $(`[data-uniqid="${uniqid}"]`);
spans.each(function () {
if ($(this).text() !== newValue) {
$(this).text(newValue);
}
});
});
// bulk select animation
$('#toggle-all-combinations').on('change', (event) => {
$('#accordion_combinations td:first-child input[type="checkbox"]').each(function () {
$(this).prop('checked', $(event.currentTarget).prop('checked'));
});
});
$(document).on('change', '.js-combination', () => {
if ($('.bulk-action').attr('aria-expanded') === 'false' || !$('.js-combination').is(':checked')) {
$('.js-collapse').collapse('toggle');
}
$('span.js-bulk-combinations').text($('input.js-combination:checked').length);
});
},
getSelectedCombinations: function getSelectedCombinations() {
const combinations = [];
const selectedCombinations = Array.from(
$('#accordion_combinations td:first-child input[type="checkbox"]:checked'),
);
selectedCombinations.forEach((combination) => {
const combinationId = combination.getAttribute('data-id');
const combinationIndex = combination.getAttribute('data-index');
combinations.push(new Combination(combinationId, combinationIndex));
});
return combinations;
},
applyChangesOnCombinations: function applyChangesOnCombinations() {
const values = this.getFormValues();
const combinations = this.getSelectedCombinations();
combinations.forEach((combination) => {
combination.updateForm(values);
combination.syncValues(values);
});
return this;
},
deleteCombinations: function deleteCombinations() {
const combinations = this.getSelectedCombinations();
const combinationsIds = [];
combinations.forEach((combination) => {
combinationsIds.push(combination.domId);
});
window.modalConfirmation.create(
window.translate_javascripts['Are you sure you want to delete the selected item(s)?'],
null,
{
onContinue() {
const deletionURL = $(deleteCombinationsBtn).attr('data');
$.ajax({
type: 'DELETE',
data: {
'attribute-ids': combinationsIds,
},
url: deletionURL,
beforeSend() {
$('#create-combinations, #apply-on-combinations, #submit, .btn-submit').attr('disabled', 'disabled');
},
success(response) {
window.showSuccessMessage(response.message);
window.refreshTotalCombinations(-1, combinationsIds.length);
$('span.js-bulk-combinations').text('0');
combinationsIds.forEach((combinationId) => {
const combination = new Combination(combinationId);
combination.removeFromDOM();
});
window.displayFieldsManager.refresh();
},
error(response) {
window.showErrorMessage(jQuery.parseJSON(response.responseText).message);
},
complete() {
$('#create-combinations, #apply-on-combinations, #submit, .btn-submit').removeAttr('disabled');
},
});
},
}).show();
},
getFormValues: function getFormValues() {
const values = [];
$(bulkForm).find('input').each(function () {
if ($(this).val() !== '' && $(this).attr('id') !== 'product_combination_bulk__token') {
values.push({
id: $(this).attr('id'),
value: $(this).val(),
});
}
});
return values;
},
resetForm: function resetForm() {
bulkForm.find('input').val('');
return this;
},
unselectCombinations: function unselectCombinations() {
// Use of the bulk action button. It has an event listener to unselect all the combinations
$('#toggle-all-combinations').prop('checked', false);
return this;
},
hideForm: function toggleForm() {
bulkForm.collapse('hide');
return this;
},
submitUpdate: function submitUpdate() {
const globalProductSubmitButton = $('#form'); // @todo: choose a better identifier
globalProductSubmitButton.submit();
},
syncToPricingTab: function syncToPricingTab() {
$('tr.combination').toArray().forEach((item) => {
const tableRow = $(`#${item.id}`);
// We need this because there is a specific data="smthg" attribute so we can't use data() function
const attributeId = tableRow.attr('data');
// Get combination final price value from combination form
const combinationFinalPrice = window.priceCalculation.getCombinationFinalPriceTaxExcludedById(attributeId);
const combinationFinalPriceLabel = tableRow.find('.attribute-finalprice span.final-price');
combinationFinalPriceLabel.html(combinationFinalPrice);
// Update ecotax preview (tax included)
let combinationEcotaxTI = window.priceCalculation.getCombinationEcotaxTaxIncludedById(attributeId);
if (combinationEcotaxTI === 0) {
combinationEcotaxTI = window.priceCalculation.getProductEcotaxTaxIncluded();
}
const ecoTaxLabel = tableRow.find('.attribute-finalprice span.attribute-ecotax');
ecoTaxLabel.html(Number(window.ps_round(combinationEcotaxTI, 2)).toFixed(2)); // 2 digits for short
const ecoTaxPreview = tableRow.find('.attribute-finalprice .attribute-ecotax-preview');
ecoTaxPreview.toggleClass('d-none', Number(combinationEcotaxTI) === 0);
});
},
};
}
class Combination {
constructor(domId, index) {
this.inputBulkPattern = 'product_combination_bulk_';
this.inputPattern = `combination_${index}_`;
this.domId = domId;
this.appId = `attribute_${this.domId}`;
this.element = $(`#${this.appId}`);
this.form = $(`#combination_form_${this.domId}`);
}
isSelected() {
return this.element.checked;
}
removeFromDOM() {
$(this.element).remove();
}
updateForm(values) {
values.forEach((valueObject) => {
const valueId = valueObject.id.substr(this.inputBulkPattern.length);
const $field = $(`#${this.convertInput(valueId)}`);
if ($field.is(':checkbox')) {
$field.prop('checked', !!valueObject.value);
} else {
$field.val(valueObject.value);
}
});
return this.form;
}
/**
* Returns the related input field in legacy form from
* bulk form field
*
* @param bulkInput
* @returns {string}
*/
convertInput(bulkInput) {
let convertedInput = '';
switch (bulkInput) {
case 'quantity':
case 'reference':
case 'minimal_quantity':
case 'low_stock_threshold':
case 'low_stock_alert':
convertedInput = `${this.inputPattern}attribute_${bulkInput}`;
break;
case 'cost_price':
convertedInput = `${this.inputPattern}attribute_wholesale_price`;
break;
case 'date_availability':
convertedInput = `${this.inputPattern}available_date_attribute`;
break;
case 'impact_on_weight':
convertedInput = `${this.inputPattern}attribute_weight`;
break;
case 'impact_on_price_te':
convertedInput = `${this.inputPattern}attribute_price`;
break;
case 'impact_on_price_ti':
convertedInput = `${this.inputPattern}attribute_priceTI`;
break;
default:
}
return convertedInput;
}
/**
* Sync values with fast bulk edit form of each combination
*
* @param values
* @returns {bool}
*/
syncValues(values) {
values.forEach((valueObject) => {
let valueId = valueObject.id.substr(this.inputBulkPattern.length);
const {value} = valueObject;
const syncedProperties = [
'quantity',
'impact_on_price_te',
];
if (syncedProperties.indexOf(valueId) !== -1) {
valueId = valueId === 'quantity' ? 'quantity' : 'price';
const input = $(`#attribute_${this.domId} .attribute-${valueId} input`);
input.val(value);
input.change();
}
});
return true;
}
}