Invoice center
Set Backend
1. Invoice variables
a. Sequence variable
// variable sequence
ensure var VarInvoiceSeq kind: sequence deploy: fixedOnDeploy value: 1
b. InvoiceId pattern variable
// pattern variable for invoice id identifier
ensure var VarTextPatternFormInvoiceLinkInvoiceId kind: text
deploy: fixedOnDeploy
value: "INV-${p}"
paramSet: ["p"]
c. Rupee symbol variable
// pattern variable for rupee symbol
ensure var VarTextRupeeSymbol kind: text deploy: fixedOnDeploy value: "₹"
2. InvoiceHistory spreadsheet
// this spreadsheet stores the invoice informaion for a customer
ensure spreadsheet: InvoiceHistory
withFields: [InvoiceId, DateRange, InvoiceDate, TeaPrice, CoffeePrice, OfficeRowId, OfficeName, OfficeNo, Mobile]
ofTypes: [identifier, dateRange, date, number, number, rowId, text, text, mobileNumber]
readRoleSet: [Owner]
removeRoleSet: [Owner]
updateRoleSet: [Owner]
3. Decorate spreadsheet
// update the properties of the fields in InvoiceHistory
ensure form FormInvoiceHistory
allowToPrintForm: true
ctx rename OutputInvoice
ensure section: Details
ensure field InvoiceId
setOnSend: true
textPatternVar: {
'var': 'VarTextPatternFormInvoiceLinkInvoiceId',
'paramSet': [
'${var:VarInvoiceSeq}'
]
}
ensure field InvoiceDate defaultValue: "now"
ensure field TeaPrice
prefixVar: {
'var': 'VarTextRupeeSymbol'
}
ensure field CoffeePrice
prefixVar: {
'var': 'VarTextRupeeSymbol'
}
ensure grid: Items
ensure field Date kind: date
ensure field Time kind: pickText
sourceVar: VarSetOfTextTime
ensure field TotalTea kind: number
ensure field TotalCoffee kind: number
ensure field TotalPrice kind: number
prefixVar: {
'var': 'VarTextRupeeSymbol'
}
ensure layoutGrid Table kind: table
showComps: [Items.Date, Items.Time, TotalTea, TotalCoffee, TotalPrice]
columnSizeSet: ["Flex"]
ensure section: Summary
ensure field TotalBill kind: number
prefixVar: {
'var': 'VarTextRupeeSymbol'
}
ensure field GST kind: number
ensure field GrandTotal kind: number
prefixVar: {
'var': 'VarTextRupeeSymbol'
}
ensure field PaymentStatus kind: paymentStatus
defaultValue: pending
ensure field PaymentQR kind: showCode
label: "Payment QR"
codeType: qrCode
showLabel: false
ensure field PaymentLink kind: hyperlink
ensure field InvoiceLink kind: hyperlink
ensure field PaymentQR defaultField: PaymentLink
ensure formula TotalPrizeFormula
assignToField: TotalPrice
formula: "(${f:TotalTea} * ${f:TeaPrice}) + (${f:TotalCoffee} * ${f:CoffeePrice})"
ensure formula TotalBillFormula
assignToField: TotalBill
formula: "SUM(${f:TotalPrice})"
ensure formula GSTFormula
assignToField: GST
formula: "${f:TotalBill} * 0.18"
ensure formula GrandTotalFormula
assignToField: GrandTotal
formula: "${f:TotalBill} + ${f:GST}"
ensure spreadsheet InvoiceHistory
searchables: [OfficeName, OfficeNo, Mobile]
queryables : [PaymentStatus]
4. FilterInvoice form
// this form is used for filter out the customer for invoice generation
ensure form FilterInvoice
ensure section: Details
ensure field DateRange kind: dateRange
autoFocus: false
required: true
fromDefault: "startOfMonth"
toDefault: "endOfMonth"
ensure field OfficeRef kind: ref
spreadsheet: OfficeMaster
copyFieldMap: {
'OfficeMasterRowId': '$RowId',
'Name': 'Name'
}
layoutSpreadsheet: ListLayout
5. Reports
a. GetInvoiceCustomerInfo report
// this report fetches customer information
ensure report GetInvoiceCustomerInfo kind: query
inputForm: FilterInvoice
outputForm: OutputInvoice
fromSpreadsheets: [OfficeMaster]
neoQL: "select
{ 'from' : ${in:Details.DateRange.from}, 'to' : ${in:Details.DateRange.to} } as ${out:Details.DateRange},
${ctx:row.id} as ${out:Details.OfficeRowId},
${ss:OfficeMaster.Details.Name} as ${out:Details.OfficeName},
${ss:OfficeMaster.Details.OfficeNumber} as ${out:Details.OfficeNo},
${ss:OfficeMaster.Details.MobileNumber} as ${out:Details.Mobile},
${ss:OfficeMaster.Details.TeaPrice} as ${out:Details.TeaPrice},
${ss:OfficeMaster.Details.CoffeePrice} as ${out:Details.CoffeePrice},
MILLIS(CLOCK_LOCAL()) as ${out:Details.InvoiceDate}
from ${ss}
where ${ctx:row.type} = ${ss:OfficeMaster} and
${ctx:row.id} = ${in:Details.OfficeMasterRowId}"
b. GetInvoiceOrders report
// this report fetches information of customer's order for given date range
ensure report GetInvoiceOrders kind: query
inputForm: FilterInvoice
outputForm: OutputInvoice
fromSpreadsheets: [OrderBook]
neoQL: "select
${ss:OrderBook.Order.Date} as ${out:Items.Date},
${ss:OrderBook.Order.Time} as ${out:Items.Time},
${ss:OrderBook.Order.TeaCount} as ${out:Items.TotalTea},
${ss:OrderBook.Order.CoffeeCount} as ${out:Items.TotalCoffee},
${ss:OrderBook.Order.Total} as ${out:Items.TotalPrice}
from ${ss}
where ${ctx:row.type} = ${ss:OrderBook}
and ${ss:OrderBook.Order.Date} >= ${in:Details.DateRange.from}
and ${ss:OrderBook.Order.Date} <= ${in:Details.DateRange.to}
and ${ss:OrderBook.Office.OfficeMasterRowId} = ${in:Details.OfficeMasterRowId}
order by ${ss:OrderBook.Order.Date}"
c. GetInvoiceComposite report
// this report combines output of GetInvoiceOrders and GetInvoiceCustomerInfo reports
ensure report GetInvoiceComposite kind: composite
inputForm: FilterInvoice
outputForm: OutputInvoice
mergeReports: [GetInvoiceCustomerInfo, GetInvoiceOrders]
d. GetInvoice report
// this report maps GetInvoiceOrders report and save to spreadsheet as per output form
ensure report GetInvoice kind: mapper
description: "Prevents computing report invoice again for the same invoice filter"
label: "Get Invoice"
inputForm: FilterInvoice
outputForm: OutputInvoice
mappedReport: GetInvoiceComposite
saveToSpreadsheet: InvoiceHistory
6. Payment
// adding payment
deploy payment RazorPay
kind: razorpay
allowedPaymentMethodSet: [netbanking, card, upi]
defaultCurrency: "INR"
apiKey: "rzp_test_Yi1HjKJIQC2NJS"
apiSecret: "VQXKghIx5bJBTkHXcZ6g12HK"
default: true
7. Invoice automation
a. Automation variables
• Deeplink mapping variable
// mapping variable for deeplink form
ensure var VarMappingGenerateInvoiceDeeplink kind: mapping deploy: fixedOnDeploy
fromForm: OutputInvoice
toForm: FilterInvoice
fieldMappingMap: {
'map': {
'${f:DateRange}': 'DateRange',
'${f:OfficeName}': 'Name',
'${f:OfficeRowId}': 'OfficeMasterRowId'
}
}
• Webhook mapping variable
// mapping variable for webhook automation step
ensure var VarMappingPaymentUpdateInvoiceSheet kind: mapping deploy: fixedOnDeploy
toForm: OutputInvoice
fieldMappingMap: {
'map': {
'${d:PaymentStatus.paid}': 'Summary.PaymentStatus'
}
}
• Message variable
// message variable for message send on WhatsApp automation step
ensure var VarParagraphInvoiceMessageSendOnWhatsApp kind: paragraph
deploy: fixedOnDeploy
value: "Hello ${name},
Here is your invoice dated, ${date} with total ${total}.
* Invoice Link: ${invoice}
* Payment Link: ${payment}"
b. Deeplink
• OutputInvoice layouts
// layouts for form OutputInvoice
ensure form OutputInvoice
ensure layout Start1 kind: content
direction: vertical
start.fields: [Details.OfficeName, Details.OfficeNo, Details.Mobile, Details.InvoiceId]
ensure layout Start2 kind: content
direction: vertical
start.fields: [Details.DateRange, Details.InvoiceDate, Details.TeaPrice, Details.CoffeePrice]
ensure layout Start kind: content
direction: horizontal
showBorderSet: ["bottom", "top"]
contentPadding: thick
showPaddingSet: ["bottom", "top"]
start.formLayouts: [Start1, Start2]
ensure layout End1 kind: content
direction: vertical
start.fields: [Summary.TotalBill, Summary.GST, Summary.GrandTotal]
ensure layout End2 kind: content
direction: vertical
end.fields: [Summary.PaymentQR]
ensure layout End kind: content
direction: horizontal
showBorderSet: ["top"]
contentPadding: thick
showPaddingSet: ["top", "bottom"]
start.formLayouts: [End1]
end.formLayouts: [End2]
ensure layout Template kind: template showEnterprise: true paperSize: a4Size
ensure layout Main kind: content
direction: vertical
start.formLayouts: [Start]
flexCenter.gridLayouts: [Items.Table]
end.formLayouts: [End]
• GetInvoice deeplink
// deeplink for report GetInvoice to send the invoice in WhatsApp message
ensure deeplink DeeplinkGetInvoice kind: report
visibilityConstraint: allowPublicSharing
creationRoles: [Owner]
expiry: noExpiry
showEnterpriseImageInLinkPreview: true
report: GetInvoice
outputFormContentLayout: Main
outputFormTemplateLayout: Template
c. Automation
// spreadsheet automation to perform task on spreadsheet insert
ensure automation AutomateInvoiceCache kind: spreadsheet spreadsheet: InvoiceHistory
ensure event BeforeInsert fire: beforeInsert
ensure step GenerateInvoiceDeeplink kind: generateDeeplink
deeplink: DeeplinkGetInvoice
deeplinkField: InvoiceLink
inputFormMappingVar: VarMappingGenerateInvoiceDeeplink
ensure step GeneratePaymentLink kind: generatePaymentLink
expiryDurationValue.argName: "expiryDurationValue"
expiryDurationValue.kind: constant
allowedPaymentMethodSet: ["upi"]
referenceIdField: Details.InvoiceId
spreadsheetRowIdField: $RowId
paymentLinkField: Summary.PaymentLink
currencyValue.argName: "currencyValue"
currencyValue.kind: constant
amountValue.argName: "amountValue"
amountValue.kind: field
ensure event AfterInsert fire: afterInsert
// TODO: Change in Dto will have to decide the new Cli pattern
ensure step MessageSendOnWhatsapp kind: messageSendOnWhatsapp
messageVar: {
'var': 'VarParagraphInvoiceMessageSendOnWhatsApp',
'paramSet': [
'${f:Details.OfficeName}',
'${f:Details.InvoiceDate}',
'${f:Summary.GrandTotal}',
'${f:Summary.InvoiceLink}',
'${f:Summary.PaymentLink}'
]
}
dataSourceField: Details.Mobile
ensure automation WebhookRazorpayPayment kind: webhook callbackKind: razorpayPaymentReceipt
ensure event OnCallback fire: onCallback
ensure step UpdateSpreadsheet kind: updateSpreadsheet
targetSpreadsheet: InvoiceHistory
sourceToTargetMappingVar: VarMappingPaymentUpdateInvoiceSheet
Set frontend
1. SendInvoiceReport action
// creates the invoice for a customer and sends it on WhatsApp as deeplink
ensure action SendInvoiceReport kind: report
label: "Send invoice"
icon: "AnalyticsRounded"
report: GetInvoice
outputFormContentLayout: Main
outputFormTemplateLayout: Template
sendMessageToInbox: true
2. ShowInvoiceHistory action
// fetches the history of invoices
ensure spreadsheet InvoiceHistory
ensure layoutSpreadsheet Table kind: table
showComps: [InvoiceId, DateRange, InvoiceDate, OfficeName, GrandTotal, PaymentStatus]
ensure action ShowInvoiceHistory kind: spreadsheetEditor
icon: "EditNoteRounded"
spreadsheet: InvoiceHistory
layoutSpreadsheet: Table
3. InvoiceCenter group
// this group has all the actions those can generate invoice
ensure group InvoiceCenter hideActionMenu: true
pinnedActions: [SendInvoiceReport, ShowInvoiceHistory]
actionPermission: {
'SendInvoiceReport': {
'roles': [
'Owner'
]
},
'ShowInvoiceHistory': {
'roles': [
'Owner'
]
}
}