---
version: 20
data:

  - type: "ModificationMethod"
    variation: null
    lastChangedBy: "tmf"
    replacePermissions: true
    replaceObject: true
    attributes:
      category: "Finance"
      code:    >2-
        /*
         * *****************************************************************************
         * 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.
         * *****************************************************************************
         */
        importClass(Packages.de.ubs.xdm3.batch.modification.ModificationException);
        importClass(Packages.de.ubs.xdm3.batch.modification.HashUtils);

        var factors = [2, 1, 2, 5, 7, 1, 2, 1, 2, 1, 2, 1];
        var alphabet = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];

        /*
         * This function is called once before the processing starts. The method
         * is called once per table.
         */
        function init() {

        }

        /*
         * 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() {
            /* trim input strings */
            gender = new java.lang.String(gender).trim();
            lastName = new java.lang.String(lastName).trim();
            birthDate = new java.lang.String(birthDate).trim();
            areaNumber = new java.lang.String(areaNumber).trim();

            /* parse birthDate input into format DDMMYY */
            var year = '';
            var month = '';
            var day = '';
            if (birthDate.length < 6) {
                birthDate = '0' + birthDate;
            }
            if (birthDate.length >= 10 && birthDate[4] == '-' && birthDate[7] == '-') {
                year = birthDate.substring(2, 4);
                month = birthDate.substring(5, 7);
                day = birthDate.substring(8, 10);
                birthDate = day + month + year;
            }

            /* Read first char of lastname and get 2 byte code for it */
            var firstChar = lastName.toUpperCase().charAt(0);
            if (firstChar == 'Ä') firstChar = 'A';
            if (firstChar == 'Ö') firstChar = 'O';
            if (firstChar == 'Ü') firstChar = 'U';

            var firstCharCode = 0;
            for (var i = 0; i < alphabet.length; ++i) {
                if (alphabet[i] == firstChar) {
                    firstCharCode = i + 1;
                    break;
                }
            }
            if (firstCharCode == 0) {
                throw new ModificationException(\"First character \" + firstChar + \" not found in alphabet\");
            }

            /* Read gender and calculate code if gender is F, W, or M */
            if (gender == ''F'' || gender == ''W'' || gender == ''M'') {
                var hash = HashUtils.hashInt(HashUtils.hashStringLikeInt(areaNumber + birthDate + firstChar));
                var newGender = hash % 50;
                if (gender == ''F'' || gender == ''W'') {
                    newGender += 50;
                }
                gender = newGender + '';
            }
            if (gender.length < 2) {
                gender = ''0'' + gender;
            }

            /* combine input value to insurance policy number and calculate check sum */
            var insurancePolicyNumber = areaNumber + birthDate + ((firstCharCode <= 9) ? \"0\" : \"\") + firstCharCode + gender;
            var insurancePolicyArray = insurancePolicyNumber.split('');
            var checkSum = 0;
            for(var i = 0; i < insurancePolicyArray.length; ++i) {
                var product = (parseInt(insurancePolicyArray[i]) * factors[i]) + '';
                var productArray = product.split('');
                var crossSum = 0;
                for (var j = 0; j < productArray.length; ++j) {
                    crossSum += parseInt(productArray[j]);
                }
                checkSum += crossSum;
            }
            checkSum = checkSum % 10;
            dataArray[columnIndex] = areaNumber + birthDate + firstChar + gender + checkSum;
        }

        /*
         * This function is executed once after the modification of a table is complete. The method
         * is called once per table.
         */
        function close() {
        }

      description: "
        This method builds a new allowance number based on the following input values:
        Position 1-2 number of the insurer
        Position 3-4 birth day of the insured person
        Position 5-6 birth month of the insured person
        Position 7-8 birth year of the insured person
        Position 9 first character of the last name of the insured person
        Position 10-11 serial number
        Position 12 checksum"
      displayName: "Zulagennummer"
      inputType: "COLUMN"
      javaScriptLibraries: [ ]
      parameters:
        - possibleValues: [ ]
          variableName: "areaNumber"
          displayName: "Area Number"
          defaultValue: ""
          dataType: "STRING"
          description: "number of the insurer"
        - possibleValues: [ ]
          variableName: "birthDate"
          displayName: "BirthDate"
          defaultValue: ""
          dataType: "STRING"
          description: "birthdate in the format 'ddMMYY' or 'YYYY-MM-dd' or as Date"
        - possibleValues: [ ]
          variableName: "lastName"
          displayName: "Last Name"
          defaultValue: ""
          dataType: "STRING"
          description: "Last name at the time of the application"
        - possibleValues: [ ]
          variableName: "gender"
          displayName: "Gender"
          defaultValue: ""
          dataType: "STRING"
          description: "|-
            00-49 -> male
            50-99 -> female"