#
#===================================================
# copyright     2014-2019
#                Siemens Product Lifecycle Management Software Inc.
#                All Rights Reserved.
#===================================================
##
#
# \brief         Mapping namespace for T4S material master transfer
#
# \details       The namespace contains the custom specific part of a T4S material master transfer:
#                \li Procedure \b TC_Object2SAP_MaterialMaster maps Teamcenter attributes to SAP attributes (so called \c mapping). 
#                \li Procedure \b SAP_MaterialMaster2TC_Object maps SAP attributes back to Teamcenter attributes (so called \c reverse \c mapping). 
#
# \note          For the data exchange between Teamcenter and T4S the internal TCL dictionary \c ::TcData is used.
#                It contains specific attributes of the Teamcenter object to be transferred 
#                and additional information about the current transaction. 
#                For the data exchange between T4S and SAP the internal TCL array \c ::SAPDat is used.\n
#                Teamcenter attributes can be read from \c ::TcData with function \c ::T4X::TC::MAPPING::FieldMapping.\n
#                Teamcenter attributes can be written to \c ::TcData with function \c ::T4X::TC::MAPPING::storeReverseMappingAttribute.\n 
#                SAP attributes can be read from \c ::SAPDat using function \c ::T4S::TC::MAPPING::SAPFieldMapping.\n
#                SAP attributes can be written to \c ::SAPDat with \c set \c ::SAPDat(<key>) \c value.\n 
#
# \pre           For the material master transfer the following preferences are used:
#                \li \c T4S_MaterialMasterTypeList : list of allowed Teamcenter object types
#                \li \c T4S_MaterialMasterMapping4<ObjectType> : list of Teamcenter data types to read attributes from
#                \li \c T4S_MaterialMasterMapping2<ObjectType> : list of Teamcenter data types to write back during reverse mapping
#                \li \c T4S_MaterialMasterFieldMapping2<DataType> : list of Teamcenter attributes to write back during reverse mapping (optional)
#
# ------------------------------------------------------------------------------------------------------ 

namespace eval ::T4S::MM::CUSTOM::MAPPING {
  namespace export TC_Object2SAP_MaterialMaster
  namespace export SAP_MaterialMaster2TC_Object

  # ------------------------------------------------------------------------------------------------------
  # Method:        ::T4S::MM::CUSTOM::MAPPING::TC_Object2SAP_MaterialMaster
  ##
  #
  # \brief         Customer specific mapping function to define the material master to be transferred to SAP 
  #
  # \details       The procedure maps the following Teamcenter attributes to SAP attributes:
  #                \n \c object_name -> \c SAP \c Description
  #                \n \c user_data_1 -> \c SAP \c Id
  #                \n \c user_data_1 -> \c SAP \c Old \c material \c number
  #                \n and some default values defined in \c t4s_mapping_config.sd. 
  #
  # \param         TransactionId Unique ID for the transfer transaction
  # \param         ItemType Teamcenter item type
  # \param         ItemRevisionType Teamcenter item revision type
  # \param         args Not used
  #
  # \return        Return code used by the following transfer function. 
  #                The following values are valid:
  #                \n \c OK                 -> T4S will continue with the next transfer step
  #                \n \c REVERSEMAPPINGONLY -> T4S will skip the transfer to SAP and will just do the reverse mapping 
  #                \n \c SKIPPED            -> T4S will skip the transfer to SAP
  #                \n \c ERROR              -> T4S will stop transfer and raise an error
  #
  # ------------------------------------------------------------------------------------------------------
  
  proc TC_Object2SAP_MaterialMaster {TransactionId ItemType ItemRevisionType args} {

    # Reset some internal variables
    set ::errorCode "NONE"
    set ::errorInfo ""
  
    # Define default return code
    set rc "OK"

    # Store procedure name in variable
    set FunctionName "[lindex [info level 0] 0]"

    # Write information to session log
    tpwrite -logchannel [::PL4X::CORE::getSessionLogChannel] -mtype INTERN "$FunctionName starts with $ItemType, $ItemRevisionType"
    
    #======================================================================================================================
    # Read Teamcenter attributes from Teamcenter Item, ItemRevision, Item Revision Master....
    #======================================================================================================================
    set Item                 "$ItemRevisionType:items_tag:$ItemType"
    set ItemMaster           "$ItemRevisionType:items_tag:$ItemType:IMAN_master_form:$ItemType Master"
    set ItemRevTag           "$ItemRevisionType:items_tag"
    set ItemRev              "$ItemRevisionType"
    set ItemRevMaster        "$ItemRevisionType:IMAN_master_form_rev:$ItemRevisionType Master"
    set ItemRevComplete      "[::T4X::TC::MAPPING::FieldMapping $Item "item_id"]-[::T4X::TC::MAPPING::FieldMapping $ItemRevisionType "item_revision_id"]"  ;# Any separator
    
    if {($ItemType == "AM6_Design" || $ItemType == "AM6_DESIGN")} {
    
        
        
        set AMZDesignItemID      [::T4X::TC::MAPPING::FieldMapping $ItemRevType item_id]
        set AMZDesignRevID       [::T4X::TC::MAPPING::FieldMapping $ItemRevType item_revision_id]
        set AMZRevName           [::T4X::TC::MAPPING::FieldMapping $ItemRevType object_name ]
        set AMZDesignType        [::T4X::TC::MAPPING::FieldMapping $ItemRevType object_type ]
        set AMZTechType          [::T4X::TC::MAPPING::FieldMapping $ItemRevType am6_TechType ]
        set AMZProcType          [::T4X::TC::MAPPING::FieldMapping $ItemRevType am6_ProcurementType ]
        set AMZManufacturer      [::T4X::TC::MAPPING::FieldMapping $ItemRevType am6_Manufacturer ]
        set AMZManufPartNo       [::T4X::TC::MAPPING::FieldMapping $ItemRevType am6_ManufacturerPartNo ]
        set AMZReadyToOrder      [::T4X::TC::MAPPING::FieldMapping $ItemRevType am6_ReadyToOrder ]
        set AMZAMHSAPNumber      [::T4X::TC::MAPPING::FieldMapping $ItemRevType am6_AMHSAPNumber ]
        set AMZForReference      [::T4X::TC::MAPPING::FieldMapping $ItemRevType am6_ForReference ]
        set AMZWeight            [::T4X::TC::MAPPING::FieldMapping $ItemRevType am6_Weight ]
        
        LOG " ******* ItemID :$AMZDesignItemID  | RevID :$AMZDesignRevID | Type :$AMZDesignType < ********" $TransactionId
        
        if {($AMZTechType eq  "MAKE") || ($AMZTechType eq  "M-FABRICATED") || ($AMZTechType eq  "M-COMM MODIFIED") || ($AMZTechType eq  "E-COMM MODIFIED") || ($AMZTechType eq  "COMM MODIFIED")} {
            set MATLTYPE     "ZTEK"
        }
        elseif {($AMZTechType eq  "BUY") || ($AMZTechType eq  "M-COMM") || ($AMZTechType eq  "E-COMM") || ($AMZTechType eq  "E-HARDWARE")} {
            set MATLTYPE     "ZCOMM"   
        }   
        else {
            set MATLTYPE     ""
        }
        if {($AMZTechType eq  "MAKE") || ($AMZTechType eq  "M-FABRICATED") || ($AMZTechType eq  "M-COMM MODIFIED") || ($AMZTechType eq  "E-COMM MODIFIED") || ($AMZTechType eq  "COMM MODIFIED")} {
            set OLDMATNO $AMZDesignItemID
            append  OLDMATNO "-" 
            append  OLDMATNO $AMZDesignRevID
        }
        elseif {($AMZTechType eq  "BUY") || ($AMZTechType eq  "M-COMM") || ($AMZTechType eq  "E-COMM") || ($AMZTechType eq  "E-HARDWARE")} {
            set OLDMATNO $AMZManufPartNo    
        }   
        elseif {($AMZAMHSAPNumber ne "NULL")} {
            set OLDMATNO      $AMZManufacturer
        }
        
        
        # Read some attributes from Teamcenter object
        #
        set SAPDesc           [::T4X::TC::MAPPING::FieldMapping $ItemRev object_name];         # object_name is used for description
        set SAPId             [::T4X::TC::MAPPING::FieldMapping $ItemRevComplete];   # contains SAP Id if data exist in SAP
        #set SAPOldMatNo       [::T4X::TC::MAPPING::FieldMapping $ItemRevMaster user_data_2];   # transfer this value as OLD_MAT_NO
        #set T4STransferStatus [::T4X::TC::MAPPING::FieldMapping $ItemRevMaster item_comment];  # it is empty if item was never transferred before
        
        # Store data to the data exchange array ::SAPDat
        #
        set ::SAPDat(Material:HeadData:MATERIAL)       [string toupper [string trim $SAPId]]
        set ::SAPDat(Material:HeadData:IND_SECTOR)     $::T4S_Defaults(Industry) ;# Default value
        set ::SAPDat(Material:HeadData:MATL_TYPE)      $MATLTYPE ;# Default value
        set ::SAPDat(Material:HeadData:BASIC_VIEW)     "X" ;# Basic Data View
        
        set ::SAPDat(Material:MaktData:LANGU_ISO:1)    "EN"
        set ::SAPDat(Material:MaktData:MATL_DESC:1)    "EN: $SAPDesc"
        set ::SAPDat(Material:MaktData:LANGU_ISO:2)    "NL"
        set ::SAPDat(Material:MaktData:MATL_DESC:2)    "NL: $SAPDesc"
        #set ::SAPDat(Material:MaktData:LANGU_ISO:3)    "FR"
        #set ::SAPDat(Material:MaktData:MATL_DESC:3)    "FR: $SAPDesc"
        
        set ::SAPDat(Material:MaraData:BASE_UOM)       $::T4S_Defaults(BaseUnit) ;# Default value
        set ::SAPDat(Material:MaraData:CAD_ID)         "X" ;# CAD indicator
        set ::SAPDat(Material:MaraData:OLD_MAT_NO)     $OLDMATNO
        
        #PLANT DATA
        set ::SAPDat(Material:MarcData:PLANT)            $::T4S_Defaults(PlantId) ; #PLANT
           
        # Write return code to session log
        tpwrite -logchannel [::PL4X::CORE::getSessionLogChannel] -mtype INTERN "$FunctionName returns $rc"
      
    }
    
    return $rc
  }
    
  # ------------------------------------------------------------------------------------------------------
  # Method:        ::T4S::MM::CUSTOM::MAPPING::SAP_MaterialMaster2TC_Object
  ##
  #
  # \brief         Customer specific reverse mapping function for the T4S material master transfer
  #
  # \details       The procedure maps the following SAP attributes back to Teamcenter attributes: 
  #                \n \c SAP \c Id -> \c user_data_1
  #                \n \c SAP \c Old \c material \c number -> \c user_data_2
  #                \n \c T4S \c transfer \c status -> \c item_comment  
  #
  # \param         TransactionId Unique ID for the transfer transaction
  # \param         Status SAP transfer status. 
  #                The following values are valid:
  #                \n \c SKIPPED                   -> the transfer was skipped
  #                \n \c ERROR                     -> the transfer was stopped by an error
  #                \n \c UNKNOWN                   -> the transfer was stopped by an unknown error
  #                \n \c UPDATED_WITH_ERROR        -> the transfer was stopped by an minor error in one of the additional transfer steps
  #                \n \c CREATED, \c CHANGED, \c UPDATED -> and some other values are used for a successful transfer
  # \param         ObjectKey SAP Id of material master
  # \param         args Not used
  #
  # \return        Return code used by the following Tc object update function. 
  #                The following values are valid:
  #                \n \c OK                 -> T4S will update the Tc object based on the reverse mapping preferences and the reverse mapping buffer
  #                \n \c SKIPPED            -> T4S will skip the TcData object
  #                \n \c ERROR              -> T4S will stop transfer and raise an error
  #
  # ------------------------------------------------------------------------------------------------------
  
  proc SAP_MaterialMaster2TC_Object {TransactionId Status ObjectKey args} {

    # Reset some internal variables
    set ::errorCode "NONE"
    set ::errorInfo ""
  
    # Define default return code
    set rc "OK"

    # Store procedure name in variable
    set FunctionName "[lindex [info level 0] 0]"
    
    # Write information to session log
    tpwrite -logchannel [::PL4X::CORE::getSessionLogChannel] -mtype INTERN "$FunctionName starts with $Status, $ObjectKey"

    # Define some relation name strings
    set ItemRevisionType     $::TcData(ItemInfo:TypeName)
    set ItemRevMaster        "$ItemRevisionType:IMAN_master_form_rev:$ItemRevisionType Master"

    # Return in case of prohibited action
    foreach data [array names ::SAPDat "CtrlParam:ProhibitedAction"] {
      set rc "SKIPPED"
      tpwrite -logchannel [::PL4X::CORE::getSessionLogChannel] -mtype INTERN "$FunctionName returns $rc"
      return $rc
    }
    
    # Read some attributes from SAP object and define transfer status string
    # Store data to Teamcenter and write information to session log
    #
    # The parameter ObjectKey is always in the internal format that you need for asking SAP for more data.
    # For storing in TC, the external format is recommended (cut leading zeros...):
    set SAPId       [::TPSAP::MM::getExternalMaterialNumber $ObjectKey]
    set SAPOldMatNo [::T4S::TC::MAPPING::SAPFieldMapping MaterialMaster $ObjectKey CLIENTDATA:OLD_MAT_NO]
    set ItemComment [string trim [::T4X::TC::MAPPING::FieldMapping $ItemRevMaster item_comment]]
    set listComment [split $ItemComment "\n"]
    if {[llength $listComment] > 1 && [string length [lindex $listComment 1]] > 0} {
      set T4STransferStatusMM [lindex $listComment 1]
    } else {
      set T4STransferStatusMM ""
    }
    
    if {($Status eq "ERROR") || ($Status eq "UNKNOWN") || ($Status eq "SKIPPED")} {
      set T4STransferStatus "MM transfer $Status - [clock format [clock seconds] -format "%Y-%m-%d %R"]\n$T4STransferStatusMM"
      #
      tpwrite -logchannel [::PL4X::CORE::getSessionLogChannel] -mtype INTERN "++++++++++ Reverse mapping value 'item_comment': '$T4STransferStatus' ++++++++++"  
      ::T4X::TC::MAPPING::storeReverseMappingAttribute MaterialMaster $ItemRevMaster item_comment $T4STransferStatus
    #
    } else {
      if {$Status eq "UPDATED_WITH_ERROR"} {
        set T4STransferStatus "MM transfer $Status - [clock format [clock seconds] -format "%Y-%m-%d %R"]\n$T4STransferStatusMM"
      } else {
        set T4STransferStatus "MM transferred to $::T4S::SapInfo(SapSystem) at [clock format [clock seconds] -format "%Y-%m-%d %R"]\n$T4STransferStatusMM"
      }
      #
      tpwrite -logchannel [::PL4X::CORE::getSessionLogChannel] -mtype INTERN "++++++++++ Reverse mapping value 'user_data_1': '$SAPId' ++++++++++"  
      ::T4X::TC::MAPPING::storeReverseMappingAttribute MaterialMaster $ItemRevMaster user_data_1 $SAPId
      tpwrite -logchannel [::PL4X::CORE::getSessionLogChannel] -mtype INTERN "++++++++++ Reverse mapping value 'user_data_2': '$SAPOldMatNo' ++++++++++"  
      ::T4X::TC::MAPPING::storeReverseMappingAttribute MaterialMaster $ItemRevMaster user_data_2 $SAPOldMatNo
      tpwrite -logchannel [::PL4X::CORE::getSessionLogChannel] -mtype INTERN "++++++++++ Reverse mapping value 'item_comment': '$T4STransferStatus' ++++++++++"  
      ::T4X::TC::MAPPING::storeReverseMappingAttribute MaterialMaster $ItemRevMaster item_comment $T4STransferStatus
    }

    # Write return code to session log
    tpwrite -logchannel [::PL4X::CORE::getSessionLogChannel] -mtype INTERN "$FunctionName returns $rc"
    
    return $rc
  }
  
} 

Tool Command Language(TCL) online compiler

Write, Run & Share TCL code online using OneCompiler's TCL online compiler for free. It's one of the robust, feature-rich online compilers for TCL language, running the latest TCL version 8.6. Getting started with the OneCompiler's TCL editor is easy and fast. The editor shows sample boilerplate code when you choose language as TCL and start coding.

Taking inputs (stdin)

OneCompiler's TCL online editor supports stdin and users can give inputs to programs using the STDIN textbox under the I/O tab. Following is a sample TCL program which takes name as input and prints hello message with your name.

set name [gets stdin]
puts "Hello $name"

About TCL

Tool Command Language(TCL) is a general purpose scripting language which is commonly used for GUIs and for testing. Everything is by default string in TCL. It was created by John Osterhout in 1989.

Syntax help

Variables

Variable is a identifier which is used to hold the value. set is used to create variables.

Examples

set name onecompiler

Loops

1. If-Else:

When ever you want to perform a set of operations based on a condition IF-ELSE is used.

if(conditional-expression) {
   #code
} else {
   #code
}

You can also use if-else for nested Ifs and If-Else-If ladder when multiple conditions are to be performed on a single variable.

2. Switch:

Switch is an alternative to If-Else-If ladder.

switch(conditional-expression) {    
value1 {     
 # code
}    
value1 {     
 # code
}    
...
default {
# code
} 

3. For:

For loop is used to iterate a set of statements based on a condition.

for{start}{test}{next}{  
  # code  
} 

4. While:

While is also used to iterate a set of statements based on a condition. Usually while is preferred when number of iterations are not known in advance.

while(condition) {  
 # code 
}  

Arrays

Array is a collection of similar data which is stored in continuous memory addresses. Array values can be fetched using index. Index starts from 0 to size-1.

Syntax

set ArrayName(Index) value

Procedures

Procedure is a sub-routine which contains set of statements. Uusually procedures are required when multiple calls are made to same set of statements. Procedures increases re-usuability and modularity.

Syntax

proc procedureName {arguments} {
   # code
}