Google Sheets Script for Accounting - javascript

I'm very new to Google App Script so please bear with me. I'm trying to create custom functions in Google Sheets to monitor monthly and weekly sales and expenses. I can do it with built-in formulas, but it's too time-consuming to edit every cell every time. Here is what the Google Sheet looks like.
For monthly accounting, I use the formula below (here it's for "Sales"). I use the sum of multiple SUMIFS for the expenses since there are multiple criteria ("Supplies", "Staff", or "Operations").
=ARRAYFORMULA(SUMIFS('2019'!$F$2:$F,text('2019'!$A$2:$A,"MMM"),A3,'2019'!$E$2:$E,"Sales"))
For weekly accounting, I use another formula below. Here, I sum up all transactions (here "Sales") within a given range of dates (here Mar 31 2019 to Apr 6 2019). As in above, I use the same principle of summing up multiple SUMIFS functions for "Expenses".
Sales: =SUMIFS('2019'!$F$2:$F,'2019'!$A$2:$A,">="&date(2019,3,31),'2019'!$A$2:$A,"<="&date(2019,4,6),'2019'!$E$2:$E,"Sales")
Expenses: =SUMIFS('2019'!$F$2:$F,'2019'!$A$2:$A,">="&date(2019,3,31),'2019'!$A$2:$A,"<="&date(2019,4,6),'2019'!$E$2:$E,"Supplies")+SUMIFS('2019'!$F$2:$F,'2019'!$A$2:$A,">="&date(2019,3,31),'2019'!$A$2:$A,"<="&date(2019,4,6),'2019'!$E$2:$E,"Staff")+SUMIFS('2019'!$F$2:$F,'2019'!$A$2:$A,">="&date(2019,3,31),'2019'!$A$2:$A,"<="&date(2019,4,6),'2019'!$E$2:$E,"Operations")
How can I translate the formulas shown above into a custom function? I was trying to write something like this one:

I suggest a different strategy that avoids custom functions and allows you to use standard functions without complex parameters and, in the process, achieves a more logical layout of the data.
2019 Sheet: Category (Column E): make these a dropdown selection to avoid typos and other errors.
2019 Sheet: Column F - It's not clear whether sales should be normally negative (credit), or expenses should be normally positive (debit). Either way, the sum of this column will reconcile to something at some stage so the "sign" of transactions is important. It also means that formulas for Sales on the Summary Sheet should be prefixed with a negative (so that they appear as a positive number).
Summary Sheet-Monthly Sales - Prefix with a "minus" so that sales are shown as positive.
=-ARRAYFORMULA(SUMIFS('2019'!$F$2:$F,text('2019'!$A$2:$A,"MMM"),A3,'2019'!$E$2:$E,"Sales"))
**Summary Sheet: Monthly Expenses"" - Simplify the formula: just sum the values that are NOT "Sales"
=ARRAYFORMULA(SUMIFS('2019'!$F$2:$F,text('2019'!$A$2:$A,"MMM"),A3,'2019'!$E$2:$E,"<>Sales"))
Summary Sheet: Net - =B3-C3 (Sales minus Expenses)
Summary Sheet: Weekly reporting - It is always difficult to balance monthly results against weekly results. So much so, that many business adopt a quarterly cycle of 4/4/5 weeks to cater for the changes in the number of days per month. In any event, the formula that you are using is VERY complicated and prone to error through typos (if nothing else). I suggest:
create columns for the respective weekly "From"/"To" dates on the weekly report, and use date arithmetic to calculate the respective dates for each new week/month.
use Weekly Sales and Expenses formula that reference the "From/To" dates. This makes your formulas completely generic, enables you to copy formula with conventional "Copy/Paste" commands, and doesn't require detailed formula editing.
Consider whether you want the weekly results to align to the monthly results. If you do, then
fine-tune the month-end by adding or deleting days to the "To" date in week#4. The Week#1 "From" date for the following month will adjust automatically, as will the respective "From"/"To" dates for the other weeks in the following month(s). This will help eliminate unintentional errors such as including March 31 in both March week#4 and April week#1.
You might also add an extra three columns at the right to sum Total Sales, Total Expenses and Net profit for the four weeks. This figure will agree to the monthly result.
Formula simplification
By disclosing the From and To dates, you can use those dates in your SumIFS formula.
For example, March Week#1:
Sales: =-SUMIFS('2019'!$F$2:$F,'2019'!$A$2:$A,">="&G3,'2019'!$A$2:$A,"<="&H3,'2019'!$E$2:$E,"Sales")
Expenses: =SUMIFS('2019'!$F$2:$F,'2019'!$A$2:$A,">="&G3,'2019'!$A$2:$A,"<="&H3,'2019'!$E$2:$E,"<>Sales")
Monthly Results
Sales: =-ARRAYFORMULA(SUMIFS('2019'!$F$2:$F,text('2019'!$A$2:$A,"MMM"),A3,'2019'!$E$2:$E,"Sales"))
Expenses: =ARRAYFORMULA(SUMIFS('2019'!$F$2:$F,text('2019'!$A$2:$A,"MMM"),A3,'2019'!$E$2:$E,"<>Sales"))
Net: =B3-C3
Weekly results - extract
Week#1 Results
Sales: =-SUMIFS('2019'!$F$2:$F,'2019'!$A$2:$A,">="&F3,'2019'!$A$2:$A,"<="&G3,'2019'!$E$2:$E,"Sales")
Expenses: =SUMIFS('2019'!$F$2:$F,'2019'!$A$2:$A,">="&F3,'2019'!$A$2:$A,"<="&G3,'2019'!$E$2:$E,"<>Sales")
Net: =H3-I3
Week#2Results
Sales: =-SUMIFS('2019'!$F$2:$F,'2019'!$A$2:$A,">="&K3,'2019'!$A$2:$A,"<="&L3,'2019'!$E$2:$E,"Sales")
Expenses: =SUMIFS('2019'!$F$2:$F,'2019'!$A$2:$A,">="&K3,'2019'!$A$2:$A,"<="&L3,'2019'!$E$2:$E,"<>Sales")
Net: =M3-N3
Date Arithmetic
March Week#1 From: Mar 1 2019 (the only date that is entered manually)
March Week#1 To: =F3+6
March Week#2 From: =G3+1
March Week#2 To: =K3+6
March Week#4 To: =U3+6+3
April Week#1 From: =V3+1

Related

MySQL way to store monthly revenue

I want to store restaurant's monthly revenue (income and expenses), and later show it on a line graph for every year. I have come to this workaround I would store in year variable for example 2020-01-01 and then it should be adding values to all the following row for every month. Would it even work this way? Or should I use one date type and add months to it?
It can work, but it is not optimal.
For example if you want to see the yearly expenses you have to type every single month name into your query.
A more practical solution can be to use a single table with example columns like so:
date
is_expense (boolean)
amount (double)
restaurant_id
Where is_expense is boolean if the amount is income or expense.
You can aggregate from here everything: yearly / monthly expenses/incomes/profits etc.
You can use MySQL Functions like MONTH(date) that will give you specific month. For example if you want to aggregate all expenses for specific year & month you will do something similar to
SELECT SUM(amount) from Table WHERE is_expense=1 AND MONTH(date) = 1 AND YEAR(date) = 2020

How to make dynamic consecutive numbers in one column

I have a list of bills. I must continuously name them according to my bank accounts.
Normally I would sort my sheet by BANK ACCOUNT and DATE, then tag the NUMBER COLUMN by using the "blue square", and after that, I sort by date again.
I wanna program a script function to iterate through the column NUMBER which defines and read the ACCOUNT column and tag the NUMBER row accordingly.
I thought I make a "settings"-column somewhere to define the look of the "auto-formatter":
IF BANK {YY}-BANK-{NUMBER}
IF CASH {YY}-CASH-{NUMBER}
In the end, it should look like the example below:
DATE NUMBER ACCOUNT
|------|------------|-------|
1. Jan 18-CASH-01 CASH
1. Jan 18-BANK-01 BANK
2. Jan 18-CASH-02 CASH
3. Jan 18-CASH-03 CASH
4. Jan 18-BANK-02 BANK
I made a demo sheet that is free to change or clone.
The basic formula is implemented.
Only the formula to iterate is missing
https://docs.google.com/spreadsheets/d/1aJRqODUMyJai-aVyTj3_konvc8qpL8idKEHNCs9cxSo/edit?usp=sharing
Has anyone a suggestion or starting point for me?
I am not good at google sheets API.
Thank you very much in advance
Maybe this can be done with a formula? In F1 I entered
={"Format"; ArrayFormula(if(len(D2:D), text(C2:C7, "yy")&"-"& UPPER(D2:D)&"-"&iferror(SORT(ROW(D2:D),SORT(ROW(D2:D),D2:D,1),1)-MATCH(D2:D,SORT(D2:D),0)-ROW()+1),))}
See if that works for you?
EDIT, to match the names of the backaccounts to a range, use vlookup
={"Solution A"; ArrayFormula(if(len(D2:D), text(C2:C7, "yy")&"-"&
VLOOKUP(D2:D, SETTINGS!A10:C, 2, 0)&"-
"&iferror(SORT(ROW(D2:D),SORT(ROW(D2:D),D2:D,1),1)-
MATCH(D2:D,SORT(D2:D),0)-ROW()+1),))}

Count items and group by a datetime unit

I'm trying to organize a query which should print a count of items ordered by a time unit such as a hour, a day etc.
My limitation is that I'm using LovefieldDB javascript library and complex queries are limited.
I have a table of Units where the main field is the date of creation like this:
2017/11/29 08:17
2017/11/29 08:47
2017/11/29 09:25
2017/11/29 11:39
The result I expect is to count per hour the number of items:
08:00 (2)
09:00 (1)
11:00 (1)
What I want to avoid is to select all rows and process them in a loop because this software is going to have thousands of rows and I'll have to create similar queries for day, month and also year.
A possible solution I thought is to add 4 more datetime fields where I would save created_hour, created_day, created_month, created_year so I can order them easly.
Do you have some tips?
This is what I mean. You can format the time to be in hours and group by the formatted time.
SELECT DATE_FORMAT(datecolumn, '%H:00'), COUNT(*)
FROM SOURCETABLE
GROUP BY DATE_FORMAT(datecolumn, '%H:00')

Chart min max values from each given day using crossfilter and dc.js

I have a dataset that looks something like this and want to make a line chart with with maximum and minimum temperatures per day (there are multiple readings per day).
[...,
{datetime: '21 Feb...', surface_temperature:21.5},
{datetime: '21 Feb...', surface_temperature:21.9},
{datetime: '21 Feb...', surface_temperature:25.5},
...
{datetime: '22 Feb...', surface_temperature:23.5},
....
]
how can I get the min and max values of surface_temperature using crossfilter?
Probably easiest to use a helper library like Reductio, which will generate reduce functions for these and other aggregations.
The dc.js FAQ has a pretty extensive discussion on the topic if you want to do this manually. It's not easy to get right for incremental aggregations.

HighCharts X-Axis Date Not Working (00:00)

I have a HighChart chart which contains a series which is made up of date/value pairs. Each date in the pairs is different. When there are data pairs which have dates which are not within the same week they dates are displayed as they should (mm/dd/yyyy) but when the data set contains only a view pairs which are all within the same week or days right next to each other instead of displaying dates in the (mm/dd/yyyy) format the chart switches to what looks like a time display and shows 00:00, 08:00, 16:00 instead of the full dates.
I already scoured the HighCharts forum and cannot find nor get an answer to this strange behaviour. Maybe someone here can help.
You can see the chart at http://jsfiddle.net/schleichermann/DkgVr/
This is a foible of the auto-scaling algorithm.
Basically, it starts with the smallest unit and stops looking too soon in some cases (like yours)1.
If you know, in advance, the timescale of interest, you can tweak the xAxis settings to compensate.
In this case adding:
day: '%b %e',
hour: '%b %e',
May be adequate. See: jsfiddle.net/DkgVr/4/ .
Or setting tickInterval: 24 * 3600 * 1000 (one day) might be good enough.
See: jsfiddle.net/DkgVr/5/ .
1 It should probably work largest to smallest. Consider making a feature-request or bug report.

Categories

Resources