VERSION 1.0 CLASS
BEGIN
  MultiUse = -1  'True
  Persistable = 0  'NotPersistable
  DataBindingBehavior = 0  'vbNone
  DataSourceBehavior  = 0  'vbNone
  MTSTransactionMode  = 0  'NotAnMTSObject
END
Attribute VB_Name = "DPC_BOM"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = True
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
Option Explicit

Public BOM_StlIdentNr As String
Public BOM_Id As Long
Public BOM_Pos As Long
Public BOM_BOR_Pos As Long
Public BOM_Categ As eDPCBOMMaterial
Public BOM_CategDesc As String
Public BOM_IdentNr As String
Public BOM_Name As String
Public BOM_Material As String
Public BOM_Qty As Double
Public UM_Code As String
Public UM_Name As String
Public BOM_SalesPriceUnit As Long 'pevk
Public CURR_Code As String
Public BOM_SpecWeight As Double
Public BOM_Productivity As Double
Public BOM_CutWidth As Double
Public BOM_CutLength As Double
'Public BOM_DirectCost As Double ' property
Public BOM_TotDirectCost As Double  ' unused !!!
Public BOM_WasteFactor As Double
Public BOM_WasteQty As Long ' used just for calculated plus qty
'Public BOM_WasteCost As Double ' property
Public BOM_RejectFactor As Double
Public BOM_RejectQty As Long  ' unused !!!
'Public BOM_RejectCost As Double ' property
Public BOM_InflFactor As Double
'Public BOM_InflCost As Double 'property
Public BOM_Cost As Double
Public BOM_Manual As Boolean
Public BOM_IdentNrTmp As String
Public BOM_Export As Boolean
Public BOM_ExpDat As Date
Public BOM_Status As eDPCBOMBORStatus
Public BOM_StatusDesc As String

' temporary members - not saved into DB
Public Idx As Long
Public RowStatus As eDPCRowStatus

Public Ben1 As String
Public Klasse As String
Public Norm As String
Public NormNr As String
Public Agr As String  ' article group
Public BOM_DatVon As Date
Public BOM_Menge_Ab As Double

'#If LIVE = 1 Then
'  Private mo_Db As Object
'  Private mo_FSO As Object
'#Else
'  Private mo_Db As ARMSYSCOMLib.ArmDb
'  Private mo_FSO As FileSystemObject
'#End If

Private mo_Tools As DPC_Tools

Private Const C_ERRORRAISE As Long = 2500
Private Const SEP = "®©"
Private Const C_SEP As String = "@@"
Private Const SEP1 As String = "®"
Private Const SEP2 As String = "©"

Private Enum ArmErr
    DBCnxFailed = vbObjectError + 1             ' Unable to connect to the database
    CPTAlreadyInitialized = vbObjectError + 2   ' We try to initialize a component that is already initialized
    CPTNotInitialized = vbObjectError + 3       ' We try to use or free that is not initialized yet
    InvalidArgument = vbObjectError + 4
    PropertyNotSet = vbObjectError + 5
    SQLFailure = vbObjectError + 6               ' A SQL runtime error has occured : syntax wrong....
    SQLBadRowAffectedCount = vbObjectError + 7   ' A SQL request has not affected the expected rowcount (ex: one Update do nothing)
    SQLBadRowExpectedCount = vbObjectError + 8   ' A SQL request does not return the expected rowcount : select an item return nothing...
    DrivingError = vbObjectError + 9
    CompFncFailed = vbObjectError + 10           ' when component function fail
    GridLoadFailed = vbObjectError + 11          ' load function failed ... bad sql
    QuietException = vbObjectError + 12          ' do not display error message
    SQLTableReferenceConstraint = vbObjectError + 13 ' A SQL request cannot be executed : Table reference constraint
    DuplicityDetected = vbObjectError + 2301     ' detected row with same unique id
End Enum

'Public Property Set ArmDb(ByRef lo_Db As Object)
'  If Not (lo_Db Is Nothing) Then
'      Set mo_Db = lo_Db
'  End If
'End Property

Public Property Set Tools(ByRef ao_Tools As Object)
On Error GoTo ErrorHandler

  Set mo_Tools = ao_Tools
  Exit Property
ErrorHandler:
  Call ErrorHandler("Tools.Set")
End Property

Public Sub Clear()
On Error GoTo ErrHandler

  BOM_Categ = eDPCBOMMaterial.bcNone
  BOM_IdentNr = ""
  BOM_Name = ""
  BOM_Material = ""
  BOM_Qty = 0
  UM_Code = ""
  UM_Name = ""
  BOM_Cost = 0
  BOM_SalesPriceUnit = 0
  CURR_Code = ""
  BOM_SpecWeight = 0
  BOM_Productivity = 0
  BOM_CutWidth = 0
  BOM_CutLength = 0
  BOM_WasteFactor = 0
  BOM_WasteQty = 0
  BOM_Manual = False
  BOM_IdentNrTmp = ""
  BOM_Export = False
  BOM_ExpDat = 0
  BOM_DatVon = 0
  BOM_Menge_Ab = 0
  BOM_Status = eDPCBOMBORStatus.boNone
  BOM_StatusDesc = ""
  Exit Sub
ErrHandler:
  Call ErrorHandler("Clear")
End Sub

Public Sub CopyFrom(ByVal ao_BOM As DPC_BOM)
On Error GoTo ErrHandler

  BOM_StlIdentNr = ao_BOM.BOM_StlIdentNr
  BOM_Id = ao_BOM.BOM_Id
  BOM_Pos = ao_BOM.BOM_Pos
  BOM_BOR_Pos = ao_BOM.BOM_BOR_Pos
  BOM_Categ = ao_BOM.BOM_Categ
  BOM_CategDesc = ao_BOM.BOM_CategDesc
  BOM_IdentNr = ao_BOM.BOM_IdentNr
  BOM_Name = ao_BOM.BOM_Name
  BOM_Material = ao_BOM.BOM_Material
  BOM_Qty = ao_BOM.BOM_Qty
  UM_Code = ao_BOM.UM_Code
  UM_Name = ao_BOM.UM_Name
  BOM_Cost = ao_BOM.BOM_Cost
  BOM_SalesPriceUnit = ao_BOM.BOM_SalesPriceUnit
  CURR_Code = ao_BOM.CURR_Code
  BOM_SpecWeight = ao_BOM.BOM_SpecWeight
  BOM_Productivity = ao_BOM.BOM_Productivity
  BOM_CutWidth = ao_BOM.BOM_CutWidth
  BOM_CutLength = ao_BOM.BOM_CutLength
  BOM_WasteFactor = ao_BOM.BOM_WasteFactor
  BOM_WasteQty = ao_BOM.BOM_WasteQty
  BOM_Manual = ao_BOM.BOM_Manual
  BOM_IdentNrTmp = ao_BOM.BOM_IdentNrTmp
  BOM_Export = ao_BOM.BOM_Export
  BOM_ExpDat = ao_BOM.BOM_ExpDat
  BOM_DatVon = ao_BOM.BOM_DatVon
  BOM_Menge_Ab = ao_BOM.BOM_Menge_Ab
  BOM_Status = ao_BOM.BOM_Status
  BOM_StatusDesc = ao_BOM.BOM_StatusDesc
  
  Idx = ao_BOM.Idx
  Exit Sub
ErrHandler:
  Call ErrorHandler("CopyFrom")
End Sub

Public Property Get BOM_DirectCost() As Double
On Error GoTo ErrHandler
  
  If BOM_SalesPriceUnit > 0 Then
    BOM_DirectCost = (BOM_Qty * (BOM_Cost / (10 ^ (BOM_SalesPriceUnit - 1))))
  Else
    BOM_DirectCost = 0
  End If
  Exit Property
ErrHandler:
  Call ErrorHandler("BOM_DirectCost")
End Property

Public Property Get BOM_WasteCost() As Double
On Error GoTo ErrHandler
  
  BOM_WasteCost = BOM_DirectCost * BOM_WasteFactor
  Exit Property
ErrHandler:
  Call ErrorHandler("BOM_WasteCost")
End Property

Public Property Get BOM_RejectCost() As Double
On Error GoTo ErrHandler
  
  BOM_RejectCost = BOM_DirectCost * BOM_RejectFactor
  Exit Property
ErrHandler:
  Call ErrorHandler("BOM_RejectCost")
End Property

Public Property Get BOM_InflCost() As Double
On Error GoTo ErrHandler
  
  BOM_InflCost = BOM_DirectCost * BOM_InflFactor
  Exit Property
ErrHandler:
  Call ErrorHandler("BOM_InflCost")
End Property

Public Sub ReadBOM(ByVal ao_Db As Object, ByVal ac_Cursor As Long)
On Error GoTo ErrHandler

  BOM_Id = ao_Db.GetFields(ac_Cursor, "BOM_Id")
  BOM_StlIdentNr = ao_Db.GetFields(ac_Cursor, "BOM_StlIdentNr")
  BOM_Pos = ao_Db.GetFields(ac_Cursor, "BOM_Pos")
  BOM_BOR_Pos = ao_Db.GetFields(ac_Cursor, "BOM_BOR_Pos")
  BOM_Categ = ao_Db.GetFields(ac_Cursor, "BOM_Categ")
  BOM_CategDesc = ao_Db.GetFields(ac_Cursor, "BOM_CategDesc")
  BOM_IdentNr = ao_Db.GetFields(ac_Cursor, "BOM_IdentNr")
  BOM_Name = ao_Db.GetFields(ac_Cursor, "BOM_Name")
  BOM_Material = ao_Db.GetFields(ac_Cursor, "BOM_Material")
  BOM_Qty = ao_Db.GetFields(ac_Cursor, "BOM_Qty")
  UM_Code = ao_Db.GetFields(ac_Cursor, "UM_Code")
  UM_Name = ao_Db.GetFields(ac_Cursor, "UM_Name")
  BOM_Cost = ao_Db.GetFields(ac_Cursor, "BOM_Cost")
  BOM_SalesPriceUnit = ao_Db.GetFields(ac_Cursor, "BOM_SalesPriceUnit")
  CURR_Code = ao_Db.GetFields(ac_Cursor, "CURR_Code")
  BOM_SpecWeight = ao_Db.GetFields(ac_Cursor, "BOM_SpecWeight")
  BOM_Productivity = ao_Db.GetFields(ac_Cursor, "BOM_Productivity")
  BOM_CutWidth = ao_Db.GetFields(ac_Cursor, "BOM_CutWidth")
  BOM_CutLength = ao_Db.GetFields(ac_Cursor, "BOM_CutLength")
  BOM_WasteFactor = ao_Db.GetFields(ac_Cursor, "BOM_WasteFactor")
  BOM_WasteQty = ao_Db.GetFields(ac_Cursor, "BOM_WasteQty")
  BOM_Manual = StrComp(ao_Db.GetFields(ac_Cursor, "BOM_Manual"), "X", vbTextCompare) = 0
  BOM_IdentNrTmp = ao_Db.GetFields(ac_Cursor, "BOM_IdentNrTmp")
  BOM_Export = StrComp(ao_Db.GetFields(ac_Cursor, "BOM_Export"), "X", vbTextCompare) = 0
  BOM_ExpDat = ao_Db.GetFields(ac_Cursor, "BOM_ExpDat")
  BOM_DatVon = ao_Db.GetFields(ac_Cursor, "BOM_DatVon")
  BOM_Menge_Ab = ao_Db.GetFields(ac_Cursor, "BOM_Menge_Ab")
  BOM_Status = ao_Db.GetFields(ac_Cursor, "BOM_Status")
  BOM_StatusDesc = ao_Db.GetFields(ac_Cursor, "BOM_StatusDesc")
  Exit Sub
ErrHandler:
  Call ErrorHandler("ReadBOM")
End Sub

Public Function LoadBOMFromBaeurer(ByVal ao_Db As Object, ByVal ao_DbBaeurer As Object, ByVal as_Language_Code As String, ByVal as_IdentNr As String) As Boolean
On Error GoTo ErrHandler

Dim ls_req As String
Dim lc_Cursor As Long

  LoadBOMFromBaeurer = False
  
  BOM_IdentNr = ""
  BOM_Name = ""
  BOM_Material = ""
  UM_Code = ""
  UM_Name = ""
  BOM_Cost = 0
  BOM_SalesPriceUnit = 0
  BOM_SpecWeight = 0
  BOM_Productivity = 0
  BOM_CutWidth = 0
  BOM_CutLength = 0
  BOM_WasteFactor = 0
  BOM_IdentNrTmp = ""
  BOM_Export = False
  BOM_ExpDat = 0
  BOM_DatVon = 0
  BOM_Menge_Ab = 0
  
  ls_req = "SELECT DISTINCT "
  ls_req = ls_req & "g000.identnr, g043.agr, g0402.ben, g0402.ben1, g000.me, g0402.werkstoff, g0402.klasse, g0402.norm, g0402.normnr,"
  ls_req = ls_req & "g711StdCoil.ausprtxt as StandardCoil, ROUND(g711Length.ausprfloat,2) as Length, ROUND(g711Width.ausprfloat,2) as Width,"
  ls_req = ls_req & "ROUND(g711Thick.ausprfloat,2) as Thickness, g711SpecWeight.ausprfloat  as SpecWeight, g711Product.ausprfloat  as Productivity,"
  ls_req = ls_req & "g711WasteMaterial.ausprfloat as WasteFactor, k902.mgm_faktor " ' g711FertZeitAusschuss.ausprfloat as WasteFactor,
  'ls_Req = ls_Req & "g023.vpreis, g030.pevk, g040.ts,  "
  ls_req = ls_req & "FROM g000 "
  ls_req = ls_req & "LEFT JOIN g043 on (g000.fi_nr = g043.fi_nr AND g000.identnr = g043.identnr) "
  'ls_Req = ls_Req & "LEFT JOIN g040 ON (g000.fi_nr = g040.fi_nr AND g000.identnr = g040.identnr ) "
  ls_req = ls_req & "LEFT JOIN g0402 ON (g000.fi_nr = g0402.fi_nr AND g000.identnr = g0402.identnr and g0402.lang_ext =$lang_ext$) "
  ls_req = ls_req & "LEFT JOIN g711 as g711Length ON (g000.objektid = g711Length.objektid and g711Length.kritnr = 11) "
  ls_req = ls_req & "LEFT JOIN g711 as g711Width ON (g000.objektid = g711Width.objektid and g711Width.kritnr = 12) "
  ls_req = ls_req & "LEFT JOIN g711 as g711Thick ON (g000.objektid = g711Thick.objektid and g711Thick.kritnr = 17) "
  ls_req = ls_req & "LEFT JOIN g711 as g711SpecWeight ON (g000.objektid = g711SpecWeight.objektid and g711SpecWeight.kritnr = 20) "
  ls_req = ls_req & "LEFT JOIN g711 as g711Product ON (g000.objektid = g711Product.objektid and g711Product.kritnr = 37) "
  ls_req = ls_req & "LEFT JOIN g711 as g711WasteMaterial ON (g000.objektid = g711WasteMaterial.objektid and g711WasteMaterial.kritnr = 1175) "
  'ls_Req = ls_Req & "LEFT JOIN g711 as g711FertZeitAusschuss ON (g000.objektid = g711FertZeitAusschuss.objektid and g711FertZeitAusschuss.kritnr = 1178) "
  'ls_Req = ls_Req & "LEFT JOIN g020 ON (g000.identnr = g020.identnr) "
  ls_req = ls_req & "LEFT JOIN g711 as g711StdCoil ON (g000.objektid = g711StdCoil.objektid and g711StdCoil.kritnr = 1181) "
  'ls_Req = ls_Req & "LEFT JOIN g023 ON (g000.fi_nr = g023.fi_nr AND g000.identnr = g023.identnr) "
  'ls_Req = ls_Req & "LEFT JOIN g030 on (g000.identnr = g030.identnr AND g000.fi_nr = g030.fi_nr) "
  ls_req = ls_req & "LEFT JOIN k902 ON (k902.fi_nr=g000.fi_nr AND k902.mgmnr=1 AND k902.ch=g000.ch) "
  ls_req = ls_req & "WHERE "
  ls_req = ls_req & "(g000.identnr = $identnr$) AND "
  ls_req = ls_req & "(g000.fi_nr = $fi_nr$) "
  
  ls_req = Replace(ls_req, "$identnr$", mo_Tools.SQLStr(as_IdentNr), , , vbTextCompare)
  ls_req = Replace(ls_req, "$fi_nr$", mo_Tools.SqlInt(1), , , vbTextCompare)
  ls_req = Replace(ls_req, "$lang_ext$", mo_Tools.SQLStr("de_de"), , , vbTextCompare)
  lc_Cursor = mo_Tools.OpenSQLSafe(ao_DbBaeurer, ls_req)
  If ao_DbBaeurer.RowCount(lc_Cursor) = 1 Then
    BOM_IdentNr = ao_DbBaeurer.GetFields(lc_Cursor, "identnr")
    BOM_Name = ao_DbBaeurer.GetFields(lc_Cursor, "ben")
    BOM_Material = ao_DbBaeurer.GetFields(lc_Cursor, "werkstoff")
    UM_Code = mo_Tools.ConvertCodeFromBaeurer(ao_Db, eDPCCodeConversionBaeurer.ccUnitOfMeasure, ao_DbBaeurer.GetFields(lc_Cursor, "me"))
    UM_Name = mo_Tools.GetUM_Name(UM_Code, as_Language_Code)
    'BOM_SalesPriceUnit = ao_Db.GetFields(lc_Cursor, "pevk")
    'BOM_Cost = ao_Db.GetFields(lc_Cursor, "vpreis")
    'If Round(ao_DbBaeurer.GetFields(lc_Cursor, "WasteFactor"), 4) >= 1 Then
    BOM_WasteFactor = ao_DbBaeurer.GetFields(lc_Cursor, "WasteFactor") / 100
    'End If
    BOM_InflFactor = ao_DbBaeurer.GetFields(lc_Cursor, "mgm_faktor")
    BOM_Productivity = ao_DbBaeurer.GetFields(lc_Cursor, "Productivity")
    BOM_SpecWeight = ao_DbBaeurer.GetFields(lc_Cursor, "SpecWeight")
    BOM_CutWidth = ao_DbBaeurer.GetFields(lc_Cursor, "Width")
    BOM_CutLength = ao_DbBaeurer.GetFields(lc_Cursor, "Length")
    BOM_Status = eDPCBOMBORStatus.boGeneratedOK
    
    Ben1 = ao_DbBaeurer.GetFields(lc_Cursor, "ben1")
    Klasse = ao_DbBaeurer.GetFields(lc_Cursor, "klasse")
    Norm = ao_DbBaeurer.GetFields(lc_Cursor, "norm")
    NormNr = ao_DbBaeurer.GetFields(lc_Cursor, "normnr")
    Agr = ao_DbBaeurer.GetFields(lc_Cursor, "agr")
    LoadBOMFromBaeurer = True
  Else
    BOM_IdentNr = as_IdentNr
    BOM_Name = "UNKNOWN MATERIAL !!!"
    BOM_Status = eDPCBOMBORStatus.boGeneratedError
  End If
  Call ao_DbBaeurer.Close(lc_Cursor)
  Exit Function
ErrHandler:
  Call ErrorHandler("LoadBOMFromBaeurer")
End Function

Public Function LoadBOMPriceFromBaeurer(ByVal ao_DbBaeurer As Object, ByVal as_IdentNr As String, ByVal ad_Qty As Double) As Boolean
On Error GoTo ErrHandler

Dim ls_req As String
Dim lc_Cursor As Long

  LoadBOMPriceFromBaeurer = False
  
  BOM_SalesPriceUnit = 0
  BOM_Cost = 0
  CURR_Code = "EUR"
  BOM_DatVon = 0
  BOM_Menge_Ab = 0
  
  ls_req = "SELECT TOP 1 e025.identnr, e025.ekpreis, e025.peek, e025.waehrung, e025.datvon, e025.menge_ab "
  ls_req = ls_req & "FROM e025 "
  ls_req = ls_req & "WHERE "
  ls_req = ls_req & "(e025.fi_nr = $fi_nr$ OR e025.fi_nr = 0) AND "
  ls_req = ls_req & "(e025.identnr = $identnr$) AND "
  ls_req = ls_req & "(e025.datvon <= $date$ AND ($date$ < DATEADD(day, 1,e025.datbis) OR e025.datbis IS NULL)) AND "
  ls_req = ls_req & "(e025.menge_ab <= $qty$) AND "
  ls_req = ls_req & "(e025.pr_herk_e = 'A') "
  ls_req = ls_req & "ORDER BY e025.menge_ab DESC"
  
  ls_req = Replace(ls_req, "$fi_nr$", mo_Tools.SqlInt(1), , , vbTextCompare)
  ls_req = Replace(ls_req, "$identnr$", mo_Tools.SQLStr(as_IdentNr), , , vbTextCompare)
  ls_req = Replace(ls_req, "$date$", mo_Tools.SqlDate(Date), , , vbTextCompare)
  ls_req = Replace(ls_req, "$qty$", mo_Tools.SqlDbl(ad_Qty), , , vbTextCompare)
  lc_Cursor = mo_Tools.OpenSQLSafe(ao_DbBaeurer, ls_req)
  If ao_DbBaeurer.RowCount(lc_Cursor) = 1 Then
    BOM_SalesPriceUnit = ao_DbBaeurer.GetFields(lc_Cursor, "peek")
    BOM_Cost = ao_DbBaeurer.GetFields(lc_Cursor, "ekpreis")
    BOM_DatVon = ao_DbBaeurer.GetFields(lc_Cursor, "datvon")
    BOM_Menge_Ab = ao_DbBaeurer.GetFields(lc_Cursor, "menge_ab")
    CURR_Code = "EUR"
    LoadBOMPriceFromBaeurer = True
  Else
    BOM_Status = eDPCBOMBORStatus.boGeneratedError
  End If
  Call ao_DbBaeurer.Close(lc_Cursor)
  Exit Function
ErrHandler:
  Call ErrorHandler("LoadBOMPriceFromBaeurer")
End Function


Public Function GetMaterialCateg(ByVal as_AgNr As String) As eDPCBOMMaterial
On Error GoTo ErrHandler

  GetMaterialCateg = eDPCBOMMaterial.bcNone
  Select Case Val(as_AgNr)
  Case 10, 20, 30, 40, 50, 60, 70, 80, 99, 110, 120, 130, 140, 160, 170, 180
    GetMaterialCateg = eDPCBOMMaterial.bcCoil
  Case 210, 211, 220
    GetMaterialCateg = eDPCBOMMaterial.bcCoating
  Case 240, 241
    GetMaterialCateg = eDPCBOMMaterial.bcGasket
  Case 250, 260, 270
    GetMaterialCateg = eDPCBOMMaterial.bcInlay
  End Select
  Exit Function
ErrHandler:
  Call ErrorHandler("GetMaterialCateg")
End Function

Public Function CalculateCoil(ByVal ao_Db As Object, ByVal ao_DbBaeurer As Object, ByVal as_Language_Code As String, ByVal ao_Product As DPC_Product, ByVal ao_ErrCollection As Collection) As Boolean
On Error GoTo ErrHandler

Dim ld_TotalQty As Double
Dim ld_Volume As Double
Dim ls_IdentNr As String

  CalculateCoil = True
  
  BOM_CutWidth = ao_Product.RPL_CoilW
  BOM_CutLength = 0
  
  BOM_WasteQty = ao_Product.LoadWasteQty(eDPCBOMMaterial.bcCoil, ao_Product.PanelQtyPCS)
  ld_TotalQty = (ao_Product.PanelQtyPCS + BOM_WasteQty) * (1 + BOM_WasteFactor)
  
  If BOM_SpecWeight <= 0 Then
    Call mo_Tools.AddCheckError(eDPCError.erBOMMaterialSpecWeightZero, as_Language_Code, ao_ErrCollection, ao_Product)
    BOM_Status = eDPCBOMBORStatus.boGeneratedError
    CalculateCoil = False
  End If
  ld_Volume = (ao_Product.RPL_CoilW / 1000) * (ao_Product.RPL_CutA / 1000) * ao_Product.RPL_Thick * BOM_SpecWeight
  ld_TotalQty = ld_TotalQty * ld_Volume
  
  If (ao_Product.PanelQtyPCS > 0) Then
    BOM_Qty = ld_TotalQty / ao_Product.PanelQtyPCS
  Else
    BOM_Qty = 0
  End If
  
  If StrComp(BOM_IdentNr, DPC_BOM_NEW_IDENTNR, vbTextCompare) = 0 Then
    ls_IdentNr = BOM_IdentNrTmp
  Else
    ls_IdentNr = BOM_IdentNr
  End If
  
  If Not LoadBOMPriceFromBaeurer(ao_DbBaeurer, ls_IdentNr, ld_TotalQty) Then
    Call mo_Tools.AddCheckError(eDPCError.erBOMCostNotFoundB7, as_Language_Code, ao_ErrCollection, ao_Product, Me)
    CalculateCoil = False
  End If
  Exit Function
ErrHandler:
  Call ErrorHandler("CalculateCoil")
End Function

Public Function CalculateGasket(ByVal ao_Db As Object, ByVal ao_DbBaeurer As Object, ByVal as_Language_Code As String, ByVal as_GSK_Id As String, ByVal ao_Product As DPC_Product, ByVal ao_ErrCollection As Collection) As Boolean
On Error GoTo ErrHandler

Dim ld_TotalQty As Double
Dim ll_SideIdx As eDPCSide
  
  CalculateGasket = True
  ld_TotalQty = 0
  For ll_SideIdx = eDPCSide.esSideC To eDPCSide.esSideF
    If ((as_GSK_Id <> "") And StrComp(as_GSK_Id, ao_Product.GSK_Id(ll_SideIdx), vbTextCompare) = 0) Or ((as_GSK_Id = "") And ao_Product.IsGasketOn(ll_SideIdx)) Then
      Select Case ll_SideIdx
      Case eDPCSide.esSideC, eDPCSide.esSideD
        ld_TotalQty = ld_TotalQty + ao_Product.RPL_PanA
      Case eDPCSide.esSideE, eDPCSide.esSideF
        ld_TotalQty = ld_TotalQty + ao_Product.RPL_PanB
      End Select
    End If
  Next
  
  ld_TotalQty = ld_TotalQty / 1000 ' convert from mm to m
  ld_TotalQty = ld_TotalQty * ao_Product.PanelQtyPCS
  
  BOM_WasteQty = ao_Product.LoadWasteQty(eDPCBOMMaterial.bcGasket, ld_TotalQty)
  ld_TotalQty = (ld_TotalQty + BOM_WasteQty) * (1 + BOM_WasteFactor)
  
  If (ao_Product.PanelQtyPCS > 0) Then
    BOM_Qty = ld_TotalQty / ao_Product.PanelQtyPCS
  Else
    BOM_Qty = 0
  End If
  If Not LoadBOMPriceFromBaeurer(ao_DbBaeurer, BOM_IdentNr, ld_TotalQty) Then
    Call mo_Tools.AddCheckError(eDPCError.erBOMCostNotFoundB7, as_Language_Code, ao_ErrCollection, ao_Product, Me)
    CalculateGasket = False
  End If
  Exit Function
ErrHandler:
  Call ErrorHandler("CalculateGasket")
End Function

Public Function CalculateSpacer(ByVal ao_Db As Object, ByVal ao_DbBaeurer As Object, ByVal as_Language_Code As String, ByVal as_GSK_Id2 As String, ByVal ao_Product As DPC_Product, ByVal ao_ErrCollection As Collection) As Boolean
On Error GoTo ErrHandler

Dim ld_TotalQty As Double
Dim ll_SideIdx As eDPCSide
  
  CalculateSpacer = True
  ld_TotalQty = 0
  For ll_SideIdx = eDPCSide.esSideC To eDPCSide.esSideF
    If ((as_GSK_Id2 <> "") And StrComp(as_GSK_Id2, ao_Product.GSK_Id2(ll_SideIdx), vbTextCompare) = 0) Or ((as_GSK_Id2 = "") And ao_Product.IsSpacerOn(ll_SideIdx)) Then
      ld_TotalQty = ld_TotalQty + 2
    End If
  Next
  ld_TotalQty = ld_TotalQty * ao_Product.PanelQtyPCS
  
  BOM_WasteQty = ao_Product.LoadWasteQty(eDPCBOMMaterial.bcSpacer, ld_TotalQty)
  ld_TotalQty = (ld_TotalQty + BOM_WasteQty) * (1 + BOM_WasteFactor)
  
  If (ao_Product.PanelQtyPCS > 0) Then
    BOM_Qty = ld_TotalQty / ao_Product.PanelQtyPCS
  Else
    BOM_Qty = 0
  End If
  If Not LoadBOMPriceFromBaeurer(ao_DbBaeurer, BOM_IdentNr, ld_TotalQty) Then
    Call mo_Tools.AddCheckError(eDPCError.erBOMCostNotFoundB7, as_Language_Code, ao_ErrCollection, ao_Product, Me)
    CalculateSpacer = False
  End If
  Exit Function
ErrHandler:
  Call ErrorHandler("CalculateSpacer")
End Function

Public Function CalculateCoating(ByVal ao_Db As Object, ByVal ao_DbBaeurer As Object, ByVal as_Language_Code As String, ByVal ao_Product As DPC_Product, ByVal ao_ErrCollection As Collection) As Boolean
On Error GoTo ErrHandler

Dim ld_TotalQty As Double
Dim ll_SideIdx As eDPCSide
  
  CalculateCoating = True
  Select Case ao_Product.RPL_CoSid
  Case eDPCCoatingExecution.ceOneSide
    ld_TotalQty = ao_Product.PanelQtyPCS * ao_Product.PanelSurface
  Case eDPCCoatingExecution.ceBothSide, eDPCCoatingExecution.ceBackSideFull
    ld_TotalQty = 2 * ao_Product.PanelQtyPCS * ao_Product.PanelSurface
  Case Else
    Err.Raise ArmErr.InvalidArgument, "ao_Product.RPL_CoSid", "Invalid coating side parameter: " & ao_Product.RPL_CoSid
  End Select
  
  BOM_WasteQty = ao_Product.LoadWasteQty(eDPCBOMMaterial.bcCoating, ld_TotalQty)
  ld_TotalQty = (ld_TotalQty + BOM_WasteQty) * (1 + BOM_WasteFactor)
  
  If (BOM_Productivity > 0) Then
    ld_TotalQty = (ld_TotalQty / BOM_Productivity)
  Else
    ld_TotalQty = 0
    Call mo_Tools.AddCheckError(eDPCError.erBOMMaterialProductivityZero, as_Language_Code, ao_ErrCollection, ao_Product, Me)
    BOM_Status = eDPCBOMBORStatus.boGeneratedError
    CalculateCoating = False
  End If
  
  If (ao_Product.PanelQtyPCS > 0) Then
    BOM_Qty = ld_TotalQty / ao_Product.PanelQtyPCS
  Else
    BOM_Qty = 0
  End If
  If Not LoadBOMPriceFromBaeurer(ao_DbBaeurer, BOM_IdentNr, ld_TotalQty) Then
    Call mo_Tools.AddCheckError(eDPCError.erBOMCostNotFoundB7, as_Language_Code, ao_ErrCollection, ao_Product, Me)
    CalculateCoating = False
  End If
  Exit Function
ErrHandler:
  Call ErrorHandler("CalculateCoating")
End Function

Public Function CalculateInlay(ByVal ao_Db As Object, ByVal ao_DbBaeurer As Object, ByVal as_Language_Code As String, ByVal ao_Product As DPC_Product, ByVal ao_Inlay As DPC_Inlay, ByVal ao_ErrCollection As Collection) As Boolean
On Error GoTo ErrHandler

Dim ld_TotalQty As Double
Dim ld_MatWidth As Double, ld_MatLength As Double
  
  CalculateInlay = True
  
  If ao_Inlay Is Nothing Then
    Call mo_Tools.AddCheckError(eDPCError.erInlayMandatory, as_Language_Code, ao_ErrCollection, ao_Product, ao_Inlay)
    BOM_Status = eDPCBOMBORStatus.boGeneratedError
    CalculateInlay = False
    Exit Function
  Else
    ld_MatLength = ao_Inlay.PIN_SizeA
    If ao_Inlay.PIN_Purch = eDPCInlayPurchaseType.ipOrderedSize Then
      ' here we calculate with real inlay width
      ld_MatWidth = ao_Inlay.PIN_SizeB
    Else
      'here we calculate with width of the inlay roll which we cut to specific size
      ld_MatWidth = BOM_CutWidth
    End If
    BOM_CutLength = ao_Inlay.PIN_SizeA
    BOM_CutWidth = ao_Inlay.PIN_SizeB
  End If
  
  BOM_IdentNr = ao_Inlay.INL_IdentNr
  BOM_IdentNrTmp = ao_Inlay.INL_IdentNrTmp
  
  ld_TotalQty = ao_Product.PanelQtyPCS * (ld_MatLength * ld_MatWidth) / 1000000
  BOM_WasteQty = ao_Product.LoadWasteQty(eDPCBOMMaterial.bcInlay, ld_TotalQty)
  
  ld_TotalQty = (ld_TotalQty + BOM_WasteQty) * (1 + BOM_WasteFactor)
  If ao_Product.PanelQtyPCS > 0 Then
    BOM_Qty = ld_TotalQty / ao_Product.PanelQtyPCS
  Else
    Call mo_Tools.AddCheckError(eDPCError.erMandatoryQty, as_Language_Code, ao_ErrCollection, ao_Product, ao_Inlay)
    BOM_Status = eDPCBOMBORStatus.boGeneratedError
    BOM_Qty = 0
    CalculateInlay = False
  End If
  
  If LoadBOMPriceFromBaeurer(ao_DbBaeurer, BOM_IdentNrTmp, ld_TotalQty) Then
    'if price is in something else than for M2, cannot calculate and generate error
'    If StrComp(UM_Code, DPC_UOM_M2, vbTextCompare) <> 0 Then
'      BOM_Cost = 0
'      Call mo_Tools.AddCheckError(eDPCError.erBOMCostNotFoundB7, as_Language_code, ao_ErrCollection, ao_Product, ao_Inlay, Array("$BOM_IdentNr$"), Array(BOM_IdentNr))
'      BOM_Status = eDPCBOMBORStatus.boGeneratedError
'      CalculateInlay = False
'    End If
    
    If ao_Inlay.PIN_Purch = eDPCInlayPurchaseType.ipOrderedSize Then
      UM_Code = DPC_UOM_PCS
      UM_Name = mo_Tools.GetUM_Name(UM_Code, as_Language_Code)
      BOM_Qty = 1
      BOM_SalesPriceUnit = 1
      BOM_Cost = mo_Tools.FromPriceM2toPCS(BOM_Cost, (ld_MatLength * ld_MatWidth) / 1000000)
    ElseIf ao_Inlay.PIN_Purch = eDPCInlayPurchaseType.ipCutToSize Then
      BOM_Qty = (ld_MatLength * ld_MatWidth) / 1000000
    End If
  Else
    Call mo_Tools.AddCheckError(eDPCError.erBOMCostNotFoundB7, as_Language_Code, ao_ErrCollection, ao_Product, ao_Inlay, Array("$BOM_IdentNr$"), Array(BOM_IdentNrTmp))
    CalculateInlay = False
  End If
  Exit Function
ErrHandler:
  Call ErrorHandler("CalculateInlay")
End Function

Public Function ReplaceValuePlaceholder(ByVal as_Text As String) As String
On Error GoTo ErrHandler

  as_Text = Replace(as_Text, "$BOM_StlIdentNr$", BOM_StlIdentNr, , , vbTextCompare)
  as_Text = Replace(as_Text, "$BOM_Id$", BOM_Id, , , vbTextCompare)
  as_Text = Replace(as_Text, "$BOM_Pos$", BOM_Pos, , , vbTextCompare)
  as_Text = Replace(as_Text, "$BOM_BOR_Pos$", BOM_BOR_Pos, , , vbTextCompare)
  as_Text = Replace(as_Text, "$BOM_Categ$", BOM_Categ, , , vbTextCompare)
  as_Text = Replace(as_Text, "$BOM_CategDesc$", BOM_CategDesc, , , vbTextCompare)
  as_Text = Replace(as_Text, "$BOM_IdentNr$", BOM_IdentNr, , , vbTextCompare)
  as_Text = Replace(as_Text, "$BOM_Name$", BOM_Name, , , vbTextCompare)
  as_Text = Replace(as_Text, "$BOM_Material$", BOM_Material, , , vbTextCompare)
  as_Text = Replace(as_Text, "$BOM_Qty$", mo_Tools.DblToScreen(BOM_Qty, 2), , , vbTextCompare)
  as_Text = Replace(as_Text, "$UM_Code$", UM_Code, , , vbTextCompare)
  as_Text = Replace(as_Text, "$UM_Name$", UM_Name, , , vbTextCompare)
  as_Text = Replace(as_Text, "$BOM_Cost$", mo_Tools.DblToScreen(BOM_Cost, 2), , , vbTextCompare)
  as_Text = Replace(as_Text, "$BOM_SalesPriceUnit$", BOM_SalesPriceUnit, , , vbTextCompare)
  as_Text = Replace(as_Text, "$CURR_Code$", CURR_Code, , , vbTextCompare)
  as_Text = Replace(as_Text, "$BOM_SpecWeight$", mo_Tools.DblToScreen(BOM_SpecWeight, 2), , , vbTextCompare)
  as_Text = Replace(as_Text, "$BOM_Productivity$", mo_Tools.DblToScreen(BOM_Productivity, 2), , , vbTextCompare)
  as_Text = Replace(as_Text, "$BOM_CutWidth$", mo_Tools.DblToScreen(BOM_CutWidth, 2), , , vbTextCompare)
  as_Text = Replace(as_Text, "$BOM_CutLength$", mo_Tools.DblToScreen(BOM_CutLength, 2), , , vbTextCompare)
  as_Text = Replace(as_Text, "$BOM_WasteFactor$", mo_Tools.DblToScreen(BOM_WasteFactor, 2), , , vbTextCompare)
  as_Text = Replace(as_Text, "$BOM_WasteQty$", BOM_WasteQty, , , vbTextCompare)
  as_Text = Replace(as_Text, "$BOM_Manual$", BOM_Manual, , , vbTextCompare)
  as_Text = Replace(as_Text, "$BOM_IdentNrTmp$", BOM_IdentNrTmp, , , vbTextCompare)
  as_Text = Replace(as_Text, "$BOM_Export$", BOM_Export, , , vbTextCompare)
  as_Text = Replace(as_Text, "$BOM_ExpDat$", BOM_ExpDat, , , vbTextCompare)
  as_Text = Replace(as_Text, "$BOM_DatVon$", mo_Tools.DateToScreen(BOM_DatVon), , , vbTextCompare)
  as_Text = Replace(as_Text, "$BOM_Menge_Ab$", mo_Tools.DblToScreen(BOM_Menge_Ab), , , vbTextCompare)
  as_Text = Replace(as_Text, "$BOM_Status$", BOM_Status, , , vbTextCompare)
  as_Text = Replace(as_Text, "$BOM_StatusDesc$", BOM_StatusDesc, , , vbTextCompare)
  ReplaceValuePlaceholder = as_Text
  Exit Function
ErrHandler:
  Call ErrorHandler("ReplaceValuePlaceholder")
End Function

' Standard error handler
Private Sub ErrorHandler(ByVal as_Fct As String)
  
    Call Err.Raise(Err.Number, as_Fct & SEP1 & Err.Source, Err.Description)
End Sub



