Skip to content
Snippets Groups Projects
process.js 14.42 KiB
import("Sql_lib");
import("Date_lib");
import("system.vars");
import("system.datetime");
import("system.util");
import("system.db");
import("system.project");
import("system.neon");
/**
 * Class containing utility functions for copying modules
 * do not create an instance of this
 * 
 * @class
 */
function CopyModuleUtils() {}

/**
 * opens the new created modules in neonClient
 * 
 * @param {String} pNeonContext req Name of the neon context that should be opened
 * @param {Object} pModulesMapping req ModulesMapping object created by method copyModule
 * 
 * @example 
 *  var ModulesMapping = CopyModuleUtils.copyModule(InputMapping);
 *  CopyModuleUtils.openNewModules("Offer", ModulesMapping);
 */
CopyModuleUtils.openNewModules = function(pNeonContext, pModulesMapping)
{
    if(pModulesMapping != undefined)
    {
        var rootModule = Object.keys(pModulesMapping)[0];
        if(pModulesMapping[rootModule].DataRows != undefined)
        {
            var newids = [];

            for(var row in pModulesMapping[rootModule].DataRows)
            {
                newids.push(pModulesMapping[rootModule].DataRows[row].newPrimaryKey);
            }

            if(newids.length > 0)
                neon.openContext(pNeonContext, null, newids, neon.OPERATINGSTATE_VIEW, null);
        }
    }
}

/**
*   Creates a copy of a specified module together with specified subordinated modules. <br>
*   The structure of the input mapping object is the following:  <br>
*  pInputMapping {
*   (only one rootModule allowed)
*    $rootModule$: { 
*        condition: "sqlWhereCondition"
*        , ValueMapping: {$colName$: "value"}
*        , destinationModuleName: "destinationModuleName"
*        , DestinationColumnMapping: { $sourceColName$ : "destinationColName" }  
*        , SubModules: {
*            $Module$:{ 
*                condition: "sqlWhereCondition"
*                , ValueMapping: {$colName$: "value"}
*                , destinationModuleName: "destinationModuleName"
*                , DestinationColumnMapping: { $sourceColName$ : "destinationColName" }  
*                , SubModules: {...}
*            }
*        }
*    }
* }
* 
* @param {Object} pInputMapping
*
* @example var CMUtils = new CopyModuleUtils();
*
*    var InputMapping = {
*
*        "OFFER": {
*                condition: "OFFERID = '" + vars.get("$field.OFFERID") + "'"
*                ,SubModules:{
*                    "OFFERITEM": {
*                        condition: "OFFER_ID = '" + vars.get("$field.OFFERID") + "' order by ITEMSORT" 
*                }
*            }
*        }
*    }
*
*    CMUtils.copyModule(InputMapping);
*/
CopyModuleUtils.copyModule = function(pInputMapping)
{
    var AliasDefinitionStructure = project.getAliasDefinitionStructure("Data_alias", null);
    var ModulesMapping = {};
    var statements = [];
    
    if(pInputMapping["OFFERITEM"]["destinationModuleName"] == "SALESORDERITEM") //SalesOrder and Offer don't have the exact smae structure anymore: Order don't have the field "optional"
    {
        delete AliasDefinitionStructure["tables"]["OFFERITEM"]["columns"]["OPTIONAL"];
    }
    buildMapping( pInputMapping );
    buildStatements( ModulesMapping );

    if(statements.length > 0)
        db.inserts( statements ); 

    return ModulesMapping;

    /**
     * Builds a mapping Object for the copyModule Method.  <br>
     * The structure of the Object is the following:  <br>
     * ModulesMapping = {  
     * 
     *   $rootModule$: { ($$ marks an object property) 
     *   
     *        (ModuleMapping) 
     *        name: "moduleName"  
     *        , destinationModuleName: "destinationModuleName" 
     *        , DestinationColumnMapping: { $sourceColName$ : "destinationColName" } 
     *        , ValueMapping: {$colName$: "value"} 
     *        , dataRows:{ 
     *            (ModuleRowMapping) 
     *            $rowid$: {  
     *                name: "moduleName" 
     *                , oldPrimaryKey: "oldPrimaryKeyValue" 
     *                , newPrimaryKey: "newPrimaryKeyValue" 
     *                , ColumnMapping: { $colName$: { newValue: "newValue", oldValue: "oldValue", destinationColumn: "destinationColumn" } } 
     *                , ModuleMapping: object reference to ModuleMapping object that contains ModuleRowMapping objects 
     *                , ParentModuleMapping: object reference to supervised ModuleMapping object (at this point "null" because there is no supervised object) 
     *            } 
     *        }   
     *        , SubModules: { 
     *                  (ModuleMapping) 
     *                  $moduleName$: { 
     *                       name: "moduleName" 
     *                      , destinationModuleName: "destinationModuleName" 
     *                      , DestinationColumnMapping: { $sourceColName$ : "destinationColName" } 
     *                      , ValueMapping: {$colName$: "value"} 
     *                      , dataRows:{ 
     *                          (ModuleRowMapping) 
     *                           $rowid$: {  
     *                              name: "moduleName" 
     *                              , oldPrimaryKey: "oldPrimaryKeyValue" 
     *                              , newPrimaryKey: "newPrimaryKeyValue" 
     *                              , ColumnMapping: { $colName$: { newValue: "newValue", oldValue: "oldValue", destinationColumn: "destinationColumn" } } 
     *                              , ModuleMapping:  
     *                              , ParentModuleMapping: object reference to supervised ModuleMapping object (at this point "null" because there is no supervised object) 
     *                           } 
     *                      } 
     *                      , SubModules: {...} 
     *                  } 
     *        }  
     *
     *   } 
     *
     *} 
     *
     * @param {Object} pInputMapping InputMapping
     */
    function buildMapping(pInputMapping)
    {
        //root mapping
        var rootModule = Object.keys(pInputMapping)[0];
        var ModuleMapping = _ModuleMapping(rootModule, pInputMapping[rootModule]);
        var ModuleData = _getModuleData(rootModule, pInputMapping[rootModule].condition, pInputMapping[rootModule].order);
        ModulesMapping[rootModule] = ModuleMapping;

        for(var row in ModuleData)
        {
            var ModuleRowMapping = _ModuleRowMapping(ModuleMapping, null, ModuleData[row]);

            ModuleMapping.DataRows[ModuleRowMapping.oldPrimaryKey] = ModuleRowMapping;
        }

        ModulesMapping[rootModule] = ModuleMapping;

        //recursive subordinated modules mapping
        _buildSubordinatedMapping(pInputMapping, ModuleMapping);


        //delivers stored data for module in Database with condition
        function _getModuleData(pModule, pCondition, pOrder)
        {
            if(pModule == undefined)    return {};

            var ModuleColumnsStructure = AliasDefinitionStructure.tables[pModule].columns;
            var cols = Object.keys(ModuleColumnsStructure);
            var dataQuery = newSelect(cols).from(pModule);
            
            if(pCondition != undefined)
                dataQuery.where(pCondition);
            
            if(pOrder != undefined)
                dataQuery.orderBy(pOrder);

            var dbData = dataQuery.table();

            //map 2d-Array to Object { $rowNumber$: { $columnName$: { value: "valueInDB" } } }
            var DataObj = {};
            for(var row = 0; row < dbData.length; row++)
            {
                DataObj[row] = {};
                for(var col = 0; col < dbData[row].length; col++)
                {
                    DataObj[row][cols[col]] = {
                        value: dbData[row][col]
                    };
                }
            }

            return DataObj;
        }

        //recursive: ModuleMapping and ModuleRowMapping for subordinated modules
        function _buildSubordinatedMapping(pInputMapping, pParentModuleMapping)
        {
            var SubModules = pInputMapping[pParentModuleMapping.name].SubModules;
            if(SubModules == undefined)
                return;

            for(var subModuleName in SubModules)
            {
                var ModuleMapping = _ModuleMapping(subModuleName, SubModules[subModuleName]);
                ModuleData = _getModuleData(subModuleName, SubModules[subModuleName].condition);
                for(var row in ModuleData)
                {
                    ModuleRowMapping = _ModuleRowMapping(ModuleMapping, pParentModuleMapping, ModuleData[row]);
                    ModuleMapping.DataRows[ModuleRowMapping.oldPrimaryKey] = ModuleRowMapping;
                }

                ModulesMapping[pParentModuleMapping.name].SubModules[subModuleName] = ModuleMapping;

                _buildSubordinatedMapping(SubModules, ModuleMapping);
            }
        }

        function _ModuleMapping( pModuleName, pInputModuleMapping )
        {
            return {
                name: pModuleName,
                destinationModuleName: pInputModuleMapping.destinationModuleName == undefined ? pModuleName : pInputModuleMapping.destinationModuleName,
                DestinationColumnMapping: pInputModuleMapping.DestinationColumnMapping == undefined ? {} : pInputModuleMapping.DestinationColumnMapping,
                ValueMapping: pInputModuleMapping.ValueMapping == undefined ? {} : pInputModuleMapping.ValueMapping,
                DataRows:{}, 
                SubModules: {}
            };
        }

        function _ModuleRowMapping(pModuleMapping, pParentModuleMapping, pDataRow)
        {
            var ModuleRowMapping = {
                name: pModuleMapping.name,
                oldPrimaryKey: null,
                newPrimaryKey: null,
                ColumnMapping: {},
                ModuleMapping: pModuleMapping,
                ParentModuleMapping: pParentModuleMapping
            };

            var ModuleColumnsStructure = AliasDefinitionStructure.tables[ModuleRowMapping.name].columns;

            //build ColumnMapping
            for(var col in ModuleColumnsStructure)
            {
                //set defined columns from InputMapping -> if not defined, use the same column
                var destinationColumn = ModuleRowMapping.ModuleMapping.DestinationColumnMapping[col];
                if(destinationColumn == undefined)
                    destinationColumn = col; 

                //set defined values from InputMapping -> if not defined, use the value from DB
                var oldValue = pDataRow[col].value;
                var newValue = newValue = ModuleRowMapping.ModuleMapping.ValueMapping[col];
                if(newValue == undefined)
                    newValue = oldValue;

                //set new primary key
                if(ModuleColumnsStructure[col].primaryKey)  
                {
                    ModuleRowMapping.oldPrimaryKey = ModuleRowMapping.ColumnMapping[col] = oldValue;
                    newValue = util.getNewUUID();
                    ModuleRowMapping.newPrimaryKey = newValue;
                }
                ModuleRowMapping.ColumnMapping[col] = _columnMapping(newValue, oldValue, destinationColumn);
            }

            switch(ModuleRowMapping.name)
            {
                case "OFFER":
                {
                    //andere Values setzen
                    ModuleRowMapping.ColumnMapping["OFFERDATE"].newValue = DateUtils.getTodayUTC();
                }
                break;
                case "OFFERITEM":
                {
                    //OFFER_ID mappen
                    if(ModuleRowMapping.ParentModuleMapping != null && ModuleRowMapping.ParentModuleMapping.name == "OFFER")
                    {
                        ModuleRowMapping.ColumnMapping["OFFER_ID"].newValue = ModulesMapping[ModuleRowMapping.ParentModuleMapping.name].DataRows[ModuleRowMapping.ColumnMapping["OFFER_ID"].oldValue].newPrimaryKey;
                    }
                    //ASSIGNEDTO mappen
                    if(ModuleRowMapping.ColumnMapping["ASSIGNEDTO"].oldValue != "")
                    {
                        if(ModuleRowMapping.ParentModuleMapping == null)
                        {
                            ModuleRowMapping.ColumnMapping["ASSIGNEDTO"].newValue = ModulesMapping["OFFERITEM"].DataRows[ModuleRowMapping.ColumnMapping["ASSIGNEDTO"].oldValue].newPrimaryKey;
                        }
                        else
                        {
                            ModuleRowMapping.ColumnMapping["ASSIGNEDTO"].newValue = ModuleRowMapping.ModuleMapping.DataRows[ModuleRowMapping.ColumnMapping["ASSIGNEDTO"].oldValue].newPrimaryKey;
                        }
                    }
                }
                break;
                case "OFFERLINK":
                default:
                {

                }
            }

            return ModuleRowMapping;
        }

        function _columnMapping(pNewValue, pOldValue, pDestinationColumn)
        {
            return {
                newValue: pNewValue,
                oldValue: pOldValue,
                destinationColumn: pDestinationColumn
            };
        }
    }

    /**
     * Builds the insert statements for passed ModulesMapping
     * 
     * @param {Object} pModulesMapping ModulesMapping from buildMapping()
     */
    function buildStatements(pModulesMapping)
    {   
        var rootModule = Object.keys(pModulesMapping)[0];

        for(var row in pModulesMapping[rootModule].DataRows)
        {
            //buildInsertStatement
            statements.push(_statement(pModulesMapping[rootModule].DataRows[row]));
        }

        _subordinatedStatements(pModulesMapping[rootModule]);

        function _subordinatedStatements(pMapping)
        {
            if(pMapping.SubModules == undefined)
                return;

            for(var subModule in pMapping.SubModules)
            {
                for(var row in pMapping.SubModules[subModule].DataRows)
                {
                    statements.push(_statement(pMapping.SubModules[subModule].DataRows[row]));
                }
                _subordinatedStatements(pMapping.SubModules[subModule]);
            }
        }

        function _statement(pRowMapping)
        {
            var fieldValues = new Map();
            var destTable = pRowMapping.ModuleMapping.destinationModuleName;
            var colMapping = pRowMapping.ColumnMapping;

            for (let col in colMapping)
            {
                fieldValues.set(colMapping[col].destinationColumn, colMapping[col].newValue)
            }

            return new SqlBuilder().buildInsertStatement(fieldValues, destTable);
        }
    }
}