Imports CharterDotCom.CommonEntities.Library
Imports CharterDotCom.CommonEntities.Library.Enumerations
Imports CharterDotCom.CommonEntities.Library.EntityMemberServices
'Imports CharterDotCom.CommonEntities.Library.EntityEBSServices
Imports CharterDotCom.CommonEntities.Library.EntitySupport
Imports CharterDotCom.CommonEntities.Library.EntitySearch
Imports CharterDotCom.CommonEntities.Library.EntityWebConfig
'Imports CharterDotCom.CommonEntities.Library.EntityG2BServices
Imports CharterDotCom.WebSite.Library.BLCommon
Imports System.Configuration
Imports commoninterface = CommonProviderInterfaces
Imports System.Xml
Imports System.Text
Imports System.Web

Public Class BLAffiliateOrderManager
    Inherits AffiliateOrderClient

    Private LIVE As Boolean = False

    Private order As BLAffiliateOrder
    Private configdata_g2b As XmlNode

    Public Sub New()
        If System.Web.HttpContext.Current.Application("LIVE").Equals("true") Then
            LIVE = True
        Else
            LIVE = False
        End If
    End Sub

    Public Sub New(ByVal DictionaryOfVariables As Dictionary(Of String, Object))
        If DictionaryOfVariables.ContainsKey("order") Then
            If Not (DictionaryOfVariables("order") Is Nothing) Then
                Me.order = CType(DictionaryOfVariables("order"), BLAffiliateOrder)
                If System.Web.HttpContext.Current.Application("LIVE").Equals("true") Then
                    LIVE = True
                Else
                    LIVE = False
                End If
            End If
        End If

    End Sub

    Public ReadOnly Property ValuesForSetSession() As Dictionary(Of String, Object)
        Get
            Dim VarList As New Dictionary(Of String, Object)
            VarList.Add("order", Me.order)
            Return VarList
        End Get
    End Property

    Protected Overrides Sub PopulateLocalVariables(ByVal trackingID As String)
        Try
            If Not (trackingID Is Nothing) Then
                MyBase.TrackingID = trackingID
                Dim sessionEntry As Object = Session(BLCommon.AffiliateOrderManagerKey)
                If Not sessionEntry Is Nothing Then
                    Dim lManager As New BLAffiliateOrderManager(CType(sessionEntry, Dictionary(Of String, Object)))
                    Me.order = lManager.order
                End If

                'Dim lProviderSection As ProviderSectionHandler = CType(System.Web.HttpContext.Current.Application("ProviderSection"), ProviderSectionHandler)
                'configdata_g2b = lProviderSection.ProviderData("G2BServicesProvider")
            End If
        Catch ex As Exception
            Throw New ApplicationException("Cannt load values from Session", ex)
        End Try
    End Sub

#Region "Order"

    Public Overloads Overrides Function SubmitOrder(ByVal trackingID As String) As Boolean
        Try
            PopulateLocalVariables(trackingID)
            Dim response As Boolean
            response = SendOrderToProvider()
            Return response
        Catch ex As ApplicationException
            BLCommon.LogException(ex, ExceptionSeverity.Catastrophic)
            Throw ex
        Catch ex As Exception
            Dim aex As New ApplicationException("Cannot submit Order", ex)
            BLCommon.LogException(aex, ExceptionSeverity.Catastrophic)
            Throw aex
        Finally
            Dim cm As New BLAffliateCatalogManager(CType(Session(BLCommon.AffiliateCatalogManagerKey), Dictionary(Of String, Object)))
            CType(cm.ProductCatalog.Cart, BLShoppingCart).OrderSubmitted = True
            SetSession(AffiliateCatalogManagerKey, cm.ValuesForSetSession)
            Dim am As New BLAccountManager(CType(Session(BLCommon.AccountManagerKey), Dictionary(Of String, Object)))
            CType(am.account, BLAccount).SSN = String.Empty
            SetSession(AccountManagerKey, am.ValuesForSetSession)
        End Try
    End Function

    Private Function SendOrderToProvider() As Boolean
        Dim iProvider As IG2BServicesProvider = CType(Activator.GetObject(GetType(IG2BServicesProvider), CStr(HttpContext.Current.Application("RemoteURL_G2BServicesProvider"))), IG2BServicesProvider)
        Dim providerRequest As EntityG2BServices.G2BSubmitOrderRequest
        Dim offers As List(Of EntityG2BServices.OfferOrderTypeG2BOrder)
        Dim lManager As New BLAccountManager(CType(Session(BLCommon.AccountManagerKey), Dictionary(Of String, Object)))
        Dim account As BLAccount = lManager.account

        offers = PopulateGwyOrderOffers(account.SSN)
        Dim eMail As String
        If account.User.Email Is Nothing OrElse account.User.Email.Count = 0 Then
            eMail = Nothing
        Else
            For Each e As IAccount.IMember.IEmail In account.User.Email
                eMail = e.MailID
            Next
        End If



        '9/18/2007 Brad Miller - Send ShippingAddress for G2B 4.1
        Dim objShippingAddress As Address
        If account.ShippingAddress IsNot Nothing Then
            Dim zip4 As String = Nothing
            If account.ShippingAddress.Zip.Length > 5 Then
                If Not account.ShippingAddress.Zip Is Nothing Then
                    zip4 = account.ShippingAddress.Zip.Replace("-", "")
                    zip4 = zip4.Substring(5, zip4.Length - 5)
                    account.ShippingAddress.Zip = account.ShippingAddress.Zip.Substring(0, 5)
                End If
            End If
            If zip4 = Nothing Then
                objShippingAddress = New Address(account.ShippingAddress.Street1, account.ShippingAddress.Street2, account.ShippingAddress.City, account.ShippingAddress.State, account.ShippingAddress.Zip)
            Else
                objShippingAddress = New Address(account.ShippingAddress.Street1, account.ShippingAddress.Street2, account.ShippingAddress.City, account.ShippingAddress.State, account.ShippingAddress.Zip, zip4)
            End If
        End If






        providerRequest = New EntityG2BServices.G2BSubmitOrderRequest(offers, account.User.FirstName, account.User.LastName, account.HomePhone, account.HomePhone, eMail, Nothing, Nothing, objShippingAddress, Nothing, account.TrackingID, account.MSOID, account.AddressID, 0, account.IsMoving, New List(Of EntityG2BServices.CustomerHardwareType))

        Dim response As EntityG2BServices.G2BSubmitOrderResponse = DirectCast(iProvider.SubmitOrder(providerRequest), EntityG2BServices.G2BSubmitOrderResponse)
        If response Is Nothing Then
            If account.IsMoving Then
                SetSession(AffiliateOrderManagerKey, Me.ValuesForSetSession)
                Return True
            Else
                Return False
            End If
        Else
            If LIVE Then
                If response.Exception Then
                    BLCommon.LogException(New ApplicationException("Order Manager: Submit Order failed for " + account.User.FirstName + " , " + account.User.LastName + " for address " + account.Address.Zip, New ApplicationException(response.ExceptionStackTrace)), ExceptionSeverity.Catastrophic)
                    Return False
                End If
            End If


            ' create schedule and confirmation objects

            '9/18/2007 Brad Miller - Send ShippingAddress for G2B 4.1
            PopulateOrderFromResonse(response, providerRequest.ShippingAddress)

            Return True
        End If
    End Function

    Private Function PopulateGwyOrderOffers(ByVal ssn As String) As List(Of EntityG2BServices.OfferOrderTypeG2BOrder)
        Dim offers As New List(Of EntityG2BServices.OfferOrderTypeG2BOrder)
        Dim lManager As New BLAffliateCatalogManager(CType(Session(BLCommon.AffiliateCatalogManagerKey), Dictionary(Of String, Object)))
        Dim cart As ICart = lManager.ProductCatalog.Cart
        Dim offer As EntityG2BServices.OfferOrderTypeG2BOrder
        Dim customizations As List(Of EntityG2BServices.CustomizationTypeOrder)
        Dim gwyCustomization As EntityG2BServices.CustomizationTypeOrder
        Dim items As Object
        Dim ssnCustomizationID As String = String.Empty

        If System.Web.HttpContext.Current.Application("SSNCustomizationID") IsNot Nothing Then
            ssnCustomizationID = CType(System.Web.HttpContext.Current.Application("SSNCustomizationID"), String)
        End If
        For Each item As ICartItem In cart.CartItems.Values
            customizations = New List(Of EntityG2BServices.CustomizationTypeOrder)
            If item.Type = ItemType.Bundle Then
                ' add all the serviceplans in a bundle to offers
                For Each sp As BLServicePlan In item.Children.Values
                    For Each cz As BLFeature In sp.Features.Values
                        If cz.ID = ItemType.Feature & ssnCustomizationID Then
                            'If Not (ssn Is Nothing OrElse ssn.Equals(String.Empty)) Then
                            '    'items = New Object()
                            '    'items = ssn
                            '    'customizations.Add(New EntityG2BServices.CustomizationTypeOrder(items, cz.gwyFeature.ID))
                            '    items = New EntityG2BServices.InputTextTypeOrder(CType(cz.gwyFeature.ID, Integer), ssn)
                            '    customizations.Add(New EntityG2BServices.CustomizationTypeOrder(items, cz.gwyFeature.ID))

                            'End If
                        Else
                            If cz.ISSelected Then
                                gwyCustomization = PopulateGwyOrderCustomization(cz)
                                If Not gwyCustomization Is Nothing Then
                                    customizations.Add(gwyCustomization)
                                End If
                            End If
                        End If
                    Next
                Next
            Else ' service plan
                For Each cz As BLFeature In item.Children.Values
                    If cz.ID = ItemType.Feature & ssnCustomizationID Then
                        'If Not (ssn Is Nothing OrElse ssn.Equals(String.Empty)) Then
                        '    'items = New Object()
                        '    'items = ssn
                        '    'customizations.Add(New EntityG2BServices.CustomizationTypeOrder(items, cz.gwyFeature.ID))
                        '    items = New EntityG2BServices.InputTextTypeOrder(CType(cz.gwyFeature.ID, Integer), ssn)
                        '    customizations.Add(New EntityG2BServices.CustomizationTypeOrder(items, cz.gwyFeature.ID))

                        'End If
                    Else
                        If cz.ISSelected Then
                            gwyCustomization = PopulateGwyOrderCustomization(cz)
                            If Not gwyCustomization Is Nothing Then
                                customizations.Add(gwyCustomization)
                            End If
                        End If
                    End If
                Next
            End If
            offer = New EntityG2BServices.OfferOrderTypeG2BOrder(customizations, ConvertToActualOfferID(item.ID))
            offers.Add(offer)
        Next
        Return offers
    End Function

    Private Function PopulateGwyOrderCustomization(ByVal cz As BLFeature) As EntityG2BServices.CustomizationTypeOrder
        Dim items As Object
        Dim selectionItem As EntityG2BServices.SelectionTypeOrder
        Dim subitems As List(Of String)

        ' loop through all the features of given serviceplan
        If Not cz.FeatureType = FeatureType.IsIncluded AndAlso cz.ISSelected Then
            ' customization type and also selected
            items = New List(Of Object)
            ''If cz.MaxSelection > 0 Then
            ''  ' this is a number type
            ''  items = cz.QuantitySelected
            ''  Return New EntityG2BServices.CustomizationTypeOrder(items, cz.gwyFeature.ID)
            ''  ' j += 1
            ''Else
            ''  ' this is a selection type
            ''  subitems = New List(Of String)
            ''  For Each c As BLFeature In cz.Choices.Values
            ''    If c.ISSelected Then
            ''      ' this choice is selected so add it to items list
            ''      subitems.Add(ConvertToActualChoiceID(c.ID))
            ''    End If
            ''  Next
            ''  selectionItem = New EntityG2BServices.SelectionTypeOrder(subitems)
            ''  items = selectionItem
            ''  Return New EntityG2BServices.CustomizationTypeOrder(items, cz.gwyFeature.ID)
            ''End If
            Select Case cz.InputType
                Case InputType.Selection
                    ' this is a selection type
                    subitems = New List(Of String)
                    For Each c As BLFeature In cz.Choices.Values
                        If c.ISSelected Then
                            ' this choice is selected so add it to items list
                            subitems.Add(ConvertToActualChoiceID(c.ID))
                        End If
                    Next
                    selectionItem = New EntityG2BServices.SelectionTypeOrder(subitems)
                    items = selectionItem
                    Return New EntityG2BServices.CustomizationTypeOrder(items, cz.m_gwyFeature.ID)
                Case InputType.Number
                    ' this is a number type
                    items = cz.QuantitySelected
                    Return New EntityG2BServices.CustomizationTypeOrder(items, cz.m_gwyFeature.ID)
                    ' j += 1
                Case InputType.Text
                    items = New EntityG2BServices.InputTextTypeOrder(CType(cz.m_gwyFeature.ID, Integer), cz.Text)
                    Return New EntityG2BServices.CustomizationTypeOrder(items, cz.m_gwyFeature.ID)
                Case InputType.Other
                    ' this is a text type
                    items = cz.Text
                    Return New EntityG2BServices.CustomizationTypeOrder(items, cz.m_gwyFeature.ID)
            End Select
        End If
        Return Nothing
    End Function

    Private Sub PopulateOrderFromResonse(ByVal providerResponse As EntityG2BServices.G2BSubmitOrderResponse, ByVal pobjShipAddr As Address)
        Dim lManager As New BLAccountManager(CType(Session(BLCommon.AccountManagerKey), Dictionary(Of String, Object)))
        Dim am As BLAccountManager = lManager
        Try

            With providerResponse
                am.account.TrackingID = .TrackingID
                am.account.MSOID = .MSOID
                am.account.AddressID = .AddressID

                ' 8/2007 jwg added for 4.1
                If Not (am.account.Eligibility Is Nothing) Then
                    If Not (.Eligibility Is Nothing) Then
                        am.account.Eligibility.AccountNumber = .Eligibility.accountNumber
                        am.account.Eligibility.BillingCycle = .Eligibility.billingCycle
                        am.account.Eligibility.BillingCycleFieldSpecified = .Eligibility.billingCycleFieldSpecified
                        am.account.Eligibility.CreditClassField = .Eligibility.creditClassField
                        am.account.Eligibility.DepositAmountField = .Eligibility.depositAmountField
                        am.account.Eligibility.DepositAmountFieldSpecified = .Eligibility.depositAmountFieldSpecified
                    End If
                End If


                If pobjShipAddr IsNot Nothing Then
                    am.account.ShippingAddress.Street1 = pobjShipAddr.Street1
                    am.account.ShippingAddress.Street2 = pobjShipAddr.Street2
                    am.account.ShippingAddress.City = pobjShipAddr.City
                    am.account.ShippingAddress.State = pobjShipAddr.State
                    am.account.ShippingAddress.Zip = pobjShipAddr.Zip
                End If
            End With
            SetSession(AccountManagerKey, am.ValuesForSetSession)

            If Not LIVE Then

                Dim rConfirms As New List(Of EntityG2BServices.ConfirmationType)
                Dim rInstalls As List(Of EntityG2BServices.InstallWindowType)

                ' schedule for hsd
                Dim day As DateTime
                rInstalls = New List(Of EntityG2BServices.InstallWindowType)
                day = Date.Today()
                If Not (day.DayOfWeek = DayOfWeek.Saturday OrElse day.DayOfWeek = DayOfWeek.Sunday) Then
                    rInstalls.Add(New EntityG2BServices.InstallWindowType("1", day.ToShortDateString(), "9", "Noon"))
                    rInstalls.Add(New EntityG2BServices.InstallWindowType("21", day.ToShortDateString(), "Noon", "5 PM"))
                End If
                day = Today.AddDays(1)
                If Not (day.DayOfWeek = DayOfWeek.Saturday OrElse day.DayOfWeek = DayOfWeek.Sunday) Then
                    rInstalls.Add(New EntityG2BServices.InstallWindowType("31", day.ToShortDateString(), "9", "Noon"))
                    rInstalls.Add(New EntityG2BServices.InstallWindowType("41", day.ToShortDateString(), "Noon", "5 PM"))
                End If
                day = Today.AddDays(2)
                If Not (day.DayOfWeek = DayOfWeek.Saturday OrElse day.DayOfWeek = DayOfWeek.Sunday) Then
                    rInstalls.Add(New EntityG2BServices.InstallWindowType("51", day.ToShortDateString(), "9", "Noon"))
                    rInstalls.Add(New EntityG2BServices.InstallWindowType("61", day.ToShortDateString(), "Noon", "5 PM"))
                End If

                day = Today.AddDays(8)
                If Not (day.DayOfWeek = DayOfWeek.Saturday OrElse day.DayOfWeek = DayOfWeek.Sunday) Then
                    rInstalls.Add(New EntityG2BServices.InstallWindowType("571", day.ToShortDateString(), "9", "Noon"))
                    rInstalls.Add(New EntityG2BServices.InstallWindowType("671", day.ToShortDateString(), "Noon", "5 PM"))
                End If

                day = Today.AddDays(10)
                If Not (day.DayOfWeek = DayOfWeek.Saturday OrElse day.DayOfWeek = DayOfWeek.Sunday) Then
                    rInstalls.Add(New EntityG2BServices.InstallWindowType("71", day.ToShortDateString(), "9", "Noon"))
                    rInstalls.Add(New EntityG2BServices.InstallWindowType("81", day.ToShortDateString(), "Noon", "5 PM"))
                End If
                day = Today.AddDays(11)
                If Not (day.DayOfWeek = DayOfWeek.Saturday OrElse day.DayOfWeek = DayOfWeek.Sunday) Then
                    rInstalls.Add(New EntityG2BServices.InstallWindowType("771", day.ToShortDateString(), "9", "Noon"))
                    rInstalls.Add(New EntityG2BServices.InstallWindowType("881", day.ToShortDateString(), "Noon", "5 PM"))
                End If
                day = Today.AddDays(12)
                If Not (day.DayOfWeek = DayOfWeek.Saturday OrElse day.DayOfWeek = DayOfWeek.Sunday) Then
                    rInstalls.Add(New EntityG2BServices.InstallWindowType("91", day.ToShortDateString(), "9", "Noon"))
                    rInstalls.Add(New EntityG2BServices.InstallWindowType("101", day.ToShortDateString(), "Noon", "5 PM"))
                End If

                day = Today.AddDays(16)
                If Not (day.DayOfWeek = DayOfWeek.Saturday OrElse day.DayOfWeek = DayOfWeek.Sunday) Then
                    rInstalls.Add(New EntityG2BServices.InstallWindowType("201", day.ToShortDateString(), "9", "Noon"))
                    rInstalls.Add(New EntityG2BServices.InstallWindowType("501", day.ToShortDateString(), "Noon", "5 PM"))
                End If
                day = Today.AddDays(20)
                If Not (day.DayOfWeek = DayOfWeek.Saturday OrElse day.DayOfWeek = DayOfWeek.Sunday) Then
                    rInstalls.Add(New EntityG2BServices.InstallWindowType("301", day.ToShortDateString(), "9", "Noon"))
                    rInstalls.Add(New EntityG2BServices.InstallWindowType("401", day.ToShortDateString(), "Noon", "5 PM"))
                End If
                rConfirms.Add(New EntityG2BServices.ConfirmationType(rInstalls, "6700", "1267", "Nothing"))

                ' schedule for telephone
                rInstalls = New List(Of EntityG2BServices.InstallWindowType)
                day = Date.Today()
                If Not (day.DayOfWeek = DayOfWeek.Saturday OrElse day.DayOfWeek = DayOfWeek.Sunday) Then
                    rInstalls.Add(New EntityG2BServices.InstallWindowType("111", day.ToShortDateString(), "9", "Noon"))
                    rInstalls.Add(New EntityG2BServices.InstallWindowType("211", day.ToShortDateString(), "Noon", "5 PM"))
                End If
                day = Today.AddDays(1)
                If Not (day.DayOfWeek = DayOfWeek.Saturday OrElse day.DayOfWeek = DayOfWeek.Sunday) Then
                    rInstalls.Add(New EntityG2BServices.InstallWindowType("311", day.ToShortDateString(), "9", "Noon"))
                    rInstalls.Add(New EntityG2BServices.InstallWindowType("411", day.ToShortDateString(), "Noon", "5 PM"))
                End If
                day = Today.AddDays(2)
                If Not (day.DayOfWeek = DayOfWeek.Saturday OrElse day.DayOfWeek = DayOfWeek.Sunday) Then
                    rInstalls.Add(New EntityG2BServices.InstallWindowType("511", day.ToShortDateString(), "9", "Noon"))
                    rInstalls.Add(New EntityG2BServices.InstallWindowType("611", day.ToShortDateString(), "Noon", "5 PM"))
                End If
                rConfirms.Add(New EntityG2BServices.ConfirmationType(rInstalls, "6900", "7677676", "Nothing"))

                providerResponse = New EntityG2BServices.G2BSubmitOrderResponse(am.account.TrackingID, am.account.MSOID, am.account.AddressID, rConfirms)

                'end
            End If



            If Not providerResponse.Confirmation Is Nothing Then

                ' populate order object
                Dim confirmations As New List(Of IAffiliateOrder.IAffiliateOrderConfirmation)
                Dim schedule As BLAffiliateSchedule
                Dim scheduleWindows As Dictionary(Of String, IAffiliateOrder.IAffiliateScheduleWindow)
                Dim category As Category

                Dim _dict As Dictionary(Of String, Object) = DirectCast(Session(BLCommon.AffiliateCatalogManagerKey), Dictionary(Of String, Object))
                Dim cm As BLAffliateCatalogManager = New BLAffliateCatalogManager(_dict)
                Dim cart As BLShoppingCart = DirectCast(cm.ProductCatalog.Cart, BLShoppingCart)
                Dim type As ScheduleType
                Dim offerID As String

                For Each c As EntityG2BServices.ConfirmationType In providerResponse.Confirmation
                    If cart.ContainsThisKey(ItemType.ServicePlan & c.OfferID) Then
                        ' service plan
                        category = cart.GetCartItemCategory(ItemType.ServicePlan & c.OfferID)
                        offerID = ItemType.ServicePlan & c.OfferID
                    Else
                        ' bundle
                        category = category.UnSpecified
                        offerID = ItemType.Bundle & c.OfferID
                    End If

                    Select Case category
                        Case category.Cable
                            type = ScheduleType.Cable
                        Case category.HSD
                            type = ScheduleType.HSD
                        Case category.Telephoney
                            type = ScheduleType.Telephone
                        Case Else ' unspecified ( bundle)
                            Dim bundle As BLBundle = DirectCast(cm.ProductCatalog.Bundles(offerID), BLBundle)
                            Dim cable As Boolean = False
                            Dim hsd As Boolean = False
                            Dim telephone As Boolean = False
                            For Each sp As BLServicePlan In bundle.ServicePlans.Values
                                Select Case sp.Category
                                    Case category.Cable
                                        cable = True
                                    Case category.HSD
                                        hsd = True
                                    Case category.Telephoney
                                        telephone = True
                                End Select
                            Next
                            ' find what are the categories this bundle has and set appropriate schedule type
                            If cable And hsd And telephone Then
                                type = ScheduleType.All
                            Else
                                If cable And hsd Then
                                    type = ScheduleType.CableAndHSD
                                Else
                                    If cable And telephone Then
                                        type = ScheduleType.CableAndTelephone
                                    Else
                                        If hsd And telephone Then
                                            type = ScheduleType.HSDAndTelephone
                                        End If
                                    End If
                                End If
                            End If
                    End Select

                    scheduleWindows = New Dictionary(Of String, IAffiliateOrder.IAffiliateScheduleWindow)
                    If Not c.InstallWindow Is Nothing Then
                        For Each s As EntityG2BServices.InstallWindowType In c.InstallWindow
                            scheduleWindows.Add(s.InstallWindowID, New BLAffiliateScheduleWindow(s.InstallWindowID, s.StartTime, s.EndTime, s.Date))
                        Next
                        schedule = New BLAffiliateSchedule(type, scheduleWindows)
                    End If
                    confirmations.Add(New BLAffiliateOrderConfirmation(offerID, c.OrderConfirmationID, c.FollowUpMessage, schedule, category))
                Next
                order = New BLAffiliateOrder(confirmations)
            End If
            SetSession(AffiliateOrderManagerKey, Me.ValuesForSetSession)
        Catch ex As ApplicationException
            Throw ex
        Catch ex As Exception
            Throw New ApplicationException("Cannot build Order Object from provider response", ex)
        End Try
    End Sub

    Public Overrides Sub GetConfirmationInfo(ByVal trackID As String, ByRef list As Dictionary(Of String, IConfirmation))
        Try
            PopulateLocalVariables(trackID)
            ' Dim list As Dictionary(Of String, IConfirmation)

            If Not (order Is Nothing OrElse order.Confirmations Is Nothing) Then
                Dim offerName As String = String.Empty
                Dim cm As New BLAffliateCatalogManager(CType(Session(BLCommon.AffiliateCatalogManagerKey), Dictionary(Of String, Object)))
                Dim catalog As ICatalog = cm.ProductCatalog

                list = New Dictionary(Of String, IConfirmation)
                For Each confirm As BLAffiliateOrderConfirmation In order.Confirmations
                    If catalog.ServicePlans.ContainsKey(confirm.OfferID) Then
                        offerName = catalog.ServicePlans(confirm.OfferID).Name
                    ElseIf catalog.Bundles.ContainsKey(confirm.OfferID) Then
                        offerName = catalog.Bundles(confirm.OfferID).Name
                    End If
                    list.Add(offerName, confirm.Confirmation)
                Next
            End If

        Catch ex As Exception
            Dim aex As New ApplicationException("Cannot retrive Confirmation Information", ex)
            BLCommon.LogException(aex, ExceptionSeverity.Catastrophic)
            Throw aex
        End Try

    End Sub

    Public Overrides Function GetOrderConfirmations(ByVal trackID As String) As List(Of IAffiliateOrder.IAffiliateOrderConfirmation)
        Try
            PopulateLocalVariables(trackID)
            If Not order Is Nothing Then
                Return order.Confirmations
            Else
                Return Nothing
            End If

        Catch ex As Exception
            Dim aex As New ApplicationException("Cannot retrive Confirmations", ex)
            BLCommon.LogException(aex, ExceptionSeverity.Catastrophic)
            Throw aex
        End Try

    End Function

#End Region

#Region "Schedule"

    Public Overrides Sub GetSchedule(ByVal trackingID As String, ByRef schedule1 As IAffiliateOrder.IAffiliateSchedule, ByRef schedule2 As IAffiliateOrder.IAffiliateSchedule)
        ' this method returns the available schedules for cable, hsd and Telephone categories 
        Try
            PopulateLocalVariables(trackingID)

            'TODO: add schedule logic

        Catch ex As ApplicationException
            BLCommon.LogException(ex, ExceptionSeverity.Catastrophic)
            Throw ex
        Catch ex As Exception
            Dim aex As New ApplicationException("Cannot populate schedules", ex)
            BLCommon.LogException(aex, ExceptionSeverity.Catastrophic)
            Throw ex
        End Try
    End Sub

    Public Overrides Function SubmitSchedules(ByVal trackingID As String, ByVal type1 As String, ByVal schedule1 As List(Of String), ByVal type2 As String, ByVal schedule2 As List(Of String)) As Boolean
        ' submit 2 installation times for each category
        Try
            PopulateLocalVariables(trackingID)
            Dim result As Boolean = False
            If Not (order Is Nothing OrElse order.Confirmations Is Nothing) Then
                Dim iProvider As IG2BServicesProvider

                iProvider = CType(Activator.GetObject(GetType(IG2BServicesProvider), CStr(HttpContext.Current.Application("RemoteURL_G2BServicesProvider"))), IG2BServicesProvider)

                Dim providerRequest As EntityG2BServices.G2BScheduleInstallRequest
                Dim lManager As New BLAccountManager(CType(Session(BLCommon.AccountManagerKey), Dictionary(Of String, Object)))
                Dim account As BLAccount = lManager.account
                Dim offers As List(Of EntityG2BServices.OfferOrderTypeG2BScheduleInstall)
                offers = PopulateGwyScheduleOffers(type1, schedule1, type2, schedule2)
                providerRequest = New EntityG2BServices.G2BScheduleInstallRequest(offers, account.TrackingID, account.MSOID, account.AddressID)
                Dim providerResponse As EntityG2BServices.G2BScheduleInstallResponse
                providerResponse = DirectCast(iProvider.ScheduleInstall(providerRequest), EntityG2BServices.G2BScheduleInstallResponse)
                If LIVE Then
                    If providerResponse.Exception Then
                        BLCommon.LogException(New ApplicationException("Order Manager: Submit Schedule failed to submit schedule for G2B tracking id " + account.TrackingID.ToString + " Inner Exception " + providerResponse.ExceptionMessage), ExceptionSeverity.Catastrophic)
                        Return False
                    Else
                        result = True
                    End If
                End If
                PopulateAppointments(providerResponse)
            End If
            SetSession(AffiliateOrderManagerKey, Me.ValuesForSetSession)
            Return result
        Catch ex As ApplicationException
            BLCommon.LogException(ex, ExceptionSeverity.Catastrophic)
            Throw ex
        Catch ex As Exception
            Dim aex As New ApplicationException("Cannot submit installation schedules ", ex)
            BLCommon.LogException(aex, ExceptionSeverity.Catastrophic)
            Throw aex
        End Try
    End Function

    Private Function PopulateGwyScheduleOffers(ByVal type1 As String, ByVal schedule1 As List(Of String), ByVal type2 As String, ByVal schedule2 As List(Of String)) As List(Of EntityG2BServices.OfferOrderTypeG2BScheduleInstall)
        Dim offers As New List(Of EntityG2BServices.OfferOrderTypeG2BScheduleInstall)
        Dim offer As EntityG2BServices.OfferOrderTypeG2BScheduleInstall
        Dim offerItemTypes As List(Of EntityG2BServices.ItemsChoiceType)
        Dim confirmList As List(Of BLOrderConfirmation)
        Try
            ' schedule1
            If Not (schedule1 Is Nothing OrElse type1 Is Nothing) Then
                confirmList = IdentifyConfirmations(type1)
                For Each confirm As BLOrderConfirmation In confirmList
                    offerItemTypes = New List(Of EntityG2BServices.ItemsChoiceType)
                    For i As Integer = 0 To schedule1.Count - 1
                        offerItemTypes.Add(EntityG2BServices.ItemsChoiceType.InstallWindowID)
                    Next
                    offer = New EntityG2BServices.OfferOrderTypeG2BScheduleInstall(schedule1, offerItemTypes, ConvertToActualOfferID(confirm.OfferID), confirm.Confirmation.Number)
                    offers.Add(offer)
                Next
            End If
            ' schedule2
            If Not (schedule2 Is Nothing OrElse type2 Is Nothing) Then
                confirmList = IdentifyConfirmations(type2)
                For Each confirm As BLOrderConfirmation In confirmList
                    offerItemTypes = New List(Of EntityG2BServices.ItemsChoiceType)
                    For i As Integer = 0 To schedule2.Count - 1
                        offerItemTypes.Add(EntityG2BServices.ItemsChoiceType.InstallWindowID)
                    Next
                    offer = New EntityG2BServices.OfferOrderTypeG2BScheduleInstall(schedule2, offerItemTypes, ConvertToActualOfferID(confirm.OfferID), confirm.Confirmation.Number)
                    offers.Add(offer)
                Next
            End If
            Return offers
        Catch ex As Exception
            Dim aex As New ApplicationException("Error populating provider request", ex)
            BLCommon.LogException(aex, ExceptionSeverity.Catastrophic)
            Throw ex
        End Try
    End Function

    Public Function IdentifyConfirmations(ByVal type As String) As List(Of BLOrderConfirmation)
        Dim list As New List(Of BLOrderConfirmation)
        Select Case type
            Case ScheduleType.Cable.ToString
                list.Add(CType(order.Confirmations(Category.Cable), BLOrderConfirmation))
            Case ScheduleType.HSD.ToString
                list.Add(CType(order.Confirmations(Category.HSD), BLOrderConfirmation))
            Case ScheduleType.Telephone.ToString
                list.Add(CType(order.Confirmations(Category.Telephoney), BLOrderConfirmation))
            Case ScheduleType.CableAndHSD.ToString
                list.Add(CType(order.Confirmations(Category.Cable), BLOrderConfirmation))
                list.Add(CType(order.Confirmations(Category.HSD), BLOrderConfirmation))
            Case ScheduleType.CableAndTelephone.ToString
                list.Add(CType(order.Confirmations(Category.UnSpecified), BLOrderConfirmation))
            Case ScheduleType.HSDAndTelephone.ToString
                list.Add(CType(order.Confirmations(Category.UnSpecified), BLOrderConfirmation))
            Case Else '(all)
                list.Add(CType(order.Confirmations(Category.UnSpecified), BLOrderConfirmation))
        End Select
        Return list
    End Function

    Private Sub PopulateAppointments(ByVal pResponse As EntityG2BServices.G2BScheduleInstallResponse)
        Dim am As New BLAccountManager(CType(Session(BLCommon.AccountManagerKey), Dictionary(Of String, Object)))
        Dim account As BLAccount = am.account
        Dim category As Category
        Dim appointment As BLInstallation
        Dim schedule As IAffiliateOrder.IAffiliateScheduleWindow
        Try
            If Not LIVE Then
                'ToDo: once G2b returns data take out this block( this block is just for testing)
                Dim cs As New List(Of EntityG2BServices.InstallWindowConfirmationType)
                'cs.Add(New EntityG2BServices.InstallWindowConfirmationType("2", "25634324", "1", "No Message"))
                cs.Add(New EntityG2BServices.InstallWindowConfirmationType("6700", "256343767", "1", "No Message"))
                cs.Add(New EntityG2BServices.InstallWindowConfirmationType("6900", "25634324", "111", "No Message"))
                pResponse = New EntityG2BServices.G2BScheduleInstallResponse(cs, account.TrackingID, account.MSOID, account.AddressID)
                'End
            End If

            account.TrackingID = pResponse.TrackingID
            account.MSOID = pResponse.MSOID
            account.AddressID = pResponse.AddressID
            SetSession(AccountManagerKey, am.ValuesForSetSession)
            For Each installConfirm As EntityG2BServices.InstallWindowConfirmationType In pResponse.InstallWindowConfirmation
                Dim cm As New BLAffliateCatalogManager(CType(Session(BLCommon.AffiliateCatalogManagerKey), Dictionary(Of String, Object)))
                With installConfirm

                    If cm.ProductCatalog.Cart.CartItems.ContainsKey(ItemType.ServicePlan & .OfferID) Then
                        category = DirectCast(cm.ProductCatalog.Cart, BLShoppingCart).GetCartItemCategory(ItemType.ServicePlan & .OfferID)
                    Else
                        If cm.ProductCatalog.Cart.CartItems.ContainsKey(ItemType.Bundle & .OfferID) Then
                            category = DirectCast(cm.ProductCatalog.Cart, BLShoppingCart).GetCartItemCategory(ItemType.Bundle & .OfferID)
                        End If
                    End If
                    appointment = DirectCast(order.Confirmations(category).Appointment, BLInstallation)
                    schedule = order.Confirmations(category).Schedules.ScheduleWindow(.InstallWindowID)
                    appointment = New BLInstallation(.InstallWindowID, .InstallConfirmationID, .FollowUpMessage, schedule.ScheduleDate, schedule.StartTime, schedule.EndTime)
                    DirectCast(order.Confirmations(category), BLOrderConfirmation).Appointment = appointment
                End With
            Next
            SetSession(AffiliateOrderManagerKey, Me.ValuesForSetSession)
        Catch ex As Exception
            Throw New ApplicationException("Error populating Appointment object", ex)
        End Try
    End Sub


#End Region

#Region "Appointments"

    Public Overrides Sub GetAppointments(ByVal trackingID As String, ByRef list As Dictionary(Of ScheduleType, IAffiliateOrder.IAffiliateAppointment))
        Try
            PopulateLocalVariables(trackingID)
            list = New Dictionary(Of ScheduleType, IAffiliateOrder.IAffiliateAppointment)
            If Not (order Is Nothing OrElse order.Confirmations Is Nothing) Then
                'TODO:add logic for combining HSD and Cable
                For Each confirm As BLAffiliateOrderConfirmation In order.Confirmations
                    If Not confirm.Appointment Is Nothing Then
                        list.Add(confirm.Schedules.Type, confirm.Appointment)
                    End If
                Next
            End If
            SetSession(AffiliateOrderManagerKey, Me.ValuesForSetSession)

        Catch ex As ApplicationException
            BLCommon.LogException(ex, ExceptionSeverity.Catastrophic)
            Throw ex
        Catch ex As Exception
            Dim aex As New ApplicationException("Cannot retrive Appointments", ex)
            BLCommon.LogException(aex, ExceptionSeverity.Catastrophic)
            Throw aex
        End Try
    End Sub

#End Region

    Public Overrides Sub ClearShoppingCart(ByVal trackingID As String)
        Try
            PopulateLocalVariables(trackingID)
            Dim cm As New BLAffliateCatalogManager(CType(Session(BLCommon.AffiliateCatalogManagerKey), Dictionary(Of String, Object)))
            Dim catalog As BLProductCatalog = cm.ProductCatalog
            catalog.ClearCart()
            SetSession(AffiliateCatalogManagerKey, cm.ValuesForSetSession)
        Catch ex As Exception
            Dim aex As New ApplicationException("Cannot Clear cart", ex)
            BLCommon.LogException(aex, ExceptionSeverity.High)
            Throw aex
        End Try
    End Sub

    Public Overrides Function SendOrderConfirmationEmail(ByVal trackingID As String) As Boolean
        Dim subject As String = "Your Charter.com Order Confirmation Information"
        Dim fromEmail As String
        Dim toEmail As String = String.Empty
        Dim body As New System.Text.StringBuilder

        Try
            PopulateLocalVariables(trackingID)

            fromEmail = DirectCast(System.Web.HttpContext.Current.Application(BLCommon.ORDER_EMAIL_SENDER), String)
            Dim am As New BLAccountManager(CType(Session(AccountManagerKey), Dictionary(Of String, Object)))
            Dim account As IAccount = am.account

            Dim cm As New BLAffliateCatalogManager(CType(Session(AffiliateCatalogManagerKey), Dictionary(Of String, Object)))
            Dim catalog As ICatalog = cm.ProductCatalog

            If account.Person.Email.Count = 0 Then
                BLCommon.LogException(New ApplicationException("Email information is not available"), ExceptionSeverity.High)
                Return False
            End If
            If account.Person.Email Is Nothing OrElse account.Person.Email.Count = 0 Then
                Return False
            End If
            ' find primary email 
            For Each email As IAccount.IMember.IEmail In account.Person.Email
                If email.IsPrimary Then
                    toEmail = email.MailID
                End If
            Next
            If toEmail.Equals(String.Empty) Then
                toEmail = account.Person.Email(0).MailID
            End If
            ' create subject 
            subject = "Your Order Confirmation Information"

            ' build body part
            ' get body format from content

            Dim com As New BLContentManager(CType(Session(ContentManagerKey), Dictionary(Of String, Object)))
            Dim b As String = com.GetContent(trackingID, "affiliate:orderconfirmationemail", "1", OwnerType.Other.ToString)
            If Not (b Is Nothing AndAlso b = String.Empty) Then
                body = New System.Text.StringBuilder(b)
                With account
                    ' populate customer information from Account 
                    body.Replace("{FirstName}", .Person.FirstName)
                    body.Replace("{LastName}", .Person.LastName)
                    With .Address
                        body.Replace("{Street}", .Street1)
                        body.Replace("{Apt}", .Street2)
                        body.Replace("{City}", .City)
                        body.Replace("{State}", .State)
                        body.Replace("{Zip}", .Zip)
                    End With
                    If Not .BillingAddress Is Nothing Then
                        With .BillingAddress
                            body.Replace("{BillStreet}", .Street1)
                            body.Replace("{BillApt}", .Street2)
                            body.Replace("{BillCity}", .City)
                            body.Replace("{BillState}", .State)
                            body.Replace("{BillZip}", .Zip)
                        End With
                    Else
                        With .Address
                            body.Replace("{BillStreet}", .Street1)
                            body.Replace("{BillApt}", .Street2)
                            body.Replace("{BillCity}", .City)
                            body.Replace("{BillState}", .State)
                            body.Replace("{BillZip}", .Zip)
                        End With
                    End If
                End With
                body.Replace("{OrderMonth}", Now.Month.ToString)
                body.Replace("{OrderDay}", Now.Day.ToString())
                body.Replace("{OrderYear}", Now.Year.ToString)


                ' dynamically populate order information

                If Not (order Is Nothing OrElse order.Confirmations Is Nothing) Then
                    ' ORDER CONFIRMATION INFORMATION
                    Dim con As IAffiliateOrder.IAffiliateOrderConfirmation
                    'Dim pName1, pName2, pName3 As String
                    'Dim price1, price2, price3 As Decimal
                    Dim productName As String
                    Dim i As Integer = 1
                    Dim bundle As BLBundle
                    Dim sp As BLServicePlan
                    Dim itemsContent As New StringBuilder("<table width=""100%"">")
                    Dim c As Category
                    For Each conf As BLAffiliateOrderConfirmation In order.Confirmations
                        c = conf.ConfirmationCategory
                        If Not (order.Confirmations Is Nothing) Then
                            If order.Confirmations.Count > 0 Then
                                con = order.Confirmations(0)
                            End If
                        End If
                        If Not con Is Nothing Then
                            body.Replace("{ConfirmationNumber}", con.Confirmation.Number)
                            Dim confirm As BLAffiliateOrderConfirmation = CType(con, BLAffiliateOrderConfirmation)
                            If c = Category.UnSpecified Then
                                If catalog.Bundles.ContainsKey(confirm.OfferID) Then
                                    bundle = DirectCast(catalog.Bundles(confirm.OfferID), BLBundle)
                                    productName = bundle.Name
                                    itemsContent.Append("<tr><td align=right>" + productName + "</td> <td align=right>" + String.Format("{0:C}", bundle.Price) + "</td></tr>")
                                    For Each sps As BLServicePlan In bundle.ServicePlans.Values
                                        FindCustomizations(sps, itemsContent)
                                    Next
                                End If
                            Else
                                If catalog.ServicePlans.ContainsKey(confirm.OfferID) Then
                                    sp = DirectCast(catalog.ServicePlans(confirm.OfferID), BLServicePlan)
                                    productName = sp.Name
                                    itemsContent.Append("<tr><td align=right>" + productName + "</td> <td align=right>" + String.Format("{0:C}", sp.Price) + "</td></tr>")
                                    FindCustomizations(sp, itemsContent)
                                End If
                            End If
                            body.Replace("{Product" + i.ToString + "}", productName)

                            ' SCHEDULE INFORMATION
                            If Not confirm.Appointment Is Nothing Then
                                body.Replace("{SD" + i.ToString + "}", confirm.Appointment.InstallDate)
                                body.Replace("{ST" + i.ToString + "}", confirm.Appointment.StartTime)
                            End If
                            i += 1
                        End If
                    Next
                    itemsContent.Append("</table>")
                    body.Replace("{Items}", itemsContent.ToString)
                Else
                    body.Append("We need more information to finish your order")
                    body.Append(ControlChars.NewLine)
                    body.Append("A Customer Care Representative will chat with you in just a moment.")
                    body.Append(ControlChars.NewLine)
                    body.Append("If you experience any difficulties, please call us at 1-888-GET-CHARTER")
                    body.Append(ControlChars.NewLine)
                End If
                ' if less than 3 products, we want to replace the others with empty string
                For i As Integer = 1 To 3
                    body.Replace("{Product" + i.ToString + "}", String.Empty)
                    'body.Replace("SMM" + i.ToString + "}", String.Empty)
                    body.Replace("{SD" + i.ToString + "}", String.Empty)
                    ' body.Replace("SYY" + i.ToString + "}", String.Empty)
                    body.Replace("{ST" + i.ToString + "}", String.Empty)
                    'body.Replace("{Price" + i.ToString + "}", String.Empty)
                Next

                body.Replace("{MonthlyTotal}", String.Format("{0:C}", catalog.Cart.MonthlyTotal))
                body.Replace("{OneTimeTotal}", String.Format("{0:C}", catalog.Cart.OneTimeTotal))
                body.Replace("{GrandTotal}", String.Format("{0:C}", catalog.Cart.GrandTotal))

                Dim iMail As ISupportProvider = CType(Activator.GetObject(GetType(ISupportProvider), CStr(System.Web.HttpContext.Current.Application("RemoteURL_SupportProvider"))), ISupportProvider)
                iMail.SendEMail(fromEmail, toEmail, subject, body.ToString, True)

            End If
            Return True
        Catch ex As Exception
            Dim aex As New ApplicationException("Cannot send Order Confirmation Email", ex)
            BLCommon.LogException(aex, ExceptionSeverity.High)
            Return False
        End Try
    End Function

    Private Sub FindCustomizations(ByVal sp As BLServicePlan, ByVal itemsContent As StringBuilder)
        For Each f As BLFeature In sp.Features.Values
            If f.Choices Is Nothing AndAlso f.Choices.Count = 0 Then
                If f.ISSelected AndAlso f.FeatureType = FeatureType.IsCustomization Then
                    itemsContent.Append("<tr><td align=right>" + f.Name + "</td> <td align=right>" + String.Format("{0:C}", f.Price) + "</td></tr>")
                End If
            Else
                For Each c As BLFeature In f.Choices.Values
                    If c.ISSelected AndAlso Not c.PriceFrequency = PriceFrequency.OneTime Then
                        If c.FeatureType = FeatureType.IsCustomization Then
                            itemsContent.Append("<tr><td align=right>" + c.Name + "</td> <td align=right>" + String.Format("{0:C}", c.Price) + "</td></tr>")
                        Else
                            If c.FeatureType = FeatureType.IsPlaceholder Then
                                Select Case c.FeatureCategory
                                    Case FeatureCategory.DataEquipment, FeatureCategory.Installation, FeatureCategory.VideoEquipment, FeatureCategory.VoiceEquipment
                                        itemsContent.Append("<tr><td align=right>" + c.Name + "</td> <td align=right>" + String.Format("{0:C}", c.Price) + "</td></tr>")
                                End Select
                            End If
                        End If
                    End If
                Next
            End If
        Next
    End Sub

    Private Shared Function ConvertToActualOfferID(ByVal offerID As String) As String
        Dim i As Integer = CType(ItemType.ServicePlan, Integer)
        Return offerID.Substring(i.ToString.Length)
    End Function

    Private Shared Function ConvertToActualChoiceID(ByVal id As String) As String
        Dim i As Integer = CType(ItemType.Feature, Integer)
        ' additional "99" is addded to each choce when a choce object is created in g2bService provider.
        ' so remove that
        Return id.Substring(i.ToString.Length + 2)
    End Function

End Class
