Jira-Scripte/Script Manager/utils/FieldCopy.groovy

129 lines
3.5 KiB
Groovy

package utils
/**
* -----------------------------------------------------------------------------
* FieldCopy (Utility)
* -----------------------------------------------------------------------------
*
* Zweck
* -----
* - Extrahiert Feldwerte aus einem Issue-JSON (Map), wie von Jira REST geliefert
* - Baut Update-Payloads für PUT /rest/api/3/issue/{key}
* - Unterstützt mehrere Felder per Mapping-Liste
*
* WICHTIG
* -------
* - Kein HTTP hier drin (kein get/put/post). Nur pure Logik.
* - ADF (Rich Text / Absatz) wird 1:1 als Map übernommen.
*
* Mapping-Format
* --------------
* List von Maps:
* [
* [source: "customfield_11501", target: "customfield_11501", allowNull: false],
* [source: "customfield_12345", target: "customfield_99999", allowNull: true ]
* ]
*
* allowNull=false: null wird NICHT geschrieben (Zielfeld bleibt unverändert)
* allowNull=true : null wird geschrieben (Zielfeld wird geleert)
* -----------------------------------------------------------------------------
*/
class FieldCopy {
/**
* Liest den Rohwert eines Feldes aus dem Issue-JSON.
*/
static Object getFieldValue(Map issueJson, String fieldId) {
if (issueJson == null) return null
def fields = issueJson.get("fields")
if (!(fields instanceof Map)) return null
return (fields as Map).get(fieldId)
}
/**
* Baut einen Update-Body für ein einzelnes Feld.
*
* @return Map im Format: [fields: [(fieldId): value]]
*/
static Map buildSingleFieldUpdateBody(String fieldId, Object value) {
Map fieldsPayload = [:]
fieldsPayload.put(fieldId, value)
Map body = [:]
body.put("fields", fieldsPayload)
return body
}
/**
* Baut einen Update-Body für mehrere Felder anhand der Mapping-Liste.
*
* @return Map {fields:{...}} oder null, wenn nichts geschrieben werden soll
*/
static Map buildMultiFieldUpdateBody(Map sourceJson, List fieldMappings) {
if (sourceJson == null) return null
if (fieldMappings == null || fieldMappings.isEmpty()) return null
Map fieldsPayload = [:]
for (def m : fieldMappings) {
if (!(m instanceof Map)) {
continue
}
String sourceField = (m.get("source") ?: "").toString()
if (!sourceField) {
continue
}
String targetField = m.containsKey("target") && m.get("target") != null
? m.get("target").toString()
: sourceField
boolean allowNull = false
if (m.containsKey("allowNull") && m.get("allowNull") != null) {
allowNull = (m.get("allowNull") as Boolean)
}
Object value = getFieldValue(sourceJson, sourceField)
// null nur setzen, wenn explizit erlaubt
if (value == null && !allowNull) {
continue
}
fieldsPayload.put(targetField, value)
}
if (fieldsPayload.isEmpty()) {
return null
}
Map body = [:]
body.put("fields", fieldsPayload)
return body
}
/**
* Hilfsfunktion: Liefert die Source-Feldliste (für Jira "fields" QueryString)
* als Komma-Sequenz: "customfield_1,customfield_2"
*/
static String buildSourceFieldQuery(List fieldMappings) {
if (fieldMappings == null || fieldMappings.isEmpty()) return ""
List result = []
for (def m : fieldMappings) {
if (!(m instanceof Map)) continue
def s = m.get("source")
if (s == null) continue
String sourceField = s.toString()
if (!sourceField) continue
if (!result.contains(sourceField)) {
result.add(sourceField)
}
}
return result.join(",")
}
}