refactor price calculator into multiple files
This commit is contained in:
parent
33e8f2152a
commit
67e1b4cab1
8 changed files with 1324 additions and 1877 deletions
176
hub/services/static/js/price-calculator/addon-manager.js
Normal file
176
hub/services/static/js/price-calculator/addon-manager.js
Normal file
|
@ -0,0 +1,176 @@
|
|||
/**
|
||||
* 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;
|
Loading…
Add table
Add a link
Reference in a new issue