Implement function call (grouped running totals) in query - function

I have a function called fxGroupedRunningTotal (fxGRT) and a query (Totals). I want to call fxGRT within Totals, so that I get a column that shows the grouped running totals. I have only managed to test the fxGRT by importing the Totals query.
Query that uses Totals and calls fxGRT (built for testing the function):
let
Source = Totals,
BufferedValues = List.Buffer(Source[PD]),
BufferedMaterials = List.Buffer(Source[Material]),
RT = Table.FromColumns(
{
Source[Material], Source[Date], Source[PD],
fxGroupedRunningTotal(BufferedValues, BufferedMaterials)
},
{
"Material",
"Date",
"PD",
"Running Total"
})
in
RT
fxGroupedRunningTotals:
(values as list, grouping as list) as list =>
let
GRTList = List.Generate
(
()=> [ GRT = values{0}, i = 0 ],
each [i] < List.Count(values),
each try if grouping{[i]} = grouping{[i] + 1}
then [GRT = [GRT] + values {[i] + 1}, i = [i] + 1]
else [GRT = values{[i] + 1}, i = [i] + 1]
otherwise [i = [i] + 1]
,
each [GRT]
)
in
GRTList
Totals:
let
Källa = Table.NestedJoin(Cohv,{"Prod MDate"},Resb,{"Del Mdate"},"Resb",JoinKind.FullOuter),
#"Expanderad Resb" = Table.ExpandTableColumn(Källa, "Resb", {"Del Material", "Del Date", "Del Qty", "Del Mdate"}, {"Del Material", "Del Date", "Del Qty", "Del Mdate"}),
#"PD Date" = Table.AddColumn(#"Expanderad Resb", "PD Date", each if [Prod Date] = null then [Del Date] else [Prod Date]),
#"PD Material" = Table.AddColumn(#"PD Date", "PD Material", each if [Material Number] = null then [Del Material] else [Material Number]),
#"PD Mdate" = Table.AddColumn(#"PD Material", "PD Mdate", each [PD Material] & "." & Date.ToText([PD Date])),
#"Borttagna kolumner" = Table.RemoveColumns(#"PD Mdate",{"Prod Date", "Prod MDate", "Del Date", "Del Mdate"}),
#"Ändrad typ1" = Table.TransformColumnTypes(#"Borttagna kolumner",{{"PD Date", type date}}),
#"Ihopslagna frågor" = Table.NestedJoin(#"Ändrad typ1",{"PD Material"},Matmas,{"Material"},"Matmas",JoinKind.FullOuter),
#"Expanderad Matmas" = Table.ExpandTableColumn(#"Ihopslagna frågor", "Matmas", {"Material", "Material Description", "MRP Controller", "Safety stock", "Minimum Lot Size", "In Stock"}, {"Material", "Material Description", "MRP Controller", "Safety stock", "Minimum Lot Size", "In Stock"}),
#"Omdöpta kolumner" = Table.RenameColumns(#"Expanderad Matmas",{{"Material", "M Material"}}),
#"Lägg till egen" = Table.AddColumn(#"Omdöpta kolumner", "Material", each if [PD Material] = null then [M Material]else [PD Material]),
#"Borttagna kolumner1" = Table.RemoveColumns(#"Lägg till egen",{"Material Number", "Del Material", "PD Material", "M Material"}),
#"Lägg till egen1" = Table.AddColumn(#"Borttagna kolumner1", "Date", each if [PD Date] = null then DateTime.LocalNow() else [PD Date]),
#"Borttagna kolumner2" = Table.RemoveColumns(#"Lägg till egen1",{"PD Date"}),
#"Lägg till egen2" = Table.AddColumn(#"Borttagna kolumner2", "Date in stock", each if [Date] = DateTime.Date(DateTime.LocalNow()) then [In Stock] else null),
#"Borttagna kolumner3" = Table.RemoveColumns(#"Lägg till egen2",{"Date in stock"}),
#"Ändrad typ" = Table.TransformColumnTypes(#"Borttagna kolumner3",{{"Date", type date}}),
#"Ersatt värde" = Table.ReplaceValue(#"Ändrad typ",null,0,Replacer.ReplaceValue,{"Prod Qty"}),
#"Ersatt värde1" = Table.ReplaceValue(#"Ersatt värde",null,0,Replacer.ReplaceValue,{"Del Qty"}),
#"Ihopslagna frågor1" = Table.NestedJoin(#"Ersatt värde1",{"Date"},Dates,{"Date"},"Dates",JoinKind.RightOuter),
#"Expanderad Dates" = Table.ExpandTableColumn(#"Ihopslagna frågor1", "Dates", {"Current Date"}, {"Current Date"}),
#"Omdöpta kolumner1" = Table.RenameColumns(#"Expanderad Dates",{{"Date", "D Date"}}),
Date = Table.AddColumn(#"Omdöpta kolumner1", "Date", each if [D Date] is null then DateTime.Date(DateTime.LocalNow()) else [D Date]),
PD = Table.AddColumn(Date, "PD", each if [Current Date] = "Yes" then [In Stock]+[Prod Qty]-[Del Qty] else [Prod Qty]-[Del Qty])
in
PD
So how do I implement this function into a new column in my Totals? My attempts keep failing. Do I have to make a reference to Totals in order to make this work? It feels so wrong, since that would double the work load (?) with the data. I would like it to be as quick as possible.

You can reference the previous step as a table. Thus your query can be written
let
[...all your previous steps...]
PD = Table.AddColumn(Date, "PD", each if [Current Date] = "Yes" then [In Stock]+[Prod Qty]-[Del Qty] else [Prod Qty]-[Del Qty]),
RT =
Table.FromColumns(
List.Combine({Table.ToColumns(PD), {fxGroupedRunningTotals(PD[Material], PD[PD])}}),
List.Combine({Table.ColumnNames(PD), {"Running Total"}})
)
in
RT
This converts the table to a list of columns, adds on the new running total column (calling the function you've defined on specific columns of the table from the previous step PD), and then glues those columns back together with a similar method to preserve the column names and add a new one.

Related

Parse Large amount of Json in Excel

I have an application which reads in files containing json data parses them then performs some formatting and calculations.
The Core of the code itself works fine, however the issue I have is that it is slow.
I got Json Parsing code from another site (not sure if i'm allowed to link to it), and what I do is I split the file from the data into an array, Parse each row and put it into another array then perform all my tasks later.
The slow part is the Parsing of the data, overall it's pretty quick and works through about 10-15 rows a second, however my files have upwards of 5k rows of data in them, meaning each file takes roughly 5 minutes, and when as there are hundreds of files to get through, it takes almost an entire day to full parse all the data.
I've attached snippets of my code (not the full parsing functions as that's really long) just to give an idea of how my code is currently working
My query is, is there a way I can parse the entire file (each record is seperated by a line feed) instead of having to parse it row by row?
sourceArray = Split(sourceText, vbLf)
For Ctr = LBound(sourceArray) To UBound(sourceArray)
Set dic = ParseJSON(sourceArray(Ctr)
For Each v In dic
(do some formatting stuff, I tested by completely commenting out this part to make sure the ParseJSON is where the slowdown is)
next v
Next Ctr
Json Parser code
'-------------------------------------------------------------------
' VBA JSON Parser
'-------------------------------------------------------------------
Function ParseJSON(json$, Optional key$ = "obj") As Object
p = 1
token = Tokenize(json)
Set dic = CreateObject("Scripting.Dictionary")
If token(p) = "{" Then ParseObj key Else ParseArr key
Set ParseJSON = dic
End Function
Function ParseObj(key$)
Do: p = p + 1
Select Case token(p)
Case "]"
Case "[": ParseArr key
Case "{"
If token(p + 1) = "}" Then
p = p + 1
dic.Add key, "null"
Else
ParseObj key
End If
Case "}": key = ReducePath(key): Exit Do
Case ":": key = key & "." & token(p - 1)
Case ",": key = ReducePath(key)
Case Else: If token(p + 1) <> ":" Then dic.Add key, token(p)
End Select
Loop
End Function
Function ParseArr(key$)
Dim e&
Do: p = p + 1
Select Case token(p)
Case "}"
Case "{": ParseObj key & ArrayID(e)
Case "[": ParseArr key
Case "],": e = e
Case "]": Exit Do
Case ":": key = key & ArrayID(e)
Case ",": e = e + 1
Case Else: dic.Add key & ArrayID(e), token(p)
End Select
Loop
End Function
'-------------------------------------------------------------------
' Support Functions
'-------------------------------------------------------------------
Function Tokenize(s$)
Const Pattern = """(([^""\\]|\\.)*)""|[+\-]?(?:0|[1-9]\d*)(?:\.\d*)?(?:[eE][+\-]?\d+)?|\w+|[^\s""']+?"
Tokenize = RExtract(s, Pattern, True)
End Function
Function RExtract(s$, Pattern, Optional bGroup1Bias As Boolean, Optional bGlobal As Boolean = True)
Dim c&, m, n, v
With CreateObject("vbscript.regexp")
.Global = bGlobal
.MultiLine = False
.IgnoreCase = True
.Pattern = Pattern
If .test(s) Then
Set m = .Execute(s)
ReDim v(1 To m.Count)
For Each n In m
c = c + 1
v(c) = n.Value
If bGroup1Bias Then If Len(n.subMatches(0)) Or n.Value = """""" Then v(c) = n.subMatches(0)
Next
End If
End With
RExtract = v
End Function
Function ArrayID$(e)
ArrayID = "(" & e & ")"
End Function
Function ReducePath$(key$)
If InStr(key, ".") Then ReducePath = Left(key, InStrRev(key, ".") - 1) Else ReducePath = key
End Function
Function ListPaths(dic)
Dim s$, v
For Each v In dic
s = s & v & " --> " & dic(v) & vbLf
Next
End Function
Function GetFilteredValues(dic, Match)
Dim c&, i&, v, w
v = dic.Keys
ReDim w(1 To dic.Count)
For i = 0 To UBound(v)
If v(i) Like Match Then
c = c + 1
w(c) = dic(v(i))
End If
Next
ReDim Preserve w(1 To c)
GetFilteredValues = w
End Function
Function GetFilteredTable(dic, cols)
Dim c&, i&, j&, v, w, z
v = dic.Keys
z = GetFilteredValues(dic, cols(0))
ReDim w(1 To UBound(z), 1 To UBound(cols) + 1)
For j = 1 To UBound(cols) + 1
z = GetFilteredValues(dic, cols(j - 1))
For i = 1 To UBound(z)
w(i, j) = z(i)
Next
Next
GetFilteredTable = w
End Function
Function OpenTextFile$(f)
With CreateObject("ADODB.Stream")
.Charset = "utf-8"
.Open
.LoadFromFile f
OpenTextFile = .ReadText
End With
End Function
Sample Data
{
"op": "mcm",
"clk": "4985835795",
"pt": 1641446989915,
"mc": [
{
"id": "1.193068822",
"rc": [
{
"batl": [
[
0,
85,
10
]
],
"ltp": 0.0,
"tv": 0.0,
"id": 536162
},
{
"batl": [
[
0,
85,
5
]
],
"ltp": 0.0,
"tv": 0.0,
"id": 36024159
},
{
"batb": [
[
0,
1.02,
322
]
],
"ltp": 0.0,
"tv": 0.0,
"id": 22734575
},
{
"batb": [
[
0,
1.02,
322
]
],
"ltp": 0.0,
"tv": 0.0,
"id": 16286497
},
{
"batb": [
[
0,
1.02,
322
]
],
"ltp": 0.0,
"tv": 0.0,
"id": 18673417
},
{
"batl": [
[
0,
85,
10
]
],
"ltp": 0.0,
"tv": 0.0,
"id": 38835846
},
{
"batl": [
[
0,
85,
10
]
],
"ltp": 0.0,
"tv": 0.0,
"id": 1527689
},
{
"batb": [
[
0,
1.02,
322
]
],
"ltp": 0.0,
"tv": 0.0,
"id": 36394575
},
{
"batb": [
[
0,
1.02,
322
]
],
"ltp": 0.0,
"tv": 0.0,
"id": 1276636
}
]
}
]
}
I'm using this library to parse a json file with 4560 objects and 532kb under 3 seconds.
https://github.com/VBA-tools/VBA-JSON
Sub main()
Dim FSO As New FileSystemObject
Dim JsonTS As TextStream
Dim JsonText As String
Dim Parsed As Dictionary
Set JsonTS = FSO.OpenTextFile("sample4.json", ForReading)
JsonText = JsonTS.ReadAll
JsonTS.Close
Set Parsed = JsonConverter.ParseJson(JsonText)
For i = 1 To Parsed("people").Count
With Sheets(1)
Range("A" & i).Value = Parsed("people")(i)("firstName")
Range("B" & i).Value = Parsed("people")(i)("lastName")
Range("C" & i).Value = Parsed("people")(i)("gender")
Range("D" & i).Value = Parsed("people")(i)("age")
Range("E" & i).Value = Parsed("people")(i)("number")
End With
Next
End Sub
{
"people": [
{
"firstName": "Joe",
"lastName": "Jackson",
"gender": "male",
"age": 28,
"number": "7349282382"
}
]
}

JSON to Excel PowerQuery import - how to get a row per nested field

I'm looking to use the Excel Power Query to import some json that looks like the following (but much bigger, more fields etc.):
example-records.json
{
"records": {
"record_id_1": {
"file_no": "5792C",
"loads": {
"load_id_1": {
"docket_no": "3116115"
},
"load_id_2": {
"docket_no": "3116118"
},
"load_id_3": {
"docket_no": "3208776"
}
}
},
"record_id_2": {
"file_no": "5645C",
"loads": {
"load_id_4": {
"docket_no": "2000527155"
},
"load_id_5": {
"docket_no": "2000527156"
},
"load_id_6": {
"docket_no": "2000527146"
}
}
}
}
}
I want to get a table like the following at the load_id / docket level. A row per load_id
What I've tried
Clicking buttons in power query UI I get the following.
The problem is I can't include a file_no column and this doesn't work when there are lots of load ids.
let
Source = Json.Document(File.Contents("H:\Software\Site Apps\example-records.json")),
records = Source[records],
#"Converted to Table" = Record.ToTable(records),
#"Expanded Value" = Table.ExpandRecordColumn(#"Converted to Table", "Value", {"file_no", "loads"}, {"Value.file_no", "Value.loads"}),
#"Removed Columns" = Table.RemoveColumns(#"Expanded Value",{"Value.file_no"}),
#"Expanded Value.loads" = Table.ExpandRecordColumn(#"Removed Columns", "Value.loads", {"load_id_1", "load_id_2", "load_id_3", "load_id_4", "load_id_5", "load_id_6"}, {"Value.loads.load_id_1", "Value.loads.load_id_2", "Value.loads.load_id_3", "Value.loads.load_id_4", "Value.loads.load_id_5", "Value.loads.load_id_6"}),
#"Unpivoted Columns" = Table.UnpivotOtherColumns(#"Expanded Value.loads", {"Name"}, "Attribute", "Value"),
#"Expanded Value1" = Table.ExpandRecordColumn(#"Unpivoted Columns", "Value", {"docket_no"}, {"Value.docket_no"})
in
#"Expanded Value1"
You can use
let Source = JSON(Json.Document(File.Contents("c:\temp\example.json"))),
#"Removed Other Columns" = Table.SelectColumns(Source,{"Name.1", "Name.3", "Value"}),
#"Added Custom" = Table.AddColumn(#"Removed Other Columns", "Custom", each if [Name.3]=null then [Value] else null),
#"Filled Down" = Table.FillDown(#"Added Custom",{"Custom"}),
#"Filtered Rows" = Table.SelectRows(#"Filled Down", each ([Name.3] <> null))
in #"Filtered Rows"
based on this function I named JSON which comes from Imke https://www.thebiccountant.com/2018/06/17/automatically-expand-all-fields-from-a-json-document-in-power-bi-and-power-query/ which is reproduced below
let
func = (JSON) =>
let
Source = JSON,
ParseJSON = try Json.Document(Source) otherwise Source,
TransformForTable =
if Value.Is(ParseJSON, type record) then
Record.ToTable(ParseJSON)
else
#table(
{"Name", "Value"},
List.Zip({List.Repeat({0}, List.Count(ParseJSON)), ParseJSON})
),
AddSort = Table.Buffer(Table.AddColumn(TransformForTable, "Sort", each 0)),
LG = List.Skip(
List.Generate(
() => [Next = AddSort, Counter = 1, AddIndex = #table({"Sort"}, {{""}})],
each [AddIndex]{0}[Sort] <> "End",
each [
AddIndex = Table.AddIndexColumn([Next], "Index", 0, 1),
MergeSort = Table.CombineColumns(
Table.TransformColumnTypes(
AddIndex,
{{"Sort", type text}, {"Index", type text}},
"en-GB"
),
{"Sort", "Index"},
Combiner.CombineTextByDelimiter(".", QuoteStyle.None),
"Sort"
),
PJson = Table.TransformColumns(
MergeSort,
{{"Value", each try Json.Document(_) otherwise _}}
),
AddType = Table.AddColumn(
PJson,
"Type",
each
if Value.Is([Value], type record) then
"Record"
else if Value.Is([Value], type list) then
"List"
else if Value.Is([Value], type table) then
"Table"
else
"other"
),
AddStatus = Table.AddColumn(
AddType,
"Status",
each if [Type] = "other" then "Finished" else "Unfinished"
),
Finished = Table.SelectRows(AddStatus, each ([Status] = "Finished")),
Unfinished = Table.SelectRows(AddStatus, each ([Status] = "Unfinished")),
AddNext = Table.AddColumn(
Unfinished,
"Next",
each if [Type] = "Record" then {[Value]} else [Value]
),
RemoveCols = Table.RemoveColumns(AddNext, {"Value", "Type", "Status"}),
ExpandNext = Table.ExpandListColumn(RemoveCols, "Next"),
AddIndex2 = Table.AddIndexColumn(ExpandNext, "Index", 0, 1),
MergeSort2 = Table.CombineColumns(
Table.TransformColumnTypes(
AddIndex2,
{{"Sort", type text}, {"Index", type text}},
"en-GB"
),
{"Sort", "Index"},
Combiner.CombineTextByDelimiter(".", QuoteStyle.None),
"Sort"
),
TransformRecord = Table.TransformColumns(
MergeSort2,
{
{
"Next",
each try
Record.ToTable(_)
otherwise
try
if Value.Is(Text.From(_), type text) then
#table({"Value"}, {{_}})
else
_
otherwise
_
}
}
),
FilterOutNulls = Table.SelectRows(TransformRecord, each [Next] <> null),
Next =
if Table.IsEmpty(FilterOutNulls) then
#table({"Sort"}, {{"End"}})
else if Value.Is(FilterOutNulls[Next]{0}, type table) = true then
Table.ExpandTableColumn(
FilterOutNulls,
"Next",
{"Name", "Value"},
{"Name." & Text.From([Counter]), "Value"}
)
else
Table.RenameColumns(FilterOutNulls, {{"Next", "Value"}}),
Counter = [Counter] + 1
],
each Table.AddColumn([Finished], "Level", (x) => _[Counter] - 2)
)
),
Check = LG{2},
Combine = Table.Combine(LG),
Clean = Table.RemoveColumns(Combine, {"Status", "Type"}),
Trim = Table.TransformColumns(Clean, {{"Sort", each Text.Trim(_, "."), type text}}),
// Dynamic Padding for the sort-column so that it sorts by number in text strings
SelectSort = Table.SelectColumns(Trim, {"Sort"}),
SplitSort = Table.AddColumn(
SelectSort,
"Custom",
each List.Transform(try Text.Split([Sort], ".") otherwise {}, Number.From)
),
ToTable = Table.AddColumn(
SplitSort,
"Splitted",
each Table.AddIndexColumn(Table.FromColumns({[Custom]}), "Pos", 1, 1)
),
ExpandTable = Table.ExpandTableColumn(ToTable, "Splitted", {"Column1", "Pos"}),
GroupPos = Table.Group(
ExpandTable,
{"Pos"},
{{"All", each _, type table}, {"Max", each List.Max([Column1]), type text}}
),
Digits = Table.AddColumn(GroupPos, "Digits", each Text.Length(Text.From([Max]))),
FilteredDigits = List.Buffer(Table.SelectRows(Digits, each ([Digits] <> null))[Digits]),
SortNew = Table.AddColumn(
Trim,
"SortBy",
each Text.Combine(
List.Transform(
List.Zip({Text.Split([Sort], "."), List.Positions(Text.Split([Sort], "."))}),
each Text.PadStart(_{0}, FilteredDigits{_{1}}, "0")
),
"."
)
),
FilterNotNull = Table.SelectRows(SortNew, each ([Value] <> null)),
Reorder = Table.ReorderColumns(
FilterNotNull,
{"Value", "Level", "Sort", "SortBy"}
& List.Difference(
Table.ColumnNames(FilterNotNull),
{"Value", "Level", "Sort", "SortBy"}
)
),
Dots = Table.AddColumn(
#"Reorder",
"Dots",
each List.Select(Table.ColumnNames(#"Reorder"), (l) => Text.StartsWith(l, "Name"))
),
// This sort is just to view in the query editor. When loaded to the data model it will not be kept. Use "Sort by column" in the data model instead.
Sort = Table.Sort(Dots, {{"SortBy", Order.Ascending}})
in
Sort,
documentation = [
Documentation.Name = " Table.JsonExpandAll ",
Documentation.Description
= " Dynamically expands the <Json> Record and returns values in one column and additional columns to navigate. ",
Documentation.LongDescription
= " Dynamically expands the <Json> Record and returns values in one column and additional columns to navigate. Input can be JSON in binary format or the already parsed JSON. ",
Documentation.Category = " Table ",
Documentation.Version = " 1.2: Added column [Dots] (22/02/2019)",
Documentation.Author = " Imke Feldmann: www.TheBIccountant.com . ",
Documentation.Examples = {[Description = " ", Code = " ", Result = " "]}
]
in
Value.ReplaceType(func, Value.ReplaceMetadata(Value.Type(func), documentation))
Managed to use an added custom column, the action that enables the expansion to one load id per row.
#"Added Custom" = Table.AddColumn(#"Expanded Value", "Custom", each Record.ToTable([Value.loads]))
let
Source = Json.Document(File.Contents("H:\Software\Site Apps\example-records.json")),
records = Source[records],
#"Converted to Table" = Record.ToTable(records),
#"Expanded Value" = Table.ExpandRecordColumn(#"Converted to Table", "Value", {"file_no", "loads"}, {"Value.file_no", "Value.loads"}),
#"Added Custom" = Table.AddColumn(#"Expanded Value", "Custom", each Record.ToTable([Value.loads])),
#"Removed Columns" = Table.RemoveColumns(#"Added Custom",{"Value.loads"}),
#"Expanded Custom" = Table.ExpandTableColumn(#"Removed Columns", "Custom", {"Name", "Value"}, {"Custom.Name", "Custom.Value"}),
#"Expanded Custom.Value" = Table.ExpandRecordColumn(#"Expanded Custom", "Custom.Value", {"docket_no"}, {"Custom.Value.docket_no"}),
#"Renamed Columns" = Table.RenameColumns(#"Expanded Custom.Value",{{"Name", "record_id"}, {"Value.file_no", "file_no"}, {"Custom.Name", "load_id"}, {"Custom.Value.docket_no", "docket_no"}})
in
#"Renamed Columns"

Server side pagination in Graphql Scala

I need to do server side pagination in graphql in scala. I have seven reports and have used one graphql query with different operations to get the data. Now I need to add server side pagination to it and I am not able to do that. Any help would be appreciated. Below are my code:
Schema:
val PanelNominationStatusReportDataType = ObjectType(
"PanelNominationStatus",
"Dashboard Reports",
fields[Unit, PanelRewardSatusDetail](
Field("awardName", OptionType(StringType), resolve = _.value.awardName),
Field("nominatorEmail", OptionType(StringType), resolve = _.value.nominatorEmail),
Field("nomineeEmail", OptionType(StringType), resolve = _.value.nomineeEmail),
Field("nomineeLocation", OptionType(StringType), resolve = _.value.nomineeLocation),
Field("approverEmail", OptionType(StringType), resolve = _.value.approverEmail),
Field("citation", OptionType(StringType), resolve = _.value.citation),
Field("businessJustification", OptionType(StringType), resolve = _.value.businessJustification),
Field("rating", OptionType(IntType), resolve = _.value.rating),
Field("votingStatus", OptionType(StringType), resolve = _.value.votingStatus),
Field("nominatedDate", OptionType(StringType), resolve = _.value.nominatedDate),
Field("approvedDate", OptionType(StringType), resolve = _.value.approvedDate)
)
)
Graphql Query:
Field(
"PanelNominationStatus",
ListType(PanelNominationStatusReportDataType),
description = Some("Returns the Employee Reward Report Data"),
arguments = companyIdType :: rewardNamesType :: startDateType :: endDateType :: Nil,
resolve = { c =>
c.ctx.getPanelStatusReport(c.arg(companyIdType), c.arg(startDateType), c.arg(endDateType), c.arg(rewardNamesType))
})
DataRepo:
def getPanelStatusReport(companyId: Int, startDate: Long, endDate: Long, rewardNames: Seq[String]): List[PanelRewardSatusDetail] = {
val redemptionReport = Await.result(reportsModel.findPanelRewardStatusDetailsReport(companyId, rewardNames, startDate, endDate), 20.seconds).toList
redemptionReport
}
And at last the model:
def findPanelRewardStatusDetailsReport(companyId: Int, rewardNames: Seq[String], startDate: Long, endDate: Long): Future[Seq[PanelRewardSatusDetail]] = {
val df = new SimpleDateFormat("dd-MM-yyyy")
val start = stringToDateTime(df.format(startDate * 1000L), None).toDateTime()
val end = stringToDateTime(df.format(endDate * 1000L), None).toDateTime()
val rewardFilter = if(rewardNames.nonEmpty) "AND vrrc.reward_name IN (" + rewardNames.map(a => "'" + a + "'").mkString(",") + ")" else ""
implicit val getOrdersResult = GetResult(r => PanelRewardSatusDetail(r.<<, r.<<, r.<<, r.<<, r.<<, r.<<, r.<<, r.<<, r.<<, r.<<, r.<<))
val q = sql"""select vrrc.reward_name, (select login from users where id=vrur.sender_id), (select login from users where id=vrur.receiver_ids), (select city_name from cities where id=(select city_id from users where id=vrur.receiver_ids)), (select login from users where id=approver_user_id), vrur.comment, vrur.business_justification, vrpa.rating, CASE WHEN vrpa.is_approved = 1 THEN 'VOTED' ELSE 'NOT VOTED' END, date(vrpa.created_at), date(vrpa.approved_at) from vr_panel_approval vrpa inner join vr_user_reward vrur on vrur.id=vrpa.user_reward_id inner join vr_reward_config vrrc on vrrc.id=vrur.reward_config_id where vrrc.company_id = $companyId and date(vrpa.created_at) between date($start) and date($end) #$rewardFilter"""
db.run(q.as[PanelRewardSatusDetail])
}
My request query:
{
"query": "query PanelNominationStatus($startDate: Long!, $endDate: Long!, $companyId: Int!, $rewardNames: [String!]!) { PanelNominationStatus( startDate: $startDate, endDate: $endDate, companyId: $companyId, rewardNames: $rewardNames ) { awardName nominatorEmail nomineeEmail nomineeLocation approverEmail citation businessJustification rating votingStatus nominatedDate approvedDate }}",
"operationName": "PanelNominationStatus",
"variables": {
"startDate": 1285891200,
"endDate": 1576108800,
"companyId": 355,
"rewardNames": ["PANEL AWARD FEBRUARY", "PANEL AWARD MARCH"]
}
}
I can make it possible using limit in the query and accepting it in the query but I need to send the total count of rows in the response as well. But I am not able to figure out where to make change in schema.
You just need to define another GraphQL type for your result which also contains the count,
val PanelNominationStatusResultType = ObjectType(
"PanelNominationStatusResult",
"Dashboard Reports",
fields[Unit, List[PanelRewardSatusDetail]](
Field(
"count",
IntType,
description = Some("count of nomination-status-reports in this response"),
resolve = _.value.length
),
Field(
"panelNominationStatusList",
ListType(PanelNominationStatusReportDataType),
description = Some("list of nomination-status-reports"),
resolve = _.value
)
)
)
Now, as for your query,
Field(
"panelNominationStatusResult",
PanelNominationStatusResultType,
description = Some("Returns the details of ............"),
arguments = companyIdType :: rewardNamesType :: startDateType :: endDateType :: Nil,
resolve = { c =>
c.ctx.getPanelStatusReport(c.arg(companyIdType), c.arg(startDateType), c.arg(endDateType), c.arg(rewardNamesType))
}
)
If you want the totalCount, then first of all you need to change your getPanelStatusReport method to also return the totalCount
def findPanelRewardStatusDetailsReport(
companyId: Int,
rewardNames: Seq[String],
startDate: Long,
endDate: Long
): Future[(Int, Seq[PanelRewardSatusDetail])] = ???
// updated result type
val PanelNominationStatusResultType = ObjectType(
"PanelNominationStatusResult",
"Dashboard Reports",
fields[Unit, (Int, List[PanelRewardSatusDetail])](
Field(
"totalCount",
IntType,
description = Some("total count of nomination-status-reports"),
resolve = _.value._1
),
Field(
"count",
IntType,
description = Some("count of nomination-status-reports in this response"),
resolve = _.value._2.length
),
Field(
"panelNominationStatusList",
ListType(PanelNominationStatusReportDataType),
description = Some("list of nomination-status-reports"),
resolve = _.value._2
)
)
)

How to add padding between regular button and actionButton in shinyApp?

I have 2 individual (differently styled) buttons in my shiny App that unfortunately have no vertical padding between them. One of them is a simple HTML button while the other is a shiny actionButton.
I have tried using tags$style but don't think I am using it correctly. My code for the relevant parts are
HTML('<button data-toggle="collapse" data-target="#addtools">Additional tools</button>'),
tags$div(id = 'addtools', class="collapse",
checkboxInput("cluster", "Cluster customers", value = TRUE),
checkboxInput("circle", "Add circles", value = FALSE),
conditionalPanel("input.circle",
selectInput("sizes", "Radius:",
c("5 miles" = "5",
"10 miles" = "10",
"20 miles" = "20"))
)
),
actionButton("runfilters", label = "Apply filters")
The entire UI part of this file is:
tabPanel("Map",
div(class="outer",
tags$head(
includeCSS("styles.css"),
includeScript("gomap.js")
),
leafletOutput(outputId = "map", width = "100%", height = "100%"),
absolutePanel(id = "controls", class = "panel panel-default", fixed = TRUE,
draggable = TRUE, top = 60, left = "auto", right = 20, bottom = "auto",
width = 330, height = "auto",
h2("Select your filters:"),
selectInput("level",
"Detail level:",
c("Customer level", "County level"),
selected = "County level"),
selectInput("mapstates","States:", c("All states"="",
structure(state.abb, names=state.name),
"Washington, DC"="DC"),
multiple = TRUE
),
conditionalPanel("input.mapstates",
selectInput("mapcounties", "Counties", c("All counties"=""),
multiple = TRUE
)
),
radioButtons("retailcorrection","Customer ownership:",
c("Private",
"Public"),
selected = "Private",
inline = TRUE),
conditionalPanel("input.level == 'Customer level'",
selectInput("var",
label = "Customer type:",
choices = c("ALL",
"ESSENTIAL",
"NON-ESSENTIAL"),
selected = "ALL"
),
radioButtons("custoporoh","Widget Category:",
c("Widget A",
"Widget B"),
selected = "Widget A",
inline = TRUE),
conditionalPanel("input.custoporoh == 'Widget A'",
numericInput("oprange",
label = "Minimum average monthly Widget A ordering (in dosage units):",
min = 0, max = 1000000, value = 0
),
numericInput("opprange",
label = "Minimum average monthly Widget A ordering as a percentage of total ordering:",
min = -1, max = 1, value = -1
)
),
conditionalPanel("input.custoporoh == 'Widget B'",
numericInput("ohrange","Minimum average monthly Widget B ordering (in dosage units):",
min = 0, max = 1000000, value = 0
),
numericInput("ohprange",
label = "Minimum average monthly Widget B ordering as a percentage of total ordering:",
min = -1, max = 1, value = -1
)
),
HTML('<button data-toggle="collapse" data-target="#addtools">Additional tools</button>'),
tags$div(id = 'addtools', class="collapse",
checkboxInput("cluster", "Cluster customers", value = TRUE),
checkboxInput("circle", "Add circles", value = FALSE),
conditionalPanel("input.circle",
selectInput("sizes", "Radius:",
c("5 miles" = "5",
"10 miles" = "10",
"20 miles" = "20"))
)
)
),
conditionalPanel("input.level == 'County level'",
selectInput("countyvar",
label = "Customer type:",
choices = c("ALL",
"ESSENTIAL"),
selected = "ALL"
),
selectInput("year", "Year:",
choices = c("2006","2007","2008","2009","2010","2011", "2012",
"2013","2014","2015","2016","2017","2018", "All years" = "2019"),
selected = "2019"
),
radioButtons("oporoh","Widget Category:",
c("Widget A",
"Widget B"),
selected = "Widget A",
inline = TRUE),
conditionalPanel("input.oporoh == 'Widget A'",
numericInput("opppcrange",
label = HTML("Minimum Widget A units per adult per month:"),
min = 0, max = 160, value = 0
),
numericInput("opcrange",
label = "Minimum average monthly Widget A ordering (in dosage units):",
min = 0, max = 10000000, value = 0
),
numericInput("oppcrange",
label = "Minimum average monthly Widget A ordering as a percentage of total ordering:",
min = -1, max = 1, value = -1
)
),
conditionalPanel("input.oporoh == 'Widget B'",
numericInput("ohppcrange",
label = "Minimum Widget B units per adult per month:",
min = 0, max = 160, value = 0
),
numericInput("ohcrange","Minimum average monthly Widget B ordering (in dosage units):",
min = 0, max = 10000000, value = 0
),
numericInput("ohpcrange",
label = "Minimum average monthly Widget B ordering as a percentage of total ordering:",
min = -1, max = 1, value = -1
)
)
),
actionButton("runfilters", label = "Apply filters")
)
)
)
I have tried to implement:
HTML('<button data-toggle="collapse" data-target="#addtools">Additional tools</button>'),
tags$div(id = 'addtools', class="collapse", tags$style = "padding=10px"
but that doesn't seem to be working. Any help would be appreciated.

MySql case statement error

When I use this code in a create view construct it returns empty result set.
I have tried using a column name after the case and removing the column name in the when lines...no change... any ideas. I have determined the issue is at the case statement by commenting it out and running it and it works fine then....
CREATE or REPLACE VIEW orderMSTRview
AS
SELECT SB.name "Brand", O.orderID "Order ID", O.orderRecID "Record ID", O.orderDate "Date Created",
O.salesRepName "Sales Rep Name", O.salesRepEmail "Sales Rep Email",
O.orderNumer "Order Number", O.orderType "Order Type",
CASE
when fulfillStatus = 0 then 'open'
when fulfillStatus = 1 then 'processing'
when fulfillStatus = 2 then 'complete'
when fulfillStatus = 5 then 'Shipped'
when fulfillStatus = 9 then 'void'
END as "Order Status" ,
IF(O.payStatus=0,'unpaid','paid') "Payment Status",
O.totalOrderQuantity "Total Order Quantity",
O.subtotalOrderValue "Subtotal Order Value",
O.totalOrderValue "Total Order Value", O.credit "Order Credit",
O.taxAmount "Tax Amount", O.shippingCost "Shipping Cost",
O.finalInvoiceValue "Invoice Amount", O.currency "Currency",
O.shipDate "Ship Date", O.cancelAfter "Cancel Date", O.terms "Terms",
O.buyerName "Buyer Name", O.buyerEmail "Buyer Email", O.buyerPhone "Buyer Phone", O.custCode1 "Customer Code1", O.custCode2 "Customer Code2",
O.custERP "Customer ERP", O.customerPO "Customer PO", O.custVat "VAT number",
O.billToName "Bill To Name", O.billToStreet1 "Bill To Address1" ,
O.billToStreet2 "Bill To Address2", O.billToCity "Bill To City",
O.billToState "Bill To State", O.billToZip "Bill To Zip code",
O.shipToName "Ship To Name", O.shipToStreet1 "Ship To Address1",
O.shipToStreet2 "Ship To Address2",
O.shipToCity "Ship To City", O.shipToState "Ship To State",
O.shipToZip "Ship To Zip code",
O.tagname1 "Tag 1", O.tagname2 "Tag 2", O.tagname3 "Tag 3"
FROM orders as O left join showroom_brand as SB on O.showroomID = SB.sid
WHERE O.orderDate >= '2015-01-01' and SB.name IS NOT NULL;
Do it like this example:
try to run this
set #fulfillStatus = 1;
select
CASE
when #fulfillStatus = 0 then 'open'
when #fulfillStatus = 1 then 'processing'
when #fulfillStatus = 2 then 'complete'
when #fulfillStatus = 5 then 'Shipped'
when #fulfillStatus = 9 then 'void'
else "None"
END as "Order Status"