Browse Source

Ver 0.1

master
Asitav Sen 3 years ago
parent
commit
f93702dd87
  1. 4
      .gitignore
  2. 212
      Pre_runner.Rmd
  3. 13
      bUdgEtRack.Rproj
  4. BIN
      cred.sqlite
  5. 23
      data/Jul22.csv
  6. 23
      data/Jun22.csv
  7. 23
      data/apr22.csv
  8. BIN
      data/costcenters.RDS
  9. 7
      data/dev.limits.csv
  10. 1
      data/email_creds
  11. BIN
      data/glaccounts.RDS
  12. 67
      data/initial.csv
  13. 23
      data/may22.csv
  14. BIN
      data/may22.xlsx
  15. BIN
      data/months.RDS
  16. 1
      email_creds
  17. 87
      helper_server.R
  18. 169
      helper_ui.R
  19. 29
      mod_datatable.R
  20. 32
      mod_elinearea.R
  21. 27
      mod_step.R
  22. 24
      mod_valuebox.R
  23. 568
      server.R
  24. 125
      ui.R
  25. BIN
      www/loader.gif
  26. BIN
      www/logo.png

4
.gitignore

@ -0,0 +1,4 @@
.Rproj.user
.Rhistory
.RData
.Ruserdata

212
Pre_runner.Rmd

@ -0,0 +1,212 @@
---
title: "Pre"
author: "Scary Scarecrow"
date: '2022-06-27'
output: html_document
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
library(dplyr)
library(echarts4r)
library(lubridate)
library(shinymanager)
```
## Credentials
```{r}
credentials <- data.frame(
user = c("shiny", "asitav", "rigo", "aldo"),
password = c("lanubia@2021", "lanubia@2021","lanubia@2021","lanubia@2021"),
admin = c(FALSE, TRUE, FALSE, FALSE),
email = c("hello@asitavsen.com","asitav.sen@lanubia.com","rigo.selassa@lanubia.com","aldo.silvano@lanubia.com"),
stringsAsFactors = FALSE
)
create_db(
credentials_data = credentials,
sqlite_path = "./cred.sqlite", # will be created
passphrase = "kJuyhG657Hj&^%gshj*762hjsknh&662"
)
```
## DB
```{r}
connec <- dbConnect(
RPostgres::Postgres(),
dbname = dsn_database,
host = dsn_hostname,
port = dsn_port,
user = dsn_uid,
password = dsn_pwd
)
```
```{r}
#dat<-read.csv("./data/initial.csv")
#lims<-read.csv("./data/dev.limits.csv")
dat.1<-
dat |>
mutate(devia=Actual-Plan) |>
mutate(devia.per=round(devia/Plan,2))
#dbCreateTable(connec, "calculated", dat.1)
dbWriteTable(connec, "calculated", dat.1, append=TRUE)
dbWriteTable(connec, "limits", lims, append=TRUE)
#dbRemoveTable(connec,"calculated")
dat<-dbGetQuery(
connec,
'SELECT * FROM calculated'
)
lims<-dbGetQuery(
connec,
'SELECT * FROM limits'
)
#dbReadTable(connec, "calculated")
exp<-
dat |>
inner_join(lims, by=c("GL.account")) |>
mutate(act.req=ifelse(devia.per>Limit & devia > 500,T,F)) |>
filter(act.req) |>
select(1:3) |>
mutate(explanation=c("Cyberattack","Overwork","Interview","Maintenance","Quarterly Report","New Legislation"))
dbWriteTable(connec, "explanations", exp, append=TRUE)
exp<-dbGetQuery(
connec,
'SELECT * FROM explanations'
)
approvals<- exp |> mutate(approved=F)
dbWriteTable(connec, "approvals", approvals, overwrite=T)
approvals<-dbGetQuery(
connec,
'SELECT * FROM approvals'
)
dat |>
inner_join(lims, by=c("GL.account")) |>
mutate(act.req=ifelse(devia.per>Limit & devia > 500,T,F)) |>
filter(act.req) |>
left_join(exp, by=c("month"="month","Cost.center"="Cost.center","GL.account"="GL.account"))
emailsids<-dat |>
select(Cost.center, GL.account) |>
distinct() |>
mutate(email=c("asitav.sen@lanubia.com"))
dbWriteTable(connec, "emails", emailsids, overwrite=T)
emailsids<-dbGetQuery(
connec,
'SELECT * FROM emails'
)
sel.emails<- emailsids |>
filter(email=="asitav.sen@lanubia.com")
dat |>
inner_join(lims, by=c("GL.account")) |>
mutate(act.req=ifelse(devia.per>Limit & devia > 500,T,F)) |>
filter(act.req) |>
left_join(sel.emails, by=c("Cost.center"="Cost.center","GL.account"="GL.account")) |>
left_join(exp, by=c("month"="month","Cost.center"="Cost.center","GL.account"="GL.account")) |>
filter(is.na(explanation) | explanation=="") |>
filter(email=="asitav.sen@lanubia.com") |>
select(-c(9,10))
exp
```
```{r}
dat.2<-
dat |>
mutate(month=ym(month)) |>
group_by(month) |>
summarise(Plan=sum(Plan),Actual=sum(Actual)) |>
mutate(devia=Actual-Plan) |>
mutate(deviation.percent=round(devia*100/Plan,2))
e_chart(dat.2, x=month) |>
e_line(serie = deviation.percent, smooth=T, color="cyan") |>
e_area(serie = deviation.percent, smooth=T, color="gray") |>
e_axis_labels(x = "month", y="Deviation") |>
e_format_y_axis(suffix = " %") |>
e_title("Deviation", "Selected Cost Centers") |>
e_tooltip() |>
e_legend(right = 100) |>
e_datazoom(x_index = c(0, 1)) |>
e_toolbox_feature(feature = c("saveAsImage","dataView")) |>
e_theme("chalk")
history<-dat.2 |> select(month,deviation.percent) |> rename(ds=month, y=deviation.percent)
model <- prophet::prophet(history)
future <- prophet::make_future_dataframe(model, periods = 2)
forecast <- predict(model, future)
dat |>
filter(month==max(month)) |>
mutate(cost_gl=paste0(Cost.center,"_",GL.account)) |>
group_by(cost_gl) |>
summarise(Plan=sum(Plan),Actual=sum(Actual)) |>
mutate(devia=Actual-Plan) |>
mutate(deviation.percent=round(devia*100/Plan,2)) |>
arrange(desc(deviation.percent)) |>
e_charts(cost_gl) |>
e_bar(Plan, name = "Plan", color="gray") |>
e_step(Actual, name = "Actual", color="red") |>
e_axis_labels(x = "GL+Cost Center", y="Deviation") |>
e_title("Selected Cost Centers") |>
e_tooltip() |>
e_legend(right = 100) |>
e_datazoom(x_index = 0, type = "slider") |>
e_datazoom(y_index = 0, type = "slider") |>
e_toolbox_feature(feature = c("saveAsImage","dataView")) |>
e_theme("chalk")
```
```{r}
unique(dat$Cost.center) |> saveRDS("./data/costcenters.RDS")
unique(dat$GL.account) |> saveRDS("./data/glaccounts.RDS")
unique(dat$month) |> saveRDS("./data/months.RDS")
lims
```
```{r}
dat.dev<-dat |>
filter(devia>0) |>
select(2,3,6)
e_charts(dat.dev) |>
e_pie(devia)
blastula::create_smtp_creds_file(
file = "email_creds",
user = "apikey",
host = "smtp.sendgrid.net",
port = 465,
use_ssl = TRUE
)
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
```

13
bUdgEtRack.Rproj

@ -0,0 +1,13 @@
Version: 1.0
RestoreWorkspace: Default
SaveWorkspace: Default
AlwaysSaveHistory: Default
EnableCodeIndexing: Yes
UseSpacesForTab: Yes
NumSpacesForTab: 2
Encoding: UTF-8
RnwWeave: Sweave
LaTeX: pdfLaTeX

BIN
cred.sqlite

Binary file not shown.

23
data/Jul22.csv

@ -0,0 +1,23 @@
month,Cost center,GL account,Plan,Actual
202205,IT,Salaries,30000,29000
202205,IT,Business travel,5000,6000
202205,IT,Consultancy,10000,10500
202205,IT,Training costs,5000,6000
202205,HR local support,Salaries,15000,13000
202205,HR local support,Events,10000,9000
202205,HR local support,Training costs,2000,2700
202205,Finance,Salaries,13000,11000
202205,Finance,Consultancy,6000,5000
202205,Finance,Training costs,500,500
202205,Purchasing,Salaries,40000,40000
202205,Purchasing,Consultancy,2000,1500
202205,Purchasing,Training costs,1000,1500
202205,HR services,Salaries,35000,39000
202205,HR services,Business travel,10000,9000
202205,HR services,Training costs,2000,1000
202205,Public Relations,Salaries,10000,12000
202205,Public Relations,Events,18000,19200
202205,Public Relations,Business travel,2000,1000
202205,Public Relations,Training costs,600,700
202205,Facility management,Office lease,50000,50000
202205,Facility management,Salaries,5000,4000
1 month Cost center GL account Plan Actual
2 202205 IT Salaries 30000 29000
3 202205 IT Business travel 5000 6000
4 202205 IT Consultancy 10000 10500
5 202205 IT Training costs 5000 6000
6 202205 HR local support Salaries 15000 13000
7 202205 HR local support Events 10000 9000
8 202205 HR local support Training costs 2000 2700
9 202205 Finance Salaries 13000 11000
10 202205 Finance Consultancy 6000 5000
11 202205 Finance Training costs 500 500
12 202205 Purchasing Salaries 40000 40000
13 202205 Purchasing Consultancy 2000 1500
14 202205 Purchasing Training costs 1000 1500
15 202205 HR services Salaries 35000 39000
16 202205 HR services Business travel 10000 9000
17 202205 HR services Training costs 2000 1000
18 202205 Public Relations Salaries 10000 12000
19 202205 Public Relations Events 18000 19200
20 202205 Public Relations Business travel 2000 1000
21 202205 Public Relations Training costs 600 700
22 202205 Facility management Office lease 50000 50000
23 202205 Facility management Salaries 5000 4000

23
data/Jun22.csv

@ -0,0 +1,23 @@
month,Cost center,GL account,Plan,Actual
202205,IT,Salaries,30000,33000
202205,IT,Business travel,5000,4000
202205,IT,Consultancy,10000,11000
202205,IT,Training costs,5000,6000
202205,HR local support,Salaries,15000,16000
202205,HR local support,Events,10000,8000
202205,HR local support,Training costs,2000,3000
202205,Finance,Salaries,13000,15000
202205,Finance,Consultancy,6000,5000
202205,Finance,Training costs,500,500
202205,Purchasing,Salaries,40000,42000
202205,Purchasing,Consultancy,2000,3000
202205,Purchasing,Training costs,1000,2000
202205,HR services,Salaries,35000,39000
202205,HR services,Business travel,10000,9000
202205,HR services,Training costs,2000,1000
202205,Public Relations,Salaries,10000,12000
202205,Public Relations,Events,18000,19000
202205,Public Relations,Business travel,2000,1000
202205,Public Relations,Training costs,600,600
202205,Facility management,Office lease,50000,50000
202205,Facility management,Salaries,5000,4000
1 month Cost center GL account Plan Actual
2 202205 IT Salaries 30000 33000
3 202205 IT Business travel 5000 4000
4 202205 IT Consultancy 10000 11000
5 202205 IT Training costs 5000 6000
6 202205 HR local support Salaries 15000 16000
7 202205 HR local support Events 10000 8000
8 202205 HR local support Training costs 2000 3000
9 202205 Finance Salaries 13000 15000
10 202205 Finance Consultancy 6000 5000
11 202205 Finance Training costs 500 500
12 202205 Purchasing Salaries 40000 42000
13 202205 Purchasing Consultancy 2000 3000
14 202205 Purchasing Training costs 1000 2000
15 202205 HR services Salaries 35000 39000
16 202205 HR services Business travel 10000 9000
17 202205 HR services Training costs 2000 1000
18 202205 Public Relations Salaries 10000 12000
19 202205 Public Relations Events 18000 19000
20 202205 Public Relations Business travel 2000 1000
21 202205 Public Relations Training costs 600 600
22 202205 Facility management Office lease 50000 50000
23 202205 Facility management Salaries 5000 4000

23
data/apr22.csv

@ -0,0 +1,23 @@
month,Cost center,GL account,Plan,Actual
202204,IT,Salaries,30000,31000
202204,IT,Business travel,5000,6000
202204,IT,Consultancy,10000,10500
202204,IT,Training costs,5000,5000
202204,HR local support,Salaries,15000,13000
202204,HR local support,Events,10000,9000
202204,HR local support,Training costs,2000,2700
202204,Finance,Salaries,13000,15000
202204,Finance,Consultancy,6000,5000
202204,Finance,Training costs,500,500
202204,Purchasing,Salaries,40000,40000
202204,Purchasing,Consultancy,2000,1500
202204,Purchasing,Training costs,1000,1500
202204,HR services,Salaries,35000,39000
202204,HR services,Business travel,10000,9000
202204,HR services,Training costs,2000,1000
202204,Public Relations,Salaries,10000,10000
202204,Public Relations,Events,18000,19200
202204,Public Relations,Business travel,2000,1000
202204,Public Relations,Training costs,600,600
202204,Facility management,Office lease,50000,50000
202204,Facility management,Salaries,5000,4000
1 month Cost center GL account Plan Actual
2 202204 IT Salaries 30000 31000
3 202204 IT Business travel 5000 6000
4 202204 IT Consultancy 10000 10500
5 202204 IT Training costs 5000 5000
6 202204 HR local support Salaries 15000 13000
7 202204 HR local support Events 10000 9000
8 202204 HR local support Training costs 2000 2700
9 202204 Finance Salaries 13000 15000
10 202204 Finance Consultancy 6000 5000
11 202204 Finance Training costs 500 500
12 202204 Purchasing Salaries 40000 40000
13 202204 Purchasing Consultancy 2000 1500
14 202204 Purchasing Training costs 1000 1500
15 202204 HR services Salaries 35000 39000
16 202204 HR services Business travel 10000 9000
17 202204 HR services Training costs 2000 1000
18 202204 Public Relations Salaries 10000 10000
19 202204 Public Relations Events 18000 19200
20 202204 Public Relations Business travel 2000 1000
21 202204 Public Relations Training costs 600 600
22 202204 Facility management Office lease 50000 50000
23 202204 Facility management Salaries 5000 4000

BIN
data/costcenters.RDS

Binary file not shown.

7
data/dev.limits.csv

@ -0,0 +1,7 @@
GL account,Limit
Office lease,0.15
Events,0.10
Consultancy,0.10
Business travel,0.10
Salaries,0.10
Training costs,0.15
1 GL account Limit
2 Office lease 0.15
3 Events 0.10
4 Consultancy 0.10
5 Business travel 0.10
6 Salaries 0.10
7 Training costs 0.15

1
data/email_creds

@ -0,0 +1 @@
{"type":"list","attributes":{"names":{"type":"character","attributes":{},"value":["version","host","port","use_ssl","user","password"]}},"value":[{"type":"integer","attributes":{},"value":[1]},{"type":"character","attributes":{},"value":["smtp.sendgrid.net"]},{"type":"double","attributes":{},"value":[465]},{"type":"logical","attributes":{},"value":[true]},{"type":"character","attributes":{},"value":["apikey"]},{"type":"character","attributes":{},"value":["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"]}]}

BIN
data/glaccounts.RDS

Binary file not shown.

67
data/initial.csv

@ -0,0 +1,67 @@
month,Cost center,GL account,Plan,Actual
202201,IT,Salaries,30000,29000
202201,IT,Business travel,5000,6150
202201,IT,Consultancy,10000,12000
202201,IT,Training costs,5000,4800
202201,HR local support,Salaries,15000,15500
202201,HR local support,Events,5000,4900
202201,HR local support,Training costs,2000,1500
202201,Finance,Salaries,13000,13000
202201,Finance,Consultancy,6000,6500
202201,Finance,Training costs,4000,4500
202201,Purchasing,Salaries,40000,41500
202201,Purchasing,Consultancy,2000,2000
202201,Purchasing,Training costs,1000,1000
202201,HR services,Salaries,35000,36000
202201,HR services,Business travel,10000,14000
202201,HR services,Training costs,2000,1800
202201,Public Relations,Salaries,10000,8000
202201,Public Relations,Events,18000,19000
202201,Public Relations,Business travel,2000,1950
202201,Public Relations,Training costs,600,500
202201,Facility management,Office lease,50000,48000
202201,Facility management,Salaries,5000,4500
202202,IT,Salaries,30000,29000
202202,IT,Business travel,5000,5000
202202,IT,Consultancy,10000,9000
202202,IT,Training costs,5000,5000
202202,HR local support,Salaries,15000,15500
202202,HR local support,Events,0,0
202202,HR local support,Training costs,2000,2200
202202,Finance,Salaries,13000,13000
202202,Finance,Consultancy,6000,5000
202202,Finance,Training costs,0,0
202202,Purchasing,Salaries,40000,41500
202202,Purchasing,Consultancy,2000,2000
202202,Purchasing,Training costs,1000,0
202202,HR services,Salaries,35000,36000
202202,HR services,Business travel,10000,7000
202202,HR services,Training costs,2000,2000
202202,Public Relations,Salaries,10000,8000
202202,Public Relations,Events,18000,10000
202202,Public Relations,Business travel,2000,2200
202202,Public Relations,Training costs,600,600
202202,Facility management,Office lease,50000,48000
202202,Facility management,Salaries,5000,4500
202203,IT,Salaries,30000,30000
202203,IT,Business travel,5000,6000
202203,IT,Consultancy,10000,10500
202203,IT,Training costs,5000,5000
202203,HR local support,Salaries,15000,15000
202203,HR local support,Events,10000,5000
202203,HR local support,Training costs,2000,1000
202203,Finance,Salaries,13000,13000
202203,Finance,Consultancy,6000,7000
202203,Finance,Training costs,500,500
202203,Purchasing,Salaries,40000,40000
202203,Purchasing,Consultancy,2000,2000
202203,Purchasing,Training costs,1000,1000
202203,HR services,Salaries,35000,35000
202203,HR services,Business travel,10000,10000
202203,HR services,Training costs,2000,3000
202203,Public Relations,Salaries,10000,10600
202203,Public Relations,Events,18000,18000
202203,Public Relations,Business travel,2000,1000
202203,Public Relations,Training costs,600,1000
202203,Facility management,Office lease,50000,50000
202203,Facility management,Salaries,5000,5000
1 month Cost center GL account Plan Actual
2 202201 IT Salaries 30000 29000
3 202201 IT Business travel 5000 6150
4 202201 IT Consultancy 10000 12000
5 202201 IT Training costs 5000 4800
6 202201 HR local support Salaries 15000 15500
7 202201 HR local support Events 5000 4900
8 202201 HR local support Training costs 2000 1500
9 202201 Finance Salaries 13000 13000
10 202201 Finance Consultancy 6000 6500
11 202201 Finance Training costs 4000 4500
12 202201 Purchasing Salaries 40000 41500
13 202201 Purchasing Consultancy 2000 2000
14 202201 Purchasing Training costs 1000 1000
15 202201 HR services Salaries 35000 36000
16 202201 HR services Business travel 10000 14000
17 202201 HR services Training costs 2000 1800
18 202201 Public Relations Salaries 10000 8000
19 202201 Public Relations Events 18000 19000
20 202201 Public Relations Business travel 2000 1950
21 202201 Public Relations Training costs 600 500
22 202201 Facility management Office lease 50000 48000
23 202201 Facility management Salaries 5000 4500
24 202202 IT Salaries 30000 29000
25 202202 IT Business travel 5000 5000
26 202202 IT Consultancy 10000 9000
27 202202 IT Training costs 5000 5000
28 202202 HR local support Salaries 15000 15500
29 202202 HR local support Events 0 0
30 202202 HR local support Training costs 2000 2200
31 202202 Finance Salaries 13000 13000
32 202202 Finance Consultancy 6000 5000
33 202202 Finance Training costs 0 0
34 202202 Purchasing Salaries 40000 41500
35 202202 Purchasing Consultancy 2000 2000
36 202202 Purchasing Training costs 1000 0
37 202202 HR services Salaries 35000 36000
38 202202 HR services Business travel 10000 7000
39 202202 HR services Training costs 2000 2000
40 202202 Public Relations Salaries 10000 8000
41 202202 Public Relations Events 18000 10000
42 202202 Public Relations Business travel 2000 2200
43 202202 Public Relations Training costs 600 600
44 202202 Facility management Office lease 50000 48000
45 202202 Facility management Salaries 5000 4500
46 202203 IT Salaries 30000 30000
47 202203 IT Business travel 5000 6000
48 202203 IT Consultancy 10000 10500
49 202203 IT Training costs 5000 5000
50 202203 HR local support Salaries 15000 15000
51 202203 HR local support Events 10000 5000
52 202203 HR local support Training costs 2000 1000
53 202203 Finance Salaries 13000 13000
54 202203 Finance Consultancy 6000 7000
55 202203 Finance Training costs 500 500
56 202203 Purchasing Salaries 40000 40000
57 202203 Purchasing Consultancy 2000 2000
58 202203 Purchasing Training costs 1000 1000
59 202203 HR services Salaries 35000 35000
60 202203 HR services Business travel 10000 10000
61 202203 HR services Training costs 2000 3000
62 202203 Public Relations Salaries 10000 10600
63 202203 Public Relations Events 18000 18000
64 202203 Public Relations Business travel 2000 1000
65 202203 Public Relations Training costs 600 1000
66 202203 Facility management Office lease 50000 50000
67 202203 Facility management Salaries 5000 5000

23
data/may22.csv

@ -0,0 +1,23 @@
month,Cost center,GL account,Plan,Actual
202205,IT,Salaries,30000,31000
202205,IT,Business travel,5000,6000
202205,IT,Consultancy,10000,10500
202205,IT,Training costs,5000,5000
202205,HR local support,Salaries,15000,13000
202205,HR local support,Events,10000,9000
202205,HR local support,Training costs,2000,2700
202205,Finance,Salaries,13000,15000
202205,Finance,Consultancy,6000,5000
202205,Finance,Training costs,500,500
202205,Purchasing,Salaries,40000,40000
202205,Purchasing,Consultancy,2000,1500
202205,Purchasing,Training costs,1000,1500
202205,HR services,Salaries,35000,39000
202205,HR services,Business travel,10000,9000
202205,HR services,Training costs,2000,1000
202205,Public Relations,Salaries,10000,10000
202205,Public Relations,Events,18000,19200
202205,Public Relations,Business travel,2000,1000
202205,Public Relations,Training costs,600,600
202205,Facility management,Office lease,50000,50000
202205,Facility management,Salaries,5000,4000
1 month Cost center GL account Plan Actual
2 202205 IT Salaries 30000 31000
3 202205 IT Business travel 5000 6000
4 202205 IT Consultancy 10000 10500
5 202205 IT Training costs 5000 5000
6 202205 HR local support Salaries 15000 13000
7 202205 HR local support Events 10000 9000
8 202205 HR local support Training costs 2000 2700
9 202205 Finance Salaries 13000 15000
10 202205 Finance Consultancy 6000 5000
11 202205 Finance Training costs 500 500
12 202205 Purchasing Salaries 40000 40000
13 202205 Purchasing Consultancy 2000 1500
14 202205 Purchasing Training costs 1000 1500
15 202205 HR services Salaries 35000 39000
16 202205 HR services Business travel 10000 9000
17 202205 HR services Training costs 2000 1000
18 202205 Public Relations Salaries 10000 10000
19 202205 Public Relations Events 18000 19200
20 202205 Public Relations Business travel 2000 1000
21 202205 Public Relations Training costs 600 600
22 202205 Facility management Office lease 50000 50000
23 202205 Facility management Salaries 5000 4000

BIN
data/may22.xlsx

Binary file not shown.

BIN
data/months.RDS

Binary file not shown.

1
email_creds

@ -0,0 +1 @@
{"type":"list","attributes":{"names":{"type":"character","attributes":{},"value":["version","host","port","use_ssl","user","password"]}},"value":[{"type":"integer","attributes":{},"value":[1]},{"type":"character","attributes":{},"value":["smtp.sendgrid.net"]},{"type":"double","attributes":{},"value":[465]},{"type":"logical","attributes":{},"value":[true]},{"type":"character","attributes":{},"value":["apikey"]},{"type":"character","attributes":{},"value":["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"]}]}

87
helper_server.R

@ -0,0 +1,87 @@
# Database details
dsn_database <- "postgres"
dsn_hostname <- "localhost"
dsn_port <- "5432"
dsn_uid <- "postgres"
dsn_pwd <- "julley09"
# Read Cost Center etc. list from data (Changes, modification needs creating the file again and redeploying the app)
cost.centers <- readRDS("./data/costcenters.RDS")
glaccounts <- readRDS("./data/glaccounts.RDS")
mont <- readRDS("./data/months.RDS")
# Email settings
# smtp <- server(
# host = "smtp.sendgrid.net",
# port = 465,
# username = "apikey",
# password = "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"
# )
# Function to get data from DB
get.db.data <- function(qry = 'SELECT * FROM calculated') {
dbGetQuery(connec,
qry)
}
# Function to aggregate monthly deviation
mon.dev <- function(dat) {
dat |>
mutate(month = ym(month)) |>
group_by(month) |>
summarise(Plan = sum(Plan), Actual = sum(Actual)) |>
mutate(devia = Actual - Plan) |>
mutate(deviation.percent = round(devia * 100 / Plan, 2))
}
# Function to aggregate last month by gl and cost
last.mon <- function(dat) {
dat |>
filter(month == max(month)) |>
mutate(cost_gl = paste0(Cost.center, "_", GL.account)) |>
group_by(cost_gl) |>
summarise(Plan = sum(Plan), Actual = sum(Actual)) |>
mutate(devia = Actual - Plan) |>
mutate(deviation.percent = round(devia * 100 / Plan, 2)) |>
arrange(desc(deviation.percent))
}
admin.menu <- sidebarMenu(
id = "m",
menuItem("Dashboard", tabName = "dashboard", icon = icon("chart-line")),
menuItem("Upload", icon = icon("upload"), tabName = "upload"),
menuItem("Approvals", icon = icon("check"), tabName = "approvals"),
menuItem("Explanations", icon = icon("file"), tabName = "explanations"),
menuItem("Admin", icon = icon("toolbox"), tabName = "admin"),
menuItem("Contact us", icon = icon("at"), href = "https://lanubia.com/contact/")
)
other.menu <- sidebarMenu(
id = "m",
menuItem(
"Dashboard",
tabName = "dashboard",
icon = icon("dashboard")
),
menuItem("Explanations", icon = icon("th"), tabName = "explanations"),
menuItem("Contact us", icon = icon("id-card"), href = "https://lanubia.com/contact/")
)

169
helper_ui.R

@ -0,0 +1,169 @@
dashboard<- tabItem(
tabName = "dashboard",
autoWaiter(),
fluidRow(
column(
width = 4,
"Filter Cost Center and GL Accounts"
),
column(
width = 4,
pickerInput(
"glaccount",
choices = glaccounts,
selected = glaccounts,
options = list(
`actions-box` = TRUE),
multiple = TRUE
)
),
column(
width = 4,
pickerInput(
"costcenter",
choices = cost.centers, # Getting the list from reading data from local. See helper_server
selected = cost.centers,
options = list(
`actions-box` = TRUE),
multiple = TRUE
)
)
),
fluidRow(
valueUI("variation"),
valueUI("variabs"),
valueUI("actexpe"),
),
fluidRow(
shinydashboardPlus::box(
title = "Deviation % by Month",
collapsible = TRUE,
status = "navy",
solidHeader = TRUE,
echarts4rOutput("monthlypervar",height = "300px")
),
shinydashboardPlus::box(
title = "Abs. Deviation by Month",
collapsible = TRUE,
status = "navy",
solidHeader = TRUE,
echarts4rOutput("monthlyabsvar",height = "300px")
)
),
fluidRow(
shinydashboardPlus::box(
title = "Plan vs Actual",
collapsible = TRUE,
status = "navy",
solidHeader = TRUE,
sidebar = boxSidebar(
startOpen = FALSE,
id = "monthselector",
pickerInput(
"mont",
choices = mont,
selected = max(mont)
)
),
echarts4rOutput("monthlyabs",height = "300px")
)
)
)
upload<- tabItem(
tabName = "upload",
autoWaiter(),
fluidRow(
shinydashboardPlus::box(
title = "Fresh Upload",
collapsible = TRUE,
width = 12,
status = "navy",
solidHeader = TRUE,
fileInput(
"inpfile",
"Upload the file",
multiple = FALSE,
accept = ".csv",
width = NULL,
buttonLabel = "Browse...",
placeholder = "No file selected"
),
datatableUI("freshdat"),
actionBttn("datsubmit","Submit")
)
)
)
appndev <- tabItem(
tabName = "approvals",
autoWaiter(),
shinydashboardPlus::box(
title = "Deviations without explanation",
collapsible = TRUE,
width = 12,
status = "navy",
solidHeader = TRUE,
sidebar = boxSidebar(
startOpen = FALSE,
id = "limitselector",
sliderInput("limittoignore","Define limit", min=100, max=2000, step=100, value = 500)
),
datatableUI("devnoexp"),
actionBttn("notify","Notify")
),
shinydashboardPlus::box(
title = "Awaiting Approval",
collapsible = TRUE,
width = 12,
status = "navy",
solidHeader = TRUE,
excelOutput("expnoapp"),
actionBttn("approvalsubmit","Submit")
)
)
explan <- tabItem(
tabName = "explanations",
autoWaiter(),
shinydashboardPlus::box(
title = "Explanations Pending",
collapsible = TRUE,
width = 12,
status = "navy",
solidHeader = TRUE,
excelOutput("explanationtofill"),
actionBttn("explanationsubmit","Submit")
)
)
admin<-tabItem(
tabName = "admin",
autoWaiter(),
shinydashboardPlus::box(
title = "Email IDs",
width = 8,
collapsible = TRUE,
status = "navy",
solidHeader = TRUE,
excelOutput("emailtable"),
actionBttn("emailsubmit","Submit")
),
shinydashboardPlus::box(
title = "Deviation Rules",
width = 4,
collapsible = TRUE,
status = "navy",
solidHeader = TRUE,
excelOutput("limitable"),
actionBttn("limitsubmit","Submit")
)
)

29
mod_datatable.R

@ -0,0 +1,29 @@
datatableUI<- function(id){
ns<-NS(id)
DT::dataTableOutput(ns("dtable"))
}
datatableServer<-function(id, dat){
moduleServer(
id,
function(input,output,session){
output$dtable<- renderDataTable({
validate(need(nrow(dat())>0, "No data"))
datatable(
dat(),
extensions = "Buttons",
options = list(
paging = TRUE,
scrollX = TRUE,
searching = TRUE,
ordering = TRUE,
dom = 'Bfrtip',
buttons = c('copy', 'csv', 'excel', 'pdf'),
pageLength = 10,
lengthMenu = c(3, 5, 10)
)
)
})
}
)
}

32
mod_elinearea.R

@ -0,0 +1,32 @@
elineareaUI<- function(id){
ns<-NS(id)
echarts4rOutput("elaplot")
}
elineareaServer<-function(id, dat){
moduleServer(
id,
function(input,output,session){
output$elaplot<- renderEcharts4r({
dat |>
e_chart(x=month) |>
e_line(serie = deviation.percent, smooth=T, color="cyan") |>
e_area(serie = deviation.percent, smooth=T, color="cyan") |>
e_axis_labels(x = "month", y="Deviation") |>
e_format_y_axis(suffix = " %") |>
e_title("Deviation", "Selected Cost Centers") |>
e_tooltip(formatter = htmlwidgets::JS("
function(params){
return('Month: ' + params.value[0] + '<br />Deviation: ' + params.value[1] + '%')
}
")
) |>
e_legend(right = 100) |>
e_datazoom(x_index = c(0, 1)) |>
e_toolbox_feature(feature = c("saveAsImage","dataView")) |>
e_theme("forest")
})
}
)
}

27
mod_step.R

@ -0,0 +1,27 @@
stepUI<- function(id){
ns<-NS(id)
echarts4rOutput("elaplot")
}
stepServer<-function(id, dat){
moduleServer(
id,
function(input,output,session){
output$elaplot<- renderEcharts4r({
dat |>
e_charts(cost_gl) |>
e_bar(Plan, name = "Plan", color="gray") |>
e_step(Actual, name = "Actual", color="red") |>
e_axis_labels(x = "GL+Cost Center", y="Deviation") |>
e_title("Selected Cost Centers") |>
e_tooltip() |>
e_legend(right = 100) |>
e_datazoom(x_index = 0, type = "slider") |>
e_datazoom(y_index = 0, type = "slider") |>
e_toolbox_feature(feature = c("saveAsImage","dataView")) |>
e_theme("chalk")
})
}
)
}

24
mod_valuebox.R

@ -0,0 +1,24 @@
valueUI<- function(id){
ns<-NS(id)
valueBoxOutput(ns("vbox"))
}
valueServer<-function(id, ttl="title",n,icn="credit-card",clr="red",symbl){
moduleServer(
id,
function(input,output,session){
#print(n())
output$vbox<- renderValueBox({
valueBox(
paste0(n," ", symbl),
ttl,
icon=icon(icn),
color = clr
)
})
}
)
}

568
server.R

@ -0,0 +1,568 @@
# Server logic
# Budget variation tracking of Aramco
# ::::::Asitav Sen::::::
# ::LaNubia Consulting::
library(shiny)
# Define server logic
shinyServer(function(input, output, session) {
res_auth <- secure_server(
check_credentials = check_credentials("cred.sqlite",
passphrase = "kJuyhG657Hj&^%gshj*762hjsknh&662"),
keep_token=TRUE
)
output$menu <- renderMenu({
if (res_auth$admin == FALSE) {
other.menu
} else
admin.menu
})
# Connect to DB
connec <- dbConnect(
RPostgres::Postgres(),
dbname = dsn_database,
host = dsn_hostname,
port = dsn_port,
user = dsn_uid,
password = dsn_pwd
)
# On stop disconnect from DB
onStop(function() {
dbDisconnect(connec)
})
# Getting the data from DB
dat <- reactive({
dbGetQuery(connec,
'SELECT * FROM calculated')
#get.db.data('SELECT * FROM calculated')
})
# Getting deviation limits from DB
lims <- reactive({
dbGetQuery(connec,
'SELECT * FROM limits')
#get.db.data('SELECT * FROM limits')
})
# Getting the explanations from DB
exp <- reactive({
dbGetQuery(connec,
'SELECT * FROM explanations')
#get.db.data('SELECT * FROM explanations')
})
# Getting approval Table from DB
approvals <- reactive({
dbGetQuery(connec,
'SELECT * FROM approvals')
#get.db.data('SELECT * FROM approvals')
})
# Getting email ids
emailids <- reactive({
dbGetQuery(connec,
'SELECT * FROM emails')
#get.db.data('SELECT * FROM emails')
})
dat.need.exp <- reactive({
req(dat())
dat() |>
inner_join(lims(), by = c("GL.account")) |>
mutate(act.req = ifelse(devia.per > Limit &
devia > input$limittoignore, T, F)) |>
filter(act.req) |>
left_join(
exp(),
by = c(
"month" = "month",
"Cost.center" = "Cost.center",
"GL.account" = "GL.account"
)
) |>
filter(is.na(explanation) | explanation == "")
})
# Update the gl account selector
observeEvent(input$costcenter, {
req(dat())
choi <- dat() |>
filter(Cost.center %in% input$costcenter) |>
select(GL.account) |> distinct() |> pull()
updatePickerInput(
session = session,
inputId = "glaccount",
choices = choi,
selected = choi
)
})
observeEvent(c(input$costcenter, input$glaccount), {
# Creating data that will be filtered using the GL and cost center selection
dat.filtered <- dat() |>
filter(Cost.center %in% input$costcenter) |>
filter(GL.account %in% input$glaccount) |>
mon.dev() |>
filter(month == max(month))
last.var.per <- dat.filtered |>
pull(deviation.percent) #Last variation percent
last.var.abs <- dat.filtered |>
pull(devia) #Last variation absolute val
last.exp.act <- dat.filtered |>
pull(Actual) #Last expense
valueServer(
"variation",
ttl = "Latest Variation %",
n = last.var.per,
icn = "percent",
clr = "red",
symbl = "%"
)
valueServer(
"variabs",
ttl = "Last Variation Amount",
n = last.var.abs,
icn = "dollar-sign",
clr = "green",
symbl = "$"
)
valueServer(
"actexpe",
ttl = "Last Expense",
n = last.exp.act,
icn = "coins",
clr = "blue",
symbl = "$"
)
})
# Data selected after aplying the filters of cost center and gl account
dat.selected <- reactive({
req(dat())
req(input$costcenter)
req(input$glaccount)
dat() |>
filter(Cost.center %in% input$costcenter) |>
filter(GL.account %in% input$glaccount)
})
# Monthly aggregate
dat.monthly.per <- reactive({
req(dat.selected())
dat.selected() |>
mutate(month = ym(month)) |>
group_by(month) |>
summarise(Plan = sum(Plan), Actual = sum(Actual)) |>
mutate(devia = Actual - Plan) |>
mutate(deviation.percent = round(devia * 100 / Plan, 2))
})
# Monthly percentage deviation
output$monthlypervar <- renderEcharts4r({
req(dat.monthly.per())
e_chart(dat.monthly.per(), x = month) |>
e_line(serie = deviation.percent,
smooth = T,
color = "cyan", opacity=0.8) |>
e_area(serie = deviation.percent,
smooth = T,
color = "gray", opacity=0.6) |>
e_axis_labels(x = "month", y = "Deviation") |>
e_format_y_axis(suffix = " %") |>
e_tooltip() |>
e_legend(right = 100) |>
e_datazoom(x_index = c(0, 1)) |>
e_image_g(
right = 50,
top = 20,
z = -999,
style = list(
image = "logo.png",
width = 75,
height = 75,
opacity = .6
)
) |>
e_toolbox_feature(feature = c("saveAsImage", "dataView")) |>
e_theme("roma")
})
# Monthly Absolute Deviation
dat.monthly.abs <- reactive({
dat.selected() |>
filter(month == input$mont) |>
mutate(cost_gl = paste0(Cost.center, "_", GL.account)) |>
group_by(cost_gl) |>
summarise(Plan = sum(Plan), Actual = sum(Actual)) |>
mutate(devia = Actual - Plan) |>
mutate(deviation.percent = round(devia * 100 / Plan, 2)) |>
arrange(desc(deviation.percent))
})
# Monthly absolute by cost center + gl account
output$monthlyabs <- renderEcharts4r({
req(dat.monthly.abs())
dat.monthly.abs() |>
e_charts(cost_gl) |>
e_bar(Plan, name = "Plan", color = "gray", opacity=0.6) |>
e_step(Actual, name = "Actual", color = "red") |>
e_axis_labels(x = "GL+Cost Center", y = "Deviation") |>
#e_title("Plan Vs. Actual") |>
e_tooltip() |>
e_legend(right = 100) |>
e_datazoom(x_index = 0, type = "slider") |>
e_datazoom(y_index = 0, type = "slider") |>
e_image_g(
right = 50,
top = 20,
z = -999,
style = list(
image = "logo.png",
width = 75,
height = 75,
opacity = .6
)
) |>
e_toolbox_feature(feature = c("saveAsImage", "dataView")) |>
e_theme("roma")
})
output$monthlyabsvar <- renderEcharts4r({
req(dat.monthly.per())
e_chart(dat.monthly.per(), x = month) |>
e_bar(serie = devia) |>
e_axis_labels(x = "month", y = "Deviation") |>
e_format_y_axis(suffix = "€") |>
#e_title("Deviation Percentage by month") |>
e_tooltip() |>
e_legend(right = 100) |>
e_datazoom(x_index = c(0, 1)) |>
e_image_g(
right = 50,
top = 20,
z = -999,
style = list(
image = "logo.png",
width = 75,
height = 75,
opacity = .6
)
) |>
e_visual_map(type = "piecewise",
pieces = list(list(gt = 0,
color = "red", opacity=0.5),
list(lte = 0,
color = "green", opacity=0.5))) |>
e_toolbox_feature(feature = c("saveAsImage", "dataView")) |>
e_theme("roma")
})
# Table of deviations without explanation
datatableServer("devnoexp", dat.need.exp)
# Notify
observeEvent(input$notify, {
req(dat.need.exp())
emaildf<-dat.need.exp() |>
inner_join(emailids(), by=c("Cost.center"="Cost.center","GL.account"="GL.account"))
print(emaildf)
if(is.null(emaildf) | nrow(emaildf)==0){
showModal(modalDialog("No Data"))
} else {
emails<-
emaildf |>
select(email) |> pull() |> unique()
for(i in 1:length(emails)){
tbl <- emaildf |>
filter(email==emails[i]) |> kbl()
date_time <- add_readable_time()
email <-
compose_email(body = md(c(
glue::glue(
"Hello,
Explanation required for expense deviation. Please visit xyz. Details are as follows.
"
),
tbl
)),
footer = md(glue::glue("Email sent on {date_time}.")))
email |>
smtp_send(
to = emails[i],
from = "asitav.sen@lanubia.com",
subject = "Testing",
credentials = creds_file("email_creds")
)
}
showModal(modalDialog(title = "Done"))
}
})
# Approvals
output$expnoapp <- renderExcel({
req(approvals())
appro <- approvals()
row.names(appro) <- NULL
appro <- appro[appro$approved == FALSE, ]
columns = data.frame(
title = colnames(appro),
type = c('numeric', 'text', 'text', 'text', 'checkbox')
)
excelTable(data = appro, columns = columns, autoFill = TRUE)
})
# Update approvals
observeEvent(input$approvalsubmit, {
approved.now <- excel_to_R(input$expnoapp)
if (is.null(input$expnoapp) || nrow(approved.now) == 0) {
showModal(modalDialog(title = "Nothing to Upload"))
} else{
showModal(modalDialog(title = "Upload in Database?",
actionButton("finalapprovalsubmit", "Yes")))
}
})
observeEvent(input$finalapprovalsubmit, {
appro <- approvals()
appro <- appro[appro$approved == TRUE, ]
approved.now <- excel_to_R(input$expnoapp)
appro <- rbind(appro, approved.now)
if (nrow(approved.now) > 0) {
if (dbWriteTable(connec, "approvals", appro, overwrite = TRUE)) {
removeModal()
session$reload()
}
}
})
# New Data
fresh.dat <- reactive({
req(input$inpfile)
file <- input$inpfile
ext <- tools::file_ext(file$datapath)
req(file)
validate(need(ext == "csv", "Please upload a csv file"))
new.dat <- read.csv(file$datapath, header = T)
new.dat |>
mutate(devia = Actual - Plan) |>
mutate(devia.per = round(devia / Plan, 2))
}, label = "fresh")
# Show uploaded data
datatableServer("freshdat", fresh.dat)
# Update DB
observeEvent(input$datsubmit, {
req(nrow(fresh.dat()) > 0)
fresh.dt <- fresh.dat()
if (is.null(fresh.dt) || nrow(fresh.dt) == 0) {
showModal(modalDialog(title = "Nothing to Upload"))
} else{
showModal(modalDialog(title = "Upload in Database?",
actionButton("finaldatsubmit", "Yes")))
}
})
observeEvent(input$finaldatsubmit, {
fresh.dt <- fresh.dat()
if (nrow(fresh.dt) > 0) {
if (dbWriteTable(connec, "calculated", fresh.dt, append = TRUE)) {
unique(fresh.dt$month) |> saveRDS("./data/months.RDS")
removeModal()
session$reload()
}
}
})
# Email id edit and show
output$emailtable <- renderExcel({
req(emailids())
email.table <- emailids()
columns = data.frame(title = colnames(email.table),
type = c('text', 'text', 'text'))
excelTable(data = email.table, columns = columns, autoFill = TRUE)
})
# Email id table update
observeEvent(input$emailsubmit, {
email.table <- excel_to_R(input$emailtable)
if (is.null(input$emailtable) || nrow(email.table) == 0) {
showModal(modalDialog(title = "Nothing to Upload"))
} else{
showModal(modalDialog(title = "Upload in Database?",
actionButton("finalemailsubmit", "Yes")))
}
})
observeEvent(input$finalemailsubmit, {
email.table <- excel_to_R(input$emailtable)
if (nrow(email.table) > 0) {
if (dbWriteTable(connec, "emails", email.table, overwrite = TRUE)) {
removeModal()
session$reload()
}
}
})
# Limits (deviation rules) id edit and show
output$limitable <- renderExcel({
req(lims())
limit.table <- lims()
columns = data.frame(title = colnames(limit.table),
type = c('text', 'numeric'))
excelTable(data = limit.table, columns = columns, autoFill = TRUE)
})
# Email id table update
observeEvent(input$limitsubmit, {
limit.table <- excel_to_R(input$limitable)
if (is.null(input$limitable) || nrow(limit.table) == 0) {
showModal(modalDialog(title = "Nothing to Upload"))
} else{
showModal(modalDialog(title = "Upload in Database?",
actionButton("finallimitsubmit", "Yes")))
}
})
observeEvent(input$finallimitsubmit, {
limit.table <- excel_to_R(input$limitable)
if (nrow(limit.table) > 0) {
if (dbWriteTable(connec, "limits", limit.table, overwrite = TRUE)) {
removeModal()
session$reload()
}
}
})
# User specific explanation filter
user.accounts <- reactive({
req(dat())
req(emailids())
req(exp())
req(res_auth$email)
dat() |>
inner_join(lims(), by = c("GL.account")) |>
mutate(act.req = ifelse(devia.per > Limit &
devia > input$limittoignore, T, F)) |> #change 500 to input
filter(act.req) |>
left_join(emailids(),
by = c("Cost.center" = "Cost.center", "GL.account" = "GL.account")) |>
left_join(
exp(),
by = c(
"month" = "month",
"Cost.center" = "Cost.center",
"GL.account" = "GL.account"
)
) |>
filter(is.na(explanation) | explanation == "") |>
filter(email == res_auth$email) |>
select(-c(9, 10))
})
output$explanationtofill <- renderExcel({
req(user.accounts())
explanation.table <- user.accounts()
columns = data.frame(
title = colnames(explanation.table),
type = c(
'numeric',
'text',
'text',
'numeric',
'numeric',
'numeric',
'numeric',
'numeric',
'text'
)
)
excelTable(data = explanation.table, columns = columns, autoFill = TRUE)
})
# Explanations table update
observeEvent(input$explanationsubmit, {
explanation.table <- excel_to_R(input$explanationtofill)
if (is.null(input$explanationtofill) ||
nrow(explanation.table) == 0) {
showModal(modalDialog(title = "Nothing to Upload"))
} else{
showModal(modalDialog(title = "Upload in Database?",
actionButton("finalexpsubmit", "Yes")))
}
})
observeEvent(input$finalexpsubmit, {
explanation.table <- excel_to_R(input$explanationtofill)
explanation.table <- explanation.table |>
select(c(month, Cost.center, GL.account, explanation))
if (nrow(explanation.table) > 0) {
if (dbWriteTable(connec, "explanations", explanation.table, append = TRUE)) {
appr <- explanation.table |> mutate(approved = F)
if (dbWriteTable(connec, "approvals", appr, append = TRUE)) {
removeModal()
session$reload()
}
}
}
})
})

125
ui.R

@ -0,0 +1,125 @@
#
# Custom App developed for Finance Team of Aramco
# ::Asitav Sen::
# ::LaNubia Consulting::
# ::asitav.sen@lanubia.com::
#
library(shiny)
library(shinydashboard)
library(countup)
library(shinyWidgets)
library(shinydashboardPlus)
library(DBI)
library(RPostgres)
library(dplyr)
library(echarts4r)
library(lubridate)
library(DT)
library(excelR)
library(blastula)
library(shinymanager)
library(glue)
library(shinythemes)
library(kableExtra)
library(waiter)
source("helper_server.R")
source("mod_valuebox.R")
source("mod_elinearea.R")
source("mod_step.R")
source("mod_datatable.R")
source("helper_ui.R")
# Define UI for application
shinyUI(
secure_app(
shinydashboardPlus::dashboardPage(
title = "Budgetrack",
#skin = "blue-light",
#skin = "midnight",
header = shinydashboardPlus::dashboardHeader(title = "Budgetrack"),
sidebar = shinydashboardPlus::dashboardSidebar(
sidebarMenuOutput("menu")
),
body = dashboardBody(
tags$head(tags$style(HTML(
'
/* logo */
.skin-blue .main-header .logo {
background-color: #0477ci;
}
/* logo when hovered */
.skin-blue .main-header .logo:hover {
background-color: #009adc;
}
/* navbar (rest of the header) */
.skin-blue .main-header .navbar {
background-color: #0033a0;
}
/* main sidebar */
.skin-blue .main-sidebar {
background-color: #ffffff;
}
/* active selected tab in the sidebarmenu */
.skin-blue .main-sidebar .sidebar .sidebar-menu .active a{
background-color: #01a54b;
}
/* other links in the sidebarmenu */
.skin-blue .main-sidebar .sidebar .sidebar-menu a{
background-color: #ffffff;
color: #000000;
}
/* other links in the sidebarmenu when hovered */
.skin-blue .main-sidebar .sidebar .sidebar-menu a:hover{
background-color: #009adc;
}
'
))),
tabItems(dashboard,
upload,
appndev,
explan,
admin))
),
enable_admin = TRUE,
theme = shinythemes::shinytheme("united"),
tags_top =
tags$div(
tags$h4("Created exclusively for ", style ="align:center"),
br(),
tags$img(
src = "https://www.aramco.com/images/affiliateLogo-2x.png", width = 100
),
br(),
br(),
tags$h4("By", style ="align:center"),
tags$img(src="logo.png", width=100)
),
tags_bottom = tags$p(
"For any question, please contact",
tags$a(
href ="mailto:asitav.sen@lanubia.com?Subject=Aramco%20aBugdet",
target="_top","Asitav Sen"
)
),
background = "linear-gradient(225deg,rgb(0,163,224),
rgb(0,51,160),
rgb(0,132,61),
rgb(132,189,0));"
)
)

BIN
www/loader.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

BIN
www/logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Loading…
Cancel
Save