The SAP classification system allows you to use characteristics to describe all types of objects and to group similar objects in classes. Class and classification are used to find objects more easily later. In this blog, I’ll explain tables and model these using CDS.
We will use material class in the blog to explore the classification system. We will start by defining characteristics like carbohydrate, fat, fiber, protein, Iron, Manganese etc. then we will club these characteristics together into two classes – macro and micronutrient.
Introduction to SAP Classification System and Tables
Characteristics
Characteristics are defined in the transaction CT04. There is a lot you can define here for characteristics along with descriptions in various languages, and restrictions on which class type they are valid for.
Most of this information will be stored in table CABN.
CDS- I_ClfnCharcBasic, I_Relstartchar, I_Characteristic .
Class
A class is used to group classifications together, is defined in transaction CL01. While defining class, a class type needs to be specified. Class type usually defines the object we are working with. In this particular case, its Material hence class type 001.
Class header data is stored in table KSSK and KLAH
CDS: I_ClassHeader, I_ClfnClass, I_Relstratclass
Assign Characteristics to Class
In the same transaction CL01 under ‘Char.‘ tab characteristics are assigned to the class.
These relationships between class and characteristic are stored in table KSML.
CDS: I_ClfnClassCharcBasic
Using Class and Classification in Object
Objects which support classification usually have a screen where you can assign class to it and specify values to characteristics. I’ve assigned class and ZMACRONUTRIENT and ZMICRONUTRIENT (and one more) to material 262 and specified values for characteristics.
Values to object can also be defined in generic transaction CL20N.
These values against the object, Material in this case, are stored in table AUSP.
Classification can be of type character, numeric, date, time or range. To support all these types of values AUSP table has quite a few columns ATWRT, ATFLV, DEC_VALUE_FROM, DEC_VALUE_TO, DATE_FROM, DATE_TO, TIME_FROM, TIME_TO.
Class type can be assigned to exactly one object or multiple (TCLA-MULTOBJ). Depending on this restriction you can either select values from AUSP directly with the object key (Material number) or you first get the internal object number from INOB then you go to AUSP.
In the system I am working flag TCLA-MULTOBJ is set for class type 001 hence using INOB to get to AUSP.
Object to class assignment is stored in table KSSK. I have not included that in the below screenshot.
Where flag TCLA-MULTOBJ is not set, you can directly go to table AUSP with object key value in AUSP-OBJEK.
CDS: I_ClfnObjectCharcValueBasic
CDS: I_ClfnInternalIdObjectMapping (INOB Mapping)
References
CDS Modelling
Taking inspiration from CL20N or MM03 I have modelled the data in three layers; Object, Class (Assignment) and Characteristics values.
CDS ZI_CProduct has Product detail and its internal classification number (INOB). CDS ZI_CProdClass has classes assigned to Products and CDS ZI_CProdChValues has values specified under characteristics for Product.
For my test Product 262, data looks like this.
Fiori App using Odata service and list and object page UI annotation
CDS ZI_CProduct
CDS for Object key and its Internal classification number. For the reason explained earlier to get classification values for Material I need to go through INOB table. CDS is exposed as OData service in the Fiori example I used. Association to Class and Characteristics are used in Object Page.
@AbapCatalog.sqlViewName: 'ZICPROD'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Product'
define view ZI_CProduct
as select from I_Product
left outer join I_ClfnInternalIdObjectMapping as mapping on mapping.ClfnObjectTable = 'MARA'
and mapping.ClassType = '001'
and mapping.ClfnObjectID = I_Product.Product
association [0..*] to ZI_CProdClass as _AssignedClass on $projection.ClfnObjectInternalID = _AssignedClass.ClfnObjectID
association [0..*] to ZI_CProdChValues as _AssignedCharc on $projection.ClfnObjectInternalID = _AssignedCharc.ClfnObjectID
{
key I_Product.Product,
@UI.lineItem: [{ position: 20 }]
@UI.identification: [{ position: 10 }]
_Text[ Language = $session.system_language ].ProductName,
mapping.ClfnObjectInternalID,
_AssignedClass,
_AssignedCharc
}
where
Product = '000000000000000262'
CDS ZI_CProdClass
CDS model class assigned to product
@AbapCatalog.sqlViewName: 'ZICLPROD'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Product Class Assigment'
define view ZI_CProdClass
as select from I_ClfnObjectClassBasic
inner join I_ClassHeader as class on I_ClfnObjectClassBasic.ClassInternalID = class.ClassInternalID
and class.ClassType = '001'
association to ZI_CProdChValues as _ClassCharacteristics on $projection.ClassInternalID = _ClassCharacteristics.ClassInternalID
{
key I_ClfnObjectClassBasic.ClfnObjectID,
key I_ClfnObjectClassBasic.ClassInternalID,
class.Class,
class._ClassText[Language = $session.system_language ].ClassDescription,
_ClassCharacteristics
}
where
I_ClfnObjectClassBasic.ClassType = '001'
and ClfnObjectType = 'O'
and IsDeleted = ''
CDS ZI_CProdChValues
CDS brings characteristics values from AUSP.
@AbapCatalog.sqlViewName: 'ZICPVAL'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Material Characteristics Values'
define view ZI_CProdChValues
as select from I_ClfnObjectCharcValueBasic as ausp
inner join I_ClfnCharcBasic as cabn on ausp.CharcInternalID = cabn.CharcInternalID
inner join I_ClfnClassCharcBasic as ksml on ausp.CharcInternalID = ksml.CharcInternalID
{
key ausp.ClfnObjectID,
key cabn.Characteristic,
case cabn.Characteristic
when 'PACKTYPE' then ausp.CharcValue
else concat_with_space( cast( cast( ausp.CharcFromDecimalValue as abap.dec(7,2) ) as abap.char( 30 ) ) , cabn.CharcValueUnit , 1 )
end as CharacteristicsValue,
ksml.ClassInternalID
}
where
ausp.ClfnObjectType = 'O'
and ausp.ClassType = '001'
Quick Reference
SPRO: SAP Customizing Implementation Guide->Cross-Application Components->Classification System
Transactions: CT04 , CL01, CL20N
Tables: KSSK, KLAH, CABN, KSML, INOB, AUSP