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

    //@include lib_Class.js
    //@include lib_sol.common.IxUtils.js
    //@include lib_sol.common.RepoUtils.js
    //@include lib_sol.common.Template.js
    //@include lib_sol.common.ix.FunctionBase.js
    //@include lib_sol.contract.ix.ContractUtils.js

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

    /**
     * This function can be used to create contracts without user interaction.
     *
     * The function used to create new contracts is called `RF_sol_contract_function_CreateContractHeadless` and has a defined interface.
     * To create a contract this function needs a {@link #sordMetadata} object, which has to be a template sord containing the new contracts metadata.
     * Further a {@link #template} configuration is needed to determine the template which will be used to create the new contract.
     *
     * ### Examples
     *
     * ### Configuration for createing a contract
     *
     *     {
     *       template: { name: "Standard contract" },
     *       sordMetadata: {
     *         objKeys: {
     *           CONTRACT_NAME: "Vertragsname",
     *           CONTRACT_NO: "C#0815",
     *           CONTRACT_RESPONSIBLE: "Sandra Renz",
     *           CONTACT_FIRSTNAME: "Gerd",
     *           CONTACT_LASTNAME: "Baum"
     *         },
     *         mapKeys: {
     *           PARTNER_EMAIL: "g.baum@contelo.de"
     *         }
     *       }
     *     }
     *
     *
     * @eloix
     *
     * @requires sol.common.IxUtils
     * @requires sol.common.RepoUtils
     * @requires sol.common.Template
     * @requires sol.common.ix.FunctionBase
     * @requires sol.contract.ix.ContractUtils
     */
    sol.define("sol.contract.ix.functions.CreateContractHeadless", {
      extend: "sol.common.ix.FunctionBase",

      requiredConfig: ["user", "template", "sordMetadata"],

      /**
       * @cfg {Object} sordMetadata (required) A template sord containing the contract information.
       */

      /**
       * @cfg {Object} template (required) Configuration to determine the contract template.
       * @cfg {String} template.name (required) Name of the contract template.
       */

      /**
       * @cfg {de.elo.ix.client.UserInfo} user (required)
       * The user used as contract responsible (if there is no defined in {@link #sordMetadata}).
       * This user will be granted full access to the contract.
       * If calling this via the registered function, the logged in user will be used.
       */

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

      /**
       * Creates the contract.
       * @return {Object}
       */
      process: function () {
        var me = this,
            name, createSordConfig, fillSordConfig, contract;

        me.prepareTemplate();
        me.prepareMetadata();
        name = me.buildElementName(me.template.name);

        createSordConfig = {
          sourceElement: {
            objId: me.template.id,
            options: {
              copySourceAcl: true
            }
          },
          targetFolder: {
            objId: "0"
          },
          onCreatedElement: {
            setName: name,
            setPermissions: {
              mode: "SET",
              users: [me.user.name],
              rights: { r: true, w: true, d: true, e: true, l: true },
              recursive: true
            }
          }
        };

        fillSordConfig = {
          source: me.getSource(),
          target: {
            fromService: {
              name: "RF_sol_function_CreateSord",
              params: createSordConfig
            },
            startWorkflow: {
              name: me.getUpdateWorkflow(),
              title: name,
              concluding: true
            }
          },
          options: {}
        };

        contract = sol.common.IxUtils.execute("RF_sol_function_FillSord", fillSordConfig);

        return { code: "success", data: contract, info: "Contract created successfully" };
      },

      /**
       * @private
       * Retrieves the template for the contract.
       * Ensures that the template at least has a 'name' and an 'id'
       */
      prepareTemplate: function () {
        var me = this;
        if (!me.template.name) {
          throw "Headless Create: No parameter `name` defined in `template`";
        }

        me.template.id = sol.common.RepoUtils.getObjIdFromRelativePath(me.config.templateFolderId, "/" + me.template.name);

        if (!me.template.id) {
          throw "Headless Create: No template found for name '" + me.template.name + "'";
        }
      },

      /**
       * @private
       * Prepares the metadata object.
       * Ensures that the SOL_TYPE and the contract type is set.
       */
      prepareMetadata: function () {
        var me = this;

        if (me.sordMetadata && !me.sordMetadata.objKeys) {
          me.sordMetadata.objKeys = {};
        }

        me.sordMetadata.objKeys[me.config.fields.objectType] = me.config.objectTypes[0];
        me.sordMetadata.objKeys[me.config.fields.contractType] = me.template.name;

        if (!me.sordMetadata.objKeys[me.config.fields.contractResponsible]) {
          me.sordMetadata.objKeys[me.config.fields.contractResponsible] = me.user.name;
        }
      },

      /**
       * @private
       * Creates the temporary element and workflow name.
       * @param {String} contractType
       * @return {String}
       */
      buildElementName: function (contractType) {
        var me = this;
        return sol.create("sol.common.Template", { source: me.config.workflows.createContract.workflowNameTemplate }).apply({ contractType: contractType });
      },

      /**
       * @private
       * Prepares the datasource for the new contract
       * @return {Object}
       */
      getSource: function () {
        var me = this,
            source = {};

        source.templateSord = me.sordMetadata;

        return source;
      },

      /**
       * @private
       * Retrieves the headless workflow.
       * @return {String}
       */
      getUpdateWorkflow: function () {
        var me = this;
        return me.config.workflows.createContractHeadless.workflowTemplateName;
      }

    });

    /**
     * @member sol.common.ix.functions.ChangeRights
     * @method RF_sol_contract_function_CreateContractHeadless
     * @static
     * @inheritdoc sol.common.ix.FunctionBase#RF_FunctionName
     */
    function RF_sol_contract_function_CreateContractHeadless(ec, args) {
      var params, module;

      logger.enter("RF_sol_contract_function_CreateContractHeadless", args);

      params = sol.common.ix.RfUtils.parseAndCheckParams(ec, arguments.callee.name, args, "template", "sordMetadata");
      params.user = ec.user;
      module = sol.create("sol.contract.ix.functions.CreateContractHeadless", params);
      module.process();

      logger.exit("RF_sol_contract_function_CreateContractHeadless");
    }