VERSION 1.0 CLASS
BEGIN
  MultiUse = -1  'True
END
Attribute VB_Name = "months"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = True
Option Explicit

Private x As New TheBigOne
Private units() As Variant
Private price() As Variant
Private sales() As Variant
Private tunits() As Variant
Private tprice() As Variant
Private tsales() As Variant
Private dumping As Boolean
Private vedit As String
Private adjust() As Object
Private jtext() As Variant
Private basejson As Object



Private Sub Worksheet_Change(ByVal target As Range)

    
    If Not dumping Then

        If Not Intersect(target, Range("E6:E17")) Is Nothing Then Call Me.mvp_adj
        If Not Intersect(target, Range("F6:F17")) Is Nothing Then Call Me.mvp_set
        If Not Intersect(target, Range("K6:K17")) Is Nothing Then Call Me.mvp_adj
        If Not Intersect(target, Range("L6:L17")) Is Nothing Then Call Me.mvp_set
        'If Not Intersect(Target, Range("Q6:Q17")) Is Nothing Then Call Me.ms_adj
        'If Not Intersect(Target, Range("R6:R17")) Is Nothing Then Call Me.ms_set
            
    End If
    
    'Call Me.set_format
    

End Sub

Sub mvp_set()

    Dim i As Integer
    Call Me.get_sheet

    For i = 1 To 12
        If units(i, 5) = "" Then units(i, 5) = 0
        If price(i, 5) = "" Then price(i, 5) = 0
        units(i, 4) = units(i, 5) - (units(i, 2) + units(i, 3))
        price(i, 4) = price(i, 5) - (price(i, 2) + price(i, 3))
        sales(i, 5) = units(i, 5) * price(i, 5)
        sales(i, 4) = sales(i, 5) - (sales(i, 2) + sales(i, 3))
        Call Me.build_json(i)
    Next i
    
    Me.crunch_array
    Me.set_sheet
    
        
End Sub

Sub mvp_adj()

    Dim i As Integer
    Call Me.get_sheet

    For i = 1 To 12
        If units(i, 4) = "" Then units(i, 4) = 0
        If price(i, 4) = "" Then price(i, 4) = 0
        units(i, 5) = units(i, 4) + (units(i, 2) + units(i, 3))
        price(i, 5) = price(i, 4) + (price(i, 2) + price(i, 3))
        sales(i, 5) = units(i, 5) * price(i, 5)
        sales(i, 4) = sales(i, 5) - (sales(i, 2) + sales(i, 3))
        Call Me.build_json(i)
    Next i
    
    Me.crunch_array
    Me.set_sheet
    
        
End Sub

Sub ms_set()

    Dim i As Integer
    Call Me.get_sheet

    For i = 1 To 12
        units(i, 4) = units(i, 5) - (units(i, 2) + units(i, 3))
        price(i, 4) = price(i, 5) - (price(i, 2) + price(i, 3))
        sales(i, 5) = units(i, 5) * price(i, 5)
        sales(i, 4) = sales(i, 5) - (sales(i, 2) + sales(i, 3))
    Next i
    
    set_sheet
    
        
End Sub


Sub get_sheet()

    Dim i As Integer
    
    units = Range("B6:F17")
    price = Range("H6:L17")
    sales = Range("N6:R17")
    tunits = Range("B18:F18")
    tprice = Range("H18:L18")
    tsales = Range("N18:R18")
    ReDim adjust(12)
    Set basejson = JsonConverter.ParseJson("{""scenario"":" & Sheets("_month").Range("P1").FormulaR1C1 & "}")
      
End Sub

Sub set_sheet()

    Dim i As Integer

    dumping = True
    
    Range("B6:F17") = units
    Range("H6:L17") = price
    Range("N6:R17") = sales
    Range("B18:F18").FormulaR1C1 = tunits
    Range("H18:L18").FormulaR1C1 = tprice
    Range("N18:R18").FormulaR1C1 = tsales
    
    For i = 1 To 12
        Sheets("_month").Cells(i + 1, 16) = JsonConverter.ConvertToJson(adjust(i))
    Next i
    dumping = False
    
End Sub

Sub load_sheet()

    units = Sheets("_month").Range("A2:E13").FormulaR1C1
    price = Sheets("_month").Range("F2:J13").FormulaR1C1
    sales = Sheets("_month").Range("K2:O13").FormulaR1C1
    tunits = Range("B18:F18")
    tprice = Range("H18:L18")
    tsales = Range("N18:R18")
    ReDim adjust(12)
    Me.crunch_array
    Me.set_sheet

End Sub

Sub set_format()

    Dim prices As Range
    Dim price_adj As Range
    Dim price_set As Range
    Dim vol As Range
    Dim vol_adj As Range
    Dim vol_set As Range
    Dim val As Range
    Dim val_adj As Range
    Dim val_set As Range
    
    Set prices = Sheets("month").Range("H6:L17")
    Set price_adj = Sheets("month").Range("K6:K17")
    Set price_set = Sheets("month").Range("L6:L17")
    
    Set vol = Sheets("month").Range("B6:F17")
    Set vol_adj = Sheets("month").Range("E6:E17")
    Set vol_set = Sheets("month").Range("F6:F17")
    
    Set val = Sheets("month").Range("N6:R17")
    Set val_adj = Sheets("month").Range("Q6:Q17")
    Set val_set = Sheets("month").Range("R6:R17")
    
    Call Me.format_price(prices)
    Call Me.set_border(prices)
    Call Me.fill_yellow(price_adj)
    Call Me.fill_none(price_set)
    
    Call Me.format_number(vol)
    Call Me.set_border(vol)
    Call Me.fill_yellow(vol_adj)
    Call Me.fill_none(vol_set)
    
    Call Me.format_number(val)
    Call Me.set_border(val)
    Call Me.fill_yellow(val_adj)
    Call Me.fill_none(val_set)
    
End Sub

Sub set_border(ByRef targ As Range)

    targ.Borders(xlDiagonalDown).LineStyle = xlNone
    targ.Borders(xlDiagonalUp).LineStyle = xlNone
    With targ.Borders(xlEdgeLeft)
        .LineStyle = xlContinuous
        .ColorIndex = 0
        .TintAndShade = 0
        .Weight = xlThin
    End With
    With targ.Borders(xlEdgeTop)
        .LineStyle = xlContinuous
        .ColorIndex = 0
        .TintAndShade = 0
        .Weight = xlThin
    End With
    With targ.Borders(xlEdgeBottom)
        .LineStyle = xlContinuous
        .ColorIndex = 0
        .TintAndShade = 0
        .Weight = xlThin
    End With
    With targ.Borders(xlEdgeRight)
        .LineStyle = xlContinuous
        .ColorIndex = 0
        .TintAndShade = 0
        .Weight = xlThin
    End With
    With targ.Borders(xlInsideVertical)
        .LineStyle = xlContinuous
        .ColorIndex = 0
        .TintAndShade = 0
        .Weight = xlThin
    End With
    With targ.Borders(xlInsideHorizontal)
        .LineStyle = xlContinuous
        .ColorIndex = 0
        .TintAndShade = 0
        .Weight = xlThin
    End With

End Sub

Sub fill_yellow(ByRef target As Range)

    With target.Interior
        .Pattern = xlSolid
        .PatternColorIndex = xlAutomatic
        .ThemeColor = xlThemeColorAccent4
        .TintAndShade = 0.799981688894314
        .PatternTintAndShade = 0
    End With

End Sub

Sub fill_none(ByRef target As Range)

    With target.Interior
        .Pattern = xlNone
        .TintAndShade = 0
        .PatternTintAndShade = 0
    End With
    
End Sub

Sub format_price(ByRef target As Range)

    target.NumberFormat = "_(* #,##0.000_);_(* (#,##0.000);_(* ""-""???_);_(@_)"

End Sub

Sub format_number(ByRef target As Range)

    target.NumberFormat = "_(* #,##0_);_(* (#,##0);_(* ""-""_);_(@_)"

End Sub

Sub build_json(ByVal pos As Integer)

    'if something is changing
    If Round(units(pos, 4), 2) <> 0 Or Round(price(pos, 4), 8) <> 0 Or Round(sales(pos, 4), 8) <> 0 Then
        Set adjust(pos) = basejson
        'if there is no existing volume on the target month but units are being added
        If units(pos, 2) + units(pos, 3) = 0 And units(pos, 4) <> 0 Then
            'add month
            If Round(price(pos, 5), 8) <> Round(tprice(1, 2) + tprice(1, 3), 8) Then
                'if the target price is diferent from the average and a month is being added
                adjust(pos)("type") = "addmonth_vp"
            Else
                'if the target price is the same as average and a month is being added
                adjust(pos)("type") = "addmonth_v"
            End If
            adjust(pos)("qty") = units(pos, 4)
            adjust(pos)("amount") = sales(pos, 4)
        Else
            'scale the existing volume(price) on the target month
            If Round(price(pos, 4), 8) <> 0 Then
                'if the target price is diferent from the average and a month is being added
                adjust(pos)("type") = "scale_vp"
            Else
                'if the target price is the same as average and a month is being added
                adjust(pos)("type") = "scale_v"
            End If
            adjust(pos)("qty") = units(pos, 4)
            adjust(pos)("amount") = sales(pos, 4)
        End If
    End If

End Sub

Sub crunch_array()

    Dim i As Integer
    Dim j As Integer
    
    For i = 1 To 5
        tunits(1, i) = 0
        tprice(1, i) = 0
        tsales(1, i) = 0
    Next i
    
    For i = 1 To 12
        For j = 1 To 5
            tunits(1, j) = tunits(1, j) + units(i, j)
            tsales(1, j) = tsales(1, j) + sales(i, j)
        Next j
    Next i
    
    'prior
    tprice(1, 1) = tsales(1, 1) / tunits(1, 1)
    'base
    tprice(1, 2) = tsales(1, 2) / tunits(1, 2)
    'forecast
    tprice(1, 5) = tsales(1, 5) / tunits(1, 5)
    'adjust
    tprice(1, 3) = (tsales(1, 2) + tsales(1, 3)) / (tunits(1, 2) + tunits(1, 3)) - tprice(1, 2)
    'current adjust
    tprice(1, 4) = tprice(1, 5) - (tprice(1, 2) + tprice(1, 3))
    

End Sub
