176 lines
6.9 KiB
JavaScript
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;
|