    importPackage(Packages.de.elo.ix.client);

    //@include lib_Class.js
    //@include lib_sol.common.Config.js
    //@include lib_sol.common.ObjectUtils.js
    //@include lib_sol.common.StringUtils.js
    //@include lib_sol.common.DateUtils.js
    //@include lib_sol.common.SordUtils.js
    //@include lib_sol.common.RepoUtils.js
    //@include lib_sol.common.Map.js
    //@include lib_sol.common.ObjectFormatter.js
    //@include lib_sol.common.ix.ServiceBase.js
    //@include lib_sol.contract.ix.ContractUtils.js

    var logger = sol.create("sol.Logger", { scope: "sol.contract.ix.services.PaymentPlanCollector" });

    /**
     * Returns the payment plan items
     *
     * @author MW, ELO Digital Office GmbH
     * @version 1.03.002
     *
     * @eloix
     *
     * @requires sol.common.Config
     * @requires sol.common.ObjectUtils
     * @requires sol.common.StringUtils
     * @requires sol.common.DateUtils
     * @requires sol.common.SordUtils
     * @requires sol.common.RepoUtils
     * @requires sol.common.Map
     * @requires sol.common.ObjectFormatter
     * @requires sol.common.ix.ServiceBase
     * @requires sol.contract.ix.ContractUtils
     */
    sol.define("sol.contract.ix.services.PaymentPlanCollector", {
      extend: "sol.common.ix.ServiceBase",

      requiredConfig: ["parentId"],

      /**
       * @cfg {String} parentId (required)
       */

      initialize: function (config) {
        var me = this;
        me.$super("sol.common.ix.ServiceBase", "initialize", [config]);
        me.contractConfig = sol.contract.ix.ContractUtils.loadConfig();
      },

      process: function () {
        var me = this,
            solTypeFieldName, solTypes, objKeysObj, sord, sords, i;

        me.items = [];

        solTypeFieldName = me.contractConfig.fields.objType || "SOL_TYPE";
        solTypes = me.contractConfig.objectTypes || ["CONTRACT"];

        objKeysObj = {};
        objKeysObj[solTypeFieldName] = sol.common.RepoUtils.buildOrValuesSearchString(solTypes);

        // Single contract
        sord = sol.common.RepoUtils.getSord(me.parentId);
        if (solTypes.indexOf(sol.common.SordUtils.getObjKeyValue(sord, solTypeFieldName) + "") > -1) {
          sords = [sord];
        } else {
          sords = sol.common.RepoUtils.findChildren(me.parentId, { includeFolders: true, includeDocuments: false, includeReferences: true, objKeysObj: objKeysObj, recursive: true, level: 32, sordZ: SordC.mbAllIndex });
        }

        for (i = 0; i < sords.length; i++) {
          me.processContract(sords[i]);
        }
        return { sords: me.items };
      },

      /**
       * @private
       * @param {de.elo.ix.client.Sord} sord
       */
      processContract: function (sord) {
        var me = this;

        me.sordMap = sol.create("sol.common.SordMap", { objId: sord.id });
        me.sordMap.read();

        me.sordMap.forEachRow(me.contractConfig.mapFields.contractCashflowRecurringUnit, function (i) {
          var singleAmount, description, endDateIso, startDate, endDate, unit, startDateIso;
          startDateIso = "";
          singleAmount = me.sordMap.getNumValue(me.contractConfig.mapFields.contractCashflowSingle + i);

          if (singleAmount) {
            description = me.sordMap.getValue(me.contractConfig.mapFields.contractCashflowDesc + i);
            startDateIso = me.sordMap.getValue(me.contractConfig.mapFields.contractCashflowDate + i) || sol.common.SordUtils.getObjKeyValue(sord, me.contractConfig.fields.contractStart);
            endDateIso = me.sordMap.getValue(me.contractConfig.mapFields.contractCashflowTo + i) || sol.common.SordUtils.getObjKeyValue(sord, me.contractConfig.fields.contractEnd);

            startDate = startDateIso ? sol.common.DateUtils.isoToDate(startDateIso) : new Date();
            endDate = endDateIso ? sol.common.DateUtils.isoToDate(endDateIso) : new Date();
            unit = me.sordMap.getKwlKey(me.contractConfig.mapFields.contractCashflowRecurringUnit + i);

            do {
              startDateIso = sol.common.DateUtils.dateToIso(startDate);
              me.items.push(me.createLineTemplateSord(sord, me.sordMap.data, { description: description, amount: singleAmount, date: startDateIso }));
              if (unit == "O") {
                break;
              }
              startDate = sol.common.DateUtils.shift(startDate, 1, { unit: unit });
            } while (startDate < endDate);
          }
        }, me);

      },

      createLineTemplateSord: function (sord, mapEntries, calculatedProperties) {
        var me = this,
            tSord;

        tSord = sol.common.ObjectFormatter.format({
          sord: {
            formatter: "sol.common.ObjectFormatter.TemplateSord",
            data: sord,
            config: {
              sordKeys: ["id", "guid", "maskName", "name", "desc", "IDateIso", "XDateIso", "ownerName"]
            }
          }
        }).sord;

        tSord.mapKeys = me.filterIndexedMapEntries(mapEntries);

        tSord.mapKeys.CONTRACT_CASHFLOW_DESC = calculatedProperties.description;
        tSord.mapKeys.CONTRACT_CASHFLOW_AMOUNT = calculatedProperties.amount;
        tSord.mapKeys.CONTRACT_CASHFLOW_DATE = calculatedProperties.date;

        return tSord;
      },

      filterIndexedMapEntries: function (mapEntries) {
        var filteredEntries = {},
            key;

        for (key in mapEntries) {
          if (mapEntries.hasOwnProperty(key) && !sol.common.StringUtils.getTrailingNumber(key)) {
            filteredEntries[key] = mapEntries[key];
          }
        }

        return filteredEntries;
      }

    });

    /**
     * @member sol.contract.ix.services.PaymentPlanCollector
     * @method RF_sol_contract_service_PaymentPlanCollector
     * @static
     * @inheritdoc sol.common.ix.ServiceBase#RF_ServiceBaseName
     */
    function RF_sol_contract_service_PaymentPlanCollector(iXSEContext, args) {
      logger.enter("RF_sol_contract_service_PaymentPlanCollector", args);
      var config, service, result, resultString;

      config = sol.common.ix.RfUtils.parseAndCheckParams(iXSEContext, arguments.callee.name, args),

      service = sol.create("sol.contract.ix.services.PaymentPlanCollector", config);
      result = service.process();
      resultString = sol.common.ix.RfUtils.stringify(result, { tabStop: 2 });
      logger.exit("RF_sol_contract_service_PaymentPlanCollector", resultString);

      return resultString;
    }