davide.cucurnia@vola.it
2024-02-01 555a537e2e5d9220e3777c30b185606823c817f2
commit | author | age
d2a29b 1 /**
DC 2  * quest' oggetto definisce i metodi XML
3  * se is_editable è true la stringa XML verrà modificato dall' update massivo
4  * @type {{sso_getWebcustomerInformation: {defaultXML: string, is_editable: boolean, actualXML: string}, sso_getSelectedMSISDNDetails: {defaultXML: string, is_editable: boolean, actualXML: string}, sso_getMSISDNDetails: {defaultXML: string, is_editable: boolean, actualXML: string}, picasso_getWebcustomerInformation: {defaultXML: string, is_editable: boolean, actualXML: string}, sso_getMSISDNList: {defaultXML: string, is_editable: boolean, actualXML: string}, sso_getInfoActivationWSC: {defaultXML: string, is_editable: boolean, actualXML: string}}}
5  */
6 let xmlMethods = {
7     'sso_getWebcustomerInformation': {
8         'defaultXML': sso_getWebcustomerInformation,
9         'actualXML': sso_getWebcustomerInformation, // dopo le modifiche
10         'is_editable': true // verrà modificato dalle modifiche massive?
11     },
12     'sso_getMSISDNDetails': {
13         'defaultXML': sso_getMSISDNDetails,
14         'actualXML': sso_getMSISDNDetails,
15         'is_editable': true
16     },
17     'sso_getMSISDNList': {
18         'defaultXML': sso_getMSISDNList,
19         'actualXML': sso_getMSISDNList,
20         'is_editable': true
21     },
22     'sso_getSelectedMSISDNDetails': {
23         'defaultXML': sso_getSelectedMSISDNDetails,
24         'actualXML': sso_getSelectedMSISDNDetails,
25         'is_editable': true
26     },
27     'sso_getInfoActivationWSC': {
28         'defaultXML': sso_getInfoActivationWSC,
29         'actualXML': sso_getInfoActivationWSC,
30         'is_editable': true
31     },
32     'picasso_getWebcustomerInformation': {
33         'defaultXML': picasso_getWebcustomerInformation,
34         'actualXML': picasso_getWebcustomerInformation,
35         'is_editable': true
36     },
37 }
38
39 /**
40  * questa è la lista di campi mostrati nella sezione di update massivo
41  * per aggiungere un campo è necessario aggiungere un oggetto di questo tipo alla lista
42  * @type {({defaultValue: number, inputType: string, requireCheckbox: boolean, inputName: string}|{defaultValue: string, onChangeEditFields: {custcode: {editType: string}}, inputName: string}|{defaultValue: string, inputName: string}|{defaultValue: string, inputName: string}|{defaultValue: string, inputName: string})[]}
43  */
44 let editableFields = [
45     {
46         'inputName': 'n_sim',
47         'inputType': 'number',
48         "defaultValue": 1,
49         'requireCheckbox': false,
50     },
51     {
52         'inputName': 'profile_user_name',
53         "defaultValue": "NAME FAKESSO | DUAL TM9 RIC 5.49275",
54         'requireCheckbox': false,
55     },
56     {
57         'inputName': 'Custcode',
58         'defaultValue': '5.49275',
59         'onChangeEditFields': {
60             'custcode': {
61                 'editType': 'copyMain'
62             }
63         }
64     },
65     {
66         'inputName': 'EmailAddress',
67         'defaultValue': 'pippo@vola.it'
68     },
69     {
70         'inputName': 'Name',
71         'defaultValue': 'Paola'
72     },
73     {
74         'inputName': 'ProfileIdentifier',
75         'defaultValue': 'BUSINESS_EMPLOYEE'
76     },
77     {
78         'inputName': 'Surname',
79         'defaultValue': 'Sandrelli'
80     },
81     {
82         'inputName': 'Username',
83         'defaultValue': 'FAKE_SSO_',
84         'onChangeEditFields': {
85             'username': {
86                 'editType': 'copyMain'
87             },
88         }
89     },
90     {
91         'inputName': 'IdPiano',
92         'defaultValue': '2491'
93     },
94     {
95         'inputName': 'OMProductId',
96         'defaultValue': '2156' // se uno di quelli dual risulto come dual già attivo
97     },
98     {
99         'inputName': 'tmCode',
100         'defaultValue': '2491'
101     },
102     {
103         'inputName': 'sim_1',
104         'defaultValue': '3464232371',
105         'onChangeEditFields': {
106             'MSISDN': {
107                 'editType': 'copyMain'
108             },
109             'selectedBoID': {
110                 'editType': 'copyMain'
111             }
112         }
113     }
114     // {
115     //     'inputName': 'Type_ID',
116     // 'defaultValue':'...',
117     //     'labelText': 'Type_ID ex. (2)'
118     // },
119     // {
120     //     'inputName': 'providerID',
121     // 'defaultValue':'...'
122     // },
123     // {
124     //     'inputName': 'selectedBoId',
125     // 'defaultValue':'...'
126     // // },
127     // {
128     //     'inputName': 'selectedBoType',
129     // 'defaultValue':'...'
130     // },
131     // {
132     //     'inputName': 'username',
133     // 'defaultValue':'...'
134     // },
135     // {
136     //     'inputName': 'productId',
137     // 'defaultValue':'...'
138     // },
139     // {
140     //     'inputName': 'productType',
141     // 'defaultValue':'...'
142     // },
143     // {
144     //     'inputName': 'offerType',
145     // 'defaultValue':'...'
146     // },
147     // {
148     //     'inputName': 'rewardID',
149     // 'defaultValue':'...'
150     // },
151     // {
152     //     'inputName': 'groupTypeID',
153     // 'defaultValue':'...'
154     // }
155 ];
156
157 $(document).ready(function () {
158     addEditableFieldsInputs();
159     $.each(xmlMethods, function (method_name) {
160         setDefaultXML(method_name);
161         if (xmlMethods[method_name]["is_editable"]) {
162             $(`input[name="is_editable_${method_name}"]`).prop("checked", true);
163         }
164     })
165     serializeInputAndEditXML(true, true);
166     $('input[name="n_sim"]').on('change', displayNInputsForNSims);
167     $('input[name^="shouldReplace_"]').on('change', shouldReplaceOption);
168     $(document).on('change', '#edit-all input:not([type="checkbox"])', serializeInputAndEditXML);
169     $(document).on('click', '#edit-all button', serializeInputAndEditXML);
170     $('input[name^="is_editable_"]').on('change', changeEditOption);
171     $(document).on('input', 'textarea', validateTextarea);
172     $(document).on('click', 'button[id^="set_default_xml_"]', setDefaultXML);
173     $(document).on('click', 'button[name="show_result"]', showResult);
174     $(document).on('click', 'button[name="copy-result"]', copyToClipboard);
175 })
176
177 /**
178  * partendo dalla lista di sim aggiungo tutti i tag sim all' xml del metodo getMSISDNList
179  * @param sim_list
180  */
181 function editGetMSISDNListXML(sim_list) {
182     let jsonMsisdn = $.xml2json(sso_getMSISDNList)
183     let MSISDNList = jsonMsisdn["getMDISDNList"]["msisdn_list"]
184
185     sim_list.forEach(function (sim_obj) {
186         MSISDNList[sim_obj.inputName] = ""
187     });
188
189     const newXML = $.json2xml(jsonMsisdn)
190     let encodingValue = $.parseXML(sso_getMSISDNList)["xmlEncoding"] ?? null;
191     const xmlHead = `<?xml version="1.0" encoding="${encodingValue}"?>`;
192     xmlMethods.sso_getMSISDNList.actualXML = xmlHead + newXML
193     const formattedXML = vkbeautify.xml(xmlMethods.sso_getMSISDNList.actualXML)
194     $(`textarea#sso_getMSISDNList`).val(formattedXML)
195 }
196
197 /**
198  * aggiungo una textarea per ogni sim per il metodo selezionato
199  * @param sim_list
200  * @param genericMethodName valori tipo -> "sso_getSelectedMSISDNDetails", "sso_getInfoActivationWSC"
201  */
202 function add_N_areatext_sections(sim_list, genericMethodName) {
203     let additional_methods_wrapper = $('#' + "additional_methods_" + genericMethodName)
204     additional_methods_wrapper.empty()
205
206     sim_list.forEach(function (sim_obj) {
207             let sim_code = sim_obj.inputName
208             let uniqueMethodName = sim_code + "_" + genericMethodName
209             xmlMethods[uniqueMethodName] = {
210                 'defaultXML': xmlMethods.sso_getSelectedMSISDNDetails.defaultXML,
211                 'actualXML': xmlMethods.sso_getSelectedMSISDNDetails.defaultXML,
212                 'is_editable': true
213             }
214             let formattedXML = vkbeautify.xml(xmlMethods[uniqueMethodName]["defaultXML"])
215             let additionalMethodArea = `
216             <div class="mb-3">
217                 <label for="${uniqueMethodName}" class="form-label text-danger font-weight-bolder">${uniqueMethodName}</label>
218                 <label>
219                     Questo metodo deve essere modificato dal replace massivo?
220                     <input type="checkbox" name="is_editable_${uniqueMethodName}" class="check-control" checked>
221                 </label>
222                 <button id="set_default_xml_${uniqueMethodName}" class="btn btn-primary btn-sm m-0 mx-3">
223                     DEFAULT XML
224                 </button>
225                 <textarea class="form-control" id="${uniqueMethodName}" name="${uniqueMethodName}" rows="10">${formattedXML}</textarea>
226                 <div id="${uniqueMethodName}_errorBox" class="text-danger font-size-sm"></div>
227             </div>`;
228             additional_methods_wrapper.append(additionalMethodArea)
229         }
230     )
231 }
232
233 /**
234  * questo metodo viene chiamato ogni volta che cambia in numero di sim e:
235  *
236  * genero gli oggetti input per ogni sim
237  * passo la lista di oggetti input a addEditableFieldsInput (aggiunti nella sezione modifica massiva)
238  * aggiorno l' xml del metodo getMSISDNList con le nuove sim
239  * aggiungo una nuova textarea di editing metodo per ogni sim per i metodi getSelectedMSISDNDetails getInfoActivationWSC
240  * @return void
241  */
242 function displayNInputsForNSims() {
243     $("[id^=sim_][id$=_wrapper]:not(#sim_1_wrapper)").remove();//rimuovo i vecchi input
244     editableFields = editableFields.filter(field => !(field.inputName.startsWith('sim_') && (field.inputName !== "sim_1")));
245     let numberOfSim = $(this).val();
246
247     if (!(0 < numberOfSim) || !(numberOfSim <= 6)) {
248         $(this).val(1)
249         numberOfSim = 1
250     }
251
252     const phone_number_sim_1 = $('input[name="sim_1"]').val()
253     let sim_list = [];
254     for (let sim_n = 2; sim_n <= numberOfSim; sim_n++) {
255         let inputObj = {
256             "inputName": "sim_" + sim_n,
257             "defaultValue": phone_number_sim_1 + sim_n//qui
258         };
259         sim_list.push(inputObj)
260         editableFields.push(inputObj)
261     }
262
263     addEditableFieldsInputs(sim_list)
264     //cambio actualXML di conseguenza inserendo dove necessario le chiavi aggiuntive di sim_1, sim_2, sim_3...
265     // lista di xml che devono essere cambiati:
266     // getMSISDNList (deve avere N tag sim_1, sim_2... )
267     editGetMSISDNListXML(sim_list)
268     // getSelectedMSISDNDetails deve avere N textarea una per ogni sim
269     add_N_areatext_sections(sim_list, "sso_getSelectedMSISDNDetails")
270     // getInfoActivationWSC deve avere N textarea una per ogni sim
271     add_N_areatext_sections(sim_list, "sso_getInfoActivationWSC")
272 }
273
274 /**
275  * inserisco la lista di input in pagina per l' editing massivo dei campi
276  * @param inputList
277  */
278 function addEditableFieldsInputs(inputList = editableFields) {
279     let inputWrapper = $('#wrapper-input-list')
280
281     inputList.forEach(function (inputObj, index) {
282
283         let div = $("<div>", {id: inputObj["inputName"] + "_wrapper", class: "col mb-2"});
284         let labelText = inputObj["labelText"] ?? inputObj["inputName"];
285         let label = $("<label>", {for: inputObj["inputName"], class: "form-label"}).text(labelText);
286
287         let checkbox = ""
288         let input = $("<input>", {
289             class: "form-control",
290             type: inputObj["inputType"] ?? "text",
291             value: inputObj["defaultValue"] ?? "",
292             name: inputObj["inputName"],
293             placeholder: inputObj["inputName"],
294             id: inputObj["inputName"]
295         });
296
297         if (inputObj.requireCheckbox !== false) {
298             checkbox = $("<input>", { //necessaria per verificare se l' input corrispondente deve essere modificato
299                 class: "check-control mx-1",
300                 type: "checkbox",
301                 name: "shouldReplace_" + inputObj["inputName"]
302             });
303         }
304
305
306         div.append(label);
307         div.append(checkbox);
308         div.append(input);
309
310         inputWrapper.append(div);
311     })
312
313 }
314
315 function showError(errorBox = $('#main_errorBox'), msg = "xml non formattato correttamente") {
316     errorBox.show()
317     const listItem = $('<li>', {
318         text: msg
319     })
320     errorBox.append(listItem)
321 }
322
323 /**
324  * in questo metodo voglio prendere tutti gli input nella lista editableField (lista degli input edit massivo) parametrizzarli
325  * una volta parametrizzati gli input partendo dalla struttura del vecchio xml (oggetto)
326  * sostituisco tutte le chiavi che combaciano con i nuovi valori
327  * @param alwaysEditable
328  * @param updateDefaultXML
329  */
330 function serializeInputAndEditXML(alwaysEditable = false, updateDefaultXML = false) {
331     let serializedInputs = $('form#edit-all').serializeArray();
332
333     $.each(xmlMethods, function (methodName, methodObj) {
334             if ((methodObj.is_editable) || (alwaysEditable === true)) {
335                 let encodingValue = $.parseXML(methodObj.actualXML)["xmlEncoding"] ?? null;
336
337                 let oldObj = $.xml2json(methodObj.actualXML)
338                 let newXML = mergeAndConvertObjInXML(oldObj, serializedInputs)
339
340                 if (encodingValue !== null) {
341                     const xmlHead = `<?xml version="1.0" encoding="${encodingValue}"?>`;
342                     methodObj.actualXML = xmlHead + newXML
343                 } else {
344                     methodObj.actualXML = newXML
345                 }
346
347                 if (updateDefaultXML === true) {
348                     methodObj.defaultXML = newXML
349                 }
350
351                 let isValid = $.isXmlValid(newXML)
352
353                 if (isValid) {
354                     const formattedXML = vkbeautify.xml(newXML)
355                     $(`textarea#${methodName}`).val(formattedXML.trim())
356                 } else {
357                     $('#main_errorBox').empty()
358                     showError($('#' + methodName + '_errorBox'))
359                 }
360             }
361         }
362     );
363 }
364
365 /**
366  * faccio merge di tutti i valori in newValues in finalObj mantenendo invariata la struttura di finalObj
367  * @param finalObj
368  * @param newValues
369  * @return {object}
370  */
371 function mergeObjects(finalObj, newValues) {
372     let newProperties = newValues[Object.keys(newValues)[0]]
373
374     $.each(newProperties, function (name, value) {
375         findAndReplaceKeyInObj(finalObj, name, value)
376     })
377     return finalObj
378 }
379
380 /**
381  * prendo l' obj passato e cerco all' interno di esso una chiave key (a qualsiasi livello di indentazione)
382  * se esiste la sostituisco con newValue
383  * @param obj
384  * @param key
385  * @param newValue
386  * @return {object}
387  */
388 function findAndReplaceKeyInObj(obj, key, newValue) {
389     if (obj instanceof Object) {
390         if (obj.hasOwnProperty(key)) {
391             obj[key] = newValue;
392             return;
393         }
394         for (let subKey in obj) {
395             if (obj.hasOwnProperty(subKey) && obj[subKey] instanceof Object) {
396                 findAndReplaceKeyInObj(obj[subKey], key, newValue);
397             }
398         }
399     }
400     return obj
401 }
402
403
404 /**
405  * group -> subEditFunction
406  *  prendo il valore del main e do alla subKey lo stesso valore
407  */
408 function copyMain() {
409     return (subFields, obj) => {
410         const mainName = subFields.inputName
411         return obj[mainName] //main value
412     }
413 }
414
415 /**
416  * la lista di metodi aggiuntivi che se presenti in subFields.onChangeEditFields invocano delle funzioni secondarie
417  * per il campo che è stato modificato
418  *
419  * ad esempio copyMain prende il valore del campo modificato e lo passa a tutti i subField
420  * quindi nel caso di sim_1 quando viene cambiato il valore viene passato anche a MSISDN selectedBoID perché si trovano sotto il campo principale sim_1 con edit_type copyMain
421  * @type {{copyMain: (function(*, *): *)}}
422  */
423 let subEditFunctions = {
424     "copyMain": copyMain()
425 }
426
427 /**
428  * se il campo principale ha delle funzioni onChangeEditFields chiamare le invoca
429  * @param subFields
430  * @param obj
431  * @return {object}
432  */
433 function editSubFields(subFields, obj) {
434     const subChanges = subFields.onChangeEditFields
435     $.each(subChanges, function (subFieldName, subObj) {
436         if (subObj.editType in subEditFunctions) {
437             obj[subFieldName] = subEditFunctions[subObj.editType](subFields, obj)
438         }
439     })
440     return obj
441 }
442
443 /**
444  * prendo un oggetto complesso e lo semplifico mettendo tutte le chiavi sullo stesso livello
445  * @param objInputList
446  * @param mainKey
447  * @return {{object}}
448  */
449 function simplifyObj(objInputList, mainKey = null) {
450     let newObj = {};
451
452     objInputList.forEach(function (objInput) {
453         let editableField = editableFields.find(fields => fields.inputName === objInput.name);
454         if (editableField) {
455             newObj[objInput.name] = objInput.value;
456             if (editableField.onChangeEditFields) {
457                 newObj = editSubFields(editableField, newObj)
458             }
459         }
460     })
461
462     if (typeof mainKey == 'string') {
463         return {
464             [mainKey]: newObj
465         }
466     }
467
468     return newObj;
469 }
470
471 /**
472  * prendo i valori del vecchio oggetto xml li sostituisco con quelli nuovi e trasformo nuovamente l' obj xml in una stringa XML
473  * @param oldObj
474  * @param replacingValuesObj
475  * @return {string}
476  */
477 function mergeAndConvertObjInXML(oldObj, replacingValuesObj) {
478     const mainKey = Object.keys(oldObj)[0]
479     let newObj = simplifyObj(replacingValuesObj, mainKey)
480
481     let mergedObj = mergeObjects(oldObj, newObj)
482     return $.json2xml(mergedObj)
483 }
484
485 /**
486  * modifico l' editabiltà massiva di un oggetto in xmlMethods in base al valore della sua checkbox
487  * se non è flaggata non modifico il metodo
488  */
489 function changeEditOption() {
490     let input_name = $(this).attr('name')
491     const isEditable = $(this).is(':checked')
492     const methodName = input_name.split("is_editable_")[1] ?? ""
493
494     if (xmlMethods[methodName]) {
495         xmlMethods[methodName]["is_editable"] = isEditable;
496     }
497 }
498
499 /**
500  * setto i valori di default degli XML e li inserisco nelle rispettive textarea
501  * se methodName === null arriva da un input event quindi prendo dinamicamente il nome del metodo a cui settare default XML
502  * @param methodName
503  */
504 function setDefaultXML(methodName = null) {
505     if (typeof methodName !== 'string') { // il caso in cui venga chiamato da un evento
506         let btn_id = $(this).attr('id')
507         methodName = btn_id.split("set_default_xml_")[1] ?? ""
508     }
509
510     if (xmlMethods[methodName]) {
511         xmlMethods[methodName]["actualXML"] = xmlMethods[methodName]["defaultXML"]
512         const formattedXML = vkbeautify.xml(xmlMethods[methodName]["actualXML"])
513         $(`textarea#${methodName}`).val(formattedXML.trim())
514
515         let errorBox = $('#' + methodName + '_errorBox');
516         errorBox.empty()
517     }
518 }
519
520 /**
521  * abilita e disabilita il singolo input per la modifica massiva
522  * se la checkbox è flaggata il campo non verrà modificato
523  */
524 function shouldReplaceOption() {
525     let checkbox_name = $(this).attr('name')
526     let checkbox_value = $(this).is(':checked')
527     const input_name = checkbox_name.split("shouldReplace_")[1] ?? ""
528
529     if (checkbox_value) {
530         $(`input[name="${input_name}"]`).prop('disabled', true);
531     } else {
532         $(`input[name="${input_name}"]`).removeAttr('disabled');
533     }
534 }
535
536 /**
537  * verifico la validità di un valore XML nella textarea che invoca l' evento
538  */
539 function validateTextarea() {
540     const xml = $(this).val()
541     const methodName = $(this).attr('id')
542     let errorBox = $('#' + methodName + '_errorBox');
543     errorBox.empty()
544     if ((typeof xml === 'string') && (xml.trim() !== '')) {
545         let isValid = $.isXmlValid(xml);
546         if (isValid !== true) {
547             showError(errorBox, "errore nella validazione dell' xml " + isValid)
548         }
549     }
550 }
551
552 /**
553  * trasformo un oggetto JS in una stringa con sintassi array PHP
554  * @param profileObj
555  * @return {string}
556  */
557 function buildArrayPHP(profileObj) {
558     const newJSON = JSON.stringify(profileObj)
559     const prettyJson = vkbeautify.json(newJSON)
560     let arrayPHP = prettyJson.replaceAll("{", "[")
561     arrayPHP = arrayPHP.replaceAll("}", "]")
562     arrayPHP = arrayPHP.replaceAll(":", "=>")
563     return '"n" => ' + arrayPHP
564 }
565
566 /**
567  * partendo dall' oggetto profileObj sostituisco i valori dentro parametri[param] inserendo chiavi valore corrette
568  * chiave -> (sim_*) | valore -> (sim_*_method_name["actual"])
569  * @param profileObj
570  * @param method_name
571  * @param param_key
572  * @return {*}
573  */
574 function set_dynamic_keys_for_profile_method(profileObj, method_name, param_key) {
575
576     profileObj["sso"][method_name]["parametri"][param_key] = {}
577
578     const sso_method_name = `sso_${method_name}`
579     const main_phone_number = $(`input[name="sim_1"]`).val()
580     const XML_sim_1 = xmlMethods[sso_method_name]["actualXML"];
581     let encodingValue = $.parseXML(XML_sim_1)["xmlEncoding"] ?? null;
582     const xmlHead = `<?xml version="1.0" encoding="${encodingValue}"?>`;
583
584     profileObj["sso"][method_name]["parametri"][param_key][main_phone_number] = XML_sim_1
585
586     let sim_length = $('input[name="n_sim"]').val()
587     for (let index = 2; index <= sim_length; index++) {
588         let sim_code = 'sim_' + index
589         let phone_number = $(`input[name="${sim_code}"]`).val()
590
591         let new_method_name = sim_code + "_" + sso_method_name
592         profileObj["sso"][method_name]["parametri"][param_key][phone_number] = xmlHead + xmlMethods[new_method_name]["actualXML"]
593     }
594
595     return profileObj
596 }
597
598 /**
599  * costruisco e mostro l' array (formato PHP) in pagina
600  */
601 function showResult() {
602     let profileObj = {
603         "name": $('input[name="profile_user_name"]').val() ?? "inserire un nome utente",
604         "sso": {
605             "getWebcustomerInformation":
606                 {
607                     "parametri": {
608                         "t":
609                             {
610                                 "415F2B31F1C15FA45C9A6E1CBEB0ADF3": xmlMethods.sso_getWebcustomerInformation.actualXML
611                             }
612                     }
613                 }
614             ,
615             "getMSISDNDetails":
616                 {
617                     "parametri": {
618                         "t":
619                             {
620                                 "415F2B31F1C15FA45C9A6E1CBEB0ADF3": xmlMethods.sso_getMSISDNDetails.actualXML
621                             }
622                     }
623                 }
624             ,
625             "getMSISDNList":
626                 {
627                     "parametri": {
628                         "t":
629                             {
630                                 "415F2B31F1C15FA45C9A6E1CBEB0ADF3": xmlMethods.sso_getMSISDNList.actualXML
631                             }
632                     }
633                 }
634             ,
635             "getSelectedMSISDNDetails":
636                 {
637                     "parametri": {
638                         "t":
639                             {
640                                 "415F2B31F1C15FA45C9A6E1CBEB0ADF3": '<?xml version="1.0" encoding="iso-8859-1"?><getMDISDNDetails><CardType>Ric</CardType><SimSeniorityDate>15/02/2020</SimSeniorityDate><VodafoneOne>false</VodafoneOne><TopClub>false</TopClub><IdPiano>2491</IdPiano><SeniorityCluster></SeniorityCluster></getMDISDNDetails>'
641                             },
642                         "ms":
643                             {
644                                 '3464232371': '',//deve essere gestito con un foreach
645                                 '3464232372': ''//deve essere gestito con un foreach
646                             }
647                     }
648                 }
649             ,
650             "getInfoActivationWSC":
651                 {
652                     "parametri": {
653                         "t":
654                             {
655                                 "415F2B31F1C15FA45C9A6E1CBEB0ADF3": '<?xml version="1.0" encoding="iso-8859-1"?><getInfoActivationWSC><catalog><channel>SSO</channel><providerID></providerID><appidID></appidID><selectedBoId>3464232371</selectedBoId><selectedBoType>SIM_MOBILE</selectedBoType><username>FAKE_SSO_1</username><readOnlyCondition></readOnlyCondition><showcase><showcaseId>27</showcaseId><showcaseDescription>Vetrina Elite</showcaseDescription><tabs><tabPosition>1</tabPosition><tabDescription>new Corporate Infoattivazione Showcase</tabDescription><tabId>17</tabId><sections><collapsed>N</collapsed><sectionPosition>20</sectionPosition><sectionDescription>Tutti gli altri servizi</sectionDescription><sectionId>112</sectionId><products><productId>2583</productId><activationDate><time>1702249200000</time></activationDate><changeStateDate><time>1702249200000</time></changeStateDate><inheritanceRule></inheritanceRule><buyCost>0.0</buyCost><frequency></frequency><infoRecurringFees>N</infoRecurringFees><invertStatus>N</invertStatus><maxNumOfTry>0</maxNumOfTry><monopoliFlag>N</monopoliFlag><longDescription>Abilita la SIM alla distinzione del traffico personale da quello aziendale</longDescription><longName>Autorizzazione Dual</longName><productPosition>1</productPosition><numberOfUsedTry>0</numberOfUsedTry><numberOfTryAvailable>0</numberOfTryAvailable><OMProductId>2156</OMProductId><OMSource>CCBS</OMSource><productType>Service</productType><shortDescription>Abilita la SIM alla distinzione del traffico personale da quello aziendale</shortDescription><shortName>Autorizzazione Dual</shortName><productStateOnSim>ACTIVE</productStateOnSim><spyderId></spyderId><flagCommitment></flagCommitment><mm4MPromoId></mm4MPromoId><idJoin></idJoin><lastPaidFlag></lastPaidFlag><offerType></offerType><lastChargeZeroReason></lastChargeZeroReason></products><products><productId>3823</productId><activationDate><time>1702854000000</time></activationDate><changeStateDate><time>1702854000000</time></changeStateDate><inheritanceRule></inheritanceRule><buyCost>0.0</buyCost><frequency></frequency><infoRecurringFees>N</infoRecurringFees><invertStatus>N</invertStatus><maxNumOfTry>0</maxNumOfTry><monopoliFlag>N</monopoliFlag><longDescription></longDescription><longName>TM9 Smart Passport Extra Europa 1 Rinnovo Ricaricabile</longName><productPosition>1</productPosition><numberOfUsedTry>0</numberOfUsedTry><numberOfTryAvailable>0</numberOfTryAvailable><OMProductId>14644</OMProductId><OMSource>CCBS</OMSource><productType>Service</productType><shortDescription></shortDescription><shortName>TM9 Smart Passport Extra Europa 1 Rinnovo Ricaricabile</shortName><productStateOnSim>ACTIVE</productStateOnSim><spyderId></spyderId><flagCommitment></flagCommitment><mm4MPromoId></mm4MPromoId><idJoin></idJoin><lastPaidFlag></lastPaidFlag><offerType></offerType><lastChargeZeroReason></lastChargeZeroReason></products><____hashCodeCalc>false</____hashCodeCalc></sections><____hashCodeCalc>false</____hashCodeCalc></tabs><____hashCodeCalc>false</____hashCodeCalc></showcase><tmProduct><tmCode>2491</tmCode><description>TM9 Ricaricabile P30</description><activationDate><time>1696244062000</time></activationDate><____hashCodeCalc>false</____hashCodeCalc></tmProduct><convergentOffer><rewardID></rewardID><groupTypeID></groupTypeID><hungReasonID></hungReasonID><cli></cli><status></status></convergentOffer></catalog><operationStatus><status>OK</status><errCode>0</errCode><diagnostic>SUCCESS</diagnostic><____hashCodeCalc>false</____hashCodeCalc></operationStatus></getInfoActivationWSC>'
656                             },
657                         "boID":
658                             {
659                                 '3464232371': '',//deve essere gestito con un foreach
660                                 '3464232372': ''//deve essere gestito con un foreach
661                             }
662                     }
663                 }
664         },
665         "picasso": {
666             "getWebcustomerInformation": {
667                 "parametri": {
668                     "t": {
669                         "415F2B31F1C15FA45C9A6E1CBEB0ADF3": xmlMethods.picasso_getWebcustomerInformation.actualXML
670                     }
671                 }
672             }
673         }
674     }
675
676
677     profileObj = set_dynamic_keys_for_profile_method(profileObj, "getSelectedMSISDNDetails", "ms")
678     profileObj = set_dynamic_keys_for_profile_method(profileObj, "getInfoActivationWSC", "boID")
679     const arrayPHP = buildArrayPHP(profileObj);
680
681     $('#final_result  pre').text(arrayPHP);
682     $("html, body").animate({scrollTop: $(document).height()}, "slow");
683     $('#final_result').show();
684 }
685
686 function copyToClipboard() {
687     let textToCopy = $("#final_result_text").text();
688     let tempInput = $("<textarea>");
689     $("body").append(tempInput);
690     tempInput.val(textToCopy).select();
691     document.execCommand("copy");
692     tempInput.remove();
693 }