From 382ac2cac8a936005190571de7ef5f9186bfb1fd Mon Sep 17 00:00:00 2001 From: Debora Crescenzo Date: Tue, 21 Jul 2026 17:17:37 +0100 Subject: [PATCH] MT#65546 Fix resource deletion across all CF types * Previously, the resource was removed from only one CF type before deletion. The backend then deleted any CF still referencing the resource, causing groups to disappear. We amend the delete resource logic to unlink the resource from any existing CF type. * Added missing subscriber_id property for bnumberset and sourceset deletion to make sure we clean up the correct mapping before deleting the resource. * Removed duplicate of normalizeFullMappingsResponse Unassign the resource from all CF mappings before deleting it. Change-Id: I5a2cd8ee7a057cdaeb281a83bfc3eabc2087cb68 (cherry picked from commit b7230e3c14861717afdc73ed35f1b41e6ad792bd) (cherry picked from commit dc2889ceb21f8c12769643eeb8f91876487aa44c) --- src/api/call-forwarding.js | 9 +++ .../CscCfGroupConditionSourceSetCreate.vue | 3 +- src/store/call-forwarding/actions.js | 67 ++++++++++++++----- yarn.lock | 7 +- 4 files changed, 62 insertions(+), 24 deletions(-) diff --git a/src/api/call-forwarding.js b/src/api/call-forwarding.js index 3b41fa10..99a17ed5 100644 --- a/src/api/call-forwarding.js +++ b/src/api/call-forwarding.js @@ -5,6 +5,7 @@ import { getList, patchReplace, post, + put, putMinimal } from 'src/api/common' import { showGlobalError } from 'src/helpers/ui' @@ -17,6 +18,14 @@ export async function cfLoadMappings (subscriberId) { }) } +export async function cfUpdateFullMapping (payload) { + return await put({ + resource: 'cfmappings', + resourceId: payload.subscriberId, + body: payload.body + }) +} + export async function cfLoadDestinationSets (subscriberId) { return getList({ resource: 'cfdestinationsets', diff --git a/src/components/call-forwarding/CscCfGroupConditionSourceSetCreate.vue b/src/components/call-forwarding/CscCfGroupConditionSourceSetCreate.vue index 6ee8254d..961afe33 100644 --- a/src/components/call-forwarding/CscCfGroupConditionSourceSetCreate.vue +++ b/src/components/call-forwarding/CscCfGroupConditionSourceSetCreate.vue @@ -225,7 +225,8 @@ export default { if (this.sourceSet) { await this.deleteSourceSet({ mapping: this.mapping, - id: this.sourceSet.id + id: this.sourceSet.id, + subscriberId: this.subscriberId }) } }, diff --git a/src/store/call-forwarding/actions.js b/src/store/call-forwarding/actions.js index 70c7d301..6a644c48 100644 --- a/src/store/call-forwarding/actions.js +++ b/src/store/call-forwarding/actions.js @@ -11,7 +11,7 @@ import { cfLoadDestinationSets, cfLoadMappingsFull, cfLoadSourceSets, - cfLoadTimeSets, cfUpdateOfficeHours, + cfLoadTimeSets, cfUpdateFullMapping, cfUpdateOfficeHours, cfUpdateSourceSet, cfUpdateTimeSetDate, cfUpdateTimeSetDateRange, @@ -309,14 +309,26 @@ export async function updateSourceSet ({ dispatch, commit, rootGetters }, payloa export async function deleteSourceSet ({ dispatch, commit, rootGetters, state }, payload) { try { dispatch('wait/start', 'csc-cf-source-set-create', { root: true }) - const updatedMapping = _.cloneDeep(state.mappings[payload.mapping.type]) - updatedMapping[payload.mapping.index].sourceset_id = null - updatedMapping[payload.mapping.index].sourceset = null - const updatedMappings = await patchReplaceFull({ - resource: 'cfmappings', - resourceId: (payload.subscriberId) ? payload.subscriberId : rootGetters['user/getSubscriberId'], - fieldPath: payload.mapping.type, - value: updatedMapping + const subscriberId = payload.subscriberId || rootGetters['user/getSubscriberId'] + const currentMappings = { ...state.mappings } + const mappingTypes = Object.keys(currentMappings).filter((key) => key !== 'cft_ringtimeout' && key !== 'id') + + mappingTypes.forEach((type) => { + currentMappings[type] = currentMappings[type].map((mapping) => { + if (mapping.sourceset_id === payload.id) { + return { + ...mapping, + sourceset_id: null, + sourceset: null + } + } + return mapping + }) + }) + + const updatedMappings = await cfUpdateFullMapping({ + subscriberId, + body: currentMappings }) try { await cfDeleteSourceSet(payload.id) @@ -418,15 +430,28 @@ export async function updateTimeSetDate ({ dispatch, commit }, payload) { export async function deleteTimeSet ({ dispatch, commit, rootGetters, state }, payload) { dispatch('wait/start', 'csc-cf-time-set-create', { root: true }) - const updatedMapping = _.cloneDeep(state.mappings[payload.mapping.type]) - updatedMapping[payload.mapping.index].timeset_id = null - updatedMapping[payload.mapping.index].timeset = null - const updatedMappings = await patchReplaceFull({ - resource: 'cfmappings', - resourceId: (payload.subscriberId) ? payload.subscriberId : rootGetters['user/getSubscriberId'], - fieldPath: payload.mapping.type, - value: updatedMapping + const subscriberId = payload.subscriberId || rootGetters['user/getSubscriberId'] + const currentMappings = { ...state.mappings } + const mappingTypes = Object.keys(currentMappings).filter((key) => key !== 'cft_ringtimeout' && key !== 'id') + + mappingTypes.forEach((type) => { + currentMappings[type] = currentMappings[type].map((mapping) => { + if (mapping.timeset_id === payload.id) { + return { + ...mapping, + timeset_id: null, + timeset: null + } + } + return mapping + }) + }) + + const updatedMappings = await cfUpdateFullMapping({ + subscriberId, + body: currentMappings }) + try { await cfDeleteTimeSet(payload.id) } catch (e) { @@ -655,3 +680,11 @@ export async function updateAnnouncement ({ dispatch, commit, state }, payload) destinationSets: destinationSets.items }) } + +export function resetCallForwardingState ({ commit }) { + commit('resetState') +} + +export function setPopupShow ({ commit }, popupId) { + commit('popupShow', popupId) +} diff --git a/yarn.lock b/yarn.lock index 02420fb1..8473b0c0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5783,12 +5783,7 @@ flow-parser@0.*: resolved "https://npm-registry.sipwise.com/flow-parser/-/flow-parser-0.309.0.tgz#ca2eae0b1a604cafbba99863785a92f7164671ee" integrity sha512-poYRskeIXiHsE19Fb9sRE/CV7PYOq21j3lS5vKr27ujFBvSAhmCbbilAonJ0/u0Uai+Xgyq30/twHQeQc2Ngiw== -follow-redirects@^1.0.0, follow-redirects@^1.15.11: - version "1.16.0" - resolved "https://npm-registry.sipwise.com/follow-redirects/-/follow-redirects-1.16.0.tgz#28474a159d3b9d11ef62050a14ed60e4df6d61bc" - integrity sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw== - -follow-redirects@^1.16.0: +follow-redirects@^1.0.0, follow-redirects@^1.16.0: version "1.16.0" resolved "https://npm-registry.sipwise.com/follow-redirects/-/follow-redirects-1.16.0.tgz#28474a159d3b9d11ef62050a14ed60e4df6d61bc" integrity sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==