diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 3dd1f66f9..78e64002e 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -23,7 +23,7 @@ jobs: with: fetch-depth: 1 - name: Setup Go - uses: WillAbides/setup-go-faster@v1.11.0 + uses: WillAbides/setup-go-faster@v1.12.0 with: go-version: 1.19 - name: Static Check diff --git a/admin-ui/src/App.vue b/admin-ui/src/App.vue index aaeb09ee7..bc86a482c 100644 --- a/admin-ui/src/App.vue +++ b/admin-ui/src/App.vue @@ -259,7 +259,7 @@ - + @@ -276,7 +276,6 @@ - diff --git a/admin-ui/src/components/account/info.vue b/admin-ui/src/components/account/info.vue index 04f99a03a..11aac9850 100644 --- a/admin-ui/src/components/account/info.vue +++ b/admin-ui/src/components/account/info.vue @@ -1,17 +1,30 @@ diff --git a/admin-ui/src/components/modules/ione/additionalInstanceInfo.vue b/admin-ui/src/components/modules/ione/additionalInstanceInfo.vue index a78b9237e..a37e1e8eb 100644 --- a/admin-ui/src/components/modules/ione/additionalInstanceInfo.vue +++ b/admin-ui/src/components/modules/ione/additionalInstanceInfo.vue @@ -4,7 +4,7 @@ diff --git a/admin-ui/src/components/modules/ione/billingInfo.vue b/admin-ui/src/components/modules/ione/billingInfo.vue index 5179cf814..6771648eb 100644 --- a/admin-ui/src/components/modules/ione/billingInfo.vue +++ b/admin-ui/src/components/modules/ione/billingInfo.vue @@ -13,28 +13,15 @@ - - - - - - - > - - - Prices - - - - - - - - - - + + + + + + + + + { billingItems.value = getBillingItems(); - price.value = totalPrice.value; - fetchAccountRate(accountCurrency); }); const date = computed(() => - formatSecondsToDate( - +template.value?.data?.last_monitoring + - +template.value.billingPlan.products[template.value.product].period - ) + formatSecondsToDate(+template.value?.data?.next_payment_date) ); const defaultCurrency = computed(() => store.getters["currencies/default"]); const isMonitoringEmpty = computed(() => date.value === "-"); @@ -262,9 +230,11 @@ const totalAccountPrice = computed(() => toAccountPrice(totalPrice.value)); const getBillingItems = () => { const items = []; + const price = billingPlan.value.products[template.value.product]?.price; items.push({ name: template.value.product, - price: billingPlan.value.products[template.value.product]?.price, + price, + accountPrice: toAccountPrice(price), path: `billingPlan.products.${template.value.product}.price`, quantity: 1, unit: "pcs", @@ -286,6 +256,7 @@ const getBillingItems = () => { items.push({ name: resourceKey, price: addon.price, + accountPrice: toAccountPrice(addon.price), kind: addon.kind, period: addon.period, quantity, @@ -305,6 +276,7 @@ const getBillingItems = () => { items.push({ name: driveType, price: drive?.price, + accountPrice: toAccountPrice(drive.price), path: `billingPlan.resources.${driveIndex}.price`, kind: drive?.kind, quantity: template.value.resources.drive_size / 1024, @@ -347,7 +319,6 @@ watch(accountRate, () => { i.accountPrice = toAccountPrice(i.price); return i; }); - accountPrice.value = totalAccountPrice.value; }); diff --git a/admin-ui/src/components/modules/ione/billingLabel.vue b/admin-ui/src/components/modules/ione/billingLabel.vue index c4a42ba27..77bd514a0 100644 --- a/admin-ui/src/components/modules/ione/billingLabel.vue +++ b/admin-ui/src/components/modules/ione/billingLabel.vue @@ -5,6 +5,7 @@ :addons-price="addonsPrice" :tariff-price="tariffPrice" :due-date="dueDate" + @update="emit('update', $event)" /> @@ -15,6 +16,7 @@ import { useStore } from "@/store"; import billingLabel from "@/components/ui/billingLabel.vue"; const props = defineProps(["template"]); +const emit = defineEmits(["update"]); const store = useStore(); @@ -64,10 +66,7 @@ const addonsPrice = ref( ); const dueDate = computed(() => { - return formatSecondsToDate( - +template.value?.data?.last_monitoring + - +template.value.billingPlan.products[template.value.product].period - ); + return formatSecondsToDate(+template.value?.data?.next_payment_date); }); diff --git a/admin-ui/src/components/modules/ione/planConfiguration.vue b/admin-ui/src/components/modules/ione/planConfiguration.vue index f02128e5a..ecf7345a8 100644 --- a/admin-ui/src/components/modules/ione/planConfiguration.vue +++ b/admin-ui/src/components/modules/ione/planConfiguration.vue @@ -5,6 +5,7 @@ @@ -12,6 +13,7 @@ @@ -54,7 +56,7 @@ export default { }, }, mounted() { - this.meta=this.template.meta + this.meta = this.template.meta; }, watch: { "template.meta"(newVal) { @@ -64,4 +66,4 @@ export default { }; - \ No newline at end of file + diff --git a/admin-ui/src/components/modules/openai/billingInfo.vue b/admin-ui/src/components/modules/openai/billingInfo.vue index b8f29235f..783665662 100644 --- a/admin-ui/src/components/modules/openai/billingInfo.vue +++ b/admin-ui/src/components/modules/openai/billingInfo.vue @@ -90,7 +90,7 @@ import { watch, } from "vue"; import NocloudTable from "@/components/table.vue"; -import useAccountConverter from "@/hooks/useAccountConverter"; +import useInstancePrices from "@/hooks/useInstancePrices"; import { useStore } from "@/store"; import api from "@/api"; @@ -101,12 +101,11 @@ const { template, plans, service } = toRefs(props); const store = useStore(); const { - fetchAccountRate, accountCurrency, toAccountPrice, accountRate, fromAccountPrice, -} = useAccountConverter(template.value); +} = useInstancePrices(template.value); const priceModelDialog = ref(false); const newPlan = ref(); @@ -121,7 +120,6 @@ const billingHeaders = ref([ onMounted(() => { billingItems.value = getBillingItems(); - fetchAccountRate(accountCurrency); }); const filteredPlans = computed(() => plans.value.filter((p) => p.type === "openai") diff --git a/admin-ui/src/components/modules/ovh/additionalInstanceInfo.vue b/admin-ui/src/components/modules/ovh/additionalInstanceInfo.vue index e41be9376..f9b3c61a6 100644 --- a/admin-ui/src/components/modules/ovh/additionalInstanceInfo.vue +++ b/admin-ui/src/components/modules/ovh/additionalInstanceInfo.vue @@ -24,11 +24,11 @@ @click:append="isVisible = !isVisible" /> + + - - diff --git a/admin-ui/src/components/modules/ovh/billingInfo.vue b/admin-ui/src/components/modules/ovh/billingInfo.vue index d78d972eb..accb6357b 100644 --- a/admin-ui/src/components/modules/ovh/billingInfo.vue +++ b/admin-ui/src/components/modules/ovh/billingInfo.vue @@ -13,28 +13,12 @@ - - - - - - - - - Prices - - - + + { const prices = {}; const planCodeCurr = meta.plans.find((p) => planCode.value === p.planCode); - prices["tarrif"] = getPriceFromProduct(planCodeCurr); + prices[planCode.value] = getPriceFromProduct(planCodeCurr); addons.value.forEach((addon) => { Object.keys(meta).forEach((metaKey) => { const product = @@ -262,7 +231,7 @@ const getDedicatedPrice = async () => { const prices = {}; const planCodeCurr = meta.plans.find((p) => planCode.value === p.planCode); - prices["tarrif"] = getPriceFromProduct(planCodeCurr); + prices[planCode.value] = getPriceFromProduct(planCodeCurr); const addonsPrice = await api.servicesProviders.action({ action: "get_baremetal_options", uuid: template.value.sp, @@ -304,7 +273,7 @@ const getCloudPrices = async () => { projectId: fullSp.vars?.projectId?.value?.default, }, }); - prices["tarrif"] = meta.codes[tarrif.value?.meta?.priceCode]; + prices[planCode.value] = meta.codes[tarrif.value?.meta?.priceCode]; return prices; }; const getPriceFromProduct = (product) => { @@ -328,23 +297,18 @@ const getAddonKey = (key) => { }; const date = computed(() => { - if (type.value === "cloud") { - return formatSecondsToDate( - +template.value?.data?.last_monitoring + +tarrif.value.period - ); - } - - return template.value.data.expiration; + return formatSecondsToDate(+template.value?.data?.next_payment_date); }); const initPrices = () => { pricesItems.value.push({ - title: "tarrif", - key: "tarrif", + title: planCode.value, + key: planCode.value, ind: 0, path: `billingPlan.products.${[duration.value, planCode.value].join( " " )}.price`, + kind: tarrif.value.kind, price: tarrif.value?.price, period: tarrif.value?.period, }); @@ -354,19 +318,26 @@ const initPrices = () => { (p) => p.key === getAddonKey(key) ); + const addon = template.value.billingPlan.resources[addonIndex]; + + if (!addon) { + return; + } + pricesItems.value.push({ - price: template.value.billingPlan.resources[addonIndex]?.price || 0, + price: addon.price || 0, path: `billingPlan.resources.${addonIndex}.price`, title: key, + kind: addon.kind, key: key, index: ind + 1, - period: template.value.billingPlan.resources[addonIndex]?.period, + period: addon.period, }); }); pricesItems.value = pricesItems.value.map((i) => { i.period = getBillingPeriod(i.period); - i.accountPrice = i.price * accountRate.value; + i.accountPrice = toAccountPrice(i.price); return i; }); @@ -386,20 +357,6 @@ const tarrif = computed(() => { } return template.value.billingPlan.products[key]; }); -const getPrice = computed(() => { - const prices = []; - prices.push(tarrif.value?.price); - addons.value.forEach((name) => { - prices.push( - template.value.billingPlan.resources.find( - (p) => - p.key === [duration.value, planCode, name].join(" ") || - p.key === [duration.value, name].join(" ") - )?.price || 0 - ); - }); - return prices.reduce((acc, val) => acc + val, 0); -}); const service = computed(() => store.getters["services/all"].find((s) => s.uuid === template.value.service) @@ -431,14 +388,6 @@ const getBasePrices = async () => { onMounted(() => { initPrices(); getBasePrices(); - if (accountCurrency.value) { - fetchAccountRate(accountCurrency.value).then(() => { - pricesItems.value = pricesItems.value.map((i) => { - i.accountPrice = toAccountPrice(i.price); - return i; - }); - }); - } }); diff --git a/admin-ui/src/components/modules/ovh/billingLabel.vue b/admin-ui/src/components/modules/ovh/billingLabel.vue index c702d8a9b..da8f9b37a 100644 --- a/admin-ui/src/components/modules/ovh/billingLabel.vue +++ b/admin-ui/src/components/modules/ovh/billingLabel.vue @@ -5,6 +5,7 @@ :template="template" :addons-price="addonsPrice" :account="account" + @update="emit('update', $event)" /> @@ -15,6 +16,7 @@ import billingLabel from "@/components/ui/billingLabel.vue"; import { useStore } from "@/store"; const props = defineProps(["template"]); +const emit = defineEmits(["update"]); const { template } = toRefs(props); @@ -31,16 +33,7 @@ const account = computed(() => { }); const dueDate = computed(() => { - const { duration, planCode } = props.template.config; - const key = `${duration} ${planCode}`; - if (props.template.config.type === "cloud") { - return formatSecondsToDate( - +props.template?.data?.last_monitoring + - +props.template.billingPlan.products[key].period - ); - } - - return props.template.data.expiration; + return formatSecondsToDate(+props.template?.data?.next_payment_date); }); const tariffPrice = computed(() => { diff --git a/admin-ui/src/components/modules/ovh/instanceCreate.vue b/admin-ui/src/components/modules/ovh/instanceCreate.vue index fda46bfa4..7a927c4f3 100644 --- a/admin-ui/src/components/modules/ovh/instanceCreate.vue +++ b/admin-ui/src/components/modules/ovh/instanceCreate.vue @@ -164,8 +164,8 @@ const getDefaultInstance = () => ({ vps_datacenter: null, vps_os: null, }, - duration: "P1M", - pricingMode: "default", + duration: "", + pricingMode: "", addons: [], }, data: { existing: false }, @@ -193,7 +193,6 @@ export default { regions: {}, images: {}, addons: {}, - durationItems: ["P1H", "P1M", "P1Y"], ovhTypes: [ { title: "ovh vps", value: "vps" }, @@ -247,6 +246,7 @@ export default { this.addons[planCode] = newAddons; }, setValue(path, val) { + console.log(path, val); const data = JSON.parse(JSON.stringify(this.instance)); if (path.includes("billing_plan")) { @@ -321,7 +321,10 @@ export default { } if (path.includes("duration")) { - data.config.pricingMode = val === "P1M" ? "default" : "upfront12"; + this.$emit("set-value", { + value: val === "P1Y" ? "upfront12" : "default", + key: "config.pricingMode", + }); } if (path.includes("addons")) { @@ -371,13 +374,10 @@ export default { return this.instance.config.addons.find((a) => addon.includes(a)); }, setProduct() { - const data = JSON.parse(JSON.stringify(this.instance)); - if (data.billing_plan?.kind?.toLowerCase() === "static") { - this.$emit("set-value", { - value: `${data.config?.duration} ${data.config?.planCode}`, - key: "product", - }); - } + this.$emit("set-value", { + value: this.product, + key: "product", + }); }, setInstanceGroup(key, value) { this.$emit("set-instance-group", { ...this.instanceGroup, [key]: value }); @@ -397,6 +397,20 @@ export default { return tariffs; }, + product() { + return [ + this.instance.config.duration, + this.instance.config.planCode, + ].join(" "); + }, + durationItems() { + const items = new Set(); + this.flavors[this.instance.billing_plan?.uuid]?.forEach((item) => { + items.add(item.duration); + }); + + return [...items.values()]; + }, }, async created() { if (!this.isEdit) { @@ -415,9 +429,7 @@ export default { this.instance.config.configuration.vps_os ); this.setAddons( - this.instance.billing_plan.products[ - `${this.instance.config.duration} ${this.instance.config.planCode}` - ]?.meta?.addons, + this.instance.billing_plan.products[this.product]?.meta?.addons, this.instance.config.planCode ); } diff --git a/admin-ui/src/components/modules/virtual/billingInfo.vue b/admin-ui/src/components/modules/virtual/billingInfo.vue index d876d5931..fe56c1890 100644 --- a/admin-ui/src/components/modules/virtual/billingInfo.vue +++ b/admin-ui/src/components/modules/virtual/billingInfo.vue @@ -13,23 +13,12 @@ - - - - - - - - - - - + + + + + + + + - formatSecondsToDate(template.value?.data?.last_monitoring) + formatSecondsToDate(template.value?.data?.next_payment_date) ); const isMonitoringsEmpty = computed(() => date.value === "-"); -const price = computed(() => { - return template.value.billingPlan.products[template.value.product]?.price; -}); - const filtredPlans = computed(() => plans.value.filter((p) => p.type === "virtual") ); -const totalAccountPrice = computed(() => { - return toAccountPrice(totalPrice.value); -}); const totalPrice = computed(() => { return billingItems.value.reduce((acc, i) => acc + +i.price, 0); }); +const totalAccountPrice = computed(() => { + return billingItems.value.reduce((acc, i) => acc + +i.accountPrice, 0); +}); + const billingPlan = computed(() => template.value.billingPlan); +const defaultCurrency = computed(() => store.getters["currencies/default"]); + onMounted(() => { - fetchAccountRate(); billingItems.value = getBillingItems(); }); watch(accountRate, () => { - accountPrice.value = totalAccountPrice.value; billingItems.value = billingItems.value.map((i) => { i.accountPrice = toAccountPrice(i.price); return i; @@ -175,13 +175,14 @@ watch(accountRate, () => { const getBillingItems = () => { const items = []; - + const price = billingPlan.value.products[template.value.product]?.price; items.push({ name: template.value.product, - price: billingPlan.value.products[template.value.product]?.price, + price, path: `billingPlan.products.${template.value.product}.price`, kind: billingPlan.value.products[template.value.product]?.kind, period: billingPlan.value.products[template.value.product]?.period, + accountPrice: toAccountPrice(price), }); return items.map((i) => { diff --git a/admin-ui/src/components/modules/virtual/billingLabel.vue b/admin-ui/src/components/modules/virtual/billingLabel.vue new file mode 100644 index 000000000..0e0496ea9 --- /dev/null +++ b/admin-ui/src/components/modules/virtual/billingLabel.vue @@ -0,0 +1,46 @@ + + + + + diff --git a/admin-ui/src/components/plan/cloudTable.vue b/admin-ui/src/components/plan/cloudTable.vue index 69bc83c56..d9cd711a4 100644 --- a/admin-ui/src/components/plan/cloudTable.vue +++ b/admin-ui/src/components/plan/cloudTable.vue @@ -43,11 +43,15 @@ +