Skip to content

Commit

Permalink
fix(pci-block-storage): use 730 hours for monthly price
Browse files Browse the repository at this point in the history
ref: TAPC-2177

Signed-off-by: Simon Chaumet <[email protected]>
  • Loading branch information
SimonChaumet committed Dec 11, 2024
1 parent 53bf8c0 commit 46a1bc0
Show file tree
Hide file tree
Showing 12 changed files with 30 additions and 130 deletions.
2 changes: 1 addition & 1 deletion packages/manager/apps/pci-block-storage/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"@ovh-ux/manager-config": "^8.0.1",
"@ovh-ux/manager-core-api": "^0.9.0",
"@ovh-ux/manager-pci-common": "^0.13.0",
"@ovh-ux/manager-react-components": "^1.41.2",
"@ovh-ux/manager-react-components": "^1.43.0",
"@ovh-ux/manager-react-core-application": "^0.11.3",
"@ovh-ux/manager-react-shell-client": "^0.8.3",
"@ovh-ux/manager-tailwind-config": "^0.2.1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
"pci_projects_project_storages_blocks_block_volume-edit_size_label": "Volume-Kapazität:",
"pci_projects_project_storages_blocks_block_volume-edit_size_help": "Die maximale Größe ist von Ihrem verfügbaren Quota abhängig.",
"pci_projects_project_storages_blocks_block_volume-edit_size_unit": "GB",
"pci_projects_project_storages_blocks_block_volume-edit_price_text": "Geschätzter Betrag: {{ price }} / Monat (zzgl. MwSt.)",
"pci_projects_project_storages_blocks_block_volume-edit_bootable_label": "Bootfähig",
"pci_projects_project_storages_blocks_block_volume-edit_bootable_help": "Indem Sie ein Volume als bootfähig definieren, kann es für den Start Ihrer Instanz verwendet werden.",
"pci_projects_project_storages_blocks_block_volume-edit_cancel_label": "Abbrechen"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
"pci_projects_project_storages_blocks_block_volume-edit_size_label": "Volume capacity",
"pci_projects_project_storages_blocks_block_volume-edit_size_help": "The maximum size depends on your available quota.",
"pci_projects_project_storages_blocks_block_volume-edit_size_unit": "GB",
"pci_projects_project_storages_blocks_block_volume-edit_price_text": "Estimated amount: {{price}} ex. VAT/month",
"pci_projects_project_storages_blocks_block_volume-edit_bootable_label": "Bootable",
"pci_projects_project_storages_blocks_block_volume-edit_bootable_help": "By defining a volume as bootable, you can use the volume when your instance is booted.",
"pci_projects_project_storages_blocks_block_volume-edit_cancel_label": "Cancel"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
"pci_projects_project_storages_blocks_block_volume-edit_size_label": "Capacidad del volumen",
"pci_projects_project_storages_blocks_block_volume-edit_size_help": "El tamaño máximo depende de la cuota de su proyecto.",
"pci_projects_project_storages_blocks_block_volume-edit_size_unit": "GB",
"pci_projects_project_storages_blocks_block_volume-edit_price_text": "Importe estimado: {{ price }}/mes + IVA",
"pci_projects_project_storages_blocks_block_volume-edit_bootable_label": "Vol. de arranque",
"pci_projects_project_storages_blocks_block_volume-edit_bootable_help": "Definir un volumen como volumen de arranque permite utilizar dicho volumen al iniciar la instancia.",
"pci_projects_project_storages_blocks_block_volume-edit_cancel_label": "Cancelar"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
"pci_projects_project_storages_blocks_block_volume-edit_size_label": "Capacité du volume",
"pci_projects_project_storages_blocks_block_volume-edit_size_help": "La taille maximale dépend de votre quota disponible.",
"pci_projects_project_storages_blocks_block_volume-edit_size_unit": "Go",
"pci_projects_project_storages_blocks_block_volume-edit_price_text": "Montant estimé : {{ price }} HT/mois",
"pci_projects_project_storages_blocks_block_volume-edit_bootable_label": "Amorçable",
"pci_projects_project_storages_blocks_block_volume-edit_bootable_help": "Définir un volume comme amorçable permet d'utiliser ce volume au démarrage de votre instance.",

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
"pci_projects_project_storages_blocks_block_volume-edit_size_label": "Capacité du volume",
"pci_projects_project_storages_blocks_block_volume-edit_size_help": "La taille maximale dépend de votre quota disponible.",
"pci_projects_project_storages_blocks_block_volume-edit_size_unit": "Go",
"pci_projects_project_storages_blocks_block_volume-edit_price_text": "Montant estimé : {{ price }} HT/mois",
"pci_projects_project_storages_blocks_block_volume-edit_bootable_label": "Amorçable",
"pci_projects_project_storages_blocks_block_volume-edit_bootable_help": "Définir un volume comme amorçable permet d'utiliser ce volume au démarrage de votre instance.",

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
"pci_projects_project_storages_blocks_block_volume-edit_size_label": "Capacità del volume",
"pci_projects_project_storages_blocks_block_volume-edit_size_help": "La dimensione massima dipende dalla quota disponibile.",
"pci_projects_project_storages_blocks_block_volume-edit_size_unit": "GB",
"pci_projects_project_storages_blocks_block_volume-edit_price_text": "Importo stimato: {{ price }} +IVA/mese",
"pci_projects_project_storages_blocks_block_volume-edit_bootable_label": "Boot",
"pci_projects_project_storages_blocks_block_volume-edit_bootable_help": "Definire un volume come “boot” permette di utilizzare questo disco all’avvio della tua istanza.",
"pci_projects_project_storages_blocks_block_volume-edit_cancel_label": "Annullare"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
"pci_projects_project_storages_blocks_block_volume-edit_size_label": "Rozmiar wolumenu",
"pci_projects_project_storages_blocks_block_volume-edit_size_help": "Maksymalny rozmiar zależy od dostępnego limitu.",
"pci_projects_project_storages_blocks_block_volume-edit_size_unit": "GB",
"pci_projects_project_storages_blocks_block_volume-edit_price_text": "Szacowana kwota: {{ price }} netto/m-c",
"pci_projects_project_storages_blocks_block_volume-edit_bootable_label": "Bootowalny",
"pci_projects_project_storages_blocks_block_volume-edit_bootable_help": "Zdefiniowanie wolumenu jako bootowalnego pozwala używać go przy uruchamianiu Twojej instancji.",
"pci_projects_project_storages_blocks_block_volume-edit_cancel_label": "Anuluj"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
"pci_projects_project_storages_blocks_block_volume-edit_size_label": "Capacidade do volume",
"pci_projects_project_storages_blocks_block_volume-edit_size_help": "O tamanho máximo depende do seu limite disponível.",
"pci_projects_project_storages_blocks_block_volume-edit_size_unit": "GB",
"pci_projects_project_storages_blocks_block_volume-edit_price_text": "Montante estimado: {{ price }}/mês + IVA",
"pci_projects_project_storages_blocks_block_volume-edit_bootable_label": "Volume de arranque",
"pci_projects_project_storages_blocks_block_volume-edit_bootable_help": "Definir um volume como volume de arranque permite utilizar esse volume ao iniciar a instância.",
"pci_projects_project_storages_blocks_block_volume-edit_cancel_label": "Anular"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
import { useMemo } from 'react';
import { applyFilters, Filter } from '@ovh-ux/manager-core-api';
import {
useCatalogPrice,
useTranslatedMicroRegions,
} from '@ovh-ux/manager-react-components';
import { useTranslatedMicroRegions } from '@ovh-ux/manager-react-components';
import { useMutation, useQuery } from '@tanstack/react-query';
import { useProject } from '@ovh-ux/manager-pci-common';
import { TPricing } from '@/api/data/catalog';
import {
addVolume,
AddVolumeProps,
Expand All @@ -23,7 +18,6 @@ import {
updateVolume,
VolumeOptions,
} from '@/api/data/volume';
import { useCatalog } from '@/api/hooks/useCatalog';
import { UCENTS_FACTOR } from '@/hooks/currency-constants';
import queryClient from '@/queryClient';

Expand Down Expand Up @@ -265,70 +259,6 @@ export const useUpdateVolume = ({
};
};

export const usePriceTransformer = () => {
const { getFormattedCatalogPrice } = useCatalogPrice();
return (price: TPricing, currencyCode: string) => ({
...price,
priceInUcents: price.price,
intervalUnit: price.interval,
price: {
currencyCode,
text: getFormattedCatalogPrice(price.price?.value),
value: convertUcentsToCurrency(price.price?.value),
},
});
};

export const useGetPrices = (projectId: string, volumeId: string) => {
const { data: project } = useProject(projectId);
const { data: catalog } = useCatalog();
const { data: volume } = useVolume(projectId, volumeId);

const priceFormatter = usePriceTransformer();

if (project && catalog) {
const projectPlan = catalog.plans.find(
(plan) => plan.planCode === project.planCode,
);

if (!projectPlan) {
throw new Error('Fail to get project plan');
}

const pricesMap = {};

projectPlan.addonFamilies.forEach((family) => {
family.addons.forEach((planCode) => {
const addon = catalog.addons.find(
(addonCatalog) => addonCatalog.planCode === planCode,
);

const pricing =
addon?.pricings.find(
({ capacities }) =>
capacities.includes('renew') ||
capacities.includes('consumption'),
) || ({} as TPricing);

pricesMap[planCode] = priceFormatter(
pricing as TPricing,
catalog.locale.currencyCode,
);
});
});

if (volume) {
const relatedCatalog =
pricesMap[`volume.${volume.type}.consumption.${volume.region}`] ||
pricesMap[`volume.${volume.type}.consumption`];

return relatedCatalog;
}
}

return {};
};

type UseAddVolumeProps = AddVolumeProps & {
onError: (cause: Error) => void;
onSuccess: () => void;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { useEffect, useState } from 'react';
import { useEffect, useMemo, useState } from 'react';
import { useHref, useNavigate, useParams } from 'react-router-dom';
import { Translation, useTranslation } from 'react-i18next';
import {
Headers,
useCatalogPrice,
useNotifications,
useProjectLocalRegions,
useProjectUrl,
Expand All @@ -22,7 +21,6 @@ import {
ODS_ICON_SIZE,
ODS_INPUT_SIZE,
ODS_INPUT_TYPE,
ODS_SKELETON_SIZE,
ODS_SPINNER_SIZE,
ODS_TEXT_LEVEL,
} from '@ovhcloud/ods-components';
Expand All @@ -33,22 +31,19 @@ import {
OsdsIcon,
OsdsInput,
OsdsQuantity,
OsdsSkeleton,
OsdsSpinner,
OsdsText,
} from '@ovhcloud/ods-components/react';
import { useProject } from '@ovh-ux/manager-pci-common';
import { VOLUME_MIN_SIZE, VOLUME_UNLIMITED_QUOTA } from '@/constants';
import ChipRegion from '@/components/edit/ChipRegion.component';
import { TVolume } from '@/api/data/volume';
import {
useGetPrices,
useUpdateVolume,
useVolume,
} from '@/api/hooks/useVolume';
import { useUpdateVolume, useVolume } from '@/api/hooks/useVolume';
import HidePreloader from '@/core/HidePreloader';
import { useVolumeMaxSize } from '@/api/data/quota';
import { useRegionsQuota } from '@/api/hooks/useQuota';
import { PriceEstimate } from '@/pages/new/components/PriceEstimate';
import { useCatalog } from '@/api/hooks/useCatalog';

type TFormState = {
name: string;
Expand Down Expand Up @@ -82,16 +77,24 @@ export default function EditPage() {

const projectUrl = useProjectUrl('public-cloud');
const { data: project } = useProject(projectId || '');
const catalogPrice = useGetPrices(projectId, volumeId);
const { translateMicroRegion } = useTranslatedMicroRegions();

const { getTextPrice } = useCatalogPrice(3);

const {
data: volume,
isLoading: isLoadingVolume,
isPending: isPendingVolume,
} = useVolume(projectId, volumeId);
const { data: catalog } = useCatalog();

const catalogVolume = useMemo(() => {
if (!!catalog && !!volume) {
return (
catalog.addons.find((addon) => addon.planCode === volume.planCode) ||
null
);
}
return null;
}, [catalog, volume]);

const { volumeMaxSize } = useVolumeMaxSize(volume?.region);

Expand Down Expand Up @@ -171,19 +174,6 @@ export default function EditPage() {
return volumeMaxSize;
};

const getVolumePriceEstimationFromCatalog = (
price: { priceInUcents: number },
volumeSize: number,
) => {
const hourlyEstimation = volumeSize * price.priceInUcents;
const monthlyEstimation = hourlyEstimation * 30 * 24;

return {
hourly: hourlyEstimation,
monthly: monthlyEstimation,
};
};

const isLoading =
isLoadingVolume ||
isPendingVolume ||
Expand Down Expand Up @@ -216,11 +206,6 @@ export default function EditPage() {
updateVolume();
}
};

const estimatedPrice =
catalogPrice &&
formState.size.value >= 0 &&
getVolumePriceEstimationFromCatalog(catalogPrice, formState.size.value);
const hasError = errorState.isMinError || errorState.isMaxError;

return (
Expand Down Expand Up @@ -438,22 +423,14 @@ export default function EditPage() {
</OsdsText>
</div>

{!hasError &&
(estimatedPrice?.monthly !== undefined ? (
<OsdsText
level={ODS_THEME_TYPOGRAPHY_LEVEL.body}
size={ODS_THEME_TYPOGRAPHY_SIZE._400}
color={ODS_THEME_COLOR_INTENT.text}
className="block mb-6"
>
{tVolumeEdit(
'pci_projects_project_storages_blocks_block_volume-edit_price_text',
{ price: getTextPrice(estimatedPrice.monthly) },
)}
</OsdsText>
) : (
<OsdsSkeleton inline size={ODS_SKELETON_SIZE.md} />
))}
{!hasError && !!catalogVolume && (
<div className="mb-6">
<PriceEstimate
volumeCapacity={formState.size.value}
volumeType={catalogVolume}
/>
</div>
)}

{errorState.isMinError && (
<OsdsText
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,17 @@ import {
ODS_THEME_TYPOGRAPHY_LEVEL,
ODS_THEME_TYPOGRAPHY_SIZE,
} from '@ovhcloud/ods-common-theming';
import { useCatalogPrice } from '@ovh-ux/manager-react-components';
import {
useCatalogPrice,
convertHourlyPriceToMonthly,
} from '@ovh-ux/manager-react-components';
import { TAddon } from '@ovh-ux/manager-pci-common';

export interface PriceEstimateProps {
volumeCapacity: number;
volumeType: TAddon;
}

const ESTIMATE_MONTHLY_HOURS = 24 * 30;

export function PriceEstimate({
volumeCapacity,
volumeType,
Expand All @@ -25,7 +26,7 @@ export function PriceEstimate({
});
const { price } =
volumeType?.pricings?.find(({ type }) => type === 'consumption') || {};
const priceEstimate = price * volumeCapacity * ESTIMATE_MONTHLY_HOURS;
const priceEstimate = convertHourlyPriceToMonthly(price * volumeCapacity);

return (
<OsdsText
Expand Down

0 comments on commit 46a1bc0

Please sign in to comment.