From 6ffaa2cc70b4e3a821c4a2d286b26b06e73a01d8 Mon Sep 17 00:00:00 2001 From: fergalmcl Date: Tue, 28 Jan 2025 12:14:50 +0000 Subject: [PATCH 1/4] Added voicemail timeout to user exports correctly --- docs/resources/user.md | 10 +++ genesyscloud/user/genesyscloud_user_proxy.go | 83 ++++++++++++------- .../user/resource_genesyscloud_user.go | 8 ++ .../user/resource_genesyscloud_user_schema.go | 24 +++++- .../user/resource_genesyscloud_user_test.go | 56 +++++++++++++ .../user/resource_genesyscloud_user_utils.go | 59 +++++++++++++ 6 files changed, 209 insertions(+), 31 deletions(-) diff --git a/docs/resources/user.md b/docs/resources/user.md index adb7a2395..8c810a89f 100644 --- a/docs/resources/user.md +++ b/docs/resources/user.md @@ -132,6 +132,7 @@ resource "genesyscloud_user" "example_user" { - `routing_utilization` (List of Object) The routing utilization settings for this user. If empty list, the org default settings are used. If not set, this resource will not manage the users's utilization settings. (see [below for nested schema](#nestedatt--routing_utilization)) - `state` (String) User's state (active | inactive). Default is 'active'. Defaults to `active`. - `title` (String) User's title. +- `voicemail_userpolicies` (Block List, Max: 1) User's voicemail policies. (see [below for nested schema](#nestedblock--voicemail_userpolicies)) ### Read-Only @@ -275,3 +276,12 @@ Optional: - `interruptible_media_types` (Set of String) - `maximum_capacity` (Number) + + + +### Nested Schema for `voicemail_userpolicies` + +Optional: + +- `alert_timeout_seconds` (Number) The number of seconds to ring the user's phone before a call is transferred to voicemail. + diff --git a/genesyscloud/user/genesyscloud_user_proxy.go b/genesyscloud/user/genesyscloud_user_proxy.go index 2d300c17d..c1579f1de 100644 --- a/genesyscloud/user/genesyscloud_user_proxy.go +++ b/genesyscloud/user/genesyscloud_user_proxy.go @@ -33,6 +33,8 @@ type deleteUserFunc func(ctx context.Context, p *userProxy, id string) (*interfa type patchUserWithStateFunc func(ctx context.Context, p *userProxy, id string, updateUser *platformclientv2.Updateuser) (*platformclientv2.User, *platformclientv2.APIResponse, error) type hydrateUserCacheFunc func(ctx context.Context, p *userProxy, pageSize int, pageNum int) (*platformclientv2.Userentitylisting, *platformclientv2.APIResponse, error) type getUserByNameFunc func(ctx context.Context, p *userProxy, searchUser platformclientv2.Usersearchrequest) (*platformclientv2.Userssearchresponse, *platformclientv2.APIResponse, error) +type updateVoicemailUserpoliciesFunc func(ctx context.Context, p *userProxy, id string, policy *platformclientv2.Voicemailuserpolicy) (*platformclientv2.Voicemailuserpolicy, *platformclientv2.APIResponse, error) +type getVoicemailUserpoliciesByIdFunc func(ctx context.Context, p *userProxy, id string) (*platformclientv2.Voicemailuserpolicy, *platformclientv2.APIResponse, error) /* The userProxy struct holds all the methods responsible for making calls to @@ -42,19 +44,22 @@ enabling this terraform provider software to perform tasks like retrieving data, or triggering actions within the Genesys Cloud environment. */ type userProxy struct { - clientConfig *platformclientv2.Configuration - userApi *platformclientv2.UsersApi - routingApi *platformclientv2.RoutingApi - createUserAttr createUserFunc - getAllUserAttr getAllUserFunc - getUserIdByNameAttr getUserIdByNameFunc - getUserByIdAttr getUserByIdFunc - updateUserAttr updateUserFunc - deleteUserAttr deleteUserFunc - patchUserWithStateAttr patchUserWithStateFunc - hydrateUserCacheAttr hydrateUserCacheFunc - getUserByNameAttr getUserByNameFunc - userCache rc.CacheInterface[platformclientv2.User] //Define the cache for user resource + clientConfig *platformclientv2.Configuration + userApi *platformclientv2.UsersApi + routingApi *platformclientv2.RoutingApi + voicemailApi *platformclientv2.VoicemailApi + createUserAttr createUserFunc + getAllUserAttr getAllUserFunc + getUserIdByNameAttr getUserIdByNameFunc + getUserByIdAttr getUserByIdFunc + updateUserAttr updateUserFunc + deleteUserAttr deleteUserFunc + patchUserWithStateAttr patchUserWithStateFunc + hydrateUserCacheAttr hydrateUserCacheFunc + getUserByNameAttr getUserByNameFunc + updateVoicemailUserpoliciesAttr updateVoicemailUserpoliciesFunc + getVoicemailUserpolicicesByIdAttr getVoicemailUserpoliciesByIdFunc + userCache rc.CacheInterface[platformclientv2.User] //Define the cache for user resource } /* @@ -66,21 +71,25 @@ seamlessly with the Genesys Cloud platform. func newUserProxy(clientConfig *platformclientv2.Configuration) *userProxy { userApi := platformclientv2.NewUsersApiWithConfig(clientConfig) // NewUsersApiWithConfig creates an Genesyc Cloud API instance using the provided configuration routingApi := platformclientv2.NewRoutingApiWithConfig(clientConfig) // NewRoutingApiWithConfig creates an Genesyc Cloud API instance using the provided configuration - userCache := rc.NewResourceCache[platformclientv2.User]() // Create Cache for User resource + voicemailApi := platformclientv2.NewVoicemailApiWithConfig(clientConfig) + userCache := rc.NewResourceCache[platformclientv2.User]() // Create Cache for User resource return &userProxy{ - clientConfig: clientConfig, - userApi: userApi, - routingApi: routingApi, - userCache: userCache, - createUserAttr: createUserFn, - getAllUserAttr: getAllUserFn, - getUserIdByNameAttr: getUserIdByNameFn, - getUserByIdAttr: getUserByIdFn, - updateUserAttr: updateUserFn, - deleteUserAttr: deleteUserFn, - patchUserWithStateAttr: patchUserWithStateFn, - hydrateUserCacheAttr: hydrateUserCacheFn, - getUserByNameAttr: getUserByNameFn, + clientConfig: clientConfig, + userApi: userApi, + routingApi: routingApi, + voicemailApi: voicemailApi, + userCache: userCache, + createUserAttr: createUserFn, + getAllUserAttr: getAllUserFn, + getUserIdByNameAttr: getUserIdByNameFn, + getUserByIdAttr: getUserByIdFn, + updateUserAttr: updateUserFn, + deleteUserAttr: deleteUserFn, + patchUserWithStateAttr: patchUserWithStateFn, + hydrateUserCacheAttr: hydrateUserCacheFn, + updateVoicemailUserpoliciesAttr: updateVoicemailUserpoliciesFn, + getUserByNameAttr: getUserByNameFn, + getVoicemailUserpolicicesByIdAttr: getVoicemailUserpoliciesByUserIdFn, } } @@ -146,6 +155,16 @@ func (p *userProxy) getUserByName(ctx context.Context, searchUser platformclient return p.getUserByNameAttr(ctx, p, searchUser) } +// updateVoicemailUserpolicies +func (p *userProxy) updateVoicemailUserpolicies(ctx context.Context, userId string, updatePolicy *platformclientv2.Voicemailuserpolicy) (*platformclientv2.Voicemailuserpolicy, *platformclientv2.APIResponse, error) { + return p.updateVoicemailUserpoliciesAttr(ctx, p, userId, updatePolicy) +} + +// getVoicemailUserpoliciesById +func (p *userProxy) getVoicemailUserpoliciesById(ctx context.Context, id string) (*platformclientv2.Voicemailuserpolicy, *platformclientv2.APIResponse, error) { + return p.getVoicemailUserpolicicesByIdAttr(ctx, p, id) +} + // createUserFn is an implementation function for creating a Genesys Cloud user func createUserFn(ctx context.Context, p *userProxy, createUser *platformclientv2.Createuser) (*platformclientv2.User, *platformclientv2.APIResponse, error) { return p.userApi.PostUsers(*createUser) @@ -270,5 +289,13 @@ func getUserIdByNameFn(ctx context.Context, p *userProxy, name string) (id strin } } - return "", true, apiResponse, fmt.Errorf("Unable to find user wiht name %s", name) + return "", true, apiResponse, fmt.Errorf("Unable to find user with name %s", name) +} + +func updateVoicemailUserpoliciesFn(ctx context.Context, p *userProxy, userId string, updatePolicy *platformclientv2.Voicemailuserpolicy) (*platformclientv2.Voicemailuserpolicy, *platformclientv2.APIResponse, error) { + return p.voicemailApi.PatchVoicemailUserpolicy(userId, *updatePolicy) +} + +func getVoicemailUserpoliciesByUserIdFn(ctx context.Context, p *userProxy, id string) (*platformclientv2.Voicemailuserpolicy, *platformclientv2.APIResponse, error) { + return p.voicemailApi.GetVoicemailUserpolicy(id) } diff --git a/genesyscloud/user/resource_genesyscloud_user.go b/genesyscloud/user/resource_genesyscloud_user.go index e95040cdc..447b986cd 100644 --- a/genesyscloud/user/resource_genesyscloud_user.go +++ b/genesyscloud/user/resource_genesyscloud_user.go @@ -178,6 +178,14 @@ func readUser(ctx context.Context, d *schema.ResourceData, meta interface{}) dia d.Set("certifications", flattenUserData(currentUser.Certifications)) d.Set("employer_info", flattenUserEmployerInfo(currentUser.EmployerInfo)) + //Get attributes from Voicemail/Userpolicies resource + currentVoicemailUserpolicies, resp, err := proxy.getVoicemailUserpoliciesById(ctx, d.Id()) + if err != nil { + return retry.RetryableError(util.BuildWithRetriesApiDiagnosticError(ResourceType, fmt.Sprintf("Failed to read voicemail userpolicies %s error: %s", d.Id(), err), resp)) + } + + _ = d.Set("voicemail_userpolicies", flattenVoicemailUserpolicies(d, currentVoicemailUserpolicies)) + if diagErr := readUserRoutingUtilization(d, proxy); diagErr != nil { return retry.NonRetryableError(fmt.Errorf("%v", diagErr)) } diff --git a/genesyscloud/user/resource_genesyscloud_user_schema.go b/genesyscloud/user/resource_genesyscloud_user_schema.go index 24fed8040..6c2fd4b33 100644 --- a/genesyscloud/user/resource_genesyscloud_user_schema.go +++ b/genesyscloud/user/resource_genesyscloud_user_schema.go @@ -159,6 +159,15 @@ var ( }, }, } + voicemailUserpoliciesResource = &schema.Resource{ + Schema: map[string]*schema.Schema{ + "alert_timeout_seconds": { + Description: "The number of seconds to ring the user's phone before a call is transferred to voicemail.", + Type: schema.TypeInt, + Optional: true, + }, + }, + } ) func ResourceUser() *schema.Resource { @@ -388,6 +397,14 @@ func ResourceUser() *schema.Resource { }, }, }, + "voicemail_userpolicies": { + Description: "User's voicemail policies.", + Type: schema.TypeList, + MaxItems: 1, + Optional: true, + Computed: true, + Elem: voicemailUserpoliciesResource, + }, }, } } @@ -422,9 +439,10 @@ func UserExporter() *resourceExporter.ResourceExporter { "locations.location_id": {RefType: "genesyscloud_location"}, }, RemoveIfMissing: map[string][]string{ - "routing_skills": {"skill_id"}, - "routing_languages": {"language_id"}, - "locations": {"location_id"}, + "routing_skills": {"skill_id"}, + "routing_languages": {"language_id"}, + "locations": {"location_id"}, + "voicemail_userpolicies": {"alert_timeout_seconds"}, }, AllowZeroValues: []string{"routing_skills.proficiency", "routing_languages.proficiency"}, } diff --git a/genesyscloud/user/resource_genesyscloud_user_test.go b/genesyscloud/user/resource_genesyscloud_user_test.go index f239f3332..174318478 100644 --- a/genesyscloud/user/resource_genesyscloud_user_test.go +++ b/genesyscloud/user/resource_genesyscloud_user_test.go @@ -173,6 +173,62 @@ func TestAccResourceUserBasic(t *testing.T) { }) } +func TestAccResourceUserVoicemailUserpolicies(t *testing.T) { + var ( + userResourceLabel1 = "test-user1" + email1 = "terraform-" + uuid.NewString() + "@user.com" + email2 = "terraform-" + uuid.NewString() + "@user.com" + userName1 = "John Terraform" + userName2 = "Jim Terraform" + timeoutSeconds = 550 + timeoutSeconds2 = 450 + ) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { util.TestAccPreCheck(t) }, + ProviderFactories: provider.GetProviderFactories(providerResources, providerDataSources), + Steps: []resource.TestStep{ + { + // Create + Config: generateUserWithCustomAttrs( + userResourceLabel1, + email1, + userName1, + GenerateVoicemailUserpolicies(timeoutSeconds), + ), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(ResourceType+"."+userResourceLabel1, "email", email1), + resource.TestCheckResourceAttr(ResourceType+"."+userResourceLabel1, "name", userName1), + resource.TestCheckResourceAttr(ResourceType+"."+userResourceLabel1, "voicemail_userpolicies.0.alert_timeout_seconds", strconv.Itoa(timeoutSeconds)), + provider.TestDefaultHomeDivision(ResourceType+"."+userResourceLabel1), + ), + }, + { + // Update + Config: generateUserWithCustomAttrs( + userResourceLabel1, + email2, + userName2, + GenerateVoicemailUserpolicies(timeoutSeconds2), + ), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(ResourceType+"."+userResourceLabel1, "email", email2), + resource.TestCheckResourceAttr(ResourceType+"."+userResourceLabel1, "name", userName2), + resource.TestCheckResourceAttr(ResourceType+"."+userResourceLabel1, "voicemail_userpolicies.0.alert_timeout_seconds", strconv.Itoa(timeoutSeconds2)), + provider.TestDefaultHomeDivision(ResourceType+"."+userResourceLabel1), + ), + }, + { + // Import/Read + ResourceName: ResourceType + "." + userResourceLabel1, + ImportState: true, + ImportStateVerify: true, + }, + }, + CheckDestroy: testVerifyUsersDestroyed, + }) +} + func generateUserWithCustomAttrs(resourceLabel string, email string, name string, attrs ...string) string { return fmt.Sprintf(`resource "%s" "%s" { email = "%s" diff --git a/genesyscloud/user/resource_genesyscloud_user_utils.go b/genesyscloud/user/resource_genesyscloud_user_utils.go index 909055de0..072485254 100644 --- a/genesyscloud/user/resource_genesyscloud_user_utils.go +++ b/genesyscloud/user/resource_genesyscloud_user_utils.go @@ -115,6 +115,11 @@ func executeAllUpdates(d *schema.ResourceData, proxy *userProxy, sdkConfig *plat return diagErr } + diagErr = updateUserVoicemailPolicies(d, proxy) + if diagErr != nil { + return diagErr + } + return nil } @@ -236,6 +241,32 @@ func updateUserProfileSkills(d *schema.ResourceData, proxy *userProxy) diag.Diag return nil } +func updateUserVoicemailPolicies(d *schema.ResourceData, proxy *userProxy) diag.Diagnostics { + if d.HasChange("voicemail_userpolicies") { + if voicemailUserpolicies := d.Get("voicemail_userpolicies").([]interface{}); voicemailUserpolicies != nil { + if len(voicemailUserpolicies) > 0 { + if extractMap, ok := voicemailUserpolicies[0].(map[string]interface{}); ok { + reqBody := buildVoicemailUserpoliciesRequest(extractMap) + diagErr := util.RetryWhen(util.IsVersionMismatch, func() (*platformclientv2.APIResponse, diag.Diagnostics) { + + _, proxyPutResponse, putErr := proxy.voicemailApi.PatchVoicemailUserpolicy(d.Id(), reqBody) + if putErr != nil { + return proxyPutResponse, util.BuildAPIDiagnosticError(ResourceType, fmt.Sprintf("Failed to update voicemail userpolicices for user %s error: %s", d.Id(), putErr), proxyPutResponse) + } + + return nil, nil + }) + if diagErr != nil { + return diagErr + } + } + + } + } + } + return nil +} + func updateUserRoutingUtilization(d *schema.ResourceData, proxy *userProxy) diag.Diagnostics { if d.HasChange("routing_utilization") { if utilConfig := d.Get("routing_utilization").([]interface{}); utilConfig != nil { @@ -871,6 +902,27 @@ func getSdkUtilizationTypes() []string { return types } +func buildVoicemailUserpoliciesRequest(voicemailUserpolicyMap map[string]interface{}) platformclientv2.Voicemailuserpolicy { + alertTimeoutSeconds := voicemailUserpolicyMap["alert_timeout_seconds"].(int) + + return platformclientv2.Voicemailuserpolicy{ + AlertTimeoutSeconds: &alertTimeoutSeconds, + } +} + +func flattenVoicemailUserpolicies(d *schema.ResourceData, voicemail *platformclientv2.Voicemailuserpolicy) []interface{} { + if voicemail == nil { + return nil + } + + voicemailUserpolicy := make(map[string]interface{}) + if voicemail.AlertTimeoutSeconds != nil { + voicemailUserpolicy["alert_timeout_seconds"] = *voicemail.AlertTimeoutSeconds + } + + return []interface{}{voicemailUserpolicy} +} + func generateRoutingUtilMediaType( mediaType string, maxCapacity string, @@ -935,3 +987,10 @@ func GenerateUserResource(resourceLabel string, email string, name string, state } `, ResourceType, resourceLabel, email, name, state, title, department, manager, acdAutoAnswer, profileSkills, certifications) } + +func GenerateVoicemailUserpolicies(timeout int) string { + return fmt.Sprintf(`voicemail_userpolicies { + alert_timeout_seconds = %d + } + `, timeout) +} From 1e820948726d855e37b166fa1acea72316773ad4 Mon Sep 17 00:00:00 2001 From: fergalmcl Date: Wed, 29 Jan 2025 15:35:05 +0000 Subject: [PATCH 2/4] addressed comments on PR --- docs/resources/user.md | 1 + .../user/resource_genesyscloud_user_schema.go | 5 ++ .../user/resource_genesyscloud_user_test.go | 24 ++++++---- .../user/resource_genesyscloud_user_utils.go | 47 ++++++++++--------- 4 files changed, 45 insertions(+), 32 deletions(-) diff --git a/docs/resources/user.md b/docs/resources/user.md index 8c810a89f..5f50c2db8 100644 --- a/docs/resources/user.md +++ b/docs/resources/user.md @@ -284,4 +284,5 @@ Optional: Optional: - `alert_timeout_seconds` (Number) The number of seconds to ring the user's phone before a call is transferred to voicemail. +- `send_email_notifications` (Boolean) Whether email notifications are sent to the user when a new voicemail is received. diff --git a/genesyscloud/user/resource_genesyscloud_user_schema.go b/genesyscloud/user/resource_genesyscloud_user_schema.go index 6c2fd4b33..db84a9dda 100644 --- a/genesyscloud/user/resource_genesyscloud_user_schema.go +++ b/genesyscloud/user/resource_genesyscloud_user_schema.go @@ -166,6 +166,11 @@ var ( Type: schema.TypeInt, Optional: true, }, + "send_email_notifications": { + Description: "Whether email notifications are sent to the user when a new voicemail is received.", + Type: schema.TypeBool, + Optional: true, + }, }, } ) diff --git a/genesyscloud/user/resource_genesyscloud_user_test.go b/genesyscloud/user/resource_genesyscloud_user_test.go index 174318478..c42ba0067 100644 --- a/genesyscloud/user/resource_genesyscloud_user_test.go +++ b/genesyscloud/user/resource_genesyscloud_user_test.go @@ -175,13 +175,15 @@ func TestAccResourceUserBasic(t *testing.T) { func TestAccResourceUserVoicemailUserpolicies(t *testing.T) { var ( - userResourceLabel1 = "test-user1" - email1 = "terraform-" + uuid.NewString() + "@user.com" - email2 = "terraform-" + uuid.NewString() + "@user.com" - userName1 = "John Terraform" - userName2 = "Jim Terraform" - timeoutSeconds = 550 - timeoutSeconds2 = 450 + userResourceLabel1 = "test-user1" + email1 = "terraform-" + uuid.NewString() + "@user.com" + email2 = "terraform-" + uuid.NewString() + "@user.com" + userName1 = "John Terraform" + userName2 = "Jim Terraform" + timeoutSeconds1 = 550 + timeoutSeconds2 = 450 + sendEmailNotification1 = true + sendEmailNotification2 = false ) resource.Test(t, resource.TestCase{ @@ -194,12 +196,13 @@ func TestAccResourceUserVoicemailUserpolicies(t *testing.T) { userResourceLabel1, email1, userName1, - GenerateVoicemailUserpolicies(timeoutSeconds), + GenerateVoicemailUserpolicies(timeoutSeconds1, sendEmailNotification1), ), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(ResourceType+"."+userResourceLabel1, "email", email1), resource.TestCheckResourceAttr(ResourceType+"."+userResourceLabel1, "name", userName1), - resource.TestCheckResourceAttr(ResourceType+"."+userResourceLabel1, "voicemail_userpolicies.0.alert_timeout_seconds", strconv.Itoa(timeoutSeconds)), + resource.TestCheckResourceAttr(ResourceType+"."+userResourceLabel1, "voicemail_userpolicies.0.alert_timeout_seconds", strconv.Itoa(timeoutSeconds1)), + resource.TestCheckResourceAttr(ResourceType+"."+userResourceLabel1, "voicemail_userpolicies.0.send_email_notifications", strconv.FormatBool(sendEmailNotification1)), provider.TestDefaultHomeDivision(ResourceType+"."+userResourceLabel1), ), }, @@ -209,12 +212,13 @@ func TestAccResourceUserVoicemailUserpolicies(t *testing.T) { userResourceLabel1, email2, userName2, - GenerateVoicemailUserpolicies(timeoutSeconds2), + GenerateVoicemailUserpolicies(timeoutSeconds2, sendEmailNotification2), ), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(ResourceType+"."+userResourceLabel1, "email", email2), resource.TestCheckResourceAttr(ResourceType+"."+userResourceLabel1, "name", userName2), resource.TestCheckResourceAttr(ResourceType+"."+userResourceLabel1, "voicemail_userpolicies.0.alert_timeout_seconds", strconv.Itoa(timeoutSeconds2)), + resource.TestCheckResourceAttr(ResourceType+"."+userResourceLabel1, "voicemail_userpolicies.0.send_email_notifications", strconv.FormatBool(sendEmailNotification2)), provider.TestDefaultHomeDivision(ResourceType+"."+userResourceLabel1), ), }, diff --git a/genesyscloud/user/resource_genesyscloud_user_utils.go b/genesyscloud/user/resource_genesyscloud_user_utils.go index 072485254..5807c04a4 100644 --- a/genesyscloud/user/resource_genesyscloud_user_utils.go +++ b/genesyscloud/user/resource_genesyscloud_user_utils.go @@ -244,23 +244,16 @@ func updateUserProfileSkills(d *schema.ResourceData, proxy *userProxy) diag.Diag func updateUserVoicemailPolicies(d *schema.ResourceData, proxy *userProxy) diag.Diagnostics { if d.HasChange("voicemail_userpolicies") { if voicemailUserpolicies := d.Get("voicemail_userpolicies").([]interface{}); voicemailUserpolicies != nil { - if len(voicemailUserpolicies) > 0 { - if extractMap, ok := voicemailUserpolicies[0].(map[string]interface{}); ok { - reqBody := buildVoicemailUserpoliciesRequest(extractMap) - diagErr := util.RetryWhen(util.IsVersionMismatch, func() (*platformclientv2.APIResponse, diag.Diagnostics) { - - _, proxyPutResponse, putErr := proxy.voicemailApi.PatchVoicemailUserpolicy(d.Id(), reqBody) - if putErr != nil { - return proxyPutResponse, util.BuildAPIDiagnosticError(ResourceType, fmt.Sprintf("Failed to update voicemail userpolicices for user %s error: %s", d.Id(), putErr), proxyPutResponse) - } - - return nil, nil - }) - if diagErr != nil { - return diagErr - } + reqBody := buildVoicemailUserpoliciesRequest(voicemailUserpolicies) + diagErr := util.RetryWhen(util.IsVersionMismatch, func() (*platformclientv2.APIResponse, diag.Diagnostics) { + _, proxyPutResponse, putErr := proxy.voicemailApi.PatchVoicemailUserpolicy(d.Id(), reqBody) + if putErr != nil { + return proxyPutResponse, util.BuildAPIDiagnosticError(ResourceType, fmt.Sprintf("Failed to update voicemail userpolicices for user %s error: %s", d.Id(), putErr), proxyPutResponse) } - + return nil, nil + }) + if diagErr != nil { + return diagErr } } } @@ -902,12 +895,18 @@ func getSdkUtilizationTypes() []string { return types } -func buildVoicemailUserpoliciesRequest(voicemailUserpolicyMap map[string]interface{}) platformclientv2.Voicemailuserpolicy { - alertTimeoutSeconds := voicemailUserpolicyMap["alert_timeout_seconds"].(int) +func buildVoicemailUserpoliciesRequest(voicemailUserpolicies []interface{}) platformclientv2.Voicemailuserpolicy { + var request platformclientv2.Voicemailuserpolicy + if extractMap, ok := voicemailUserpolicies[0].(map[string]interface{}); ok { + alertTimeoutSeconds := extractMap["alert_timeout_seconds"].(int) + sendEmailNotifications := extractMap["send_email_notifications"].(bool) - return platformclientv2.Voicemailuserpolicy{ - AlertTimeoutSeconds: &alertTimeoutSeconds, + request = platformclientv2.Voicemailuserpolicy{ + AlertTimeoutSeconds: &alertTimeoutSeconds, + SendEmailNotifications: &sendEmailNotifications, + } } + return request } func flattenVoicemailUserpolicies(d *schema.ResourceData, voicemail *platformclientv2.Voicemailuserpolicy) []interface{} { @@ -919,6 +918,9 @@ func flattenVoicemailUserpolicies(d *schema.ResourceData, voicemail *platformcli if voicemail.AlertTimeoutSeconds != nil { voicemailUserpolicy["alert_timeout_seconds"] = *voicemail.AlertTimeoutSeconds } + if voicemail.SendEmailNotifications != nil { + voicemailUserpolicy["send_email_notifications"] = *voicemail.SendEmailNotifications + } return []interface{}{voicemailUserpolicy} } @@ -988,9 +990,10 @@ func GenerateUserResource(resourceLabel string, email string, name string, state `, ResourceType, resourceLabel, email, name, state, title, department, manager, acdAutoAnswer, profileSkills, certifications) } -func GenerateVoicemailUserpolicies(timeout int) string { +func GenerateVoicemailUserpolicies(timeout int, sendEmailNotifications bool) string { return fmt.Sprintf(`voicemail_userpolicies { alert_timeout_seconds = %d + send_email_notifications = %t } - `, timeout) + `, timeout, sendEmailNotifications) } From de0d138943e9ed7bf7787e7bb810af950aab1d3b Mon Sep 17 00:00:00 2001 From: fergalmcl Date: Thu, 30 Jan 2025 16:05:57 +0000 Subject: [PATCH 3/4] reduced nesting --- .../user/resource_genesyscloud_user_utils.go | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/genesyscloud/user/resource_genesyscloud_user_utils.go b/genesyscloud/user/resource_genesyscloud_user_utils.go index 5807c04a4..ff2a27335 100644 --- a/genesyscloud/user/resource_genesyscloud_user_utils.go +++ b/genesyscloud/user/resource_genesyscloud_user_utils.go @@ -242,21 +242,23 @@ func updateUserProfileSkills(d *schema.ResourceData, proxy *userProxy) diag.Diag } func updateUserVoicemailPolicies(d *schema.ResourceData, proxy *userProxy) diag.Diagnostics { - if d.HasChange("voicemail_userpolicies") { - if voicemailUserpolicies := d.Get("voicemail_userpolicies").([]interface{}); voicemailUserpolicies != nil { - reqBody := buildVoicemailUserpoliciesRequest(voicemailUserpolicies) - diagErr := util.RetryWhen(util.IsVersionMismatch, func() (*platformclientv2.APIResponse, diag.Diagnostics) { - _, proxyPutResponse, putErr := proxy.voicemailApi.PatchVoicemailUserpolicy(d.Id(), reqBody) - if putErr != nil { - return proxyPutResponse, util.BuildAPIDiagnosticError(ResourceType, fmt.Sprintf("Failed to update voicemail userpolicices for user %s error: %s", d.Id(), putErr), proxyPutResponse) - } - return nil, nil - }) - if diagErr != nil { - return diagErr - } + if !d.HasChange("voicemail_userpolicies") { + return nil + } + + voicemailUserpolicies := d.Get("voicemail_userpolicies").([]interface{}) + reqBody := buildVoicemailUserpoliciesRequest(voicemailUserpolicies) + diagErr := util.RetryWhen(util.IsVersionMismatch, func() (*platformclientv2.APIResponse, diag.Diagnostics) { + _, proxyPutResponse, putErr := proxy.voicemailApi.PatchVoicemailUserpolicy(d.Id(), reqBody) + if putErr != nil { + return proxyPutResponse, util.BuildAPIDiagnosticError(ResourceType, fmt.Sprintf("Failed to update voicemail userpolicices for user %s error: %s", d.Id(), putErr), proxyPutResponse) } + return nil, nil + }) + if diagErr != nil { + return diagErr } + return nil } From 170430e04075f7a6c02ce915f903b38428d28e73 Mon Sep 17 00:00:00 2001 From: fergalmcl Date: Thu, 6 Feb 2025 12:02:27 +0000 Subject: [PATCH 4/4] addressing new comment --- docs/resources/user.md | 2 +- genesyscloud/user/resource_genesyscloud_user_schema.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/resources/user.md b/docs/resources/user.md index 5f50c2db8..a24cb081f 100644 --- a/docs/resources/user.md +++ b/docs/resources/user.md @@ -132,7 +132,7 @@ resource "genesyscloud_user" "example_user" { - `routing_utilization` (List of Object) The routing utilization settings for this user. If empty list, the org default settings are used. If not set, this resource will not manage the users's utilization settings. (see [below for nested schema](#nestedatt--routing_utilization)) - `state` (String) User's state (active | inactive). Default is 'active'. Defaults to `active`. - `title` (String) User's title. -- `voicemail_userpolicies` (Block List, Max: 1) User's voicemail policies. (see [below for nested schema](#nestedblock--voicemail_userpolicies)) +- `voicemail_userpolicies` (Block List, Max: 1) User's voicemail policies. If not set, default user policies will be applied. (see [below for nested schema](#nestedblock--voicemail_userpolicies)) ### Read-Only diff --git a/genesyscloud/user/resource_genesyscloud_user_schema.go b/genesyscloud/user/resource_genesyscloud_user_schema.go index db84a9dda..d195f4255 100644 --- a/genesyscloud/user/resource_genesyscloud_user_schema.go +++ b/genesyscloud/user/resource_genesyscloud_user_schema.go @@ -170,6 +170,7 @@ var ( Description: "Whether email notifications are sent to the user when a new voicemail is received.", Type: schema.TypeBool, Optional: true, + Computed: true, }, }, } @@ -403,11 +404,10 @@ func ResourceUser() *schema.Resource { }, }, "voicemail_userpolicies": { - Description: "User's voicemail policies.", + Description: "User's voicemail policies. If not set, default user policies will be applied.", Type: schema.TypeList, MaxItems: 1, Optional: true, - Computed: true, Elem: voicemailUserpoliciesResource, }, },