📁 Docs
Script it

Script Tea stall

⚠️
We recommend finishing Tutorial: Task list to understand general usage before continuing here.

To create enterprise Tea stall, open terminal in the route studio by clicking the link https://web.neome.ai/studio (opens in a new tab).

Enterprise

The whole script to build the example below is available here. Open .neo files with a text editor of your choice, and copy and paste them into the terminal. Alternatively, walk the example below step by step.

Add an enterprise "Tea stall" by sending the commands below into the terminal.

// create enterprise
add enterprise name:"Your Tea stall"
update enterprise about:"Tea, Coffee, and Smiles delivered daily"
update enterprise timeZone:"Asia/Kolkata"
update enterprise displayDateFormat:"dd/MM/yyyy, HH:mm:ss"
update enterprise languages:"Hindi,English"

Backend

1. Variables

// add variable to store ₹ symbol
ensure variable VarTextRupeeSymbol kind:"Text"
update variable VarTextRupeeSymbol value:"₹"
 
// add variable to store today's date
ensure variable VarDateNow kind:"Date"
update variable VarDateNow value:"now"
 
// add variable to store tea and coffee pick list
ensure variable VarSetOfTextTime kind:"setOfText"
update variable VarSetOfTextTime value:"Morning,Afternoon"
 
// add a variable to store hyperlink to be displayed in report
ensure variable VarHyperlinkWebsite kind:"hyperlink"
update variable VarHyperlinkWebsite value:"https://neome.ai/" displayText:"Tea Stall"
update variable VarHyperlinkWebsite kind:"general"

2. Roles

ensure Role Owner
ensure Role Employee

3. Spreadsheets

a. OfficeMaster

• Create form
// create form FormOffice to provide structure to the spreadsheet OfficeMaster
 
ensure form FormOffice
update form FormOffice label:"Office"
ensure formPermission commentRoles:"Owner"
 
ensure section Details
 
ensure field Date type:"date"
update field Date defaultValue:"VarDateNow" required:"yes"
 
ensure field Name type:"text"
update field Name required:"yes"
 
ensure field OfficeNumber type:"text"
update field OfficeNumber required:"yes"
 
ensure field MobileNumber type:"mobileNumber"
update field MobileNumber required:"yes"
 
ensure field Active type:"bool"
 
ensure field Address type:"paragraph"
update field Address required:"yes"
 
ensure field TeaPrice type:"number"
update field TeaPrice prefix:"VarTextRupeeSymbol"
ensure field CoffeePrice type:"number"
update field CoffeePrice prefix:"VarTextRupeeSymbol"
• Associate form
// associate the form FormOffice with the spreadsheet OfficeMaster
 
ensure spreadsheet OfficeMaster form:"FormOffice"
 
ensure SpreadsheetPermission insertRoles:"Owner"
ensure SpreadsheetPermission updateRoles:"Owner"
ensure SpreadsheetPermission readRoles:"Owner"
ensure SpreadsheetPermission removeRoles:"Owner"
 
ensure SpreadsheetPermissionForwardRoles role:"Owner" roles:"Employee"
 
update spreadsheet OfficeMaster searchableFields:"Name,OfficeNumber,MobileNumber,Address,TeaPrice,CoffeePrice"
update spreadsheet OfficeMaster queryableFields:"Date,Name,Active,TeaPrice,CoffeePrice,MobileNumber"
• Associate list layout
// add a spreadsheet list layout
 
ensure spreadsheetLayout OfficeListLayoutForRef kind:"list"
 
// show search bar on top of the list
update spreadsheetLayout OfficeListLayoutForRef showSearchBar:"yes"
 
// list layout is composed of first line, second line and third line with first, middle and caption segments
update spreadsheetLayoutListItem line:"first" segment:"first" source:"field" text:"Name"
update spreadsheetLayoutListItem line:"first" segment:"caption" source:"field" text:"Date"
update spreadsheetLayoutListItem line:"second" segment:"first" source:"field" text:"MobileNumber"
update spreadsheetLayoutListItem line:"second" segment:"caption" source:"field" text:"OfficeNumber"
update spreadsheetLayoutListItem line:"third" segment:"first" source:"field" text:"TeaPrice, CoffeePrice" showLabels:"yes"
• Associate table layout
// add a spreadsheet table Layout
 
ensure spreadsheetLayout TableLayout kind:"table"
 
// showFields are the columns in the table
update spreadsheetLayout TableLayout showFields:"Date,Name,OfficeNumber,MobileNumber,Active,Address,TeaPrice,CoffeePrice"
update spreadsheetLayout TableLayout columnSizes:"AutoSize"
update spreadsheetLayout TableLayout showCommentCount:"yes"

b. OrderBook

• Create form
// add the form FormOrder to provide structure to the spreadsheet OrderBook
 
ensure form FormOrder
update form FormOrder label:"Order"
ensure formPermission commentRoles:"Employee"
 
ensure section Office
 
// To pick office add a "ref" field pointing to OfficeMaster spreadsheet
ensure Field OfficeRef type:"ref" spreadsheet:"OfficeMaster"
 
// copy fields from office to this section.
// $RowId points to the office in the OfficeMaster
// the office picker uses a spreadsheet layout OfficeListLayoutForRef
update field OfficeRef spreadsheetLayout:"OfficeListLayoutForRef"
update field OfficeRef copyFields:"$RowId,Name,OfficeNumber,MobileNumber,TeaPrice,CoffeePrice"
 
ensure Section Order
 
// add field date defaulting to now
ensure field Date type:"date"
update field Date defaultValue:"VarDateNow"
 
// add dropdown field with choices of delivery
ensure field Time type:"pickText"
update field Time source:"VarSetOfTextTime" defaultOption:"Morning"
 
// add fields to capture tea count, coffee count and signature
ensure field TeaCount type:"number"
update field TeaCount required:"yes" min:"0" max:"100"
 
ensure field CoffeeCount type:"number"
update field CoffeeCount required:"yes" min:"0" max:"100"
 
ensure field Signature type:"signature"
update field Signature required:"yes"
 
// add total field with a prefix and a formula to calculate total
ensure field Total type:"number"
update field Total prefix:"VarTextRupeeSymbol"
 
// f: is shortcut for field:
update field Total formula:"(${f:Office.TeaPrice} * ${f:Order.TeaCount}) + (${f:Office.CoffeePrice} * ${f:Order.CoffeeCount})"
• Associate form
// associate the form FormOrder with the spreadsheet OrderBook
 
ensure spreadsheet OrderBook form:"FormOrder"
update spreadsheet OrderBook searchableFields:"Name,OfficeNumber,TeaPrice,CoffeePrice,Time,Total,MobileNumber"
update spreadsheet OrderBook queryableFields:"Name,OfficeNumber,TeaPrice,CoffeePrice,Time,TeaCount,CoffeeCount,Total"
• Associate CRUD permissions
// spreadsheet crud permissions
 
ensure SpreadsheetPermission insertRoles:"Employee"
ensure SpreadsheetPermission updateRoles:"Owner"
ensure SpreadsheetPermission readRoles:"Owner"
ensure SpreadsheetPermission removeRoles:"Owner"
 
ensure SpreadsheetPermissionForwardRoles role:"Employee" roles:"Owner"

4. Reports

a. ReportInvoice

• Input form
// add input form for the report
 
ensure Form FormInvoiceFilter
 
ensure Section Details
 
// add dateRange field which allows the owner to select from and to dates
ensure field DateRange type:"dateRange"
update field DateRange fromDefaultVarId:"startOfMonth" toDefaultVarId:"endOfMonth"
update field DateRange required:"yes"
 
// to pick office add a "ref" field pointing to OfficeMaster spreadsheet
ensure field OfficeRef type:"ref" spreadsheet:"OfficeMaster"
 
// copy fields from office to this section.
// $RowId points to the office in the OfficeMaster
// the office picker uses a spreadsheet layout OfficeListLayoutForRef
update field OfficeRef copyFields:"$RowId,Name"
update field OfficeRef spreadsheetLayout:"OfficeListLayoutForRef"
• Output form
// add output form for the report
 
ensure Form FormInvoice
 
//** section details
 
ensure Section Details
 
// add field DateRange to capture date range for invoice
ensure Field DateRange type:"dateRange"
 
ensure Field InvoiceDate type:"date"
update Field InvoiceDate defaultValue:"now"
 
ensure Field OfficeTeaPrice type:"number"
update Field OfficeTeaPrice prefix:"VarTextRupeeSymbol"
 
ensure Field OfficeCoffeePrice type:"number"
update Field OfficeCoffeePrice prefix:"VarTextRupeeSymbol"
 
ensure Field OfficeName type:"text"
ensure Field OfficeNo type:"text"
ensure Field Mobile type:"mobileNumber"
 
//** grid Items
 
ensure Grid Items
 
update grid Items indexFieldName:"Index"
 
ensure Field Date type:"date"
 
ensure Field Time type:"pickText"
update Field Time source:"VarSetOfTextTime" defaultOption:"Morning"
 
ensure Field TotalTea type:"number"
ensure Field TotalCoffee type:"number"
 
ensure Field TeaPrice type:"number"
update Field TeaPrice prefix:"VarTextRupeeSymbol"
 
ensure Field TotalPrice type:"number"
update Field TotalPrice prefix:"VarTextRupeeSymbol"
 
// f: is shortcut for field:
update field TotalPrice formula:"(${f:Items.TotalTea} * ${f:Items.TeaPrice}) + (${f:Items.TotalCoffee} * ${f:Items.CoffeePrice})"
 
ensure Field CoffeePrice type:"number"
update Field CoffeePrice prefix:"VarTextRupeeSymbol"
 
// attach table layout to grid Items
 
ensure gridLayout ItemsTableLayout kind:"table"
 
update gridLayout ItemsTableLayout showFields:"Date,Time,TotalTea,TotalCoffee,TotalPrice"
update gridLayout ItemsTableLayout columnSizes:"AutoSize"
 
//** section Summary
 
ensure Section Summary
 
// add total bill field with a prefix and a formula to calculate the total bill
ensure Field TotalBill type:"number"
update Field TotalBill prefix:"VarTextRupeeSymbol"
update field TotalBill formula:"SUM(${f:Items.TotalPrice})"
 
// add GST field with a formula to calculate the GST
ensure Field GST type:"number"
update field GST formula:"${f:Summary.TotalBill} * 0.18"
 
// add Grand total field with a formula to calculate the grand total
ensure Field GrandTotal type:"number"
update field GrandTotal formula:"${f:Summary.TotalBill} + ${f:Summary.GST}"
update Field GrandTotal prefix:"VarTextRupeeSymbol"
 
// add dropdown PaymentStatus with choices of payment status
ensure field PaymentStatus type:"pickText"
update field PaymentStatus source:"Unpaid,Paid" defaultOption:"Unpaid"
 
// add information field for message on invoice
ensure field PaymentQR type:"showCode"
update field PaymentQR label:"Payment QR" codeType:"qrCode" defaultValue:"Thanks for purchase!" showLabel:"yes"
• Output preview
// add chat pattern to the report to provide link preview on WhatsApp
 
update form FormInvoice chatPattern:"Hello ${p1}, Total order invoice: ₹${p2}, Dated ${p3}."
ensure formProp prop:"chatPattern" param:"p1" value:"OfficeName" binder:"field"
ensure formProp prop:"chatPattern" param:"p2" value:"GrandTotal" binder:"field"
ensure formProp prop:"chatPattern" param:"p3" value:"InvoiceDate" binder:"field"

FormLayout = (Header | InvoiceLayout | Footer)(Watermark)

• Output layout header
// add form layout header
 
update formLayoutHeader showEnterprise:"yes"
update formLayoutHeader hyperlinkVars:"VarHyperlinkWebsite"
update formLayoutHeader formNamePattern:"Invoice"
update formLayoutHeader formNameFont:"h4"
update formLayoutHeader formNamePosition:"center"
• Output layout footer
// add form layout footer
 
update formLayoutFooter showSeparator:"yes" backgroundColor:"primary" foregroundColor:"white"
update formLayoutFooter line:"first" label:"first" textPattern:"+919999999999"
update formLayoutFooter line:"first" label:"second" textPattern:"GSTIN 27AABCU9600R1Z5"
update formLayoutFooter line:"first" label:"third" textPattern:"info@teastall.com"
• Output layout watermark
// add form layout watermark
 
update formLayoutWatermark textPattern:"Tea stall"
update formLayoutWatermark textFont:"h1"
update formLayoutWatermark textPosition:"diagonal"
update formLayoutWatermark textOpacity:"0.05"
• Output layout content
// add InvoiceLayout, a composite form content layout
 
// => OfficeInfoMain = OfficeInfo1 + OfficeInfo2
// => OrderTableLayout
// => SummaryInfoMain = SummaryInfo1 + SummaryInfo2
// => InvoiceLayout = OfficeInfoMain | OrderTableLayout | SummaryInfoMain
 
// create OfficeInfoMain layout
 
ensure formLayoutContent OfficeInfo1
update formLayoutContent OfficeInfo1 direction:"Vertical"
update formLayoutContent OfficeInfo1 position:"start" fields:"OfficeName,OfficeNo,Mobile"
 
ensure formLayoutContent OfficeInfo2
update formLayoutContent OfficeInfo2 direction:"Vertical"
update formLayoutContent OfficeInfo2 position:"start" fields:"DateRange,InvoiceDate,OfficeTeaPrice,OfficeCoffeePrice"
 
ensure formLayoutContent OfficeInfoMain
update formLayoutContent OfficeInfoMain direction:"Horizontal"
update formLayoutContent OfficeInfoMain showBorders:"top,bottom"
update formLayoutContent OfficeInfoMain showPaddings:"top,bottom" contentPadding:"thick"
update formLayoutContent OfficeInfoMain position:"start" contentLayouts:"OfficeInfo1,OfficeInfo2"
 
// create SummaryLayout layout
 
ensure formLayoutContent SummaryInfo1
update formLayoutContent SummaryInfo1 direction:"Vertical"
update formLayoutContent SummaryInfo1 position:"start" fields:"PaymentQR"
 
ensure formLayoutContent SummaryInfo2
update formLayoutContent SummaryInfo2 direction:"Vertical"
update formLayoutContent SummaryInfo2 position:"start" fields:"TotalBill,GST,GrandTotal,PaymentStatus"
 
ensure formLayoutContent SummaryInfoMain
update formLayoutContent SummaryInfoMain direction:"Horizontal"
update formLayoutContent SummaryInfoMain showBorders:"top"
update formLayoutContent SummaryInfoMain showPaddings:"top,bottom" contentPadding:"thick"
update formLayoutContent SummaryInfoMain position:"start" contentLayouts:"SummaryInfo1,SummaryInfo2"
 
// create InvoiceLayout
 
ensure formLayoutContent InvoiceLayout
 
update formLayoutContent InvoiceLayout direction:"Vertical"
 
update formLayoutContent InvoiceLayout position:"start" contentLayouts:"OfficeInfoMain"
 
update formLayoutContent InvoiceLayout position:"flexCenter" gridLayouts:"Items.ItemsTableLayout"
update formLayoutContent InvoiceLayout position:"flexCenter" showItemPadding:"top,bottom" padding:"thick"
 
update formLayoutContent InvoiceLayout position:"end" contentLayouts:"SummaryInfoMain"
neoQL is a SQL like query language to query and join spreadsheets. In neoQL only SELECT clauses are allowed. Within the select query string, $... syntax allows embedding of input, output, and context fields.

To write complex neoQL use the studio editor.

*neoQL grammar and available context fields are explained in the reference manual.
• Query office info
// add report ReportInvoiceSection to get office information
 
ensure Report ReportInvoiceSection kind:"query"
 
update Report ReportInvoiceSection inputForm:"FormInvoiceFilter"
update Report ReportInvoiceSection outputForm:"FormInvoice"
update Report ReportInvoiceSection fromSpreadsheets:"OfficeMaster"
update Report ReportInvoiceSection neoQL:"select\n{ 'from' : ${in:Details.DateRange.from}, 'to' : ${in:Details.DateRange.to} } as ${out:Details.DateRange},\n${spreadsheet:s1.Details.Name} as ${output:Details.OfficeName},\n${spreadsheet:s1.Details.OfficeNumber} as ${output:Details.OfficeNo},\n${spreadsheet:s1.Details.MobileNumber} as ${output:Details.Mobile},\n${spreadsheet:s1.Details.TeaPrice} as ${output:Details.OfficeTeaPrice},\n${spreadsheet:s1.Details.CoffeePrice} as ${output:Details.OfficeCoffeePrice},\nMILLIS(CLOCK_LOCAL()) as ${out:Details.InvoiceDate}\nfrom ${spreadsheet}\n where ${context:row.type} = ${spreadsheet:s1} and \n${context:row.id} = ${input:Details.OfficeMasterRowId}"
• Query order info
// add report ReportInvoiceGrid to get order table for the office
 
ensure Report ReportInvoiceGrid kind:"query"
 
// add neoQl to retrieve order data.
update Report ReportInvoiceGrid inputForm:"FormInvoiceFilter"
update Report ReportInvoiceGrid outputForm:"FormInvoice"
update Report ReportInvoiceGrid fromSpreadsheets:"OrderBook"
update report ReportInvoiceGrid neoQL:"select\n${spreadsheet:s2.Order.Date} as ${output:Items.Date},\n${spreadsheet:s2.Order.Time} as ${output:Items.Time},\n${spreadsheet:s2.Order.TeaCount} as ${output:Items.TotalTea},\n${spreadsheet:s2.Order.CoffeeCount} as ${output:Items.TotalCoffee},\n${spreadsheet:s2.Order.Total} as ${output:Items.TotalPrice},\n${spreadsheet:s2.Office.TeaPrice} as ${output:Items.TeaPrice},\n${spreadsheet:s2.Office.CoffeePrice} as ${output:Items.CoffeePrice}\nfrom ${spreadsheet}\nwhere ${context:row.type} = ${spreadsheet:s2}\nand ${spreadsheet:s2.Order.Date} >= ${input:Details.DateRange.from}\nand ${spreadsheet:s2.Order.Date} <= ${in:Details.DateRange.to}\n and ${ss:s2.Office.OfficeMasterRowId} = ${in:Details.OfficeMasterRowId}"
• Composite report
// create composite report ReportInvoice by merging ReportInvoiceSection and ReportInvoiceGrid
 
ensure Report ReportInvoice kind:"composite"
update report ReportInvoice inputForm:"FormInvoiceFilter"
update report ReportInvoice outputForm:"FormInvoice"
update Report ReportInvoice mergeReports:"ReportInvoiceSection,ReportInvoiceGrid"
• Mapper report

To prevent computation of the composite report on every invocation create a mapper report and save the composite report in a spreadsheet with input form as the key.

ensure spreadsheet InvoiceSheet form:"FormInvoice"
update spreadsheet InvoiceSheet searchableFields:"OfficeName,OfficeNo,Mobile"
ensure SpreadsheetPermission updateRoles:"Owner"
ensure SpreadsheetPermission readRoles:"Owner"
ensure SpreadsheetPermission removeRoles:"Owner"
// create a mapper report to save the computed invoice in a spreadsheet
ensure Report ReportInvoiceWrapper kind:"mapper"
update Report ReportInvoiceWrapper description:"Prevents computing report invoice again for the same invoice filter"
update Report ReportInvoiceWrapper inputForm:"FormInvoiceFilter"
update Report ReportInvoiceWrapper outputForm:"FormInvoice"
update Report ReportInvoiceWrapper mappedReport:"ReportInvoice"
update Report ReportInvoiceWrapper saveToSpreadsheet:"InvoiceSheet"

b. ReportAggregated

• Input form
// add input form for the report
 
ensure Form FormAggregatedFilter
ensure Section Details
 
ensure field DateRange type:"dateRange"
update field DateRange fromDefaultVarId:"startOfMonth" toDefaultVarId:"endOfMonth"
update field DateRange required:"yes"
• Output form
// add output form for the report
 
ensure Form FormAggregated
 
//** grid SalesByCustomer
 
ensure Grid SalesByCustomer
update Grid SalesByCustomer indexFieldName:"Index"
 
ensure Field Name type:"text"
ensure Field TotalTea type:"number"
ensure Field TotalCoffee type:"number"
ensure Field TotalPrice type:"number"
 
ensure gridLayout TableLayout kind:"table"
update gridLayout TableLayout showFields:"Name,TotalCoffee,TotalTea,TotalPrice"
update gridLayout TableLayout columnSizes:"AutoSize"
 
//** section Summary
 
ensure Section Summary
 
ensure Field TotalSales type:"number"
update Field TotalSales formula:"SUM(${field:SalesByCustomer.TotalPrice})"
update Field TotalSales prefix:"VarTextRupeeSymbol"
 
ensure Field TotalCoffee type:"number"
update Field TotalCoffee formula:"SUM(${f:SalesByCustomer.TotalCoffee})"
 
ensure Field TotalTea type:"number"
update Field TotalTea formula:"SUM(${f:SalesByCustomer.TotalTea})"
 
ensure Field Date type:"date"
update Field Date defaultValue:"VarDateNow"
 
ensure Field DateRange type:"dateRange"
• Output preview
// add chat pattern to the report to provide link preview on WhatsApp
 
update form FormAggregated chatPattern:"Hello ${p1}, Aggregated order amount: ₹${p2}, Dated ${p3}."
ensure formProp prop:"chatPattern" param:"p1" value:"ent.name" binder:"context"
ensure formProp prop:"chatPattern" param:"p2" value:"TotalSales" binder:"field"
ensure formProp prop:"chatPattern" param:"p3" value:"Date" binder:"field"
• Output layout
update formLayoutHeader showEnterprise:"yes" hyperlinkVars:"VarHyperlinkWebsite"
 
ensure formLayoutContent ContentLayout
update formLayoutContent ContentLayout direction:"vertical"
 
update formLayoutContent ContentLayout position:"start" fields:"Date,DateRange"
update formLayoutContent ContentLayout position:"start" showItemBorders:"top,bottom"
update formLayoutContent ContentLayout position:"start" showItemPadding:"top,bottom" padding:"thick"
 
update formLayoutContent ContentLayout position:"flexCenter" gridLayouts:"SalesByCustomer.TableLayout"
update formLayoutContent ContentLayout position:"flexCenter" showItemPadding:"top" padding:"thick"
 
update formLayoutContent ContentLayout position:"end" fields:"TotalTea,TotalCoffee,TotalSales"
update formLayoutContent ContentLayout position:"end" showItemBorders:"top"
update formLayoutContent ContentLayout position:"end" showItemPadding:"top,bottom" padding:"thick"
• Queries
// add query for capturing input date range
ensure Report ReportAggregatedSummary kind:"query"
update Report ReportAggregatedSummary inputForm:"FormAggregatedFilter"
update Report ReportAggregatedSummary outputForm:"FormAggregated"
update Report ReportAggregatedSummary fromSpreadsheets:"OrderBook"
update report ReportAggregatedSummary neoQL:"select\n{ 'from' : ${in:Details.DateRange.from}, 'to' : ${in:Details.DateRange.to} } as ${out:Summary.DateRange},\nMILLIS(CLOCK_LOCAL()) as ${out:Summary.Date}\nfrom ${spreadsheet}\nwhere ${context:row.type} = ${spreadsheet:s2}\nand ${spreadsheet:s2.Order.Date} >= ${input:Details.DateRange.from}\nand ${spreadsheet:s2.Order.Date} <= ${in:Details.DateRange.to}\ngroup by\n${spreadsheet:s2.Office.Name}"
 
// add report to generate order query during a month
ensure Report ReportAggregatedSalesByCustomer kind:"query"
update Report ReportAggregatedSalesByCustomer inputForm:"FormAggregatedFilter"
update Report ReportAggregatedSalesByCustomer outputForm:"FormAggregated"
update Report ReportAggregatedSalesByCustomer fromSpreadsheets:"OrderBook"
update report ReportAggregatedSalesByCustomer neoQL:"select\n${spreadsheet:s2.Office.Name} as ${output:SalesByCustomer.Name},\nsum(${spreadsheet:s2.Order.TeaCount}) as ${output:SalesByCustomer.TotalTea},\nsum(${spreadsheet:s2.Order.CoffeeCount}) as ${output:SalesByCustomer.TotalCoffee},\nsum(${spreadsheet:s2.Order.Total}) as ${output:SalesByCustomer.TotalPrice}\nfrom ${spreadsheet}\nwhere ${context:row.type} = ${spreadsheet:s2}\nand ${spreadsheet:s2.Order.Date} >= ${input:Details.DateRange.from}\nand ${spreadsheet:s2.Order.Date} <= ${in:Details.DateRange.to}\ngroup by\n${spreadsheet:s2.Office.Name}"
• Composite report
// add Aggregated order report
ensure Report ReportAggregated kind:"Composite"
update Report ReportAggregated inputForm:"FormAggregatedFilter"
update Report ReportAggregated outputForm:"FormAggregated"
update Report ReportAggregated mergeReports:"ReportAggregatedSummary,ReportAggregatedSalesByCustomer"

c. Dashboard

• Variables
ensure variable VarFunctionGetMonthName kind:"function"
update variable VarFunctionGetMonthName inputArgs:"MonthInNumber:number" outputKind:"text"
update variable VarFunctionGetMonthName javascript:"const monthNames = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']; \n\nreturn monthNames[MonthInNumber - 1];"
 
ensure variable VarColorRed kind:"color"
update variable VarColorRed value:"red"
 
ensure variable VarColorBlue kind:"color"
update variable VarColorBlue value:"blue"
 
ensure variable VarColorGreen kind:"color"
update variable VarColorGreen value:"green"
• Output form
// Dashboard output form
 
ensure form FormDashboard
 
//** grid PrevMonthOrderSet
 
ensure grid PrevMonthOrderSet
 
ensure field Date type:"date"
ensure field TotalSales type:"number"
ensure field MonthInNumber type:"number"
ensure field TotalTea type:"number"
ensure field TotalCoffee type:"number"
 
ensure field Month type:"text"
update field Month formula:"VarFunctionGetMonthName(${f:PrevMonthOrderSet.MonthInNumber})"
 
ensure gridLayout LineChart kind:"xyChart"
update gridLayout LineChart chartType:"lineChart"
update gridLayout LineChart xField:"Month"
update gridLayout LineChart yFields:"TotalSales" yFieldColors:"VarColorRed"
 
ensure gridLayout BarGraph kind:"xyChart"
update gridLayout BarGraph chartType:"BarGraph"
update gridLayout BarGraph xField:"Month"
update gridLayout BarGraph yFields:"TotalTea,TotalCoffee" yFieldColors:"VarColorBlue,VarColorGreen"
 
//** grid TopCustomerSet
 
ensure grid TopCustomerSet
update grid TopCustomerSet indexFieldName:"Index"
 
ensure field Name type:"text"
ensure field Total type:"number"
 
ensure gridLayout TableLayout kind:"table"
update gridLayout TableLayout showFields:"Name,Total"
update gridLayout TableLayout columnSizes:"AutoSize"
• Output layout
update formLayoutHeader showEnterprise:"yes"
update formLayoutHeader hyperlinkVars:"VarHyperlinkWebsite"
update formLayoutHeader formNamePattern:"Analytics Dashboard"
update formLayoutHeader formNameFont:"h4"
update formLayoutHeader formNamePosition:"center"
 
ensure formLayoutContent Layout1
update formLayoutContent Layout1 direction:"Vertical"
update formLayoutContent Layout1 displayLabel:"Previous Month Sale"
update formLayoutContent Layout1 showPaddings:"top,bottom" contentPadding:"thin"
update formLayoutContent Layout1 position:"flexCenter" gridLayouts:"PrevMonthOrderSet.LineChart"
 
ensure formLayoutContent Layout2
update formLayoutContent Layout2 direction:"Vertical"
update formLayoutContent Layout2 displayLabel:"Total Tea vs Total Coffee"
update formLayoutContent Layout2 showPaddings:"top,bottom" contentPadding:"thin"
update formLayoutContent Layout2 position:"flexCenter" gridLayouts:"PrevMonthOrderSet.BarGraph"
 
ensure formLayoutContent Layout3
update formLayoutContent Layout3 direction:"Vertical"
update formLayoutContent Layout3 displayLabel:"Top 5 Customers"
update formLayoutContent Layout3 showPaddings:"top,bottom" contentPadding:"thin"
update formLayoutContent Layout3 position:"flexCenter" gridLayouts:"TopCustomerSet.TableLayout"
 
ensure formLayoutContent DashboardLayout
update formLayoutContent DashboardLayout direction:"Vertical"
update formLayoutContent DashboardLayout position:"flexCenter" contentLayouts:"Layout1,Layout2,Layout3"
• Queries
ensure report DashboardPrevMonthOrderSet kind:"query"
update report DashboardPrevMonthOrderSet outputForm:"FormDashboard"
update report DashboardPrevMonthOrderSet fromSpreadsheets:"OrderBook"
update report DashboardPrevMonthOrderSet neoQL:"select\n${ss:s2.Order.Date} as ${out:PrevMonthOrderSet.Date},\n${ss:s2.Order.Total} as ${out:PrevMonthOrderSet.TotalSales},\n${ss:s2.Order.TeaCount} as ${out:PrevMonthOrderSet.TotalTea},\n${ss:s2.Order.CoffeeCount} as ${out:PrevMonthOrderSet.TotalCoffee},\nDATE_PART_MILLIS(${ss:s2.Order.Date}, 'month') as ${out:PrevMonthOrderSet.MonthInNumber}\nFROM ${ss}\nwhere ${ctx:row.type} = ${ss:s2}\nORDER BY ${ss:s2.Order.Date} ASC;"
 
ensure report DashboardTopCustomerSet kind:"query"
update report DashboardTopCustomerSet outputForm:"FormDashboard"
update report DashboardTopCustomerSet fromSpreadsheets:"OrderBook"
update report DashboardTopCustomerSet neoQL:"select\n${ss:s2.Office.Name} as ${out:TopCustomerSet.Name},\nsum(${ss:s2.Order.Total}) as ${out:TopCustomerSet.Total}\nfrom ${ss}\nwhere ${ctx:row.type} = ${ss:s2}\ngroup by\n${ss:s2.Office.Name}\norder by sum(${ss:s2.Order.Total}) DESC\nLIMIT 5"
• Composite report
ensure report Dashboard kind:"Composite"
update report Dashboard outputForm:"FormDashboard"
update report Dashboard mergeReports:"DashboardPrevMonthOrderSet,DashboardTopCustomerSet"

d. ReportActiveOffice

• Output form
ensure Form FormOfficeActiveSet
 
ensure Grid OfficeSet
 
ensure field OfficeRowId type:"rowId"
ensure field Date type:"date"
ensure field OfficeName type:"text"
ensure field OfficeNumber type:"text"
ensure field MobileNumber type:"mobileNumber"
ensure field Address type:"paragraph"
ensure field TeaPrice type:"number"
ensure field CoffeePrice type:"number"
 
ensure gridLayout TableLayout kind:"table"
 
update gridLayout TableLayout showFields:"Date,OfficeName,OfficeNumber,MobileNumber,Address"
update gridLayout TableLayout columnSizes:"AutoSize"
• Output layout
ensure formLayoutContent ContentLayout
update formLayoutContent ContentLayout direction:"Vertical"
update formLayoutContent ContentLayout position:"flexCenter" gridLayouts:"OfficeSet.TableLayout"
• Queries
ensure variable VarMappingActiveOffice kind:"mapping"
update variable VarMappingActiveOffice fromForm:"FormOffice" toForm:"FormOfficeActiveSet" toGrid:"OfficeSet"
ensure VariableMappingField fromField:"Date" to:"Date"
ensure VariableMappingField fromField:"Name" to:"OfficeName"
ensure VariableMappingField fromField:"OfficeNumber" to:"OfficeNumber"
ensure VariableMappingField fromField:"MobileNumber" to:"MobileNumber"
ensure VariableMappingField fromField:"Address" to:"Address"
ensure VariableMappingField fromField:"TeaPrice" to:"TeaPrice"
ensure VariableMappingField fromField:"CoffeePrice" to:"CoffeePrice"
ensure VariableMappingField fromField:"SysRowId" to:"OfficeRowId"
 
ensure variable VarConditionActiveOffice kind:"condition"
update variable VarConditionActiveOffice sourceForm:"FormOffice"
update variable VarConditionActiveOffice condition:"field:Active == Derived:Active.True"
ensure report ReportActiveOffice kind:"spreadsheet"
 
update report ReportActiveOffice fromSpreadsheet:"OfficeMaster"
update report ReportActiveOffice outputForm:"FormOfficeActiveSet" outputFormMapping:"VarMappingActiveOffice"
update report ReportActiveOffice filterCondition:"VarConditionActiveOffice"

Frontend

1. Actions

a. AddOffice

ensure Action AddOffice kind:"rowInsert"
 
update Action AddOffice spreadsheet:"OfficeMaster"
update Action AddOffice icon:"PersonAddAlt1Rounded"
update Action AddOffice sendMessageToInbox:"yes"
 
// provide default values to the OfficeMaster>FormOffice
ensure actionFormDefaultValue field:"Active" value:"yes"
ensure actionFormDefaultValue field:"TeaPrice" value:"10"
ensure actionFormDefaultValue field:"CoffeePrice" value:"15"

b. OfficeMaster

ensure Action OfficeMaster kind:"spreadsheetEditor"
 
update Action OfficeMaster spreadsheet:"OfficeMaster"
update Action OfficeMaster icon:"EditNoteRounded"
update Action OfficeMaster spreadsheetLayout:"TableLayout"

c. AddOrder

ensure Action AddOrder kind:"rowInsert"
 
update Action AddOrder spreadsheet:"OrderBook"
update Action AddOrder icon:"AddShoppingCartRounded"
update Action AddOrder sendMessageToInbox:"yes"

d. GetInvoice

ensure Action GetInvoice kind:"report"
 
update Action GetInvoice report:"ReportInvoiceWrapper"
update Action GetInvoice outputFormContentLayout:"InvoiceLayout"
update Action GetInvoice icon:"ListAltRounded"
update Action GetInvoice sendMessageToInbox:"yes"

e. ReportAggregated

ensure Action ReportAggregated kind:"report"
 
update Action ReportAggregated report:"ReportAggregated"
update Action ReportAggregated outputFormContentLayout:"ContentLayout"
update Action ReportAggregated icon:"ListAltRounded"
update Action ReportAggregated sendMessageToInbox:"yes"

f. Dashboard

ensure action Dashboard kind:"report"
 
update action Dashboard report:"Dashboard"
update action Dashboard outputFormContentLayout:"DashboardLayout"
update action Dashboard icon:"AnalyticsRounded"

g. GetActiveOfficeReport

ensure action GetActiveOfficeReport kind:"report"
 
update action GetActiveOfficeReport report:"ReportActiveOffice"
update action GetActiveOfficeReport outputFormContentLayout:"ContentLayout"
update action GetActiveOfficeReport icon:"FormatListBulletedRounded"

2. Groups

a. Add groups

ensure Group OfficeMaster
ensure Group OrderBook
ensure Group Reporting

b. Associate actions

goto group OfficeMaster
update group OfficeMaster allowPromptAssistant:"yes"
ensure groupAction action:"AddOffice" roles:"Owner" deviceSizes:"mobile,desktop"
ensure groupAction action:"OfficeMaster" roles:"Owner" deviceSizes:"mobile,desktop"
update group OfficeMaster pinnedActions:"AddOffice,OfficeMaster"
update group OfficeMaster pinnedActionsMobile:"AddOffice,OfficeMaster"
 
goto group OrderBook
ensure groupAction action:"AddOrder" roles:"Employee" notAllowedRoles:"Owner" deviceSizes:"mobile,desktop"
update group OrderBook pinnedActions:"AddOrder"
update group OrderBook pinnedActionsMobile:"AddOrder"
 
goto group Reporting
ensure groupAction action:"ReportAggregated" roles:"Owner" deviceSizes:"mobile,desktop"
ensure groupAction action:"GetInvoice" roles:"Owner" deviceSizes:"mobile,desktop"
ensure groupAction action:"Dashboard" roles:"Owner" deviceSizes:"mobile,desktop"
ensure groupAction action:"GetActiveOfficeReport" roles:"Owner" deviceSizes:"mobile,desktop"
update group Reporting pinnedActions:"GetInvoice,ReportAggregated,Dashboard"
update group Reporting pinnedActionsMobile:"Dashboard"

3. Deeplinks

a. ReportAggregated

// share monthly order report on Whatsapp via deeplink MonthlyOrderReport
ensure deeplink DlAggregatedOrderReport kind:"report"
update deeplink DlAggregatedOrderReport report:"ReportAggregated" outputFormContentLayout:"ContentLayout"
update deeplink DlAggregatedOrderReport visibilityConstraint:"allowPublicSharing"
update deeplink DlAggregatedOrderReport creationRoles:"Owner"
update deeplink DlAggregatedOrderReport showEnterprisePreviewImage:"yes"
update deeplink DlAggregatedOrderReport expiry:"noExpiry"

b. ReportInvoice

// share month end invoice to the office via deeplink ReportInvoice
ensure deeplink DlOfficeInvoice kind:"report"
update deeplink DlOfficeInvoice report:"ReportInvoiceWrapper" outputFormContentLayout:"InvoiceLayout"
update deeplink DlOfficeInvoice visibilityConstraint:"allowPublicSharing"
update deeplink DlOfficeInvoice creationRoles:"Owner"
update deeplink DlOfficeInvoice showEnterprisePreviewImage:"yes"
update deeplink DlOfficeInvoice expiry:"noExpiry"

c. OrderForm

// share order form to offices for them to order tea or coffee
ensure deeplink DlFormOrder kind:"spreadsheetRow"
update deeplink DlFormOrder spreadsheet:"OrderBook"
update deeplink DlFormOrder visibilityConstraint:"allowPublicSharing"
update deeplink DlFormOrder creationRoles:"Employee"
update deeplink DlFormOrder showHeader:"yes"
update deeplink DlFormOrder showEnterprise:"yes"
update deeplink DlFormOrder showSeparator:"yes"
update deeplink DlFormOrder showEnterprisePreviewImage:"yes"
update deeplink DlFormOrder expiry:"noExpiry"

4. Prompt

a. AddOffice

ensure prompt PromptAddOffice
update prompt PromptAddOffice action:"AddOffice"
update prompt PromptAddOffice permissionRoles:"Owner"
update prompt PromptAddOffice promptText:"Add Office Name:${f:Name}, OfficeNumber:${f:OfficeNumber}, MobileNumber:${f:MobileNumber}, Active:${f:Active}, Address:${f:Address}, TeaPrice:${f:TeaPrice}, CoffeePrice:${f:CoffeePrice}"
update prompt PromptAddOffice reviewBeforeExecuting:"yes"

b. AddOrder

ensure prompt PromptAddOrder1
update prompt PromptAddOrder1 action:"AddOrder"
update prompt PromptAddOrder1 permissionRoles:"Employee"
update prompt PromptAddOrder1 promptText:"o, ${f:OfficeNumber}, ${f:TeaCount}, ${f:CoffeeCount}"
ensure prompt PromptAddOrder2
update prompt PromptAddOrder2 action:"AddOrder"
update prompt PromptAddOrder2 permissionRoles:"Employee"
update prompt PromptAddOrder2 promptText:"o, ${f:Name}, ${f:TeaCount}, ${f:CoffeeCount}"

Deploy

// Deploy the enterprise
deploy enterprise

Try your creation

To add users to enterprise application Tea stall through a UI,

  1. Open the route production by clicking the link https://web.neome.ai/production (opens in a new tab).
  2. Add users and give them the roles.

Alternatively, you can add users by executing the following scripts in the route terminal (opens in a new tab).

a. Try for yourself

ensureSelf user roles:"Owner,Employee"

b. Try for others

add user name:"SomeOwner" handle:"owner@yourcompany.com" roles:"Owner"
add user name:"SomeDeliveryBoy1" handle:"deliveryboy1@yourcompany.com" roles:"Employee"
add user name:"SomeDeliveryBoy2" handle:"deliveryboy2@yourcompany.com" roles:"Employee"
add user name:"SomeDeliveryBoy3" handle:"deliveryboy3@yourcompany.com" roles:"Employee"
 
inviteAll users