CSLA ReadOnly Object as wrapper over SAP Web Service: few questions.

CSLA ReadOnly Object as wrapper over SAP Web Service: few questions.

Old forum URL: forums.lhotka.net/forums/t/11329.aspx


tarekahf posted on Tuesday, April 24, 2012

Apologies if I will post the following long code for Staff Pension Object, which is a CSLA Object calling a Web Service Developed in SAP. Basically, it is a CSLA Wrapper over SAP Web Service. 

I am using VS 2005, .NET 2.0 and the related CSLA framework:

Imports Csla
Imports CSLAIDB.Library.Security
<Serializable()> _
Public Class StaffPension
    Inherits ReadOnlyBase(Of StaffPension)

#Region "  Sub-Classes  "
    Public Class PensionCategories
        Public Const conNormal = "N"            ' Normal Pension
        Public Const conEarly = "E"             ' Early Pension
        Public Const conDeferred = "D"          ' Deferred Pension
        Public Const conDeathDisability = "L"   ' Death/Diability Pension
    End Class
#End Region

#Region " Business Methods "

    Private mStaffID As String
    Private mName As String
    Private mNationality As String
    Private mCostCenter As String
    Private mPosition As String
    Private mGrade As String
    Private mGroup As String
    Private mLevel As String
    Private mAppointmentDate As New SmartDate(True)
    Private mAppointmentDateH As New SmartDate(True)
    Private mEndOfServiceDate As New SmartDate(False)
    Private mEndOfServiceDateH As New SmartDate(False)
    Private mBirthDate As New SmartDate(True)
    Private mSalaryUsd As Decimal
    Private mSalarySar As Decimal
    Private mPercentCommut As Decimal       'Commutation Percentage
    Private mCommfactor As Decimal          'Commutation Factor
    'Period Calculation Details
    Private mLwpyearsB As Decimal           'None contribution (Before 1420)
    Private mSelfyearsB As Decimal          'Self contribution (Before 1420)
    Private mServyearsB As Decimal          'Net contribution period (Before 1420)
    Private mLwpyearsA As Decimal           'None contribution
    Private mSelfyearsA As Decimal          'Self contribution
    Private mServyearsA As Decimal          'Net contribution period
    Private mTotYears As Decimal            'Total period of contributed service (years):
    Private mMcYears As Decimal             'Net Period of Contribution in Years
    Private mMedPrct As Decimal             'Medical Benefits Percentage

    'Pension Calculation Details
    Private mWaasUsd As Decimal             'Weighted Average Annual Salary (US$)
    Private mWaasSar As Decimal             '== (SAR)
    Private mNormPenUsd As Decimal          'Annual Normal Pension (US$)
    Private mNormPenSar As Decimal          '== (SAR)
    Private mAnnMedUsd As Decimal           'Annual Medical Benefit (US$)
    Private mAnnMedSar As Decimal           '== (SAR)
    Private mBaseCommutationUsd As Decimal  'Base Commutation (US$)
    Private mBaseCommutationSar As Decimal  '== (SAR)
    Private mReducedPenUsd As Decimal       'Reduced Annual Pension (US$)
    Private mReducedPenSar As Decimal       '== (SAR)
    Private mMonPenSalUsd As Decimal        'Monthly Pension Payment (US$)
    Private mMonPenSalSar As Decimal        '== (SAR)
    Private mMonMedSalUsd As Decimal        'Monthly Medical Payment (US$)
    Private mMonMedSalSar As Decimal        '== (SAR)
    Private mMonTotUsd As Decimal           'Total Monthly Payment: (US$)
    Private mMonTotSar As Decimal           '== (SAR)


    Public ReadOnly Property StaffID() As String
        <System.Runtime.CompilerServices.MethodImpl(Runtime.CompilerServices.MethodImplOptions.NoInlining)> _
        Get
            CanReadProperty(True)
            Return mStaffID
        End Get
    End Property

    Public ReadOnly Property Name() As String
        Get
            Return mName
        End Get
    End Property

    Public ReadOnly Property Nationality() As String
        Get
            Return mNationality
        End Get
    End Property

    Public ReadOnly Property CostCenter() As String
        Get
            Return mCostCenter
        End Get
    End Property

    Public ReadOnly Property Position() As String
        Get
            Return mPosition
        End Get
    End Property

    Public ReadOnly Property Grade() As String
        Get
            Return mGrade
        End Get
    End Property

    Public ReadOnly Property Group() As String
        Get
            'Group
            Return mGroup
        End Get
    End Property

    Public ReadOnly Property Level() As String
        Get
            'Level
            Return mLevel
        End Get
    End Property

    Public ReadOnly Property GradeLevel() As String
        Get
            Dim result As String
            If String.IsNullOrEmpty(mLevel.Trim) Then
                result = mGrade
            Else
                result = mGrade & "-" & mLevel
            End If
            Return result
        End Get
    End Property
    Public ReadOnly Property AppointmentDateDMY() As String
        Get
            Return SmartDateToString(mAppointmentDate, conDateFmtddMMyyyy, CultInfoEnGB)
        End Get
    End Property

    Public ReadOnly Property AppointmentDateHDMY() As String
        Get
            Return SmartDateToString(mAppointmentDateH, conDateFmtddMMyyyy, CultInfoArSA)
        End Get
    End Property

    Public ReadOnly Property EndOfServiceDateDMY() As String
        Get
            Return SmartDateToString(mEndOfServiceDate, conDateFmtddMMyyyy, CultInfoEnGB)
        End Get
    End Property

    Public ReadOnly Property EndOfServiceDateHDMY() As String
        Get
            Return SmartDateToString(mEndOfServiceDateH, conDateFmtddMMyyyy, CultInfoArSA)
        End Get
    End Property

    Public ReadOnly Property BirthDateDMY() As String
        Get
            Return SmartDateToString(mBirthDate, conDateFmtddMMyyyy, CultInfoEnGB)
        End Get
    End Property

    Public ReadOnly Property SalaryUsd() As Decimal
        Get
            Return mSalaryUsd
        End Get
    End Property

    Public ReadOnly Property SalarySar() As Decimal
        Get
            Return mSalarySar
        End Get
    End Property

    Public ReadOnly Property PercentCommut() As Decimal
        Get
            Return mPercentCommut
        End Get
    End Property

    Public ReadOnly Property Commfactor() As Decimal
        Get
            Return mCommfactor
        End Get
    End Property
    Public ReadOnly Property LwpyearsB() As Decimal
        Get
            Return mLwpyearsB
        End Get
    End Property
    Public ReadOnly Property SelfyearsB() As Decimal
        Get
            Return mSelfyearsB
        End Get
    End Property
    Public ReadOnly Property ServyearsB() As Decimal
        Get
            Return mServyearsB
        End Get
    End Property
    Public ReadOnly Property LwpyearsA() As Decimal
        Get
            Return mLwpyearsA
        End Get
    End Property
    Public ReadOnly Property SelfyearsA() As Decimal
        Get
            Return mSelfyearsA
        End Get
    End Property
    Public ReadOnly Property ServyearsA() As Decimal
        Get
            Return mServyearsA
        End Get
    End Property
    Public ReadOnly Property TotYears() As Decimal
        Get
            Return mTotYears
        End Get
    End Property
    Public ReadOnly Property McYears() As Decimal
        Get
            Return mMcYears
        End Get
    End Property
    Public ReadOnly Property MedPrct() As Decimal
        Get
            Return mMedPrct
        End Get
    End Property
    Public ReadOnly Property WaasUsd() As Decimal
        Get
            Return mWaasUsd
        End Get
    End Property
    Public ReadOnly Property WaasSar() As Decimal
        Get
            Return mWaasSar
        End Get
    End Property
    Public ReadOnly Property NormPenUsd() As Decimal
        Get
            Return mNormPenUsd
        End Get
    End Property
    Public ReadOnly Property NormPenSar() As Decimal
        Get
            Return mNormPenSar
        End Get
    End Property
    Public ReadOnly Property AnnMedUsd() As Decimal
        Get
            Return mAnnMedUsd
        End Get
    End Property
    Public ReadOnly Property AnnMedSar() As Decimal
        Get
            Return mAnnMedSar
        End Get
    End Property
    Public ReadOnly Property BaseCommutationUsd() As Decimal
        Get
            Return mBaseCommutationUsd
        End Get
    End Property
    Public ReadOnly Property BaseCommutationSar() As Decimal
        Get
            Return mBaseCommutationSar
        End Get
    End Property
    Public ReadOnly Property ReducedPenUsd() As Decimal
        Get
            Return mReducedPenUsd
        End Get
    End Property
    Public ReadOnly Property ReducedPenSar() As Decimal
        Get
            Return mReducedPenSar
        End Get
    End Property
    Public ReadOnly Property MonPenSalUsd() As Decimal
        Get
            Return mMonPenSalUsd
        End Get
    End Property
    Public ReadOnly Property MonPenSalSar() As Decimal
        Get
            Return mMonPenSalSar
        End Get
    End Property
    Public ReadOnly Property MonMedSalUsd() As Decimal
        Get
            Return mMonMedSalUsd
        End Get
    End Property
    Public ReadOnly Property MonMedSalSar() As Decimal
        Get
            Return mMonMedSalSar
        End Get
    End Property
    Public ReadOnly Property MonTotUsd() As Decimal
        Get
            Return mMonTotUsd
        End Get
    End Property
    Public ReadOnly Property MonTotSar() As Decimal
        Get
            Return mMonTotSar
        End Get
    End Property

    'Public ReadOnly Property xx() As Decimal
    '    Get
    '        Return xx
    '    End Get
    'End Property

    Public ReadOnly Property ObjectName() As String
        Get
            Return AppSecurity.CodesDataTypes.StaffPension.ToString()
        End Get
    End Property

    Protected Overrides Function GetIdValue() As Object

        Return mStaffID

    End Function

#End Region

#Region " Authorization Rules "

    Protected Overrides Sub AddAuthorizationRules()
        ' TODO: add authorization rules
        'AuthorizationRules.AllowRead("", "")
    End Sub

    Public Shared Function CanGetObject(ByVal theUserCtrlInfoPack As UserCtrlInfoPack, Optional ByVal DoThrowError As Boolean = False) As Boolean
        ' TODO: customize to check user role
        Dim theAction As AppSecurity.CodesActions
        Dim result As Boolean
        theAction = AppSecurity.CodesActions.View
        result = AppSecurity.GetSingleton().IsUserAuthorized(AppSecurity.CodesApp.eHRMD, theAction, AppSecurity.CodesDataTypes.StaffPension, theUserCtrlInfoPack)
        If Not result Then
            Throw New System.Security.SecurityException(String.Format(My.Resources.NotAuthErrorPrm2, theUserCtrlInfoPack.AuthUserID, theAction.ToString, AppSecurity.CodesDataTypes.StaffPension.ToString, theUserCtrlInfoPack.QueryUserID))
        End If
        Return result
    End Function

#End Region

#Region " Factory Methods "

    Public Shared Function GetStaffPension(ByVal theUserCtrlInfoPack As UserCtrlInfoPack, _
            ByVal theDateGreg As String, ByVal theDateHijri As String, _
            ByVal thePensionCatg As String, ByVal theCommutPerc As Decimal) As StaffPension
        Dim thePension As StaffPension = Nothing
        If CanGetObject(theUserCtrlInfoPack, True) Then
            thePension = DataPortal.Fetch(Of StaffPension) _
                (New Criteria(theUserCtrlInfoPack, theDateGreg, _
                    theDateHijri, thePensionCatg, theCommutPerc))
        End If
        Return thePension
    End Function

    Friend Shared Function GetStaffPension(ByVal theCriteria As StaffPension.Criteria) As StaffPension
        Dim thePension As StaffPension = Nothing
        If CanGetObject(theCriteria.TheUserCtrlInfoPack, True) Then
            thePension = DataPortal.Fetch(Of StaffPension)(theCriteria)
        End If
        Return thePension
    End Function

    Friend Shared Function GetStaffPension(ByVal sapWS As SAPeHRMD.ZEHRMD_SERVICE_IN, ByVal theCriteria As StaffPension.Criteria) As StaffPension
        Dim result As StaffPension = Nothing
        If CanGetObject(theCriteria.TheUserCtrlInfoPack, True) Then
            result = New StaffPension(sapWS, theCriteria)
        End If
        Return result
    End Function

    Private Sub New()
        ' require use of factory methods
    End Sub

    Private Sub New(ByVal sapWS As SAPeHRMD.ZEHRMD_SERVICE_IN, ByVal theCriteria As StaffPension.Criteria)
        DoFetch(sapWS, theCriteria)
    End Sub
#End Region

#Region " Data Access "

    <Serializable()> _
    Friend Class Criteria
        Private mStaffID As String
        Private mDateGreg As String
        Private mDateHijri As String
        ' Pension Category Parameter as Input:
        '   N - normal pension
        '   E - early pension
        '   D - deferred pension
        '   L - death / disability pension
        Private mPensionCatg As String      'Pension Category
        Private mCommutPerc As Decimal
        Private mUserCtrlInfoPack As UserCtrlInfoPack

        Public ReadOnly Property StaffID() As String
            Get
                Return mStaffID
            End Get
        End Property

        Public ReadOnly Property DateGreg() As String
            Get
                Return mDateGreg
            End Get
        End Property

        Public ReadOnly Property DateHijri() As String
            Get
                Return mDateHijri
            End Get
        End Property

        Public ReadOnly Property PensionCatg() As String
            Get
                Return mPensionCatg
            End Get
        End Property

        Public ReadOnly Property CommutPerc() As Decimal
            Get
                Return mCommutPerc
            End Get
        End Property

        Public ReadOnly Property CommutPercStr() As String
            Get
                Return mCommutPerc.ToString
            End Get
        End Property

        Public ReadOnly Property TheUserCtrlInfoPack() As UserCtrlInfoPack
            Get
                Return mUserCtrlInfoPack
            End Get
        End Property

        Public Sub New(ByVal theUserCtrlInfoPack As UserCtrlInfoPack, ByVal theDateGreg As String, ByVal theDateHijri As String, ByVal thePensionCatg As String, ByVal theCommutPerc As Decimal)
            mStaffID = theUserCtrlInfoPack.QueryOrAuthUser
            mUserCtrlInfoPack = theUserCtrlInfoPack
            mDateGreg = theDateGreg
            mDateHijri = theDateHijri
            mPensionCatg = thePensionCatg
            mCommutPerc = theCommutPerc
        End Sub
    End Class

    Private Sub DoFetch(ByVal sapWS As SAPeHRMD.ZEHRMD_SERVICE_IN, ByVal criteria As Criteria)
        ' load values
        Dim theStaffPension As SAPeHRMD.ZbcpiPensionDetails = Nothing
        Dim theError As String = String.Empty
        Dim thePensionCatg As String = String.Empty
        Dim theStatus As String = String.Empty
        mStaffID = String.Empty
        Try
            thePensionCatg = _
                sapWS.GetPensionDetails(criteria.CommutPercStr, criteria.DateGreg, _
                    criteria.DateHijri, criteria.PensionCatg, criteria.StaffID, _
                    theError, theStaffPension, theStatus)
            mStaffID = theStaffPension.StaffId.Trim
        Catch ex As Exception
            Throw New eHRMDException(String.Format(My.Resources.ErrExecSAPWebSrvPrm, criteria.StaffID, ObjectName, ex.Message), ex)
        End Try
        If String.IsNullOrEmpty(mStaffID) Then
            Throw New Csla.Validation.ValidationException(String.Format(My.Resources.InvldFieldValuePrm, My.Resources.Null.ToString, "StaffID from SAP WS", ObjectName, criteria.StaffID))
        End If
        mName = theStaffPension.Name
        mNationality = theStaffPension.Nationality
        mCostCenter = theStaffPension.CostCenter
        mPosition = theStaffPension.Position
        mGrade = theStaffPension.Grade
        mGroup = theStaffPension.Group
        mLevel = theStaffPension.Trfst
        mAppointmentDate = ParseSmartDateFromSAP(theStaffPension.AppointmentDate)
        mAppointmentDateH = ParseSmartDateFromSAP(theStaffPension.AppointmentDateH, CultInfoArSA)
        mEndOfServiceDate = ParseSmartDateFromSAP(theStaffPension.EndOfServiceDate)
        mEndOfServiceDateH = ParseSmartDateFromSAP(theStaffPension.EndOfServiceDateH, CultInfoArSA)
        mBirthDate = ParseSmartDateFromSAP(theStaffPension.BirthDate)
        mSalaryUsd = theStaffPension.SalaryUsd
        mSalarySar = theStaffPension.SalarySar
        mPercentCommut = theStaffPension.PercentCommut
        mCommfactor = theStaffPension.Commfactor
        mLwpyearsB = theStaffPension.LwpyearsB
        mSelfyearsB = theStaffPension.SelfyearsB
        mServyearsB = theStaffPension.ServyearsB
        mLwpyearsA = theStaffPension.LwpyearsA
        mSelfyearsA = theStaffPension.SelfyearsA
        mServyearsA = theStaffPension.ServyearsA
        mTotYears = theStaffPension.TotYears
        mMcYears = theStaffPension.McYears
        mMedPrct = theStaffPension.MedPrct
        mWaasUsd = theStaffPension.WaasUsd
        mWaasSar = theStaffPension.WaasSar
        mNormPenUsd = theStaffPension.NormPenUsd
        mNormPenSar = theStaffPension.NormPenSar
        mAnnMedUsd = theStaffPension.AnnMedUsd
        mAnnMedSar = theStaffPension.AnnMedSar
        mBaseCommutationUsd = theStaffPension.BaseCommutationUsd
        mReducedPenUsd = theStaffPension.ReducedPenUsd
        mReducedPenSar = theStaffPension.ReducedPenSar
        mMonPenSalUsd = theStaffPension.MonPenSalUsd
        mMonPenSalSar = theStaffPension.MonPenSalSar
        mMonMedSalUsd = theStaffPension.MonMedSalUsd
        mMonMedSalSar = theStaffPension.MonMedSalSar
        mMonTotUsd = theStaffPension.MonTotUsd
        mMonTotSar = theStaffPension.MonTotSar
    End Sub

    Private Overloads Sub DataPortal_Fetch(ByVal criteria As Criteria)
        Dim sapWS As New SAPeHRMD.ZEHRMD_SERVICE_IN
        sapWS.Credentials = SAPWebserviceCred.Cred()
        DoFetch(sapWS, criteria)
    End Sub

#End Region

End Class

I have the following questions:

1. Is this a correct way for implementing such object?

2. Kindly see the code. How best to implement validation in sub "DoFetch()" above? The Web Service "sapWS.GetPensionDetails()" will return "theError" and "theStatus", so if "theStatus=E" I must return to the UI Code error reporting invalid input parameters and the error is in "theError". The logic inside the Web Service will determine error criteria, and will return full text. I am not sure how to plug this within the CSLA validation approach for such Business Object.

3. In the Factory Method above, I am using this code the get a Child Object of Staff Pension, when it is created from another Root Object:

    Friend Shared Function GetStaffPension(ByVal sapWS As SAPeHRMD.ZEHRMD_SERVICE_IN, ByVal theCriteria As StaffPension.Criteria) As StaffPension
        Dim result As StaffPension = Nothing
        If CanGetObject(theCriteria.TheUserCtrlInfoPack, True) Then
            result = New StaffPension(sapWS, theCriteria)
        End If
        Return result
    End Function

This is to avoid going in the Data Portal when the root object (caller) is already in the Data Portal. Becuase if I do not do that, then it will be nearly impossible for me to identify the exact error type thrown from the Data Portal due to nesting many levels of error when the control is back to the UI.

Is this the correct way? Any recommendations?

Appreciate your feedback.

Tarek.

Copyright (c) Marimer LLC