From 1079a597765c0a03d7600eefe9b5a34530b341df Mon Sep 17 00:00:00 2001 From: mikatong Date: Fri, 26 Sep 2025 19:23:04 +0800 Subject: [PATCH 1/3] support billing budget --- go.mod | 2 +- go.sum | 2 + tencentcloud/provider.go | 2 + tencentcloud/provider.md | 5 +- ..._source_tc_billing_budget_operation_log.go | 232 ++++ ..._source_tc_billing_budget_operation_log.md | 9 + ...ce_tc_billing_budget_operation_log_test.go | 29 + .../billing/resource_tc_billing_budget.go | 938 +++++++++++++++ .../billing/resource_tc_billing_budget.md | 47 + .../resource_tc_billing_budget_test.go | 79 ++ .../billing/service_tencentcloud_billing.go | 86 ++ .../tencentcloud/billing/v20180709/client.go | 338 ++++++ .../tencentcloud/billing/v20180709/models.go | 1063 ++++++++++++++++- vendor/modules.txt | 2 +- ...billing_budget_operation_log.html.markdown | 49 + website/docs/r/billing_budget.html.markdown | 120 ++ website/tencentcloud.erb | 12 +- 17 files changed, 3005 insertions(+), 10 deletions(-) create mode 100644 tencentcloud/services/billing/data_source_tc_billing_budget_operation_log.go create mode 100644 tencentcloud/services/billing/data_source_tc_billing_budget_operation_log.md create mode 100644 tencentcloud/services/billing/data_source_tc_billing_budget_operation_log_test.go create mode 100644 tencentcloud/services/billing/resource_tc_billing_budget.go create mode 100644 tencentcloud/services/billing/resource_tc_billing_budget.md create mode 100644 tencentcloud/services/billing/resource_tc_billing_budget_test.go create mode 100644 website/docs/d/billing_budget_operation_log.html.markdown create mode 100644 website/docs/r/billing_budget.html.markdown diff --git a/go.mod b/go.mod index 41ffbe0d90..57e403c590 100644 --- a/go.mod +++ b/go.mod @@ -107,7 +107,7 @@ require ( require ( github.com/hashicorp/go-uuid v1.0.3 - github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/billing v1.1.0 + github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/billing v1.1.31 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdc v1.0.1149 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdwdoris v1.0.993 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdwpg v1.0.1126 diff --git a/go.sum b/go.sum index 980ad3b5eb..569ca0fd8d 100644 --- a/go.sum +++ b/go.sum @@ -833,6 +833,8 @@ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/bi v1.0.824 h1:DVKvZ6h+ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/bi v1.0.824/go.mod h1:DvBpDX/qdJG4KKLeULmRvhAjPYiw8za0HeTSu2y/lFw= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/billing v1.1.0 h1:tfTh+fIqYPgWV2wi4oDvG963pi8tljtZ+5OdnhEqRnU= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/billing v1.1.0/go.mod h1:OKowLuHQjXN5pk3KnYnbmZLQucfBUUEpqWsa/3Cl+jY= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/billing v1.1.31 h1:teA14cAcXuGxas6+5YANQ5KCoPaQBKIb2Q8+sk08Mu0= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/billing v1.1.31/go.mod h1:1P9mCHgZ9pk/xftRsGC05XanvIk/sC5kLIy5jfD6DqU= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cam v1.0.1071 h1:2CeivXYc7PtD2kgZEJXk9/SDQA9dzLejH5FmNzAW3QU= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cam v1.0.1071/go.mod h1:UAjX3Vq52SQLKTe6o2HyGA/841Rnc+f4ZRATEsFHJDM= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cam v1.1.27 h1:Jo/5JV8oiPbXKXQg2xv3ZeKxLst/xXl3nWUgXalq9eg= diff --git a/tencentcloud/provider.go b/tencentcloud/provider.go index 110659abc8..b0ebd658df 100644 --- a/tencentcloud/provider.go +++ b/tencentcloud/provider.go @@ -1250,6 +1250,7 @@ func Provider() *schema.Provider { "tencentcloud_mqtt_instances": mqtt.DataSourceTencentCloudMqttInstances(), "tencentcloud_mqtt_instance_detail": mqtt.DataSourceTencentCloudMqttInstanceDetail(), "tencentcloud_mqtt_topics": mqtt.DataSourceTencentCloudMqttTopics(), + "tencentcloud_billing_budget_operation_log": billing.DataSourceTencentCloudBillingBudgetOperationLog(), }, ResourcesMap: map[string]*schema.Resource{ @@ -2376,6 +2377,7 @@ func Provider() *schema.Provider { "tencentcloud_mqtt_jwks_authenticator": mqtt.ResourceTencentCloudMqttJwksAuthenticator(), "tencentcloud_mqtt_http_authenticator": mqtt.ResourceTencentCloudMqttHttpAuthenticator(), "tencentcloud_billing_allocation_tag": billing.ResourceTencentCloudBillingAllocationTag(), + "tencentcloud_billing_budget": billing.ResourceTencentCloudBillingBudget(), }, ConfigureFunc: providerConfigure, diff --git a/tencentcloud/provider.md b/tencentcloud/provider.md index 12e04ff2b2..ccfe0a9c62 100644 --- a/tencentcloud/provider.md +++ b/tencentcloud/provider.md @@ -2349,5 +2349,8 @@ tencentcloud_mqtt_jwks_authenticator tencentcloud_mqtt_http_authenticator Billing +Data Source +tencentcloud_billing_budget_operation_log Resource -tencentcloud_billing_allocation_tag \ No newline at end of file +tencentcloud_billing_allocation_tag +tencentcloud_billing_budget \ No newline at end of file diff --git a/tencentcloud/services/billing/data_source_tc_billing_budget_operation_log.go b/tencentcloud/services/billing/data_source_tc_billing_budget_operation_log.go new file mode 100644 index 0000000000..1c1e5bed4e --- /dev/null +++ b/tencentcloud/services/billing/data_source_tc_billing_budget_operation_log.go @@ -0,0 +1,232 @@ +package billing + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + billingv20180709 "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/billing/v20180709" + + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" + "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" +) + +func DataSourceTencentCloudBillingBudgetOperationLog() *schema.Resource { + return &schema.Resource{ + Read: dataSourceTencentCloudBillingBudgetOperationLogRead, + Schema: map[string]*schema.Schema{ + "budget_id": { + Type: schema.TypeString, + Required: true, + Description: "Budget id.", + }, + + "records": { + Type: schema.TypeList, + Computed: true, + Description: "Query data list.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "payer_uin": { + Type: schema.TypeInt, + Computed: true, + Description: "Payer uin.", + }, + "owner_uin": { + Type: schema.TypeInt, + Computed: true, + Description: "Owner uin.", + }, + "operate_uin": { + Type: schema.TypeInt, + Computed: true, + Description: "Operate uin.", + }, + "bill_day": { + Type: schema.TypeInt, + Computed: true, + Description: "Bill day.", + }, + "bill_month": { + Type: schema.TypeString, + Computed: true, + Description: "Bill month.", + }, + "action": { + Type: schema.TypeString, + Computed: true, + Description: "Modification type: ADD, UPDATE.", + }, + "diff_value": { + Type: schema.TypeList, + Computed: true, + Description: "change information.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "property": { + Type: schema.TypeString, + Computed: true, + Description: "Change attributes.", + }, + "before": { + Type: schema.TypeString, + Computed: true, + Description: "Content before change.", + }, + "after": { + Type: schema.TypeString, + Computed: true, + Description: "Content after change.", + }, + }, + }, + }, + "create_time": { + Type: schema.TypeString, + Computed: true, + Description: "Create time.", + }, + "update_time": { + Type: schema.TypeString, + Computed: true, + Description: "Update time.", + }, + "operation_channel": { + Type: schema.TypeString, + Computed: true, + Description: "Operation channel.", + }, + "budget_id": { + Type: schema.TypeString, + Computed: true, + Description: "Budget item id.", + }, + }, + }, + }, + + "result_output_file": { + Type: schema.TypeString, + Optional: true, + Description: "Used to save results.", + }, + }, + } +} + +func dataSourceTencentCloudBillingBudgetOperationLogRead(d *schema.ResourceData, meta interface{}) error { + defer tccommon.LogElapsed("data_source.tencentcloud_billing_budget_operation_log.read")() + defer tccommon.InconsistentCheck(d, meta)() + + logId := tccommon.GetLogId(nil) + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) + + service := BillingService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + + var budgetId string + + paramMap := make(map[string]interface{}) + + if v, ok := d.GetOk("budget_id"); ok { + budgetId = v.(string) + paramMap["BudgetId"] = helper.String(budgetId) + } + + var respData []*billingv20180709.BudgetOperationLogEntity + err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { + result, e := service.DescribeBillingBudgetOperationLogByFilter(ctx, paramMap) + if e != nil { + return tccommon.RetryError(e) + } + respData = result + return nil + }) + if err != nil { + return err + } + + if len(respData) > 0 { + recordsList := make([]map[string]interface{}, 0, len(respData)) + + for _, records := range respData { + recordsMap := map[string]interface{}{} + + if records.PayerUin != nil { + recordsMap["payer_uin"] = records.PayerUin + } + + if records.OwnerUin != nil { + recordsMap["owner_uin"] = records.OwnerUin + } + + if records.OperateUin != nil { + recordsMap["operate_uin"] = records.OperateUin + } + + if records.BillDay != nil { + recordsMap["bill_day"] = records.BillDay + } + + if records.BillMonth != nil { + recordsMap["bill_month"] = records.BillMonth + } + + if records.Action != nil { + recordsMap["action"] = records.Action + } + + diffValueList := make([]map[string]interface{}, 0, len(records.DiffValue)) + if records.DiffValue != nil { + for _, diffValue := range records.DiffValue { + diffValueMap := map[string]interface{}{} + + if diffValue.Property != nil { + diffValueMap["property"] = diffValue.Property + } + + if diffValue.Before != nil { + diffValueMap["before"] = diffValue.Before + } + + if diffValue.After != nil { + diffValueMap["after"] = diffValue.After + } + + diffValueList = append(diffValueList, diffValueMap) + } + + recordsMap["diff_value"] = diffValueList + } + if records.CreateTime != nil { + recordsMap["create_time"] = records.CreateTime + } + + if records.UpdateTime != nil { + recordsMap["update_time"] = records.UpdateTime + } + + if records.OperationChannel != nil { + recordsMap["operation_channel"] = records.OperationChannel + } + + if records.BudgetId != nil { + recordsMap["budget_id"] = records.BudgetId + } + + recordsList = append(recordsList, recordsMap) + } + + _ = d.Set("records", recordsList) + } + + d.SetId(budgetId) + + output, ok := d.GetOk("result_output_file") + if ok && output.(string) != "" { + if e := tccommon.WriteToFile(output.(string), d); e != nil { + return e + } + } + + return nil +} diff --git a/tencentcloud/services/billing/data_source_tc_billing_budget_operation_log.md b/tencentcloud/services/billing/data_source_tc_billing_budget_operation_log.md new file mode 100644 index 0000000000..77cc846a87 --- /dev/null +++ b/tencentcloud/services/billing/data_source_tc_billing_budget_operation_log.md @@ -0,0 +1,9 @@ +Use this data source to query detailed information of billing billing_budget_operation_log + +Example Usage + +```hcl +data "tencentcloud_billing_budget_operation_log" "billing_budget_operation_log" { + budget_id = "1971489821259956225" +} +``` diff --git a/tencentcloud/services/billing/data_source_tc_billing_budget_operation_log_test.go b/tencentcloud/services/billing/data_source_tc_billing_budget_operation_log_test.go new file mode 100644 index 0000000000..09886db1f4 --- /dev/null +++ b/tencentcloud/services/billing/data_source_tc_billing_budget_operation_log_test.go @@ -0,0 +1,29 @@ +package billing_test + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + + tcacctest "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/acctest" +) + +func TestAccTencentCloudBillingBudgetOperationLogDataSource_basic(t *testing.T) { + t.Parallel() + resource.Test(t, resource.TestCase{ + PreCheck: func() { + tcacctest.AccPreCheck(t) + }, + Providers: tcacctest.AccProviders, + Steps: []resource.TestStep{{ + Config: testAccBillingBudgetOperationLogDataSource, + Check: resource.ComposeTestCheckFunc(tcacctest.AccCheckTencentCloudDataSourceID("data.tencentcloud_billing_budget_operation_log.billing_budget_operation_log")), + }}, + }) +} + +const testAccBillingBudgetOperationLogDataSource = ` +data "tencentcloud_billing_budget_operation_log" "billing_budget_operation_log" { + budget_id = "1971489821259956225" +} +` diff --git a/tencentcloud/services/billing/resource_tc_billing_budget.go b/tencentcloud/services/billing/resource_tc_billing_budget.go new file mode 100644 index 0000000000..ab14110720 --- /dev/null +++ b/tencentcloud/services/billing/resource_tc_billing_budget.go @@ -0,0 +1,938 @@ +package billing + +import ( + "context" + "log" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + billingv20180709 "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/billing/v20180709" + + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" + "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" +) + +func ResourceTencentCloudBillingBudget() *schema.Resource { + return &schema.Resource{ + Create: resourceTencentCloudBillingBudgetCreate, + Read: resourceTencentCloudBillingBudgetRead, + Update: resourceTencentCloudBillingBudgetUpdate, + Delete: resourceTencentCloudBillingBudgetDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + Schema: map[string]*schema.Schema{ + "budget_name": { + Type: schema.TypeString, + Required: true, + Description: "Budget name.", + }, + + "cycle_type": { + Type: schema.TypeString, + Required: true, + Description: "Cycle type, valid values: DAY, MONTH, QUARTER, YEAR.", + }, + + "period_begin": { + Type: schema.TypeString, + Required: true, + Description: "Valid period starting time 2025-01-01(cycle: days) / 2025-01 (cycle: months).", + }, + + "period_end": { + Type: schema.TypeString, + Required: true, + Description: "Expiration period end time 2025-12-01(cycle: days) / 2025-12 (cycle: months).", + }, + + "plan_type": { + Type: schema.TypeString, + Required: true, + Description: "FIX: fixed budget, CYCLE: planned budget.", + }, + + "budget_quota": { + Type: schema.TypeString, + Required: true, + Description: "Budget value limit. Transfer fixed value when the budget plan type is FIX(Fixed Budget); Passed when the budget plan type is CYCLE(Planned Budget)[{\"dateDesc\":\"2025-07\",\"quota\":\"1000\"},{\"dateDesc\":\"2025-08\",\"quota\":\"2000\"}].", + }, + + "bill_type": { + Type: schema.TypeString, + Required: true, + Description: "BILL: system bill, CONSUMPTION: consumption bill.", + }, + + "fee_type": { + Type: schema.TypeString, + Required: true, + Description: "COST original price, REAL_COST actual cost, CASH cash, INCENTIVE gift, VOUCHER voucher, TRANSFER share, TAX tax, AMOUNT_BEFORE_TAX cash payment (before tax).", + }, + + "warn_json": { + Type: schema.TypeList, + Required: true, + Description: "Threshold reminder.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "warn_type": { + Type: schema.TypeString, + Required: true, + Description: "ACTUAL: actual amount, FORECAST: forecast amount.", + }, + "cal_type": { + Type: schema.TypeString, + Required: true, + Description: "PERCENTAGE: Percentage of budget amount, ABS: fixed value.", + }, + "threshold_value": { + Type: schema.TypeString, + Required: true, + Description: "Threshold (greater than or equal to 0).", + }, + }, + }, + }, + + "budget_note": { + Type: schema.TypeString, + Optional: true, + Description: "Budget remarks.", + }, + + "dimensions_range": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Description: "Budget dimension range conditions.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "business": { + Type: schema.TypeSet, + Optional: true, + Description: "Products.", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "pay_mode": { + Type: schema.TypeSet, + Optional: true, + Description: "Pay mode.", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "product_codes": { + Type: schema.TypeSet, + Optional: true, + Description: "Sub-product.", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "component_codes": { + Type: schema.TypeSet, + Optional: true, + Description: "Component codes.", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "zone_ids": { + Type: schema.TypeSet, + Optional: true, + Description: "Zone ids.", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "region_ids": { + Type: schema.TypeSet, + Optional: true, + Description: "Region ids.", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "project_ids": { + Type: schema.TypeSet, + Optional: true, + Description: "Project ids.", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "action_types": { + Type: schema.TypeSet, + Optional: true, + Description: "Action types.", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "consumption_types": { + Type: schema.TypeSet, + Optional: true, + Description: "Consumption types.", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "tags": { + Type: schema.TypeList, + Optional: true, + Description: "Tags.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "tag_key": { + Type: schema.TypeString, + Optional: true, + Description: "Tag key.", + }, + "tag_value": { + Type: schema.TypeSet, + Optional: true, + Description: "Tag value.", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + }, + }, + }, + "payer_uins": { + Type: schema.TypeSet, + Optional: true, + Description: "Payer uins.", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "owner_uins": { + Type: schema.TypeSet, + Optional: true, + Description: "Owner uins.", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "tree_node_uniq_keys": { + Type: schema.TypeSet, + Optional: true, + Description: "Unique key for end-level ledger unit.", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + }, + }, + }, + + "wave_threshold_json": { + Type: schema.TypeList, + Optional: true, + Description: "Volatility reminder.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "warn_type": { + Type: schema.TypeString, + Optional: true, + Description: "ACTUAL: actual amount, FORECAST: forecast amount.", + }, + "threshold": { + Type: schema.TypeString, + Optional: true, + Description: "Volatility threshold (greater than or equal to 0).", + }, + "meta_type": { + Type: schema.TypeString, + Optional: true, + Description: "Alarm type: chain month-on-month, yoy year-on-year, fix fixed value\n (Supported types: daily month-on-month chain day, daily month-on-year chain weekday, daily month-on-year monthly month-on-year fixed value fix day, month-on-month chain month, monthly fixed value fix month).", + }, + "period_type": { + Type: schema.TypeString, + Optional: true, + Description: "Alarm dimension: day day, month month, weekday week\n (Support types: day-to-day chain day, day-to-year weekly dimension chain weekday, day-to-year monthly dimension yoy day, daily fixed value fix day, month-to-month chain month, monthly fixed value fix month).", + }, + }, + }, + }, + }, + } +} + +func resourceTencentCloudBillingBudgetCreate(d *schema.ResourceData, meta interface{}) error { + defer tccommon.LogElapsed("resource.tencentcloud_billing_budget.create")() + defer tccommon.InconsistentCheck(d, meta)() + + logId := tccommon.GetLogId(tccommon.ContextNil) + + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) + + var ( + budgetId string + ) + var ( + request = billingv20180709.NewCreateBudgetRequest() + response = billingv20180709.NewCreateBudgetResponse() + ) + + if v, ok := d.GetOk("budget_name"); ok { + request.BudgetName = helper.String(v.(string)) + } + + if v, ok := d.GetOk("cycle_type"); ok { + request.CycleType = helper.String(v.(string)) + } + + if v, ok := d.GetOk("period_begin"); ok { + request.PeriodBegin = helper.String(v.(string)) + } + + if v, ok := d.GetOk("period_end"); ok { + request.PeriodEnd = helper.String(v.(string)) + } + + if v, ok := d.GetOk("plan_type"); ok { + request.PlanType = helper.String(v.(string)) + } + + if v, ok := d.GetOk("budget_quota"); ok { + request.BudgetQuota = helper.String(v.(string)) + } + + if v, ok := d.GetOk("bill_type"); ok { + request.BillType = helper.String(v.(string)) + } + + if v, ok := d.GetOk("fee_type"); ok { + request.FeeType = helper.String(v.(string)) + } + + if v, ok := d.GetOk("warn_json"); ok { + for _, item := range v.([]interface{}) { + warnJsonMap := item.(map[string]interface{}) + budgetWarn := billingv20180709.BudgetWarn{} + if v, ok := warnJsonMap["warn_type"]; ok { + budgetWarn.WarnType = helper.String(v.(string)) + } + if v, ok := warnJsonMap["cal_type"]; ok { + budgetWarn.CalType = helper.String(v.(string)) + } + if v, ok := warnJsonMap["threshold_value"]; ok { + budgetWarn.ThresholdValue = helper.String(v.(string)) + } + request.WarnJson = append(request.WarnJson, &budgetWarn) + } + } + + if v, ok := d.GetOk("budget_note"); ok { + request.BudgetNote = helper.String(v.(string)) + } + + if dimensionsRangeMap, ok := helper.InterfacesHeadMap(d, "dimensions_range"); ok { + budgetConditionsForm := billingv20180709.BudgetConditionsForm{} + if v, ok := dimensionsRangeMap["business"]; ok { + businessSet := v.(*schema.Set).List() + for i := range businessSet { + business := businessSet[i].(string) + budgetConditionsForm.Business = append(budgetConditionsForm.Business, helper.String(business)) + } + } + if v, ok := dimensionsRangeMap["pay_mode"]; ok { + payModeSet := v.(*schema.Set).List() + for i := range payModeSet { + payMode := payModeSet[i].(string) + budgetConditionsForm.PayMode = append(budgetConditionsForm.PayMode, helper.String(payMode)) + } + } + if v, ok := dimensionsRangeMap["product_codes"]; ok { + productCodesSet := v.(*schema.Set).List() + for i := range productCodesSet { + productCodes := productCodesSet[i].(string) + budgetConditionsForm.ProductCodes = append(budgetConditionsForm.ProductCodes, helper.String(productCodes)) + } + } + if v, ok := dimensionsRangeMap["component_codes"]; ok { + componentCodesSet := v.(*schema.Set).List() + for i := range componentCodesSet { + componentCodes := componentCodesSet[i].(string) + budgetConditionsForm.ComponentCodes = append(budgetConditionsForm.ComponentCodes, helper.String(componentCodes)) + } + } + if v, ok := dimensionsRangeMap["zone_ids"]; ok { + zoneIdsSet := v.(*schema.Set).List() + for i := range zoneIdsSet { + zoneIds := zoneIdsSet[i].(string) + budgetConditionsForm.ZoneIds = append(budgetConditionsForm.ZoneIds, helper.String(zoneIds)) + } + } + if v, ok := dimensionsRangeMap["region_ids"]; ok { + regionIdsSet := v.(*schema.Set).List() + for i := range regionIdsSet { + regionIds := regionIdsSet[i].(string) + budgetConditionsForm.RegionIds = append(budgetConditionsForm.RegionIds, helper.String(regionIds)) + } + } + if v, ok := dimensionsRangeMap["project_ids"]; ok { + projectIdsSet := v.(*schema.Set).List() + for i := range projectIdsSet { + projectIds := projectIdsSet[i].(string) + budgetConditionsForm.ProjectIds = append(budgetConditionsForm.ProjectIds, helper.String(projectIds)) + } + } + if v, ok := dimensionsRangeMap["action_types"]; ok { + actionTypesSet := v.(*schema.Set).List() + for i := range actionTypesSet { + actionTypes := actionTypesSet[i].(string) + budgetConditionsForm.ActionTypes = append(budgetConditionsForm.ActionTypes, helper.String(actionTypes)) + } + } + if v, ok := dimensionsRangeMap["consumption_types"]; ok { + consumptionTypesSet := v.(*schema.Set).List() + for i := range consumptionTypesSet { + consumptionTypes := consumptionTypesSet[i].(string) + budgetConditionsForm.ConsumptionTypes = append(budgetConditionsForm.ConsumptionTypes, helper.String(consumptionTypes)) + } + } + if v, ok := dimensionsRangeMap["tags"]; ok { + for _, item := range v.([]interface{}) { + tagsMap := item.(map[string]interface{}) + tagsForm := billingv20180709.TagsForm{} + if v, ok := tagsMap["tag_key"]; ok { + tagsForm.TagKey = helper.String(v.(string)) + } + if v, ok := tagsMap["tag_value"]; ok { + tagValueSet := v.(*schema.Set).List() + for i := range tagValueSet { + tagValue := tagValueSet[i].(string) + tagsForm.TagValue = append(tagsForm.TagValue, helper.String(tagValue)) + } + } + budgetConditionsForm.Tags = append(budgetConditionsForm.Tags, &tagsForm) + } + } + if v, ok := dimensionsRangeMap["payer_uins"]; ok { + payerUinsSet := v.(*schema.Set).List() + for i := range payerUinsSet { + payerUins := payerUinsSet[i].(string) + budgetConditionsForm.PayerUins = append(budgetConditionsForm.PayerUins, helper.String(payerUins)) + } + } + if v, ok := dimensionsRangeMap["owner_uins"]; ok { + ownerUinsSet := v.(*schema.Set).List() + for i := range ownerUinsSet { + ownerUins := ownerUinsSet[i].(string) + budgetConditionsForm.OwnerUins = append(budgetConditionsForm.OwnerUins, helper.String(ownerUins)) + } + } + if v, ok := dimensionsRangeMap["tree_node_uniq_keys"]; ok { + treeNodeUniqKeysSet := v.(*schema.Set).List() + for i := range treeNodeUniqKeysSet { + treeNodeUniqKeys := treeNodeUniqKeysSet[i].(string) + budgetConditionsForm.TreeNodeUniqKeys = append(budgetConditionsForm.TreeNodeUniqKeys, helper.String(treeNodeUniqKeys)) + } + } + request.DimensionsRange = &budgetConditionsForm + } + + if v, ok := d.GetOk("wave_threshold_json"); ok { + for _, item := range v.([]interface{}) { + waveThresholdJsonMap := item.(map[string]interface{}) + waveThresholdForm := billingv20180709.WaveThresholdForm{} + if v, ok := waveThresholdJsonMap["warn_type"]; ok { + waveThresholdForm.WarnType = helper.String(v.(string)) + } + if v, ok := waveThresholdJsonMap["threshold"]; ok { + waveThresholdForm.Threshold = helper.String(v.(string)) + } + if v, ok := waveThresholdJsonMap["meta_type"]; ok { + waveThresholdForm.MetaType = helper.String(v.(string)) + } + if v, ok := waveThresholdJsonMap["period_type"]; ok { + waveThresholdForm.PeriodType = helper.String(v.(string)) + } + request.WaveThresholdJson = append(request.WaveThresholdJson, &waveThresholdForm) + } + } + + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseBillingV20180709Client().CreateBudgetWithContext(ctx, request) + if e != nil { + return tccommon.RetryError(e) + } else { + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), result.ToJsonString()) + } + response = result + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s create billing budget failed, reason:%+v", logId, err) + return err + } + + if response.Response != nil && response.Response.Data.BudgetId != nil { + budgetId = *response.Response.Data.BudgetId + } + + d.SetId(budgetId) + + return resourceTencentCloudBillingBudgetRead(d, meta) +} + +func resourceTencentCloudBillingBudgetRead(d *schema.ResourceData, meta interface{}) error { + defer tccommon.LogElapsed("resource.tencentcloud_billing_budget.read")() + defer tccommon.InconsistentCheck(d, meta)() + + logId := tccommon.GetLogId(tccommon.ContextNil) + + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) + + service := BillingService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + + budgetId := d.Id() + + respData, err := service.DescribeBillingBudgetById(ctx, budgetId) + if err != nil { + return err + } + + if respData == nil { + d.SetId("") + log.Printf("[WARN]%s resource `billing_budget` [%s] not found, please check if it has been deleted.\n", logId, d.Id()) + return nil + } + + if respData.Data == nil || len(respData.Data.Records) == 0 { + d.SetId("") + return nil + } + record := respData.Data.Records[0] + + if record.BudgetName != nil { + d.Set("budget_name", record.BudgetName) + } + if record.CycleType != nil { + d.Set("cycle_type", record.CycleType) + } + + if record.PeriodBegin != nil { + d.Set("period_begin", record.PeriodBegin) + } + + if record.PeriodEnd != nil { + d.Set("period_end", record.PeriodEnd) + } + + if record.PlanType != nil { + d.Set("plan_type", record.PlanType) + } + + if record.BudgetQuota != nil { + d.Set("budget_quota", record.BudgetQuota) + } + + if record.BillType != nil { + d.Set("bill_type", record.BillType) + } + + if record.FeeType != nil { + d.Set("fee_type", record.FeeType) + } + + warnJsonList := make([]map[string]interface{}, 0, len(record.WarnJson)) + if record.WarnJson != nil { + for _, warnJson := range record.WarnJson { + warnJsonMap := map[string]interface{}{} + + if warnJson.WarnType != nil { + warnJsonMap["warn_type"] = warnJson.WarnType + } + + if warnJson.CalType != nil { + warnJsonMap["cal_type"] = warnJson.CalType + } + + if warnJson.ThresholdValue != nil { + warnJsonMap["threshold_value"] = warnJson.ThresholdValue + } + + warnJsonList = append(warnJsonList, warnJsonMap) + } + + d.Set("warn_json", warnJsonList) + } + + if record.BudgetNote != nil { + d.Set("budget_note", record.BudgetNote) + } + + waveThresholdJsonList := make([]map[string]interface{}, 0, len(record.WaveThresholdJson)) + if record.WaveThresholdJson != nil { + for _, waveThresholdJson := range record.WaveThresholdJson { + waveThresholdJsonMap := map[string]interface{}{} + + if waveThresholdJson.WarnType != nil { + waveThresholdJsonMap["warn_type"] = waveThresholdJson.WarnType + } + + if waveThresholdJson.Threshold != nil { + waveThresholdJsonMap["threshold"] = waveThresholdJson.Threshold + } + + if waveThresholdJson.MetaType != nil { + waveThresholdJsonMap["meta_type"] = waveThresholdJson.MetaType + } + + if waveThresholdJson.PeriodType != nil { + waveThresholdJsonMap["period_type"] = waveThresholdJson.PeriodType + } + + waveThresholdJsonList = append(waveThresholdJsonList, waveThresholdJsonMap) + } + + d.Set("wave_threshold_json", waveThresholdJsonList) + } + + if record.DimensionsRange != nil { + dimensionsRangeMap := make(map[string]interface{}) + if record.DimensionsRange.Business != nil { + dimensionsRangeMap["business"] = record.DimensionsRange.Business + } + + if record.DimensionsRange.PayMode != nil { + dimensionsRangeMap["pay_mode"] = record.DimensionsRange.PayMode + } + + if record.DimensionsRange.ProductCodes != nil { + dimensionsRangeMap["product_codes"] = record.DimensionsRange.ProductCodes + } + + if record.DimensionsRange.ComponentCodes != nil { + dimensionsRangeMap["component_codes"] = record.DimensionsRange.ComponentCodes + } + + if record.DimensionsRange.ZoneIds != nil { + dimensionsRangeMap["zone_ids"] = record.DimensionsRange.ZoneIds + } + + if record.DimensionsRange.RegionIds != nil { + dimensionsRangeMap["region_ids"] = record.DimensionsRange.RegionIds + } + + if record.DimensionsRange.ProjectIds != nil { + dimensionsRangeMap["project_ids"] = record.DimensionsRange.ProjectIds + } + + if record.DimensionsRange.ActionTypes != nil { + dimensionsRangeMap["action_types"] = record.DimensionsRange.ActionTypes + } + + if record.DimensionsRange.ConsumptionTypes != nil { + dimensionsRangeMap["consumption_types"] = record.DimensionsRange.ConsumptionTypes + } + + tagsList := make([]map[string]interface{}, 0, len(record.DimensionsRange.Tags)) + if record.DimensionsRange.Tags != nil { + for _, tags := range record.DimensionsRange.Tags { + tagsMap := map[string]interface{}{} + + if tags.TagKey != nil { + tagsMap["tag_key"] = tags.TagKey + } + + if tags.TagValue != nil { + tagsMap["tag_value"] = tags.TagValue + } + + tagsList = append(tagsList, tagsMap) + } + + dimensionsRangeMap["tags"] = tagsList + } + if record.DimensionsRange.PayerUins != nil { + dimensionsRangeMap["payer_uins"] = record.DimensionsRange.PayerUins + } + + if record.DimensionsRange.OwnerUins != nil { + dimensionsRangeMap["owner_uins"] = record.DimensionsRange.OwnerUins + } + + if record.DimensionsRange.TreeNodeUniqKeys != nil { + dimensionsRangeMap["tree_node_uniq_keys"] = record.DimensionsRange.TreeNodeUniqKeys + } + hasNotNullItem := false + for _, v := range dimensionsRangeMap { + if v != nil { + hasNotNullItem = true + } + } + if hasNotNullItem { + d.Set("dimensions_range", []interface{}{dimensionsRangeMap}) + } else { + d.Set("dimensions_range", []interface{}{}) + } + + } + + return nil +} + +func resourceTencentCloudBillingBudgetUpdate(d *schema.ResourceData, meta interface{}) error { + defer tccommon.LogElapsed("resource.tencentcloud_billing_budget.update")() + defer tccommon.InconsistentCheck(d, meta)() + + logId := tccommon.GetLogId(tccommon.ContextNil) + + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) + + budgetId := d.Id() + + needChange := false + mutableArgs := []string{"budget_id", "budget_name", "cycle_type", "period_begin", "period_end", "plan_type", "budget_quota", "bill_type", "fee_type", "warn_json", "budget_note", "dimensions_range", "wave_threshold_json"} + for _, v := range mutableArgs { + if d.HasChange(v) { + needChange = true + break + } + } + + if needChange { + request := billingv20180709.NewModifyBudgetRequest() + request.BudgetId = helper.String(budgetId) + if v, ok := d.GetOk("budget_id"); ok { + request.BudgetId = helper.String(v.(string)) + } + + if v, ok := d.GetOk("budget_name"); ok { + request.BudgetName = helper.String(v.(string)) + } + + if v, ok := d.GetOk("cycle_type"); ok { + request.CycleType = helper.String(v.(string)) + } + + if v, ok := d.GetOk("period_begin"); ok { + request.PeriodBegin = helper.String(v.(string)) + } + + if v, ok := d.GetOk("period_end"); ok { + request.PeriodEnd = helper.String(v.(string)) + } + + if v, ok := d.GetOk("plan_type"); ok { + request.PlanType = helper.String(v.(string)) + } + + if v, ok := d.GetOk("budget_quota"); ok { + request.BudgetQuota = helper.String(v.(string)) + } + + if v, ok := d.GetOk("bill_type"); ok { + request.BillType = helper.String(v.(string)) + } + + if v, ok := d.GetOk("fee_type"); ok { + request.FeeType = helper.String(v.(string)) + } + + if v, ok := d.GetOk("warn_json"); ok { + for _, item := range v.([]interface{}) { + warnJsonMap := item.(map[string]interface{}) + budgetWarn := billingv20180709.BudgetWarn{} + if v, ok := warnJsonMap["warn_type"]; ok { + budgetWarn.WarnType = helper.String(v.(string)) + } + if v, ok := warnJsonMap["cal_type"]; ok { + budgetWarn.CalType = helper.String(v.(string)) + } + if v, ok := warnJsonMap["threshold_value"]; ok { + budgetWarn.ThresholdValue = helper.String(v.(string)) + } + request.WarnJson = append(request.WarnJson, &budgetWarn) + } + } + + if v, ok := d.GetOk("budget_note"); ok { + request.BudgetNote = helper.String(v.(string)) + } + + if dimensionsRangeMap, ok := helper.InterfacesHeadMap(d, "dimensions_range"); ok { + budgetConditionsForm := billingv20180709.BudgetConditionsForm{} + if v, ok := dimensionsRangeMap["business"]; ok { + businessSet := v.(*schema.Set).List() + for i := range businessSet { + business := businessSet[i].(string) + budgetConditionsForm.Business = append(budgetConditionsForm.Business, helper.String(business)) + } + } + if v, ok := dimensionsRangeMap["pay_mode"]; ok { + payModeSet := v.(*schema.Set).List() + for i := range payModeSet { + payMode := payModeSet[i].(string) + budgetConditionsForm.PayMode = append(budgetConditionsForm.PayMode, helper.String(payMode)) + } + } + if v, ok := dimensionsRangeMap["product_codes"]; ok { + productCodesSet := v.(*schema.Set).List() + for i := range productCodesSet { + productCodes := productCodesSet[i].(string) + budgetConditionsForm.ProductCodes = append(budgetConditionsForm.ProductCodes, helper.String(productCodes)) + } + } + if v, ok := dimensionsRangeMap["component_codes"]; ok { + componentCodesSet := v.(*schema.Set).List() + for i := range componentCodesSet { + componentCodes := componentCodesSet[i].(string) + budgetConditionsForm.ComponentCodes = append(budgetConditionsForm.ComponentCodes, helper.String(componentCodes)) + } + } + if v, ok := dimensionsRangeMap["zone_ids"]; ok { + zoneIdsSet := v.(*schema.Set).List() + for i := range zoneIdsSet { + zoneIds := zoneIdsSet[i].(string) + budgetConditionsForm.ZoneIds = append(budgetConditionsForm.ZoneIds, helper.String(zoneIds)) + } + } + if v, ok := dimensionsRangeMap["region_ids"]; ok { + regionIdsSet := v.(*schema.Set).List() + for i := range regionIdsSet { + regionIds := regionIdsSet[i].(string) + budgetConditionsForm.RegionIds = append(budgetConditionsForm.RegionIds, helper.String(regionIds)) + } + } + if v, ok := dimensionsRangeMap["project_ids"]; ok { + projectIdsSet := v.(*schema.Set).List() + for i := range projectIdsSet { + projectIds := projectIdsSet[i].(string) + budgetConditionsForm.ProjectIds = append(budgetConditionsForm.ProjectIds, helper.String(projectIds)) + } + } + if v, ok := dimensionsRangeMap["action_types"]; ok { + actionTypesSet := v.(*schema.Set).List() + for i := range actionTypesSet { + actionTypes := actionTypesSet[i].(string) + budgetConditionsForm.ActionTypes = append(budgetConditionsForm.ActionTypes, helper.String(actionTypes)) + } + } + if v, ok := dimensionsRangeMap["consumption_types"]; ok { + consumptionTypesSet := v.(*schema.Set).List() + for i := range consumptionTypesSet { + consumptionTypes := consumptionTypesSet[i].(string) + budgetConditionsForm.ConsumptionTypes = append(budgetConditionsForm.ConsumptionTypes, helper.String(consumptionTypes)) + } + } + if v, ok := dimensionsRangeMap["tags"]; ok { + for _, item := range v.([]interface{}) { + tagsMap := item.(map[string]interface{}) + tagsForm := billingv20180709.TagsForm{} + if v, ok := tagsMap["tag_key"]; ok { + tagsForm.TagKey = helper.String(v.(string)) + } + if v, ok := tagsMap["tag_value"]; ok { + tagValueSet := v.(*schema.Set).List() + for i := range tagValueSet { + tagValue := tagValueSet[i].(string) + tagsForm.TagValue = append(tagsForm.TagValue, helper.String(tagValue)) + } + } + budgetConditionsForm.Tags = append(budgetConditionsForm.Tags, &tagsForm) + } + } + if v, ok := dimensionsRangeMap["payer_uins"]; ok { + payerUinsSet := v.(*schema.Set).List() + for i := range payerUinsSet { + payerUins := payerUinsSet[i].(string) + budgetConditionsForm.PayerUins = append(budgetConditionsForm.PayerUins, helper.String(payerUins)) + } + } + if v, ok := dimensionsRangeMap["owner_uins"]; ok { + ownerUinsSet := v.(*schema.Set).List() + for i := range ownerUinsSet { + ownerUins := ownerUinsSet[i].(string) + budgetConditionsForm.OwnerUins = append(budgetConditionsForm.OwnerUins, helper.String(ownerUins)) + } + } + if v, ok := dimensionsRangeMap["tree_node_uniq_keys"]; ok { + treeNodeUniqKeysSet := v.(*schema.Set).List() + for i := range treeNodeUniqKeysSet { + treeNodeUniqKeys := treeNodeUniqKeysSet[i].(string) + budgetConditionsForm.TreeNodeUniqKeys = append(budgetConditionsForm.TreeNodeUniqKeys, helper.String(treeNodeUniqKeys)) + } + } + request.DimensionsRange = &budgetConditionsForm + } + + if v, ok := d.GetOk("wave_threshold_json"); ok { + for _, item := range v.([]interface{}) { + waveThresholdJsonMap := item.(map[string]interface{}) + waveThresholdForm := billingv20180709.WaveThresholdForm{} + if v, ok := waveThresholdJsonMap["warn_type"]; ok { + waveThresholdForm.WarnType = helper.String(v.(string)) + } + if v, ok := waveThresholdJsonMap["threshold"]; ok { + waveThresholdForm.Threshold = helper.String(v.(string)) + } + if v, ok := waveThresholdJsonMap["meta_type"]; ok { + waveThresholdForm.MetaType = helper.String(v.(string)) + } + if v, ok := waveThresholdJsonMap["period_type"]; ok { + waveThresholdForm.PeriodType = helper.String(v.(string)) + } + request.WaveThresholdJson = append(request.WaveThresholdJson, &waveThresholdForm) + } + } + + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseBillingV20180709Client().ModifyBudgetWithContext(ctx, request) + if e != nil { + return tccommon.RetryError(e) + } else { + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), result.ToJsonString()) + } + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s update billing budget failed, reason:%+v", logId, err) + return err + } + } + + return resourceTencentCloudBillingBudgetRead(d, meta) +} + +func resourceTencentCloudBillingBudgetDelete(d *schema.ResourceData, meta interface{}) error { + defer tccommon.LogElapsed("resource.tencentcloud_billing_budget.delete")() + defer tccommon.InconsistentCheck(d, meta)() + + logId := tccommon.GetLogId(tccommon.ContextNil) + ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta) + + budgetId := d.Id() + + var ( + request = billingv20180709.NewDeleteBudgetRequest() + response = billingv20180709.NewDeleteBudgetResponse() + ) + + request.BudgetIds = helper.Strings([]string{budgetId}) + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseBillingV20180709Client().DeleteBudgetWithContext(ctx, request) + if e != nil { + return tccommon.RetryError(e) + } else { + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), result.ToJsonString()) + } + response = result + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s delete billing budget failed, reason:%+v", logId, err) + return err + } + + _ = response + return nil +} diff --git a/tencentcloud/services/billing/resource_tc_billing_budget.md b/tencentcloud/services/billing/resource_tc_billing_budget.md new file mode 100644 index 0000000000..69831f41a1 --- /dev/null +++ b/tencentcloud/services/billing/resource_tc_billing_budget.md @@ -0,0 +1,47 @@ +Provides a resource to create a billing billing_budget + +Example Usage + +```hcl +resource "tencentcloud_billing_budget" "billing_budget" { + budget_name = "tf-test" + cycle_type = "MONTH" + period_begin = "2025-09" + period_end = "2026-09" + plan_type = "FIX" + budget_quota = "10000.00" + bill_type = "BILL" + fee_type = "REAL_COST" + + budget_note = "budget_note" + + warn_json { + warn_type = "ACTUAL" + cal_type = "PERCENTAGE" + threshold_value = "60" + } + dimensions_range { + business = ["p_cvm"] + pay_mode = ["prePay"] + product_codes = ["sp_cvm_s6"] + zone_ids = ["100006"] + region_ids = ["1"] + project_ids = ["0"] + action_types = ["prepay_purchase"] + } + wave_threshold_json { + warn_type = "ACTUAL" + threshold = "20" + meta_type = "chain" + period_type = "day" + } +} +``` + +Import + +billing billing_budget can be imported using the id, e.g. + +``` +terraform import tencentcloud_billing_budget.billing_budget billing_budget_id +``` diff --git a/tencentcloud/services/billing/resource_tc_billing_budget_test.go b/tencentcloud/services/billing/resource_tc_billing_budget_test.go new file mode 100644 index 0000000000..63987d23d7 --- /dev/null +++ b/tencentcloud/services/billing/resource_tc_billing_budget_test.go @@ -0,0 +1,79 @@ +package billing_test + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + + tcacctest "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/acctest" +) + +func TestAccTencentCloudBillingBudgetResource_basic(t *testing.T) { + t.Parallel() + resource.Test(t, resource.TestCase{ + PreCheck: func() { + tcacctest.AccPreCheck(t) + }, + Providers: tcacctest.AccProviders, + Steps: []resource.TestStep{ + { + Config: testAccBillingBudget, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet("tencentcloud_billing_budget.billing_budget", "id"), + resource.TestCheckResourceAttrSet("tencentcloud_billing_budget.billing_budget", "budget_name"), + resource.TestCheckResourceAttrSet("tencentcloud_billing_budget.billing_budget", "cycle_type"), + resource.TestCheckResourceAttrSet("tencentcloud_billing_budget.billing_budget", "period_begin"), + resource.TestCheckResourceAttrSet("tencentcloud_billing_budget.billing_budget", "period_end"), + resource.TestCheckResourceAttrSet("tencentcloud_billing_budget.billing_budget", "plan_type"), + resource.TestCheckResourceAttrSet("tencentcloud_billing_budget.billing_budget", "budget_quota"), + resource.TestCheckResourceAttrSet("tencentcloud_billing_budget.billing_budget", "bill_type"), + resource.TestCheckResourceAttrSet("tencentcloud_billing_budget.billing_budget", "fee_type"), + resource.TestCheckResourceAttr("tencentcloud_billing_budget.billing_budget", "warn_json.#", "1"), + resource.TestCheckResourceAttr("tencentcloud_billing_budget.billing_budget", "dimensions_range.#", "1"), + resource.TestCheckResourceAttr("tencentcloud_billing_budget.billing_budget", "wave_threshold_json.#", "1"), + ), + }, + { + ResourceName: "tencentcloud_billing_budget.billing_budget", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +const testAccBillingBudget = ` +resource "tencentcloud_billing_budget" "billing_budget" { + budget_name = "tf-test" + cycle_type = "MONTH" + period_begin = "2025-09" + period_end = "2026-09" + plan_type = "FIX" + budget_quota = "10000.00" + bill_type = "BILL" + fee_type = "REAL_COST" + + budget_note = "budget_note" + + warn_json { + warn_type = "ACTUAL" + cal_type = "PERCENTAGE" + threshold_value = "60" + } + dimensions_range { + business = ["p_cvm"] + pay_mode = ["prePay"] + product_codes = ["sp_cvm_s6"] + zone_ids = ["100006"] + region_ids = ["1"] + project_ids = ["0"] + action_types = ["prepay_purchase"] + } + wave_threshold_json { + warn_type = "ACTUAL" + threshold = "20" + meta_type = "chain" + period_type = "day" + } +} +` diff --git a/tencentcloud/services/billing/service_tencentcloud_billing.go b/tencentcloud/services/billing/service_tencentcloud_billing.go index 0a3c515ab9..fa894be7e7 100644 --- a/tencentcloud/services/billing/service_tencentcloud_billing.go +++ b/tencentcloud/services/billing/service_tencentcloud_billing.go @@ -89,3 +89,89 @@ func (me *BillingService) DescribeBillingAllocationTagById(ctx context.Context, return } + +func (me *BillingService) DescribeBillingBudgetById(ctx context.Context, budgetId string) (ret *billingv20180709.DescribeBudgetResponseParams, errRet error) { + logId := tccommon.GetLogId(ctx) + + request := billingv20180709.NewDescribeBudgetRequest() + request.BudgetId = helper.String(budgetId) + request.PageNo = helper.IntInt64(1) + request.PageSize = helper.IntInt64(10) + defer func() { + if errRet != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", logId, request.GetAction(), request.ToJsonString(), errRet.Error()) + } + }() + + ratelimit.Check(request.GetAction()) + + response, err := me.client.UseBillingV20180709Client().DescribeBudget(request) + if err != nil { + errRet = err + return + } + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + + ret = response.Response + return +} + +func (me *BillingService) DescribeBillingBudgetOperationLogByFilter(ctx context.Context, param map[string]interface{}) (records []*billingv20180709.BudgetOperationLogEntity, errRet error) { + logId := tccommon.GetLogId(ctx) + request := billingv20180709.NewDescribeBudgetOperationLogRequest() + response := billingv20180709.NewDescribeBudgetOperationLogResponse() + + defer func() { + if errRet != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", logId, request.GetAction(), request.ToJsonString(), errRet.Error()) + } + }() + + for k, v := range param { + if k == "BudgetId" { + request.BudgetId = v.(*string) + } + } + var ( + pageNo int64 = 1 + pageSize int64 = 100 + ) + + for { + request.PageNo = helper.Int64(pageNo) + request.PageSize = helper.Int64(pageSize) + err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { + ratelimit.Check(request.GetAction()) + result, e := me.client.UseBillingV20180709Client().DescribeBudgetOperationLog(request) + if e != nil { + return tccommon.RetryError(e) + } else { + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), result.ToJsonString()) + } + + if result == nil || result.Response == nil { + return resource.NonRetryableError(fmt.Errorf("Describe billing allocation tag failed, Response is nil.")) + } + + response = result + return nil + }) + + if err != nil { + errRet = err + return + } + + if response == nil || response.Response.Data == nil || len(response.Response.Data.Records) == 0 { + break + + } + records = append(records, response.Response.Data.Records...) + if len(response.Response.Data.Records) < int(pageSize) { + break + } + + pageNo += 1 + } + return +} diff --git a/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/billing/v20180709/client.go b/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/billing/v20180709/client.go index a0d8074d32..97cce96234 100644 --- a/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/billing/v20180709/client.go +++ b/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/billing/v20180709/client.go @@ -219,6 +219,58 @@ func (c *Client) CreateAllocationUnitWithContext(ctx context.Context, request *C return } +func NewCreateBudgetRequest() (request *CreateBudgetRequest) { + request = &CreateBudgetRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + + request.Init().WithApiInfo("billing", APIVersion, "CreateBudget") + + + return +} + +func NewCreateBudgetResponse() (response *CreateBudgetResponse) { + response = &CreateBudgetResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return + +} + +// CreateBudget +// 创建预算信息 +// +// 可能返回的错误码: +// INTERNALERROR_GATEWAYERROR = "InternalError.GatewayError" +// INTERNALERROR_UNKNOWNERROR = "InternalError.UnknownError" +func (c *Client) CreateBudget(request *CreateBudgetRequest) (response *CreateBudgetResponse, err error) { + return c.CreateBudgetWithContext(context.Background(), request) +} + +// CreateBudget +// 创建预算信息 +// +// 可能返回的错误码: +// INTERNALERROR_GATEWAYERROR = "InternalError.GatewayError" +// INTERNALERROR_UNKNOWNERROR = "InternalError.UnknownError" +func (c *Client) CreateBudgetWithContext(ctx context.Context, request *CreateBudgetRequest) (response *CreateBudgetResponse, err error) { + if request == nil { + request = NewCreateBudgetRequest() + } + c.InitBaseRequest(&request.BaseRequest, "billing", APIVersion, "CreateBudget") + + if c.GetCredential() == nil { + return nil, errors.New("CreateBudget require credential") + } + + request.SetContext(ctx) + + response = NewCreateBudgetResponse() + err = c.Send(request, response) + return +} + func NewCreateGatherRuleRequest() (request *CreateGatherRuleRequest) { request = &CreateGatherRuleRequest{ BaseRequest: &tchttp.BaseRequest{}, @@ -443,6 +495,62 @@ func (c *Client) DeleteAllocationUnitWithContext(ctx context.Context, request *D return } +func NewDeleteBudgetRequest() (request *DeleteBudgetRequest) { + request = &DeleteBudgetRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + + request.Init().WithApiInfo("billing", APIVersion, "DeleteBudget") + + + return +} + +func NewDeleteBudgetResponse() (response *DeleteBudgetResponse) { + response = &DeleteBudgetResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return + +} + +// DeleteBudget +// 依据预算ID删除对应预算项目 +// +// 可能返回的错误码: +// INTERNALERROR = "InternalError" +// INTERNALERROR_GATEWAYERROR = "InternalError.GatewayError" +// INVALIDPARAMETER = "InvalidParameter" +// OPERATIONDENIED = "OperationDenied" +func (c *Client) DeleteBudget(request *DeleteBudgetRequest) (response *DeleteBudgetResponse, err error) { + return c.DeleteBudgetWithContext(context.Background(), request) +} + +// DeleteBudget +// 依据预算ID删除对应预算项目 +// +// 可能返回的错误码: +// INTERNALERROR = "InternalError" +// INTERNALERROR_GATEWAYERROR = "InternalError.GatewayError" +// INVALIDPARAMETER = "InvalidParameter" +// OPERATIONDENIED = "OperationDenied" +func (c *Client) DeleteBudgetWithContext(ctx context.Context, request *DeleteBudgetRequest) (response *DeleteBudgetResponse, err error) { + if request == nil { + request = NewDeleteBudgetRequest() + } + c.InitBaseRequest(&request.BaseRequest, "billing", APIVersion, "DeleteBudget") + + if c.GetCredential() == nil { + return nil, errors.New("DeleteBudget require credential") + } + + request.SetContext(ctx) + + response = NewDeleteBudgetResponse() + err = c.Send(request, response) + return +} + func NewDeleteGatherRuleRequest() (request *DeleteGatherRuleRequest) { request = &DeleteGatherRuleRequest{ BaseRequest: &tchttp.BaseRequest{}, @@ -2139,6 +2247,180 @@ func (c *Client) DescribeBillSummaryForOrganizationWithContext(ctx context.Conte return } +func NewDescribeBudgetRequest() (request *DescribeBudgetRequest) { + request = &DescribeBudgetRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + + request.Init().WithApiInfo("billing", APIVersion, "DescribeBudget") + + + return +} + +func NewDescribeBudgetResponse() (response *DescribeBudgetResponse) { + response = &DescribeBudgetResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return + +} + +// DescribeBudget +// 获取预算详细信息 +// +// 可能返回的错误码: +// FAILEDOPERATION_TAGKEYNOTEXIST = "FailedOperation.TagKeyNotExist" +// INTERNALERROR = "InternalError" +// INTERNALERROR_GATEWAYERROR = "InternalError.GatewayError" +// INVALIDPARAMETER = "InvalidParameter" +// INVALIDPARAMETERVALUE = "InvalidParameterValue" +func (c *Client) DescribeBudget(request *DescribeBudgetRequest) (response *DescribeBudgetResponse, err error) { + return c.DescribeBudgetWithContext(context.Background(), request) +} + +// DescribeBudget +// 获取预算详细信息 +// +// 可能返回的错误码: +// FAILEDOPERATION_TAGKEYNOTEXIST = "FailedOperation.TagKeyNotExist" +// INTERNALERROR = "InternalError" +// INTERNALERROR_GATEWAYERROR = "InternalError.GatewayError" +// INVALIDPARAMETER = "InvalidParameter" +// INVALIDPARAMETERVALUE = "InvalidParameterValue" +func (c *Client) DescribeBudgetWithContext(ctx context.Context, request *DescribeBudgetRequest) (response *DescribeBudgetResponse, err error) { + if request == nil { + request = NewDescribeBudgetRequest() + } + c.InitBaseRequest(&request.BaseRequest, "billing", APIVersion, "DescribeBudget") + + if c.GetCredential() == nil { + return nil, errors.New("DescribeBudget require credential") + } + + request.SetContext(ctx) + + response = NewDescribeBudgetResponse() + err = c.Send(request, response) + return +} + +func NewDescribeBudgetOperationLogRequest() (request *DescribeBudgetOperationLogRequest) { + request = &DescribeBudgetOperationLogRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + + request.Init().WithApiInfo("billing", APIVersion, "DescribeBudgetOperationLog") + + + return +} + +func NewDescribeBudgetOperationLogResponse() (response *DescribeBudgetOperationLogResponse) { + response = &DescribeBudgetOperationLogResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return + +} + +// DescribeBudgetOperationLog +// 查询预算修改记录 +// +// 可能返回的错误码: +// FAILEDOPERATION_TAGKEYNOTEXIST = "FailedOperation.TagKeyNotExist" +// INTERNALERROR = "InternalError" +// INTERNALERROR_GATEWAYERROR = "InternalError.GatewayError" +// INVALIDPARAMETER = "InvalidParameter" +// INVALIDPARAMETERVALUE = "InvalidParameterValue" +func (c *Client) DescribeBudgetOperationLog(request *DescribeBudgetOperationLogRequest) (response *DescribeBudgetOperationLogResponse, err error) { + return c.DescribeBudgetOperationLogWithContext(context.Background(), request) +} + +// DescribeBudgetOperationLog +// 查询预算修改记录 +// +// 可能返回的错误码: +// FAILEDOPERATION_TAGKEYNOTEXIST = "FailedOperation.TagKeyNotExist" +// INTERNALERROR = "InternalError" +// INTERNALERROR_GATEWAYERROR = "InternalError.GatewayError" +// INVALIDPARAMETER = "InvalidParameter" +// INVALIDPARAMETERVALUE = "InvalidParameterValue" +func (c *Client) DescribeBudgetOperationLogWithContext(ctx context.Context, request *DescribeBudgetOperationLogRequest) (response *DescribeBudgetOperationLogResponse, err error) { + if request == nil { + request = NewDescribeBudgetOperationLogRequest() + } + c.InitBaseRequest(&request.BaseRequest, "billing", APIVersion, "DescribeBudgetOperationLog") + + if c.GetCredential() == nil { + return nil, errors.New("DescribeBudgetOperationLog require credential") + } + + request.SetContext(ctx) + + response = NewDescribeBudgetOperationLogResponse() + err = c.Send(request, response) + return +} + +func NewDescribeBudgetRemindRecordListRequest() (request *DescribeBudgetRemindRecordListRequest) { + request = &DescribeBudgetRemindRecordListRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + + request.Init().WithApiInfo("billing", APIVersion, "DescribeBudgetRemindRecordList") + + + return +} + +func NewDescribeBudgetRemindRecordListResponse() (response *DescribeBudgetRemindRecordListResponse) { + response = &DescribeBudgetRemindRecordListResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return + +} + +// DescribeBudgetRemindRecordList +// 返回预算提醒记录,包括预算周期、检测时间、提醒时间、提醒类型、提醒内容 +// +// 可能返回的错误码: +// FAILEDOPERATION_TAGKEYNOTEXIST = "FailedOperation.TagKeyNotExist" +// INTERNALERROR = "InternalError" +// INTERNALERROR_GATEWAYERROR = "InternalError.GatewayError" +// INVALIDPARAMETER = "InvalidParameter" +// INVALIDPARAMETERVALUE = "InvalidParameterValue" +func (c *Client) DescribeBudgetRemindRecordList(request *DescribeBudgetRemindRecordListRequest) (response *DescribeBudgetRemindRecordListResponse, err error) { + return c.DescribeBudgetRemindRecordListWithContext(context.Background(), request) +} + +// DescribeBudgetRemindRecordList +// 返回预算提醒记录,包括预算周期、检测时间、提醒时间、提醒类型、提醒内容 +// +// 可能返回的错误码: +// FAILEDOPERATION_TAGKEYNOTEXIST = "FailedOperation.TagKeyNotExist" +// INTERNALERROR = "InternalError" +// INTERNALERROR_GATEWAYERROR = "InternalError.GatewayError" +// INVALIDPARAMETER = "InvalidParameter" +// INVALIDPARAMETERVALUE = "InvalidParameterValue" +func (c *Client) DescribeBudgetRemindRecordListWithContext(ctx context.Context, request *DescribeBudgetRemindRecordListRequest) (response *DescribeBudgetRemindRecordListResponse, err error) { + if request == nil { + request = NewDescribeBudgetRemindRecordListRequest() + } + c.InitBaseRequest(&request.BaseRequest, "billing", APIVersion, "DescribeBudgetRemindRecordList") + + if c.GetCredential() == nil { + return nil, errors.New("DescribeBudgetRemindRecordList require credential") + } + + request.SetContext(ctx) + + response = NewDescribeBudgetRemindRecordListResponse() + err = c.Send(request, response) + return +} + func NewDescribeCostDetailRequest() (request *DescribeCostDetailRequest) { request = &DescribeCostDetailRequest{ BaseRequest: &tchttp.BaseRequest{}, @@ -3113,6 +3395,62 @@ func (c *Client) ModifyAllocationUnitWithContext(ctx context.Context, request *M return } +func NewModifyBudgetRequest() (request *ModifyBudgetRequest) { + request = &ModifyBudgetRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + + request.Init().WithApiInfo("billing", APIVersion, "ModifyBudget") + + + return +} + +func NewModifyBudgetResponse() (response *ModifyBudgetResponse) { + response = &ModifyBudgetResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return + +} + +// ModifyBudget +// 更新预算信息 +// +// 可能返回的错误码: +// INTERNALERROR = "InternalError" +// INTERNALERROR_DBOPERATERROR = "InternalError.DbOperatError" +// INTERNALERROR_GATEWAYERROR = "InternalError.GatewayError" +// INVALIDPARAMETER = "InvalidParameter" +func (c *Client) ModifyBudget(request *ModifyBudgetRequest) (response *ModifyBudgetResponse, err error) { + return c.ModifyBudgetWithContext(context.Background(), request) +} + +// ModifyBudget +// 更新预算信息 +// +// 可能返回的错误码: +// INTERNALERROR = "InternalError" +// INTERNALERROR_DBOPERATERROR = "InternalError.DbOperatError" +// INTERNALERROR_GATEWAYERROR = "InternalError.GatewayError" +// INVALIDPARAMETER = "InvalidParameter" +func (c *Client) ModifyBudgetWithContext(ctx context.Context, request *ModifyBudgetRequest) (response *ModifyBudgetResponse, err error) { + if request == nil { + request = NewModifyBudgetRequest() + } + c.InitBaseRequest(&request.BaseRequest, "billing", APIVersion, "ModifyBudget") + + if c.GetCredential() == nil { + return nil, errors.New("ModifyBudget require credential") + } + + request.SetContext(ctx) + + response = NewModifyBudgetResponse() + err = c.Send(request, response) + return +} + func NewModifyGatherRuleRequest() (request *ModifyGatherRuleRequest) { request = &ModifyGatherRuleRequest{ BaseRequest: &tchttp.BaseRequest{}, diff --git a/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/billing/v20180709/models.go b/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/billing/v20180709/models.go index 4393f3cb71..cc7d6f3c66 100644 --- a/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/billing/v20180709/models.go +++ b/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/billing/v20180709/models.go @@ -1902,6 +1902,368 @@ type BillZoneId struct { ZoneName *string `json:"ZoneName,omitnil,omitempty" name:"ZoneName"` } +type BudgetConditionsForm struct { + // 产品 + // 注意:此字段可能返回 null,表示取不到有效值。 + Business []*string `json:"Business,omitnil,omitempty" name:"Business"` + + // 计费模式 + // 注意:此字段可能返回 null,表示取不到有效值。 + PayMode []*string `json:"PayMode,omitnil,omitempty" name:"PayMode"` + + // 子产品 + // 注意:此字段可能返回 null,表示取不到有效值。 + ProductCodes []*string `json:"ProductCodes,omitnil,omitempty" name:"ProductCodes"` + + // 组件编码 + // 注意:此字段可能返回 null,表示取不到有效值。 + ComponentCodes []*string `json:"ComponentCodes,omitnil,omitempty" name:"ComponentCodes"` + + // 地域 + // 注意:此字段可能返回 null,表示取不到有效值。 + ZoneIds []*string `json:"ZoneIds,omitnil,omitempty" name:"ZoneIds"` + + // 可用区 + // 注意:此字段可能返回 null,表示取不到有效值。 + RegionIds []*string `json:"RegionIds,omitnil,omitempty" name:"RegionIds"` + + // 项目 + // 注意:此字段可能返回 null,表示取不到有效值。 + ProjectIds []*string `json:"ProjectIds,omitnil,omitempty" name:"ProjectIds"` + + // 交易类型 + // 注意:此字段可能返回 null,表示取不到有效值。 + ActionTypes []*string `json:"ActionTypes,omitnil,omitempty" name:"ActionTypes"` + + // 消耗类型 + // 注意:此字段可能返回 null,表示取不到有效值。 + ConsumptionTypes []*string `json:"ConsumptionTypes,omitnil,omitempty" name:"ConsumptionTypes"` + + // 标签 + // 注意:此字段可能返回 null,表示取不到有效值。 + Tags []*TagsForm `json:"Tags,omitnil,omitempty" name:"Tags"` + + // 末级分账单元 + // 注意:此字段可能返回 null,表示取不到有效值。 + PayerUins []*string `json:"PayerUins,omitnil,omitempty" name:"PayerUins"` + + // 主用户Uin + // 注意:此字段可能返回 null,表示取不到有效值。 + OwnerUins []*string `json:"OwnerUins,omitnil,omitempty" name:"OwnerUins"` + + // 末级分账单元唯一键 + // 注意:此字段可能返回 null,表示取不到有效值。 + TreeNodeUniqKeys []*string `json:"TreeNodeUniqKeys,omitnil,omitempty" name:"TreeNodeUniqKeys"` +} + +type BudgetExtend struct { + // 预算名称 + BudgetName *string `json:"BudgetName,omitnil,omitempty" name:"BudgetName"` + + // 预算额度 + BudgetQuota *string `json:"BudgetQuota,omitnil,omitempty" name:"BudgetQuota"` + + // DAY 天,MONTH 月度,QUARTER 季度 ,YEAR 年度 + CycleType *string `json:"CycleType,omitnil,omitempty" name:"CycleType"` + + // BILL 系统账单,CONSUMPTION 消耗账单 + BillType *string `json:"BillType,omitnil,omitempty" name:"BillType"` + + // COST 原价,REAL_COST 实际费用,CASH 现金,INCENTIVE 赠送金,VOUCHER 代金券,TRANSFER 分成金,TAX 税,AMOUNT_BEFORE_TAX 现金支付(税前) + FeeType *string `json:"FeeType,omitnil,omitempty" name:"FeeType"` + + // 有效期起始时间 2025-01-01 + PeriodBegin *string `json:"PeriodBegin,omitnil,omitempty" name:"PeriodBegin"` + + // 有效期结束时间 2025-12-01 + PeriodEnd *string `json:"PeriodEnd,omitnil,omitempty" name:"PeriodEnd"` + + // COST,USAGE,RI,SP + Dimensions *string `json:"Dimensions,omitnil,omitempty" name:"Dimensions"` + + // FIX 固定值,CYCLE 不同值 + PlanType *string `json:"PlanType,omitnil,omitempty" name:"PlanType"` + + // 阈值提醒 + WarnJson []*BudgetWarn `json:"WarnJson,omitnil,omitempty" name:"WarnJson"` + + // 用户Uin + PayerUin *uint64 `json:"PayerUin,omitnil,omitempty" name:"PayerUin"` + + // 波动提醒 + WaveThresholdJson []*WaveThresholdForm `json:"WaveThresholdJson,omitnil,omitempty" name:"WaveThresholdJson"` + + // 预算备注 + BudgetNote *string `json:"BudgetNote,omitnil,omitempty" name:"BudgetNote"` + + // 自定义发送对象信息 + SendDetail *string `json:"SendDetail,omitnil,omitempty" name:"SendDetail"` + + // 0:默认uin发送 + DefaultMode *int64 `json:"DefaultMode,omitnil,omitempty" name:"DefaultMode"` + + // CUS 自定义预算,ZERO_COST 零支出预算模板,BY_MONTH 按月费用预算模板 + // 注意:此字段可能返回 null,表示取不到有效值。 + TemplateType *string `json:"TemplateType,omitnil,omitempty" name:"TemplateType"` + + // (1, "未超支"), + // (2, "超支") + MoneyStatus *int64 `json:"MoneyStatus,omitnil,omitempty" name:"MoneyStatus"` + + // 提醒次数 + RemindTimes *int64 `json:"RemindTimes,omitnil,omitempty" name:"RemindTimes"` + + // 创建预算时间 + CreateTime *string `json:"CreateTime,omitnil,omitempty" name:"CreateTime"` + + // 更新预算时间 + UpdateTime *string `json:"UpdateTime,omitnil,omitempty" name:"UpdateTime"` + + // 预算关联Id + BudgetId *string `json:"BudgetId,omitnil,omitempty" name:"BudgetId"` + + // NO_FORECAST(没有设置预测), + // FORECAST_NO_DATA(设置了预测,但是没有数据), + // FORECAST_HAS_DATA(设置了预测,且有预测数据) + // 注意:此字段可能返回 null,表示取不到有效值。 + HasForecast *string `json:"HasForecast,omitnil,omitempty" name:"HasForecast"` + + // 预测费用 + // 注意:此字段可能返回 null,表示取不到有效值。 + ForecastCost *string `json:"ForecastCost,omitnil,omitempty" name:"ForecastCost"` + + // 预测进度 + // 注意:此字段可能返回 null,表示取不到有效值。 + ForecastProgress *string `json:"ForecastProgress,omitnil,omitempty" name:"ForecastProgress"` + + // 实际费用 + RealCost *string `json:"RealCost,omitnil,omitempty" name:"RealCost"` + + // 自定义发送 + BudgetSendInfoForm []*BudgetSendInfoDto `json:"BudgetSendInfoForm,omitnil,omitempty" name:"BudgetSendInfoForm"` + + // 当前周期 + CurDateDesc *string `json:"CurDateDesc,omitnil,omitempty" name:"CurDateDesc"` + + // EXPIRED 已过期 + // ACTIVE 生效中 + // UNACTIVATED 已失效 + // ACTIVATED 待生效 + BudgetStatus *string `json:"BudgetStatus,omitnil,omitempty" name:"BudgetStatus"` + + // 预算维度范围条件 + // 注意:此字段可能返回 null,表示取不到有效值。 + DimensionsRange *BudgetConditionsForm `json:"DimensionsRange,omitnil,omitempty" name:"DimensionsRange"` + + // 预算进度 + // 注意:此字段可能返回 null,表示取不到有效值。 + BudgetProgress *string `json:"BudgetProgress,omitnil,omitempty" name:"BudgetProgress"` + + // 预算类型设置为计划预算时返回预算额度 + // 注意:此字段可能返回 null,表示取不到有效值。 + BudgetQuotaJson []*BudgetPlan `json:"BudgetQuotaJson,omitnil,omitempty" name:"BudgetQuotaJson"` +} + +type BudgetInfoApiResponse struct { + // 预算项目id + BudgetId *string `json:"BudgetId,omitnil,omitempty" name:"BudgetId"` + + // 更新预算时间 + UpdateTime *string `json:"UpdateTime,omitnil,omitempty" name:"UpdateTime"` +} + +type BudgetInfoDiffEntity struct { + // 变更属性 + Property *string `json:"Property,omitnil,omitempty" name:"Property"` + + // 变更前内容 + // 注意:此字段可能返回 null,表示取不到有效值。 + Before *string `json:"Before,omitnil,omitempty" name:"Before"` + + // 变更后内容 + // 注意:此字段可能返回 null,表示取不到有效值。 + After *string `json:"After,omitnil,omitempty" name:"After"` +} + +type BudgetOperationLogEntity struct { + // Uin + PayerUin *uint64 `json:"PayerUin,omitnil,omitempty" name:"PayerUin"` + + // 主用户Uin + OwnerUin *uint64 `json:"OwnerUin,omitnil,omitempty" name:"OwnerUin"` + + // 操作用户Uin + OperateUin *uint64 `json:"OperateUin,omitnil,omitempty" name:"OperateUin"` + + // 日期 + BillDay *uint64 `json:"BillDay,omitnil,omitempty" name:"BillDay"` + + // 月份 + BillMonth *string `json:"BillMonth,omitnil,omitempty" name:"BillMonth"` + + // 修改类型:ADD(新增)、UPDATE(更新) + Action *string `json:"Action,omitnil,omitempty" name:"Action"` + + // 变更信息 + DiffValue []*BudgetInfoDiffEntity `json:"DiffValue,omitnil,omitempty" name:"DiffValue"` + + // 创建时间 + CreateTime *string `json:"CreateTime,omitnil,omitempty" name:"CreateTime"` + + // 修改时间 + UpdateTime *string `json:"UpdateTime,omitnil,omitempty" name:"UpdateTime"` + + // 修改渠道:官网修改/API修改 + OperationChannel *string `json:"OperationChannel,omitnil,omitempty" name:"OperationChannel"` + + // 预算项目id + BudgetId *string `json:"BudgetId,omitnil,omitempty" name:"BudgetId"` +} + +type BudgetPlan struct { + // 前端页面日期显示 + // 注意:此字段可能返回 null,表示取不到有效值。 + DateDesc *string `json:"DateDesc,omitnil,omitempty" name:"DateDesc"` + + // 预算额度 + // 注意:此字段可能返回 null,表示取不到有效值。 + Quota *string `json:"Quota,omitnil,omitempty" name:"Quota"` +} + +type BudgetRemindRecordList struct { + // 自动优化 COUNT SQL 如果遇到 jSqlParser 无法解析情况,设置该参数为 false + // 注意:此字段可能返回 null,表示取不到有效值。 + OptimizeCountSql *bool `json:"OptimizeCountSql,omitnil,omitempty" name:"OptimizeCountSql"` + + // 分页 + // 注意:此字段可能返回 null,表示取不到有效值。 + Pages *uint64 `json:"Pages,omitnil,omitempty" name:"Pages"` + + // 排序字段信息,允许前端传入的时候,注意 SQL 注入问题,可以使用 SqlInjectionUtils.check(...) 检查文本 + // 注意:此字段可能返回 null,表示取不到有效值。 + Orders []*OrderDto `json:"Orders,omitnil,omitempty" name:"Orders"` + + // xml 自定义 count 查询的 statementId 也可以不用指定在分页 statementId 后面加上 _mpCount 例如分页 selectPageById 指定 count 的查询 statementId 设置为 selectPageById_mpCount 即可默认找到该 SQL 执行 + // 注意:此字段可能返回 null,表示取不到有效值。 + CountId *string `json:"CountId,omitnil,omitempty" name:"CountId"` + + // 分页大小 + // 注意:此字段可能返回 null,表示取不到有效值。 + Size *uint64 `json:"Size,omitnil,omitempty" name:"Size"` + + // 总量 + // 注意:此字段可能返回 null,表示取不到有效值。 + Total *uint64 `json:"Total,omitnil,omitempty" name:"Total"` + + // 单页分页条数限制 + // 注意:此字段可能返回 null,表示取不到有效值。 + MaxLimit *string `json:"MaxLimit,omitnil,omitempty" name:"MaxLimit"` + + // 查询数据列表 + // 注意:此字段可能返回 null,表示取不到有效值。 + Records []*BudgetRemindRecords `json:"Records,omitnil,omitempty" name:"Records"` + + // 当前页 + // 注意:此字段可能返回 null,表示取不到有效值。 + Current *uint64 `json:"Current,omitnil,omitempty" name:"Current"` + + // 是否进行 count 查询,如果只想查询到列表不要查询总记录数,设置该参数为 false + // 注意:此字段可能返回 null,表示取不到有效值。 + SearchCount *bool `json:"SearchCount,omitnil,omitempty" name:"SearchCount"` +} + +type BudgetRemindRecords struct { + // 预算周期 + DateDesc *string `json:"DateDesc,omitnil,omitempty" name:"DateDesc"` + + // 实际费用 + RealCost *string `json:"RealCost,omitnil,omitempty" name:"RealCost"` + + // 预算值额度 + BudgetQuota *string `json:"BudgetQuota,omitnil,omitempty" name:"BudgetQuota"` + + // 提醒类型。 + // 枚举值: + // BUDGET 预算提醒, + // WAVE 波动提醒. + // 注意:此字段可能返回 null,表示取不到有效值。 + AlarmType *string `json:"AlarmType,omitnil,omitempty" name:"AlarmType"` + + // 消息内容 + // 注意:此字段可能返回 null,表示取不到有效值。 + MessageContent *string `json:"MessageContent,omitnil,omitempty" name:"MessageContent"` + + // 发送时间 + // 注意:此字段可能返回 null,表示取不到有效值。 + SendTime *int64 `json:"SendTime,omitnil,omitempty" name:"SendTime"` + + // 创建时间 + // 注意:此字段可能返回 null,表示取不到有效值。 + CreateTime *int64 `json:"CreateTime,omitnil,omitempty" name:"CreateTime"` +} + +type BudgetSendInfoDto struct { + // 通知周期,逗号隔开。 + // 枚举值: + // 周一:1, + // 周二:2, + // 周天:7 + // 注意:此字段可能返回 null,表示取不到有效值。 + WeekDays []*uint64 `json:"WeekDays,omitnil,omitempty" name:"WeekDays"` + + // 接收类型。 + // 枚举值: + // UIN 默认模式, + // USER 用户, + // GROUP 用户组。 + // 注意:此字段可能返回 null,表示取不到有效值。 + ReceiverType *string `json:"ReceiverType,omitnil,omitempty" name:"ReceiverType"` + + // 发送接收窗口HH:mm:ss + // 注意:此字段可能返回 null,表示取不到有效值。 + EndTime *string `json:"EndTime,omitnil,omitempty" name:"EndTime"` + + // 预算配置id(预算名称) + // 注意:此字段可能返回 null,表示取不到有效值。 + BudgetId *int64 `json:"BudgetId,omitnil,omitempty" name:"BudgetId"` + + // 接收渠道,逗号隔开; + // 枚举值: + // TITLE 标题, + // SITE 站内信, + // EMAIL 邮件, + // SMS 短信, + // WECHAT 微信, + // VOICE 语音, + // QYWX 企业微信; + // 注意:此字段可能返回 null,表示取不到有效值。 + NoticeWays []*string `json:"NoticeWays,omitnil,omitempty" name:"NoticeWays"` + + // 发送开始窗口HH:mm:ss + // 注意:此字段可能返回 null,表示取不到有效值。 + StartTime *string `json:"StartTime,omitnil,omitempty" name:"StartTime"` + + // id + // 注意:此字段可能返回 null,表示取不到有效值。 + Id *string `json:"Id,omitnil,omitempty" name:"Id"` + + // 用户id,用户组id + // 注意:此字段可能返回 null,表示取不到有效值。 + ReceiverIds []*uint64 `json:"ReceiverIds,omitnil,omitempty" name:"ReceiverIds"` +} + +type BudgetWarn struct { + // ACTUAL 实际金额, + // FORECAST 预测金额 + WarnType *string `json:"WarnType,omitnil,omitempty" name:"WarnType"` + + // PERCENTAGE 预算金额的百分比,ABS 固定值 + CalType *string `json:"CalType,omitnil,omitempty" name:"CalType"` + + // 阈值(大于等于0) + ThresholdValue *string `json:"ThresholdValue,omitnil,omitempty" name:"ThresholdValue"` +} + type BusinessSummaryInfo struct { // 产品编码 BusinessCode *string `json:"BusinessCode,omitnil,omitempty" name:"BusinessCode"` @@ -2610,6 +2972,150 @@ func (r *CreateAllocationUnitResponse) FromJsonString(s string) error { return json.Unmarshal([]byte(s), &r) } +// Predefined struct for user +type CreateBudgetRequestParams struct { + // 预算名称 + BudgetName *string `json:"BudgetName,omitnil,omitempty" name:"BudgetName"` + + // DAY 天,MONTH 月度,QUARTER 季度 ,YEAR 年度 + CycleType *string `json:"CycleType,omitnil,omitempty" name:"CycleType"` + + // 有效期起始时间 2025-01-01(周期: 天) / 2025-01(周期: 月) + PeriodBegin *string `json:"PeriodBegin,omitnil,omitempty" name:"PeriodBegin"` + + // 有效期结束时间 2025-12-01(周期:天) / 2025-12(周期:月) + PeriodEnd *string `json:"PeriodEnd,omitnil,omitempty" name:"PeriodEnd"` + + // FIX 固定预算,CYCLE 计划预算 + PlanType *string `json:"PlanType,omitnil,omitempty" name:"PlanType"` + + // 预算值额度 + // 预算计划类型为FIX(固定预算)时传定值; + // 预算计划类型为CYCLE(计划预算)时传[{"dateDesc":"2025-07","quota":"1000"},{"dateDesc":"2025-08","quota":"2000"}]; + BudgetQuota *string `json:"BudgetQuota,omitnil,omitempty" name:"BudgetQuota"` + + // BILL 系统账单,CONSUMPTION 消耗账单 + BillType *string `json:"BillType,omitnil,omitempty" name:"BillType"` + + // COST 原价,REAL_COST 实际费用,CASH 现金,INCENTIVE 赠送金,VOUCHER 代金券,TRANSFER 分成金,TAX 税,AMOUNT_BEFORE_TAX 现金支付(税前) + FeeType *string `json:"FeeType,omitnil,omitempty" name:"FeeType"` + + // 阈值提醒 + WarnJson []*BudgetWarn `json:"WarnJson,omitnil,omitempty" name:"WarnJson"` + + // 预算备注 + BudgetNote *string `json:"BudgetNote,omitnil,omitempty" name:"BudgetNote"` + + // 预算维度范围条件 + DimensionsRange *BudgetConditionsForm `json:"DimensionsRange,omitnil,omitempty" name:"DimensionsRange"` + + // 波动提醒 + WaveThresholdJson []*WaveThresholdForm `json:"WaveThresholdJson,omitnil,omitempty" name:"WaveThresholdJson"` +} + +type CreateBudgetRequest struct { + *tchttp.BaseRequest + + // 预算名称 + BudgetName *string `json:"BudgetName,omitnil,omitempty" name:"BudgetName"` + + // DAY 天,MONTH 月度,QUARTER 季度 ,YEAR 年度 + CycleType *string `json:"CycleType,omitnil,omitempty" name:"CycleType"` + + // 有效期起始时间 2025-01-01(周期: 天) / 2025-01(周期: 月) + PeriodBegin *string `json:"PeriodBegin,omitnil,omitempty" name:"PeriodBegin"` + + // 有效期结束时间 2025-12-01(周期:天) / 2025-12(周期:月) + PeriodEnd *string `json:"PeriodEnd,omitnil,omitempty" name:"PeriodEnd"` + + // FIX 固定预算,CYCLE 计划预算 + PlanType *string `json:"PlanType,omitnil,omitempty" name:"PlanType"` + + // 预算值额度 + // 预算计划类型为FIX(固定预算)时传定值; + // 预算计划类型为CYCLE(计划预算)时传[{"dateDesc":"2025-07","quota":"1000"},{"dateDesc":"2025-08","quota":"2000"}]; + BudgetQuota *string `json:"BudgetQuota,omitnil,omitempty" name:"BudgetQuota"` + + // BILL 系统账单,CONSUMPTION 消耗账单 + BillType *string `json:"BillType,omitnil,omitempty" name:"BillType"` + + // COST 原价,REAL_COST 实际费用,CASH 现金,INCENTIVE 赠送金,VOUCHER 代金券,TRANSFER 分成金,TAX 税,AMOUNT_BEFORE_TAX 现金支付(税前) + FeeType *string `json:"FeeType,omitnil,omitempty" name:"FeeType"` + + // 阈值提醒 + WarnJson []*BudgetWarn `json:"WarnJson,omitnil,omitempty" name:"WarnJson"` + + // 预算备注 + BudgetNote *string `json:"BudgetNote,omitnil,omitempty" name:"BudgetNote"` + + // 预算维度范围条件 + DimensionsRange *BudgetConditionsForm `json:"DimensionsRange,omitnil,omitempty" name:"DimensionsRange"` + + // 波动提醒 + WaveThresholdJson []*WaveThresholdForm `json:"WaveThresholdJson,omitnil,omitempty" name:"WaveThresholdJson"` +} + +func (r *CreateBudgetRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +// FromJsonString It is highly **NOT** recommended to use this function +// because it has no param check, nor strict type check +func (r *CreateBudgetRequest) FromJsonString(s string) error { + f := make(map[string]interface{}) + if err := json.Unmarshal([]byte(s), &f); err != nil { + return err + } + delete(f, "BudgetName") + delete(f, "CycleType") + delete(f, "PeriodBegin") + delete(f, "PeriodEnd") + delete(f, "PlanType") + delete(f, "BudgetQuota") + delete(f, "BillType") + delete(f, "FeeType") + delete(f, "WarnJson") + delete(f, "BudgetNote") + delete(f, "DimensionsRange") + delete(f, "WaveThresholdJson") + if len(f) > 0 { + return tcerr.NewTencentCloudSDKError("ClientError.BuildRequestError", "CreateBudgetRequest has unknown keys!", "") + } + return json.Unmarshal([]byte(s), &r) +} + +// Predefined struct for user +type CreateBudgetResponseParams struct { + // 创建预算返回信息 + Data *BudgetInfoApiResponse `json:"Data,omitnil,omitempty" name:"Data"` + + // create success + Message *string `json:"Message,omitnil,omitempty" name:"Message"` + + // 返回码 + Code *int64 `json:"Code,omitnil,omitempty" name:"Code"` + + // 唯一请求 ID,由服务端生成,每次请求都会返回(若请求因其他原因未能抵达服务端,则该次请求不会获得 RequestId)。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitnil,omitempty" name:"RequestId"` +} + +type CreateBudgetResponse struct { + *tchttp.BaseResponse + Response *CreateBudgetResponseParams `json:"Response"` +} + +func (r *CreateBudgetResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +// FromJsonString It is highly **NOT** recommended to use this function +// because it has no param check, nor strict type check +func (r *CreateBudgetResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + // Predefined struct for user type CreateGatherRuleRequestParams struct { // 规则所属分账单元ID @@ -2681,6 +3187,42 @@ func (r *CreateGatherRuleResponse) FromJsonString(s string) error { return json.Unmarshal([]byte(s), &r) } +type DataForBudgetInfoPage struct { + // 分页 + Pages *uint64 `json:"Pages,omitnil,omitempty" name:"Pages"` + + // 分页大小 + Size *uint64 `json:"Size,omitnil,omitempty" name:"Size"` + + // 总量 + Total *uint64 `json:"Total,omitnil,omitempty" name:"Total"` + + // 查询数据列表 + // 注意:此字段可能返回 null,表示取不到有效值。 + Records []*BudgetExtend `json:"Records,omitnil,omitempty" name:"Records"` + + // 当前页 + Current *uint64 `json:"Current,omitnil,omitempty" name:"Current"` +} + +type DataForBudgetOperationLogPage struct { + // 分页 + Pages *uint64 `json:"Pages,omitnil,omitempty" name:"Pages"` + + // 分页大小 + Size *uint64 `json:"Size,omitnil,omitempty" name:"Size"` + + // 总量 + Total *uint64 `json:"Total,omitnil,omitempty" name:"Total"` + + // 查询数据列表 + // 注意:此字段可能返回 null,表示取不到有效值。 + Records []*BudgetOperationLogEntity `json:"Records,omitnil,omitempty" name:"Records"` + + // 当前页 + Current *uint64 `json:"Current,omitnil,omitempty" name:"Current"` +} + type Deal struct { // 订单号 OrderId *string `json:"OrderId,omitnil,omitempty" name:"OrderId"` @@ -2923,30 +3465,93 @@ func (r *DeleteAllocationUnitRequest) FromJsonString(s string) error { delete(f, "Id") delete(f, "Month") if len(f) > 0 { - return tcerr.NewTencentCloudSDKError("ClientError.BuildRequestError", "DeleteAllocationUnitRequest has unknown keys!", "") + return tcerr.NewTencentCloudSDKError("ClientError.BuildRequestError", "DeleteAllocationUnitRequest has unknown keys!", "") + } + return json.Unmarshal([]byte(s), &r) +} + +// Predefined struct for user +type DeleteAllocationUnitResponseParams struct { + // 唯一请求 ID,由服务端生成,每次请求都会返回(若请求因其他原因未能抵达服务端,则该次请求不会获得 RequestId)。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitnil,omitempty" name:"RequestId"` +} + +type DeleteAllocationUnitResponse struct { + *tchttp.BaseResponse + Response *DeleteAllocationUnitResponseParams `json:"Response"` +} + +func (r *DeleteAllocationUnitResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +// FromJsonString It is highly **NOT** recommended to use this function +// because it has no param check, nor strict type check +func (r *DeleteAllocationUnitResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +// Predefined struct for user +type DeleteBudgetRequestParams struct { + // 预算项目id + BudgetIds []*string `json:"BudgetIds,omitnil,omitempty" name:"BudgetIds"` +} + +type DeleteBudgetRequest struct { + *tchttp.BaseRequest + + // 预算项目id + BudgetIds []*string `json:"BudgetIds,omitnil,omitempty" name:"BudgetIds"` +} + +func (r *DeleteBudgetRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +// FromJsonString It is highly **NOT** recommended to use this function +// because it has no param check, nor strict type check +func (r *DeleteBudgetRequest) FromJsonString(s string) error { + f := make(map[string]interface{}) + if err := json.Unmarshal([]byte(s), &f); err != nil { + return err + } + delete(f, "BudgetIds") + if len(f) > 0 { + return tcerr.NewTencentCloudSDKError("ClientError.BuildRequestError", "DeleteBudgetRequest has unknown keys!", "") } return json.Unmarshal([]byte(s), &r) } // Predefined struct for user -type DeleteAllocationUnitResponseParams struct { +type DeleteBudgetResponseParams struct { + // 返回删除预算项目id + Data []*string `json:"Data,omitnil,omitempty" name:"Data"` + + // 信息提示 + Message *string `json:"Message,omitnil,omitempty" name:"Message"` + + // 返回码 + Code *int64 `json:"Code,omitnil,omitempty" name:"Code"` + // 唯一请求 ID,由服务端生成,每次请求都会返回(若请求因其他原因未能抵达服务端,则该次请求不会获得 RequestId)。定位问题时需要提供该次请求的 RequestId。 RequestId *string `json:"RequestId,omitnil,omitempty" name:"RequestId"` } -type DeleteAllocationUnitResponse struct { +type DeleteBudgetResponse struct { *tchttp.BaseResponse - Response *DeleteAllocationUnitResponseParams `json:"Response"` + Response *DeleteBudgetResponseParams `json:"Response"` } -func (r *DeleteAllocationUnitResponse) ToJsonString() string { +func (r *DeleteBudgetResponse) ToJsonString() string { b, _ := json.Marshal(r) return string(b) } // FromJsonString It is highly **NOT** recommended to use this function // because it has no param check, nor strict type check -func (r *DeleteAllocationUnitResponse) FromJsonString(s string) error { +func (r *DeleteBudgetResponse) FromJsonString(s string) error { return json.Unmarshal([]byte(s), &r) } @@ -6643,6 +7248,260 @@ func (r *DescribeBillSummaryResponse) FromJsonString(s string) error { return json.Unmarshal([]byte(s), &r) } +// Predefined struct for user +type DescribeBudgetOperationLogRequestParams struct { + // 页码 + PageNo *int64 `json:"PageNo,omitnil,omitempty" name:"PageNo"` + + // 每页数目 + PageSize *int64 `json:"PageSize,omitnil,omitempty" name:"PageSize"` + + // 预算项目id + BudgetId *string `json:"BudgetId,omitnil,omitempty" name:"BudgetId"` +} + +type DescribeBudgetOperationLogRequest struct { + *tchttp.BaseRequest + + // 页码 + PageNo *int64 `json:"PageNo,omitnil,omitempty" name:"PageNo"` + + // 每页数目 + PageSize *int64 `json:"PageSize,omitnil,omitempty" name:"PageSize"` + + // 预算项目id + BudgetId *string `json:"BudgetId,omitnil,omitempty" name:"BudgetId"` +} + +func (r *DescribeBudgetOperationLogRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +// FromJsonString It is highly **NOT** recommended to use this function +// because it has no param check, nor strict type check +func (r *DescribeBudgetOperationLogRequest) FromJsonString(s string) error { + f := make(map[string]interface{}) + if err := json.Unmarshal([]byte(s), &f); err != nil { + return err + } + delete(f, "PageNo") + delete(f, "PageSize") + delete(f, "BudgetId") + if len(f) > 0 { + return tcerr.NewTencentCloudSDKError("ClientError.BuildRequestError", "DescribeBudgetOperationLogRequest has unknown keys!", "") + } + return json.Unmarshal([]byte(s), &r) +} + +// Predefined struct for user +type DescribeBudgetOperationLogResponseParams struct { + // 预算修改记录详情 + Data *DataForBudgetOperationLogPage `json:"Data,omitnil,omitempty" name:"Data"` + + // 信息提示 + Message *string `json:"Message,omitnil,omitempty" name:"Message"` + + // 返回码 + Code *int64 `json:"Code,omitnil,omitempty" name:"Code"` + + // 唯一请求 ID,由服务端生成,每次请求都会返回(若请求因其他原因未能抵达服务端,则该次请求不会获得 RequestId)。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitnil,omitempty" name:"RequestId"` +} + +type DescribeBudgetOperationLogResponse struct { + *tchttp.BaseResponse + Response *DescribeBudgetOperationLogResponseParams `json:"Response"` +} + +func (r *DescribeBudgetOperationLogResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +// FromJsonString It is highly **NOT** recommended to use this function +// because it has no param check, nor strict type check +func (r *DescribeBudgetOperationLogResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +// Predefined struct for user +type DescribeBudgetRemindRecordListRequestParams struct { + // 页码,整型 + PageNo *int64 `json:"PageNo,omitnil,omitempty" name:"PageNo"` + + // 每页数目,整型 + PageSize *int64 `json:"PageSize,omitnil,omitempty" name:"PageSize"` + + // 预算基础信息关联id + BudgetId *string `json:"BudgetId,omitnil,omitempty" name:"BudgetId"` +} + +type DescribeBudgetRemindRecordListRequest struct { + *tchttp.BaseRequest + + // 页码,整型 + PageNo *int64 `json:"PageNo,omitnil,omitempty" name:"PageNo"` + + // 每页数目,整型 + PageSize *int64 `json:"PageSize,omitnil,omitempty" name:"PageSize"` + + // 预算基础信息关联id + BudgetId *string `json:"BudgetId,omitnil,omitempty" name:"BudgetId"` +} + +func (r *DescribeBudgetRemindRecordListRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +// FromJsonString It is highly **NOT** recommended to use this function +// because it has no param check, nor strict type check +func (r *DescribeBudgetRemindRecordListRequest) FromJsonString(s string) error { + f := make(map[string]interface{}) + if err := json.Unmarshal([]byte(s), &f); err != nil { + return err + } + delete(f, "PageNo") + delete(f, "PageSize") + delete(f, "BudgetId") + if len(f) > 0 { + return tcerr.NewTencentCloudSDKError("ClientError.BuildRequestError", "DescribeBudgetRemindRecordListRequest has unknown keys!", "") + } + return json.Unmarshal([]byte(s), &r) +} + +// Predefined struct for user +type DescribeBudgetRemindRecordListResponseParams struct { + // 预算配置属性 + Data *BudgetRemindRecordList `json:"Data,omitnil,omitempty" name:"Data"` + + // 错误信息提示 + // 注意:此字段可能返回 null,表示取不到有效值。 + Message *string `json:"Message,omitnil,omitempty" name:"Message"` + + // 错误响应码 + Code *int64 `json:"Code,omitnil,omitempty" name:"Code"` + + // 唯一请求 ID,由服务端生成,每次请求都会返回(若请求因其他原因未能抵达服务端,则该次请求不会获得 RequestId)。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitnil,omitempty" name:"RequestId"` +} + +type DescribeBudgetRemindRecordListResponse struct { + *tchttp.BaseResponse + Response *DescribeBudgetRemindRecordListResponseParams `json:"Response"` +} + +func (r *DescribeBudgetRemindRecordListResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +// FromJsonString It is highly **NOT** recommended to use this function +// because it has no param check, nor strict type check +func (r *DescribeBudgetRemindRecordListResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +// Predefined struct for user +type DescribeBudgetRequestParams struct { + // 页码,整型 + PageNo *int64 `json:"PageNo,omitnil,omitempty" name:"PageNo"` + + // 每页数目,整型 + PageSize *int64 `json:"PageSize,omitnil,omitempty" name:"PageSize"` + + // 预算项目id + BudgetId *string `json:"BudgetId,omitnil,omitempty" name:"BudgetId"` + + // 预算名称 + BudgetName *string `json:"BudgetName,omitnil,omitempty" name:"BudgetName"` + + // EXPIRED失效,ACTIVE生效中, ACTIVATED待生效 + BudgetStatus *string `json:"BudgetStatus,omitnil,omitempty" name:"BudgetStatus"` + + // DAY天 MONTH月度 QUARTER季度 YEAR年度 + CycleTypes []*string `json:"CycleTypes,omitnil,omitempty" name:"CycleTypes"` +} + +type DescribeBudgetRequest struct { + *tchttp.BaseRequest + + // 页码,整型 + PageNo *int64 `json:"PageNo,omitnil,omitempty" name:"PageNo"` + + // 每页数目,整型 + PageSize *int64 `json:"PageSize,omitnil,omitempty" name:"PageSize"` + + // 预算项目id + BudgetId *string `json:"BudgetId,omitnil,omitempty" name:"BudgetId"` + + // 预算名称 + BudgetName *string `json:"BudgetName,omitnil,omitempty" name:"BudgetName"` + + // EXPIRED失效,ACTIVE生效中, ACTIVATED待生效 + BudgetStatus *string `json:"BudgetStatus,omitnil,omitempty" name:"BudgetStatus"` + + // DAY天 MONTH月度 QUARTER季度 YEAR年度 + CycleTypes []*string `json:"CycleTypes,omitnil,omitempty" name:"CycleTypes"` +} + +func (r *DescribeBudgetRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +// FromJsonString It is highly **NOT** recommended to use this function +// because it has no param check, nor strict type check +func (r *DescribeBudgetRequest) FromJsonString(s string) error { + f := make(map[string]interface{}) + if err := json.Unmarshal([]byte(s), &f); err != nil { + return err + } + delete(f, "PageNo") + delete(f, "PageSize") + delete(f, "BudgetId") + delete(f, "BudgetName") + delete(f, "BudgetStatus") + delete(f, "CycleTypes") + if len(f) > 0 { + return tcerr.NewTencentCloudSDKError("ClientError.BuildRequestError", "DescribeBudgetRequest has unknown keys!", "") + } + return json.Unmarshal([]byte(s), &r) +} + +// Predefined struct for user +type DescribeBudgetResponseParams struct { + // 预算项目详情 + Data *DataForBudgetInfoPage `json:"Data,omitnil,omitempty" name:"Data"` + + // 信息提示 + // 注意:此字段可能返回 null,表示取不到有效值。 + Message *string `json:"Message,omitnil,omitempty" name:"Message"` + + // 返回码 + Code *int64 `json:"Code,omitnil,omitempty" name:"Code"` + + // 唯一请求 ID,由服务端生成,每次请求都会返回(若请求因其他原因未能抵达服务端,则该次请求不会获得 RequestId)。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitnil,omitempty" name:"RequestId"` +} + +type DescribeBudgetResponse struct { + *tchttp.BaseResponse + Response *DescribeBudgetResponseParams `json:"Response"` +} + +func (r *DescribeBudgetResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +// FromJsonString It is highly **NOT** recommended to use this function +// because it has no param check, nor strict type check +func (r *DescribeBudgetResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + // Predefined struct for user type DescribeCostDetailRequestParams struct { // 数量,最大值为100 @@ -9056,6 +9915,158 @@ func (r *ModifyAllocationUnitResponse) FromJsonString(s string) error { return json.Unmarshal([]byte(s), &r) } +// Predefined struct for user +type ModifyBudgetRequestParams struct { + // 预算项目id + BudgetId *string `json:"BudgetId,omitnil,omitempty" name:"BudgetId"` + + // 预算名称 + BudgetName *string `json:"BudgetName,omitnil,omitempty" name:"BudgetName"` + + // DAY 天,MONTH 月度,QUARTER 季度 ,YEAR 年度 + CycleType *string `json:"CycleType,omitnil,omitempty" name:"CycleType"` + + // 有效期起始时间 2025-01-01 + PeriodBegin *string `json:"PeriodBegin,omitnil,omitempty" name:"PeriodBegin"` + + // 有效期结束时间 2025-12-01 + PeriodEnd *string `json:"PeriodEnd,omitnil,omitempty" name:"PeriodEnd"` + + // FIX 固定值,CYCLE 不同值 + PlanType *string `json:"PlanType,omitnil,omitempty" name:"PlanType"` + + // 预算值额度 + // 预算计划类型固定预算时设为定值; + // 预算计划类型为CYCLE(计划预算)时传[{"dateDesc":"2025-07","quota":"1000"},{"dateDesc":"2025-08","quota":"2000"}]; + BudgetQuota *string `json:"BudgetQuota,omitnil,omitempty" name:"BudgetQuota"` + + // BILL 系统账单,CONSUMPTION 消耗账单 + BillType *string `json:"BillType,omitnil,omitempty" name:"BillType"` + + // COST 原价,REAL_COST 实际费用,CASH 现金,INCENTIVE 赠送金,VOUCHER 代金券,TRANSFER 分成金,TAX 税,AMOUNT_BEFORE_TAX 现金支付(税前) + FeeType *string `json:"FeeType,omitnil,omitempty" name:"FeeType"` + + // 阈值提醒 + WarnJson []*BudgetWarn `json:"WarnJson,omitnil,omitempty" name:"WarnJson"` + + // 预算备注 + BudgetNote *string `json:"BudgetNote,omitnil,omitempty" name:"BudgetNote"` + + // 预算维度范围条件 + DimensionsRange *BudgetConditionsForm `json:"DimensionsRange,omitnil,omitempty" name:"DimensionsRange"` + + // 波动提醒 + WaveThresholdJson []*WaveThresholdForm `json:"WaveThresholdJson,omitnil,omitempty" name:"WaveThresholdJson"` +} + +type ModifyBudgetRequest struct { + *tchttp.BaseRequest + + // 预算项目id + BudgetId *string `json:"BudgetId,omitnil,omitempty" name:"BudgetId"` + + // 预算名称 + BudgetName *string `json:"BudgetName,omitnil,omitempty" name:"BudgetName"` + + // DAY 天,MONTH 月度,QUARTER 季度 ,YEAR 年度 + CycleType *string `json:"CycleType,omitnil,omitempty" name:"CycleType"` + + // 有效期起始时间 2025-01-01 + PeriodBegin *string `json:"PeriodBegin,omitnil,omitempty" name:"PeriodBegin"` + + // 有效期结束时间 2025-12-01 + PeriodEnd *string `json:"PeriodEnd,omitnil,omitempty" name:"PeriodEnd"` + + // FIX 固定值,CYCLE 不同值 + PlanType *string `json:"PlanType,omitnil,omitempty" name:"PlanType"` + + // 预算值额度 + // 预算计划类型固定预算时设为定值; + // 预算计划类型为CYCLE(计划预算)时传[{"dateDesc":"2025-07","quota":"1000"},{"dateDesc":"2025-08","quota":"2000"}]; + BudgetQuota *string `json:"BudgetQuota,omitnil,omitempty" name:"BudgetQuota"` + + // BILL 系统账单,CONSUMPTION 消耗账单 + BillType *string `json:"BillType,omitnil,omitempty" name:"BillType"` + + // COST 原价,REAL_COST 实际费用,CASH 现金,INCENTIVE 赠送金,VOUCHER 代金券,TRANSFER 分成金,TAX 税,AMOUNT_BEFORE_TAX 现金支付(税前) + FeeType *string `json:"FeeType,omitnil,omitempty" name:"FeeType"` + + // 阈值提醒 + WarnJson []*BudgetWarn `json:"WarnJson,omitnil,omitempty" name:"WarnJson"` + + // 预算备注 + BudgetNote *string `json:"BudgetNote,omitnil,omitempty" name:"BudgetNote"` + + // 预算维度范围条件 + DimensionsRange *BudgetConditionsForm `json:"DimensionsRange,omitnil,omitempty" name:"DimensionsRange"` + + // 波动提醒 + WaveThresholdJson []*WaveThresholdForm `json:"WaveThresholdJson,omitnil,omitempty" name:"WaveThresholdJson"` +} + +func (r *ModifyBudgetRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +// FromJsonString It is highly **NOT** recommended to use this function +// because it has no param check, nor strict type check +func (r *ModifyBudgetRequest) FromJsonString(s string) error { + f := make(map[string]interface{}) + if err := json.Unmarshal([]byte(s), &f); err != nil { + return err + } + delete(f, "BudgetId") + delete(f, "BudgetName") + delete(f, "CycleType") + delete(f, "PeriodBegin") + delete(f, "PeriodEnd") + delete(f, "PlanType") + delete(f, "BudgetQuota") + delete(f, "BillType") + delete(f, "FeeType") + delete(f, "WarnJson") + delete(f, "BudgetNote") + delete(f, "DimensionsRange") + delete(f, "WaveThresholdJson") + if len(f) > 0 { + return tcerr.NewTencentCloudSDKError("ClientError.BuildRequestError", "ModifyBudgetRequest has unknown keys!", "") + } + return json.Unmarshal([]byte(s), &r) +} + +// Predefined struct for user +type ModifyBudgetResponseParams struct { + // 更新预算返回信息 + Data *BudgetInfoApiResponse `json:"Data,omitnil,omitempty" name:"Data"` + + // update success + // 注意:此字段可能返回 null,表示取不到有效值。 + Message *string `json:"Message,omitnil,omitempty" name:"Message"` + + // 返回码 + Code *int64 `json:"Code,omitnil,omitempty" name:"Code"` + + // 唯一请求 ID,由服务端生成,每次请求都会返回(若请求因其他原因未能抵达服务端,则该次请求不会获得 RequestId)。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitnil,omitempty" name:"RequestId"` +} + +type ModifyBudgetResponse struct { + *tchttp.BaseResponse + Response *ModifyBudgetResponseParams `json:"Response"` +} + +func (r *ModifyBudgetResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +// FromJsonString It is highly **NOT** recommended to use this function +// because it has no param check, nor strict type check +func (r *ModifyBudgetResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + // Predefined struct for user type ModifyGatherRuleRequestParams struct { // 所编辑归集规则ID @@ -9124,6 +10135,16 @@ func (r *ModifyGatherRuleResponse) FromJsonString(s string) error { return json.Unmarshal([]byte(s), &r) } +type OrderDto struct { + // 字段 + // 注意:此字段可能返回 null,表示取不到有效值。 + Column *string `json:"Column,omitnil,omitempty" name:"Column"` + + // 是否升序 + // 注意:此字段可能返回 null,表示取不到有效值。 + Asc *bool `json:"Asc,omitnil,omitempty" name:"Asc"` +} + // Predefined struct for user type PayDealsRequestParams struct { // 需要支付的一个或者多个子订单号,与BigDealIds字段两者必须且仅传一个参数 @@ -9400,6 +10421,16 @@ type TagSummaryOverviewItem struct { TotalCost *string `json:"TotalCost,omitnil,omitempty" name:"TotalCost"` } +type TagsForm struct { + // key + // 注意:此字段可能返回 null,表示取不到有效值。 + TagKey *string `json:"TagKey,omitnil,omitempty" name:"TagKey"` + + // value + // 注意:此字段可能返回 null,表示取不到有效值。 + TagValue []*string `json:"TagValue,omitnil,omitempty" name:"TagValue"` +} + type UsageDetails struct { // 商品名 ProductName *string `json:"ProductName,omitnil,omitempty" name:"ProductName"` @@ -9494,4 +10525,24 @@ type VoucherInfos struct { // 发券时间 CreateTime *string `json:"CreateTime,omitnil,omitempty" name:"CreateTime"` +} + +type WaveThresholdForm struct { + // ACTUAL 实际金额,FORECAST 预测金额 + // 注意:此字段可能返回 null,表示取不到有效值。 + WarnType *string `json:"WarnType,omitnil,omitempty" name:"WarnType"` + + // 波动阈值(大于等于0) + // 注意:此字段可能返回 null,表示取不到有效值。 + Threshold *string `json:"Threshold,omitnil,omitempty" name:"Threshold"` + + // 告警类型:chain 环比,yoy 同比,fix 固定值 + // (支持类型:日环比 chain day,日同比周维度 chain weekday,日同比月维度 yoy day,日固定值 fix day,月环比 chain month,月固定值 fix month) + // 注意:此字段可能返回 null,表示取不到有效值。 + MetaType *string `json:"MetaType,omitnil,omitempty" name:"MetaType"` + + // 告警维度:day 日,month 月,weekday 周 + // (支持类型:日环比 chain day,日同比周维度 chain weekday,日同比月维度 yoy day,日固定值 fix day,月环比 chain month,月固定值 fix month) + // 注意:此字段可能返回 null,表示取不到有效值。 + PeriodType *string `json:"PeriodType,omitnil,omitempty" name:"PeriodType"` } \ No newline at end of file diff --git a/vendor/modules.txt b/vendor/modules.txt index 42aee71366..ca25ac26db 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1116,7 +1116,7 @@ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/as/v20180419 # github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/bi v1.0.824 ## explicit; go 1.14 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/bi/v20220105 -# github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/billing v1.1.0 +# github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/billing v1.1.31 ## explicit; go 1.14 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/billing/v20180709 # github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cam v1.1.27 diff --git a/website/docs/d/billing_budget_operation_log.html.markdown b/website/docs/d/billing_budget_operation_log.html.markdown new file mode 100644 index 0000000000..f6aa693a1d --- /dev/null +++ b/website/docs/d/billing_budget_operation_log.html.markdown @@ -0,0 +1,49 @@ +--- +subcategory: "Billing" +layout: "tencentcloud" +page_title: "TencentCloud: tencentcloud_billing_budget_operation_log" +sidebar_current: "docs-tencentcloud-datasource-billing_budget_operation_log" +description: |- + Use this data source to query detailed information of billing billing_budget_operation_log +--- + +# tencentcloud_billing_budget_operation_log + +Use this data source to query detailed information of billing billing_budget_operation_log + +## Example Usage + +```hcl +data "tencentcloud_billing_budget_operation_log" "billing_budget_operation_log" { + budget_id = "1971489821259956225" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `budget_id` - (Required, String) Budget id. +* `result_output_file` - (Optional, String) Used to save results. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `records` - Query data list. + * `action` - Modification type: ADD, UPDATE. + * `bill_day` - Bill day. + * `bill_month` - Bill month. + * `budget_id` - Budget item id. + * `create_time` - Create time. + * `diff_value` - change information. + * `after` - Content after change. + * `before` - Content before change. + * `property` - Change attributes. + * `operate_uin` - Operate uin. + * `operation_channel` - Operation channel. + * `owner_uin` - Owner uin. + * `payer_uin` - Payer uin. + * `update_time` - Update time. + + diff --git a/website/docs/r/billing_budget.html.markdown b/website/docs/r/billing_budget.html.markdown new file mode 100644 index 0000000000..7e2ed56293 --- /dev/null +++ b/website/docs/r/billing_budget.html.markdown @@ -0,0 +1,120 @@ +--- +subcategory: "Billing" +layout: "tencentcloud" +page_title: "TencentCloud: tencentcloud_billing_budget" +sidebar_current: "docs-tencentcloud-resource-billing_budget" +description: |- + Provides a resource to create a billing billing_budget +--- + +# tencentcloud_billing_budget + +Provides a resource to create a billing billing_budget + +## Example Usage + +```hcl +resource "tencentcloud_billing_budget" "billing_budget" { + budget_name = "tf-test" + cycle_type = "MONTH" + period_begin = "2025-09" + period_end = "2026-09" + plan_type = "FIX" + budget_quota = "10000.00" + bill_type = "BILL" + fee_type = "REAL_COST" + + budget_note = "budget_note" + + warn_json { + warn_type = "ACTUAL" + cal_type = "PERCENTAGE" + threshold_value = "60" + } + dimensions_range { + business = ["p_cvm"] + pay_mode = ["prePay"] + product_codes = ["sp_cvm_s6"] + zone_ids = ["100006"] + region_ids = ["1"] + project_ids = ["0"] + action_types = ["prepay_purchase"] + } + wave_threshold_json { + warn_type = "ACTUAL" + threshold = "20" + meta_type = "chain" + period_type = "day" + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `bill_type` - (Required, String) BILL: system bill, CONSUMPTION: consumption bill. +* `budget_name` - (Required, String) Budget name. +* `budget_quota` - (Required, String) Budget value limit. Transfer fixed value when the budget plan type is FIX(Fixed Budget); Passed when the budget plan type is CYCLE(Planned Budget)[{"dateDesc":"2025-07","quota":"1000"},{"dateDesc":"2025-08","quota":"2000"}]. +* `cycle_type` - (Required, String) Cycle type, valid values: DAY, MONTH, QUARTER, YEAR. +* `fee_type` - (Required, String) COST original price, REAL_COST actual cost, CASH cash, INCENTIVE gift, VOUCHER voucher, TRANSFER share, TAX tax, AMOUNT_BEFORE_TAX cash payment (before tax). +* `period_begin` - (Required, String) Valid period starting time 2025-01-01(cycle: days) / 2025-01 (cycle: months). +* `period_end` - (Required, String) Expiration period end time 2025-12-01(cycle: days) / 2025-12 (cycle: months). +* `plan_type` - (Required, String) FIX: fixed budget, CYCLE: planned budget. +* `warn_json` - (Required, List) Threshold reminder. +* `budget_note` - (Optional, String) Budget remarks. +* `dimensions_range` - (Optional, List) Budget dimension range conditions. +* `wave_threshold_json` - (Optional, List) Volatility reminder. + +The `dimensions_range` object supports the following: + +* `action_types` - (Optional, Set) Action types. +* `business` - (Optional, Set) Products. +* `component_codes` - (Optional, Set) Component codes. +* `consumption_types` - (Optional, Set) Consumption types. +* `owner_uins` - (Optional, Set) Owner uins. +* `pay_mode` - (Optional, Set) Pay mode. +* `payer_uins` - (Optional, Set) Payer uins. +* `product_codes` - (Optional, Set) Sub-product. +* `project_ids` - (Optional, Set) Project ids. +* `region_ids` - (Optional, Set) Region ids. +* `tags` - (Optional, List) Tags. +* `tree_node_uniq_keys` - (Optional, Set) Unique key for end-level ledger unit. +* `zone_ids` - (Optional, Set) Zone ids. + +The `tags` object of `dimensions_range` supports the following: + +* `tag_key` - (Optional, String) Tag key. +* `tag_value` - (Optional, Set) Tag value. + +The `warn_json` object supports the following: + +* `cal_type` - (Required, String) PERCENTAGE: Percentage of budget amount, ABS: fixed value. +* `threshold_value` - (Required, String) Threshold (greater than or equal to 0). +* `warn_type` - (Required, String) ACTUAL: actual amount, FORECAST: forecast amount. + +The `wave_threshold_json` object supports the following: + +* `meta_type` - (Optional, String) Alarm type: chain month-on-month, yoy year-on-year, fix fixed value + (Supported types: daily month-on-month chain day, daily month-on-year chain weekday, daily month-on-year monthly month-on-year fixed value fix day, month-on-month chain month, monthly fixed value fix month). +* `period_type` - (Optional, String) Alarm dimension: day day, month month, weekday week + (Support types: day-to-day chain day, day-to-year weekly dimension chain weekday, day-to-year monthly dimension yoy day, daily fixed value fix day, month-to-month chain month, monthly fixed value fix month). +* `threshold` - (Optional, String) Volatility threshold (greater than or equal to 0). +* `warn_type` - (Optional, String) ACTUAL: actual amount, FORECAST: forecast amount. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - ID of the resource. + + + +## Import + +billing billing_budget can be imported using the id, e.g. + +``` +terraform import tencentcloud_billing_budget.billing_budget billing_budget_id +``` + diff --git a/website/tencentcloud.erb b/website/tencentcloud.erb index 656b6fdc43..e10013face 100644 --- a/website/tencentcloud.erb +++ b/website/tencentcloud.erb @@ -490,13 +490,23 @@
  • Billing From 0296d4e3c7f284767f5d3b958d9f2d4479563432 Mon Sep 17 00:00:00 2001 From: mikatong Date: Fri, 26 Sep 2025 19:28:45 +0800 Subject: [PATCH 2/3] add changelog --- .changelog/3537.txt | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .changelog/3537.txt diff --git a/.changelog/3537.txt b/.changelog/3537.txt new file mode 100644 index 0000000000..ae61459fd5 --- /dev/null +++ b/.changelog/3537.txt @@ -0,0 +1,7 @@ +```release-note:new-data-source +tencentcloud_billing_budget_operation_log +``` + +```release-note:new-resource +tencentcloud_billing_budget +``` From 7be343770fcae68ba97251164b1bae24ef3f633a Mon Sep 17 00:00:00 2001 From: mikatong Date: Fri, 26 Sep 2025 19:40:49 +0800 Subject: [PATCH 3/3] update --- .../billing/resource_tc_billing_budget.go | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/tencentcloud/services/billing/resource_tc_billing_budget.go b/tencentcloud/services/billing/resource_tc_billing_budget.go index ab14110720..5d7d76f991 100644 --- a/tencentcloud/services/billing/resource_tc_billing_budget.go +++ b/tencentcloud/services/billing/resource_tc_billing_budget.go @@ -512,34 +512,34 @@ func resourceTencentCloudBillingBudgetRead(d *schema.ResourceData, meta interfac record := respData.Data.Records[0] if record.BudgetName != nil { - d.Set("budget_name", record.BudgetName) + _ = d.Set("budget_name", record.BudgetName) } if record.CycleType != nil { - d.Set("cycle_type", record.CycleType) + _ = d.Set("cycle_type", record.CycleType) } if record.PeriodBegin != nil { - d.Set("period_begin", record.PeriodBegin) + _ = d.Set("period_begin", record.PeriodBegin) } if record.PeriodEnd != nil { - d.Set("period_end", record.PeriodEnd) + _ = d.Set("period_end", record.PeriodEnd) } if record.PlanType != nil { - d.Set("plan_type", record.PlanType) + _ = d.Set("plan_type", record.PlanType) } if record.BudgetQuota != nil { - d.Set("budget_quota", record.BudgetQuota) + _ = d.Set("budget_quota", record.BudgetQuota) } if record.BillType != nil { - d.Set("bill_type", record.BillType) + _ = d.Set("bill_type", record.BillType) } if record.FeeType != nil { - d.Set("fee_type", record.FeeType) + _ = d.Set("fee_type", record.FeeType) } warnJsonList := make([]map[string]interface{}, 0, len(record.WarnJson)) @@ -562,11 +562,11 @@ func resourceTencentCloudBillingBudgetRead(d *schema.ResourceData, meta interfac warnJsonList = append(warnJsonList, warnJsonMap) } - d.Set("warn_json", warnJsonList) + _ = d.Set("warn_json", warnJsonList) } if record.BudgetNote != nil { - d.Set("budget_note", record.BudgetNote) + _ = d.Set("budget_note", record.BudgetNote) } waveThresholdJsonList := make([]map[string]interface{}, 0, len(record.WaveThresholdJson)) @@ -593,7 +593,7 @@ func resourceTencentCloudBillingBudgetRead(d *schema.ResourceData, meta interfac waveThresholdJsonList = append(waveThresholdJsonList, waveThresholdJsonMap) } - d.Set("wave_threshold_json", waveThresholdJsonList) + _ = d.Set("wave_threshold_json", waveThresholdJsonList) } if record.DimensionsRange != nil { @@ -670,9 +670,9 @@ func resourceTencentCloudBillingBudgetRead(d *schema.ResourceData, meta interfac } } if hasNotNullItem { - d.Set("dimensions_range", []interface{}{dimensionsRangeMap}) + _ = d.Set("dimensions_range", []interface{}{dimensionsRangeMap}) } else { - d.Set("dimensions_range", []interface{}{}) + _ = d.Set("dimensions_range", []interface{}{}) } }