website/hub/services/static/js/price-calculator/addon-manager.js

176 lines
6.9 KiB
JavaScript

/**
* Addon Manager - Handles addon functionality
*/
class AddonManager {
constructor(pricingDataManager) {
this.pricingDataManager = pricingDataManager;
}
// Update addons based on current configuration
updateAddons(domManager) {
const addonsContainer = domManager.get('addonsContainer');
const addonsData = this.pricingDataManager.getAddonsData();
if (!addonsContainer || !addonsData) {
// Hide addons section if no container or data
const addonsSection = document.getElementById('addonsSection');
if (addonsSection) addonsSection.style.display = 'none';
return;
}
const serviceLevel = domManager.getSelectedServiceLevel();
if (!serviceLevel || !addonsData[serviceLevel]) {
// Hide addons section if no service level or no addons for this level
const addonsSection = document.getElementById('addonsSection');
if (addonsSection) addonsSection.style.display = 'none';
return;
}
const addons = addonsData[serviceLevel];
// Clear existing addons
addonsContainer.innerHTML = '';
// Show or hide addons section based on availability
const addonsSection = document.getElementById('addonsSection');
if (addons && addons.length > 0) {
if (addonsSection) addonsSection.style.display = 'block';
} else {
if (addonsSection) addonsSection.style.display = 'none';
return;
}
// Add each addon
addons.forEach(addon => {
const addonElement = document.createElement('div');
addonElement.className = `addon-item mb-2 p-2 border rounded ${addon.is_mandatory ? 'bg-light' : ''}`;
addonElement.innerHTML = `
<div class="form-check">
<input class="form-check-input addon-checkbox"
type="checkbox"
id="addon-${addon.id}"
value="${addon.id}"
data-addon='${JSON.stringify(addon)}'
${addon.is_mandatory ? 'checked disabled' : ''}>
<label class="form-check-label" for="addon-${addon.id}">
<strong>${addon.name}</strong>
<div class="text-muted small">${addon.commercial_description || ''}</div>
<div class="text-primary addon-price-display">
${addon.is_mandatory ? 'Required - ' : ''}CHF <span class="addon-price-value">0.00</span>
</div>
</label>
</div>
`;
addonsContainer.appendChild(addonElement);
// Add event listener for optional addons
if (!addon.is_mandatory) {
const checkbox = addonElement.querySelector('.addon-checkbox');
checkbox.addEventListener('change', () => {
// Update addon prices and recalculate total
this.updateAddonPrices(domManager);
// Trigger pricing update through custom event
window.dispatchEvent(new CustomEvent('addon-changed'));
});
}
});
// Update addon prices
this.updateAddonPrices(domManager);
}
// Update addon prices based on current configuration
updateAddonPrices(domManager, planManager) {
const addonsContainer = domManager.get('addonsContainer');
if (!addonsContainer) return;
const config = domManager.getCurrentConfiguration();
// Find the current plan data to get variable_unit for addon calculations
const matchedPlan = planManager ? planManager.getCurrentPlan(domManager) : null;
const variableUnit = matchedPlan?.variable_unit || 'CPU';
const units = variableUnit === 'CPU' ? config.cpus : config.memory;
const totalUnits = units * config.instances;
const addonCheckboxes = addonsContainer.querySelectorAll('.addon-checkbox');
addonCheckboxes.forEach(checkbox => {
const addon = JSON.parse(checkbox.dataset.addon);
const priceElement = checkbox.parentElement.querySelector('.addon-price-value');
let calculatedPrice = 0;
// Calculate addon price based on type
if (addon.addon_type === 'BASE_FEE') {
// Base fee: price per instance
calculatedPrice = parseFloat(addon.price || 0) * config.instances;
} else if (addon.addon_type === 'UNIT_RATE') {
// Unit rate: price per unit (CPU or memory) across all instances
calculatedPrice = parseFloat(addon.price_per_unit || 0) * totalUnits;
}
// Update the display price
if (priceElement) {
priceElement.textContent = calculatedPrice.toFixed(2);
}
// Store the calculated price for later use in total calculations
checkbox.dataset.calculatedPrice = calculatedPrice.toString();
});
}
// Get selected addons with their calculated prices
getSelectedAddons(domManager) {
const addonsContainer = domManager.get('addonsContainer');
if (!addonsContainer) return { mandatory: [], optional: [] };
const mandatoryAddons = [];
const selectedOptionalAddons = [];
const addonCheckboxes = addonsContainer.querySelectorAll('.addon-checkbox');
addonCheckboxes.forEach(checkbox => {
const addon = JSON.parse(checkbox.dataset.addon);
const calculatedPrice = parseFloat(checkbox.dataset.calculatedPrice || 0);
if (addon.is_mandatory) {
mandatoryAddons.push({
name: addon.name,
price: calculatedPrice.toFixed(2)
});
} else if (checkbox.checked) {
selectedOptionalAddons.push({
name: addon.name,
price: calculatedPrice.toFixed(2)
});
}
});
return {
mandatory: mandatoryAddons,
optional: selectedOptionalAddons
};
}
// Calculate total optional addon price
calculateOptionalAddonTotal(domManager) {
const addonsContainer = domManager.get('addonsContainer');
if (!addonsContainer) return 0;
let total = 0;
const addonCheckboxes = addonsContainer.querySelectorAll('.addon-checkbox');
addonCheckboxes.forEach(checkbox => {
const addon = JSON.parse(checkbox.dataset.addon);
if (!addon.is_mandatory && checkbox.checked) {
const calculatedPrice = parseFloat(checkbox.dataset.calculatedPrice || 0);
total += calculatedPrice;
}
});
return total;
}
}
// Export for use in other modules
window.AddonManager = AddonManager;