# Mon, 22 Dec 2025 14:57:12 GMT
---
version: 23
data:


- type: ModificationMethod
  attributes:
    displayName: Czech birthday number
    description: |
          Generates a Czech birthday number based on the birthday and sex parameter. The generated number is returned as a string.
          'RAND' will generate a random value. If the value is a date it will be used as it is. All other values will be hashed.
    inputType: COLUMN
    mappingTableContainers: []
    mappingTableAccessMode: READ
    code: |
        /*
         * *****************************************************************************
         * Czech Birthday Number
         * *****************************************************************************
         *
         * The following variables are available in this script:
         * =====================================================
         * ctx             : A context object that offers a number of methods.
         *                   The method indexOf() can be used to get the index of a
         *                   specific column within the dataArray.
         * dataArray       : The data array. This array contains the contents of all
         *                   columns of the current row of the table that is being
         *                   masked by this method.
         *
         * Additionally for column based modification methods the following two
         * variables are available:
         * columnName      : The name of the column that matched the pattern.
         * columnIndex     : The position of the column that matched the pattern within
         *                   the data array. This value is zero-based.
         * *****************************************************************************
         */
        importPackage(Packages.java.text);
        importPackage(Packages.java.util);
        importClass(Packages.de.ubs.xdm3.batch.modification.HashUtils);
        importClass(Packages.de.ubs.xdm3.batch.modification.ModificationException);
        importClass(Packages.de.ubs.xdm.utils.core.HighPrecisionTimestamp);
        
        var cal = null;
        var sexes = ['M','F'];
        var dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        
        /*
         * This function is called once before the processing starts. The method
         * is called once per table.
         */
        function init() {
            cal = new GregorianCalendar();
            if (sex.length <= 0) {
                sex = "M,F";
            }
            var temp = sex.split(",");
            for (var i = 0; i < temp; ++i) {
                if (!sexes.includes(temp[i])) {
                    throw new ModificationException("Sex " + temp[i] + " is not a valid value of '" + sexes.join("','") + "'");
                }
            }
            sex = temp;
        }
        
        /*
         * This function should modify the row that is provided by the dataArray. The
         * method is called for each single row of the table.
         */
        function apply() {
            var birthdayValue = "";
            var sexValue = "";
        
            if (ctx.indexOf(birthday) != -1) {
                birthdayValue = dataArray[ctx.indexOf(birthday)];
                if (birthdayValue instanceof HighPrecisionTimestamp) {
                    birthdayValue = dateFormat.format(birthdayValue.getTime());
                }
            } else {
                birthdayValue = birthday;
            }
        
            if (birthday == "RAND") {
                cal.setTime(new Date(Math.random() * 1400000000));
            } else {
                try {
                    cal.setTime(dateFormat.parse(birthdayValue));
                } catch (e) {
                    cal.setTime(new Date(HashUtils.hashStringLikeInt(HashUtils.hashStringLikeInt(birthdayValue) % 1400000000)));
                }
            }
        
            if (ctx.indexOf(sex) != -1) {
                sexValue = dataArray[ctx.indexOf(sex)];
            } else {
                sexValue = sex[Math.floor(Math.random() * sex.length)];
            }
            if (!sexes.includes(sexValue)) {
                throw new ModificationException("Sex " + sexValue + " is not a valid value of '" + sexes.join("','") + "'");
            }
        
            var isBefore54 = cal.get(Calendar.YEAR) < 1954;
            var year = cal.get(Calendar.YEAR) % 100;
            var month = cal.get(Calendar.MONTH) + 1;
            var day = cal.get(Calendar.DAY_OF_MONTH);
        
            if (year < 10) {
                year = "0" + year;
            }
            if (sexValue == 'F') {
                month += 50;
            }
            if (month < 10) {
                month = "0" + month;
            }
            if (day < 10) {
                day = "0" + day;
            }
        
            if (isBefore54) {
                var sssc = HashUtils.hashStringLikeInt(HashUtils.hashStringLikeInt(birthdayValue), 999);
                if (sssc < 10) {
                    sssc = "00" + sssc;
                } else if (sssc < 100) {
                    sssc = "0" + sssc;
                }
            } else {
                var index = 0;
                do {
                    var sssc = HashUtils.hashStringLikeInt(HashUtils.hashStringLikeInt(birthdayValue), 9999) + index;
                    if (sssc < 10) {
                        sssc = "000" + sssc;
                    } else if (sssc < 100) {
                        sssc = "00" + sssc;
                    } else if (sssc < 1000) {
                        sssc = "0" + sssc;
                    }
                    ++index;
                } while ((year.toString() + month.toString() + day.toString() + sssc) % 11 != 0);
            }
        
            dataArray[columnIndex] = year.toString() + month.toString() + day.toString() + delimiter + sssc;
        }
        
        /*
         * This function is executed once after the modification of a table is complete. The method
         * is called once per table.
         */
        function close() {
        }
    parameters:
    - displayName: Birthday
      description: |
          Specify a value that is used to calculate the hash.
      variableName: birthday
      dataType: STRING
    - displayName: Sex
      description: |
          Specifies the gender of the first name.
      variableName: sex
      dataType: STRING
    - displayName: Delimiter
      description: |
          The delimiter character used to separate the groups of digits. May be empty.
      variableName: delimiter
      defaultValue: "/"
      dataType: STRING
