Merge branch 'side-panel' of bitbucket.org:brycecovertoperations/integreat into side-panel

This commit is contained in:
BC
2019-02-18 07:15:11 -08:00
27 changed files with 11294 additions and 466 deletions

View File

@@ -18,6 +18,7 @@
[dk.ative/docjure "1.12.0"]
[org.clojure/java.jdbc "0.7.3"]
[cljsjs/dropzone "4.3.0-0"]
[cljsjs/recharts "1.4.2-0"]
[clj-fuzzy "0.4.1"]
[honeysql "0.9.2"]
[com.walmartlabs/lacinia "0.25.0"]
@@ -47,6 +48,7 @@
[com.amazonaws/aws-java-sdk-sqs "1.11.282"]
[com.amazonaws/aws-java-sdk-s3 "1.11.282"]
[org.clojure/data.json "0.2.6"]
[org.clojure/data.csv "0.1.4"]
[cider/cider-nrepl "0.16.0"]
[io.rkn/conformity "0.5.1"]
[hiccup "1.0.5"]]
@@ -74,7 +76,6 @@
[javax.servlet/servlet-api "2.5"]
[figwheel-sidecar "0.5.13"]
[com.cemerick/piggieback "0.2.2"]
[org.clojure/data.csv "0.1.4"]
]
:plugins [[lein-figwheel "0.5.13"]
@@ -83,7 +84,8 @@
:jvm-opts ["-Dconfig=config/dev.edn" "--add-modules" "java.xml.bind"]}
:uberjar {:prep-tasks [["cljsbuild" "once" "min"] "compile"]}
:provided {:dependencies [[org.clojure/clojurescript "1.10.238"]
[reagent "0.7.0"]
[reagent "0.7.0" ]
[cljsjs/react-transition-group "2.4.0-0"]
[re-frame "0.10.2"]
[com.andrewmcveigh/cljs-time "0.5.2"]]}}

25
resources/payout-list.csv Normal file
View File

@@ -0,0 +1,25 @@
[:vendor/name],[:vendor/print-as],[:vendor/default-expense-account],[:vendor/address],[:vendor/address :address/street1],[:vendor/address :address/street2],[:vendor/address :address/city],[:vendor/address :address/state],[:vendor/address :address/zip],[:vendor/primary-contact :contact/name],[:vendor/primary-contact :contact/email],[:vendor/primary-contact :contact/phone],[:vendor/secondary-contact :contact/name],[:vendor/secondary-contact :contact/email],[:vendor/secondary-contact :contact/phone],[:vendor/invoice-reminder-schedule]
PAY OUTS - CB 5110 Food Cost,,5110,,,,,,,,,,,,,
PAY OUTS - CB 5910 Paperware Cost,,5910,,,,,,,,,,,,,
PAY OUTS - CB 7210 Flowers and ST Decorations,,7210,,,,,,,,,,,,,
PAY OUTS - CB 7315 Freight and Fuel Charges,,7315,,,,,,,,,,,,,
PAY OUTS - CB 7315 Freight and Fuel Charges,,7315,,,,,,,,,,,,,
PAY OUTS - CB 7320 Kitchen Supplies,,7320,,,,,,,,,,,,,
PAY OUTS - CB 7410 Cleaning Supplies,,7410,,,,,,,,,,,,,
PAY OUTS - CB 7450 Building Cleaning & Maintenance,,7450,,,,,,,,,,,,,
PAY OUTS - CB 7460 Repairs to Equipment,,7460,,,,,,,,,,,,,
PAY OUTS - CB 7461 Contract Labor,,7461,,,,,,,,,,,,,
PAY OUTS - CB 7510 Office Supplies,,7510,,,,,,,,,,,,,
PAY OUTS - HQ 9160 Meals and Entertainment - HQ,,9160,,,,,,,,,,,,,
PAY OUTS - HQ 9180 Food Research - HQ,,9180,,,,,,,,,,,,,
PAY OUTS - meals,,9160,,,,,,,,,,,,,
PAY OUTS - WG 5110 Food Cost,,5110,,,,,,,,,,,,,
PAY OUTS - WG 5910 Paperware Cost,,5910,,,,,,,,,,,,,
PAY OUTS - WG 7210 Flowers and ST Decorations,,7210,,,,,,,,,,,,,
PAY OUTS - WG 7315 Freight and Fuel Charges,,7315,,,,,,,,,,,,,
PAY OUTS - WG 7320 Kitchen Supplies,,7320,,,,,,,,,,,,,
PAY OUTS - WG 7410 Cleaning Supplies,,7410,,,,,,,,,,,,,
PAY OUTS - WG 7450 Building Cleaning & Maintenance,,7450,,,,,,,,,,,,,
PAY OUTS - WG 7460 Repairs to Equipment,,7460,,,,,,,,,,,,,
PAY OUTS - WG 7460 Contract Labor,,7461,,,,,,,,,,,,,
PAY OUTS - WG 7510 Office Supplies,,7510,,,,,,,,,,,,,
1 [:vendor/name] [:vendor/print-as] [:vendor/default-expense-account] [:vendor/address] [:vendor/address :address/street1] [:vendor/address :address/street2] [:vendor/address :address/city] [:vendor/address :address/state] [:vendor/address :address/zip] [:vendor/primary-contact :contact/name] [:vendor/primary-contact :contact/email] [:vendor/primary-contact :contact/phone] [:vendor/secondary-contact :contact/name] [:vendor/secondary-contact :contact/email] [:vendor/secondary-contact :contact/phone] [:vendor/invoice-reminder-schedule]
2 PAY OUTS - CB 5110 Food Cost 5110
3 PAY OUTS - CB 5910 Paperware Cost 5910
4 PAY OUTS - CB 7210 Flowers and ST Decorations 7210
5 PAY OUTS - CB 7315 Freight and Fuel Charges 7315
6 PAY OUTS - CB 7315 Freight and Fuel Charges 7315
7 PAY OUTS - CB 7320 Kitchen Supplies 7320
8 PAY OUTS - CB 7410 Cleaning Supplies 7410
9 PAY OUTS - CB 7450 Building Cleaning & Maintenance 7450
10 PAY OUTS - CB 7460 Repairs to Equipment 7460
11 PAY OUTS - CB 7461 Contract Labor 7461
12 PAY OUTS - CB 7510 Office Supplies 7510
13 PAY OUTS - HQ 9160 Meals and Entertainment - HQ 9160
14 PAY OUTS - HQ 9180 Food Research - HQ 9180
15 PAY OUTS - meals 9160
16 PAY OUTS - WG 5110 Food Cost 5110
17 PAY OUTS - WG 5910 Paperware Cost 5910
18 PAY OUTS - WG 7210 Flowers and ST Decorations 7210
19 PAY OUTS - WG 7315 Freight and Fuel Charges 7315
20 PAY OUTS - WG 7320 Kitchen Supplies 7320
21 PAY OUTS - WG 7410 Cleaning Supplies 7410
22 PAY OUTS - WG 7450 Building Cleaning & Maintenance 7450
23 PAY OUTS - WG 7460 Repairs to Equipment 7460
24 PAY OUTS - WG 7460 Contract Labor 7461
25 PAY OUTS - WG 7510 Office Supplies 7510

10525
resources/public/css/bulma.css vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -68,9 +68,6 @@
animation: flashPrimary 1.0s ease both;
animation-fill-mode: forwards;
}
.left-nav {
width: 300px;
}
.nav.is-dark {
background-color: #232B2D;
color: #F6F7F7;
@@ -146,7 +143,7 @@ nav.navbar .navbar-item.is-active {
font-weight: 700;
}
.aside .main {
padding: 40px;
padding: 40px 10px 40px 30px;
color: #6F7B7E;
}
@@ -186,7 +183,7 @@ nav.navbar .navbar-item.is-active {
font-weight: 500;
}
.messages {
padding: 40px 20px;
padding: 40px 40px 0px 20px;
}
.message {
padding: 40px 20px;

View File

@@ -1,5 +1,5 @@
<!DOCTYPE html>
<html>
<html class="has-navbar-fixed-top">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
@@ -7,7 +7,7 @@
<title>Integreat</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" integrity="sha256-eZrrJcwDc/3uDhsdt61sL2oOBY362qM3lon1gyExkL0=" crossorigin="anonymous" />
<link href="/css/font.min.css" rel="stylesheet">
<link rel="stylesheet" href="/css/bulma.min.css" integrity="sha256-HEtF7HLJZSC3Le1HcsWbz1hDYFPZCqDhZa9QsCgVUdw=" crossorigin="anonymous" />
<link rel="stylesheet" href="/css/bulma.min.css" />
<link rel="stylesheet" href="/css/bulma-calendar.min.css" />
<link rel="stylesheet" href="/css/bulma-badge.min.css" />
<link rel="stylesheet" href="/css/animate.css" />

132
resources/vendor-list.csv Normal file
View File

@@ -0,0 +1,132 @@
[:vendor/name],[:vendor/print-as],[:vendor/default-expense-account],[:vendor/address],[:vendor/address :address/street1],[:vendor/address :address/street2],[:vendor/address :address/city],[:vendor/address :address/state],[:vendor/address :address/zip],[:vendor/primary-contact :contact/name],[:vendor/primary-contact :contact/email],[:vendor/primary-contact :contact/phone],[:vendor/secondary-contact :contact/name],[:vendor/secondary-contact :contact/email],[:vendor/secondary-contact :contact/phone],[:vendor/invoice-reminder-schedule]
Aaron mendoza guadarama,,9220,,,,,,,,,,,,,
ABC Insurance Services ,,8511,,3401 Pacific Blvd,,San Mateo,CA,94403,,,,,,,
"ADP, INC",,9315,,"504 CLINTON CENTER DR, STE 4400",,CLINTON,MS,39056,,,,,,,
"ANAGO FRANCHISING, INC",,7415,,"1460 KOLL CIRCLE, SUITE B",,SAN JOSE,CA,95112,,,,,,,
Andy Younan,,A3304,,,,,,,,,,,,,
ARC LOCKSMITH,,7440,,,,,,,,,,,,,
Bakemart,,5110,,,,,,,,,,,,,
Bank of America - Los Angeles,Bank of America,A1298,,P O BOX 301200,,LOS ANGELES,CA,90030-1200,,,,,,,
Bay lighting supply,,8310,,979 el camino real,,Santa Clara,CA,95050,,,,,,,
Beaucanon,,5510,,1006 Monticello Road,,Napa,CA,94558,,,,,,,
Bellaginevera,,5110,,,,,,,,,,,,,
Benedetto Di Giallorenzo,,7440,,,,,,,,,,,,,
Big Basin Cafe,,5220,,14471 Big Basin Way,,Saratoga,CA,95070,,,,,,,
Big Four Restaurant,,9160,,,,,,,,,,,,,
BLUE SHIELD OF CA,,6040,,,,LOS ANGELES,CA,90074-5331,,,,,,,
Brendon Dias,,9220,,P. O. Box 4258,,Santa Cruz,CA,95063,,,,,,,
BURR PLUMBING,,7440,,1645 ALMADEN RD,,SAN JOSE,CA,95125,,,,,,,
CAPITAL ONE,,A1298,,P O BOX 60599 ,,CITY OF INDUSTRY,CA,91716-0599,,,,,,,
Central Storage,,9383,,,,,,,,,,,,,
Champion Plumbing,,7440,,,,San Jose,Ca,,,,,,,,
CHASE,,A1298,,P O BOX 94014,,PALATINE,IL,60094-4014,,,,,,,
City of Saratoga,,8130,,,,,,,,,,,,,
Clark Pest Control,,7450,,PO BOX 1480,,Lodi,CA,95241,,,,,,,
Classic Mix - Galloway Company,,5110,,,,,,,,,,,,,
Clyde Zaya,,A3301,,,,,,,,,,,,,
COCA-COLA,,5210,,,,LOS ANGELES,CA,90074-3158,,,,,,,
COLD Brew,,7420,,,,,,,,,,,,,
COLD CRAFT INC,,7460,,P.O. BOX 32024,,LOS GATOS,CA,95032-0104,,,,,,,
COSTCO WHOLESALE,,9190,,PO BOX 34783,,SEATTLE,WA,98124-1783,,,,,,,
Creative drinks inc.,,7460,,p.o. box 842,,Los Gatos,CA,95031-0842,,,,,,,
D.G.HEATING & AIR CONDITIONING,,7460,,,,,,,,,,,,,
DANNY APPLIANCE,,7460,,,,,,,,,,,,,
David Correa,,A1280,,P.O. Box 12084,,Pleasanton,CA,94588,,,,,,,
DMV,,9170,,PO BOX 942897,,SACRAMENTO,CA,94297-0897,,,,,,,
E M Fire Protection,,7450,,1120 Eaton Ave #5,,San Carlos,Ca,94070,,,,,,,
EDGAR MENDOZA,,7461,,,,,,,,,,,,,
EDWARD P. MATHEWSON,,9310,,"152 NORTH THIRD ST, STE 800",,SAN JOSE,CA,95112,,,,,,,
Enter Design & Lights,,7440,,1167 Chess Dr Suite # B,,Foster City,CA,94404,,,,,,,
Felix Amerian,,7244,,,,,,,,,,,,,
FIRESHIELD,,7460,,7450 DOWDY STREET,,GILROY,CA,95020,,,,,,,
Friuli italian wine imports llc,,4510,,3130 rubino dr #105,,San Jose,CA,95125,,,,,,,
"G & T TECH, Inc",,7460,,P O BOX 5762,,REDWOOD CITY,CA,94063,,,,,,,
Givmar Precision Machining,,7460,,1904 Colony Street,,Mountain View,CA,94043,,,,,,,
Greenback,,8210,,,,,,,,,,,,,
Grim fire protection,,7440,,p.o.box 1118,,Boulder Creek,Ca,95006,,,,,,,
hacienda produce company,,5120,,p.o. box 8443,,San Jose,Ca,95155,,,,,,,
HD ELECTRIC,,7440,,"1090 LINCOLN AVE, SUITE 10",,SAN JOSE,CA,95125,,,,,,,
HEALTH SMART FOODS,,5110,,,,,,,,,,,,,
Heart String Music,,7244,,2273 Old Milddlefield Way,,Mountian View,CA,94043,,,,,,,
Hugo Wainginger,,7246,,,,,,,,,,,,,
ICE CREAM SOLUTIONS,,5110,,P O BOX 33816,,GRANADA HILLSE,CA,9139,,,,,,,
Impact Paper & Ink LTD,,7510,,1590 Gilbreth Rd,,Burlingame,CA,94010,,,,,,,
IRS,,9710,,P. O. Box 37900,,Heartford,CT,6176,,,,,,,
J Drains,,A1520,,,,,,,,,,,,,
j&b,,7460,,411 lewis rd-425,,San Jose,CA,95111,,,,,,,
J&T Handyman,,7440,,100 PANORAMA WAY,,LOS GATOS,CA,,,,,,,,
JCA ARCHITECT & DESIGN,,7440,,1028 LINCOLN AVE,,SAN JOSE,CA,95125,,,,,,,
Jeff Hickey,,7440,,,,,,,,,,,,,
Jeff Mullen,,A3301,,,,,,,,,,,,,
JESSE SALECDA,,5110,,,,,,,,,,,,,
Kelex Security,,8351,,2959 s. winchester BLVD ste 100,,Campbell,CA,95008,,,,,,,
lang vo,,A1240,,,,,,,,,,,,,
Le Boulanger,,5140,,305 NORTH MATHILDA AVE.,,SUNNYVALE,CA,94085,,,,,,,
Leslie Kurnick,,A1260,,1667 Page St.,,San Francisco,CA,94117,,,,,,,
LIMPIO CLEANING,,7415,,,,,,,,,,,,,
"M.E. Fox & Company, Inc",,5410,,P.O. Box 60000,,San Francisco,CA,94160,,,,,,,
Mahnaz Khazan,,8430,,15219 Sobey rd.,,Saratoga,CA,95070,,,,,,,
MARGUARD PAINTING,,7450,,P.O. BOX 8482,,SAN JOSE,CA,95155,,,,,,,
Marz Vodka,,5610,,2350 mission college blvd suite 1152,,Santa Clara,CA,95054,,,,,,,
"METHOD CONSTRUCTION, INC.",,7440,,PO BOX 2702,,GILROY,CA,95020-4446,,,,,,,
METRO PUBLISHING INC,,9110,,BOX 39000 ,,SAN FRANCISCO,CA,94139,,,,,,,
Midwest,,8511,,PO BOX 9560,,SPRINGFIELD,IL,62791-9560,,,,,,,
Mike Windows,,7460,,4501 SNELL AVE #1202,,SAN JOSE,CA,95136,,,,,,,
MOOD MUZAK LLC,,7246,,P O BOX 71070,,CHARLOTTE,NC,28272-1070,,,,,,,
"Mr. Freeze, Inc.",,5110,,186 Cleveland Ave,,San Jose,CA,95128,,,,,,,
Muscardini cellars llc,,4510,,9380 Sonoma Highway,,Kenwood,CA,95452,,,,,,,
Newport Fish Co.,,5114,,457 South Canal ST. So.,,San Francisco,CA,94080,,,,,,,
NISSAN MOTOR ACCEPTANCE CORP,,7310,,,,,,,,,,,,,
Office of Tourism,,9730,,PO Box 101711,,Pasadena,CA,91189,,,,,,,
Olsen's Pressure Washing,,7450,,,,,,,,,,,,,
Open table,,7250,,P.O. Box 8395,,Pasadena,CA,91109-8395,,,,,,,
P & R PAPER SUPPLY CO,,5910,,2000 University Ave. ,,Berkley,CA,92373,,,,,,,
PACIFIC HARVEST SEAFOOD - San Juan,,5114,,P.O. BOX 788,,SAN JUAN BAUTISTA ,CA,95045,,,,,,,
PACIFIC PRODUCE,,5120,,P. O. BOX 879,,SOUTH SAN FRANCISCO,CA,94080,,,,,,,
Pacific seafood - Boston,,5114,,po box 842757,,Boston,MA,02284-2757,,,,,,,
Paja Glen,,8210,,,,,,,,,,,,,
Palo Alto Foods,,5110,,,,,,,,,,,,,
PETTY ACCOUNT Groceries,,5110,,,,,,,,,,,,,
PETTY ACCOUNT Hardware,,7320,,,,,,,,,,,,,
Ridge vineyards,,4510,,p.o.box 742749,,los angeles,ca,95070,,,,,,,
Rimon,,8110,,,,,,,,,,,,,
ROBERT'S GARDENING,,7415,,949 S 11TH ST ,,SAN JOSE,CA,95112,,,,,,,
Rombauer Vineyards,,5510,,Department 33313 PO Box 39000,,San Francisco,CA,94139-3313,,,,,,,
ROYAL SATELITE,,7160,,,,,,,,,,,,,
Ruben sanchez,,A2110,,,,,,,,,,,,,
Ruchi Gowda,,5510,,3550 Marsh Manor Way,,San Jose ,CA,95121,,,,,,,
Ruzz0 scholl & murphy,,8120,,,,,,,,,,,,,
S & S BOOKKEEPING,,9315,,3160 DE LA CRUZ BLVD STE 226,,SANTA CLARA,CA,95054,,,,,,,
S.C.C D.T.A.C.,,9730,,,,,,,,,,,,,
SAFEGUARD BUSINESS SYS.,,7510,,PO BOX 88043 ,,CHICAGO,IL,60680-1043,,,,,,,
SAN JOSE GIANTS,,8210,,P.O. BOX 21727 ,,SAN JOSE,CA,95151,,,,,,,
Savannah Chanelle,,5510,,3600 Congress Spring Rd,,Saratoga,CA,95070,,,,,,,
SCC Tax Collector,,9730,,"70 West Hedding Street East Wing, 6th Floor ",,San Jose,CA,95110-1767,,,,,,,
SILICON VALLEY CARDIOLOGY,,6040,,"1950 UNIVERSITY AVE, #160",,E. PALO ALTO,CA,94303,,,,,,,
Silver mountian winery,,5510,,,,,,,,,,,,,
Silver oak cellars,,5510,,7370 Highway 128,,Healdsburg,CA,95448,,,,,,,
SJP SIGNS,,9110,,1752 JUNCTION AVE,,SAN JOSE,CA,95112,,,,,,,
"Skurnik Wines West, LLC",,4510,,P. O. Box 421,,Syosset,NY,11791-1315,,,,,,,
Smart plumbers&rooter,,7440,,,,,,,,,,,,,
SOFT SERVE PARTS,,7460,,3245 E. PATRICK SUITE A ,,LAS VEGAS,NV,89120,,,,,,,
SOOTER CONSULTING INC,,8110,,PO BOX 2301,,MORGAN HILL,CA,95038,,,,,,,
SOUTH BAY REFRIGERATION INC,,7460,,P O BOX 54323,,SAN JOSE,CA,95154,,,,,,,
"SOUTHWEST TRADERS, INC.",,5110,,,,,,,,,,,,,
ST. LUCY SCHOOL,,9150,,76 KENNEDY AVE,,CAMPBELL,CA,95008,,,,,,,
STATE FARM INSURANCE SUPPORT CENTER,,6040,,P O BOX 68001 ,,DALLAS,TX,75368-001,,,,,,,
SUNLAND CANDY WHOLESALE,,5110,,3232 N. FIGUEROA ST,,LOS ANGELES,CA,90065,,,,,,,
Supernova Spirits Inc.,,5610,,2350 Mission College Blvd suite 1152,,Santa Clara,CA,95054,,,,,,,
Surveillance Solutions,,8110,,15466 Los Gatos Bvld #109-256,,Los Gatos,CA,95032,,,,,,,
TACKTIX GRAPHIX ,,9110,,14938 CAMDEN AVE. #209 ,,SAN JOSE,CA,95124,,,,,,,
THE HARDFORD,,9382,,LOCKBOX 0234 PO 7247,,PHILADELPHIA,PA,19170-0234,,,,,,,
The Iceman,,7460,,530 Lawrence Expy # 425,,Sunnyvale,CA,94085,,,,,,,
TOBIASON AND ROOK BUILDERS ,,7440,,1161 GLENN AVE,,SAN JOSE,CA,95125,,,,,,,
Troung Gia LLC,,8210,,1966 Cape Hilda Place,,San Jose,CA,95133,,,,,,,
UNITED CONTRACT SERVICES,,7415,,"1161 RINGWOOD COURT, STE 170",,SAN JOSE,CA,95131,,,,,,,
VALLEY IMAGES,,7340,,1925 KYLE PARK CT.,,SAN JOSE,CA,95125,,,,,,,
VERIZON WIRELESS ,,9380,,P O BOX 660108,,DALLAS,TX,75266-0108,,,,,,,
WELLS FARGO FINANCIAL CARDS ,,A1298,,P O BOX 30358,,LOS ANGELES,CA,90030-0358,,,,,,,
WEST VALLEY COLLECTION,,8330,,PO BOX 60248,,LOS ANGELES,CA,90060-0248,,,,,,,
"West Valley Collection & Recycling, LLC",,7450,,1333 Old Oakland,,San Jose,CA,95112,,,,,,,
Western Freezers Specialty Equipment,,7460,,42285 Osgood Rd. Unit F,,Fremont,CA,94539,,,,,,,
Winchester printing,,9350,,2383 moorpark Ave.,,San Jose,CA,95128,,,,,,,
1 [:vendor/name] [:vendor/print-as] [:vendor/default-expense-account] [:vendor/address] [:vendor/address :address/street1] [:vendor/address :address/street2] [:vendor/address :address/city] [:vendor/address :address/state] [:vendor/address :address/zip] [:vendor/primary-contact :contact/name] [:vendor/primary-contact :contact/email] [:vendor/primary-contact :contact/phone] [:vendor/secondary-contact :contact/name] [:vendor/secondary-contact :contact/email] [:vendor/secondary-contact :contact/phone] [:vendor/invoice-reminder-schedule]
2 Aaron mendoza guadarama 9220
3 ABC Insurance Services 8511 3401 Pacific Blvd San Mateo CA 94403
4 ADP, INC 9315 504 CLINTON CENTER DR, STE 4400 CLINTON MS 39056
5 ANAGO FRANCHISING, INC 7415 1460 KOLL CIRCLE, SUITE B SAN JOSE CA 95112
6 Andy Younan A3304
7 ARC LOCKSMITH 7440
8 Bakemart 5110
9 Bank of America - Los Angeles Bank of America A1298 P O BOX 301200 LOS ANGELES CA 90030-1200
10 Bay lighting supply 8310 979 el camino real Santa Clara CA 95050
11 Beaucanon 5510 1006 Monticello Road Napa CA 94558
12 Bellaginevera 5110
13 Benedetto Di Giallorenzo 7440
14 Big Basin Cafe 5220 14471 Big Basin Way Saratoga CA 95070
15 Big Four Restaurant 9160
16 BLUE SHIELD OF CA 6040 LOS ANGELES CA 90074-5331
17 Brendon Dias 9220 P. O. Box 4258 Santa Cruz CA 95063
18 BURR PLUMBING 7440 1645 ALMADEN RD SAN JOSE CA 95125
19 CAPITAL ONE A1298 P O BOX 60599 CITY OF INDUSTRY CA 91716-0599
20 Central Storage 9383
21 Champion Plumbing 7440 San Jose Ca
22 CHASE A1298 P O BOX 94014 PALATINE IL 60094-4014
23 City of Saratoga 8130
24 Clark Pest Control 7450 PO BOX 1480 Lodi CA 95241
25 Classic Mix - Galloway Company 5110
26 Clyde Zaya A3301
27 COCA-COLA 5210 LOS ANGELES CA 90074-3158
28 COLD Brew 7420
29 COLD CRAFT INC 7460 P.O. BOX 32024 LOS GATOS CA 95032-0104
30 COSTCO WHOLESALE 9190 PO BOX 34783 SEATTLE WA 98124-1783
31 Creative drinks inc. 7460 p.o. box 842 Los Gatos CA 95031-0842
32 D.G.HEATING & AIR CONDITIONING 7460
33 DANNY APPLIANCE 7460
34 David Correa A1280 P.O. Box 12084 Pleasanton CA 94588
35 DMV 9170 PO BOX 942897 SACRAMENTO CA 94297-0897
36 E M Fire Protection 7450 1120 Eaton Ave #5 San Carlos Ca 94070
37 EDGAR MENDOZA 7461
38 EDWARD P. MATHEWSON 9310 152 NORTH THIRD ST, STE 800 SAN JOSE CA 95112
39 Enter Design & Lights 7440 1167 Chess Dr Suite # B Foster City CA 94404
40 Felix Amerian 7244
41 FIRESHIELD 7460 7450 DOWDY STREET GILROY CA 95020
42 Friuli italian wine imports llc 4510 3130 rubino dr #105 San Jose CA 95125
43 G & T TECH, Inc 7460 P O BOX 5762 REDWOOD CITY CA 94063
44 Givmar Precision Machining 7460 1904 Colony Street Mountain View CA 94043
45 Greenback 8210
46 Grim fire protection 7440 p.o.box 1118 Boulder Creek Ca 95006
47 hacienda produce company 5120 p.o. box 8443 San Jose Ca 95155
48 HD ELECTRIC 7440 1090 LINCOLN AVE, SUITE 10 SAN JOSE CA 95125
49 HEALTH SMART FOODS 5110
50 Heart String Music 7244 2273 Old Milddlefield Way Mountian View CA 94043
51 Hugo Wainginger 7246
52 ICE CREAM SOLUTIONS 5110 P O BOX 33816 GRANADA HILLSE CA 9139
53 Impact Paper & Ink LTD 7510 1590 Gilbreth Rd Burlingame CA 94010
54 IRS 9710 P. O. Box 37900 Heartford CT 6176
55 J Drains A1520
56 j&b 7460 411 lewis rd-425 San Jose CA 95111
57 J&T Handyman 7440 100 PANORAMA WAY LOS GATOS CA
58 JCA ARCHITECT & DESIGN 7440 1028 LINCOLN AVE SAN JOSE CA 95125
59 Jeff Hickey 7440
60 Jeff Mullen A3301
61 JESSE SALECDA 5110
62 Kelex Security 8351 2959 s. winchester BLVD ste 100 Campbell CA 95008
63 lang vo A1240
64 Le Boulanger 5140 305 NORTH MATHILDA AVE. SUNNYVALE CA 94085
65 Leslie Kurnick A1260 1667 Page St. San Francisco CA 94117
66 LIMPIO CLEANING 7415
67 M.E. Fox & Company, Inc 5410 P.O. Box 60000 San Francisco CA 94160
68 Mahnaz Khazan 8430 15219 Sobey rd. Saratoga CA 95070
69 MARGUARD PAINTING 7450 P.O. BOX 8482 SAN JOSE CA 95155
70 Marz Vodka 5610 2350 mission college blvd suite 1152 Santa Clara CA 95054
71 METHOD CONSTRUCTION, INC. 7440 PO BOX 2702 GILROY CA 95020-4446
72 METRO PUBLISHING INC 9110 BOX 39000 SAN FRANCISCO CA 94139
73 Midwest 8511 PO BOX 9560 SPRINGFIELD IL 62791-9560
74 Mike Windows 7460 4501 SNELL AVE #1202 SAN JOSE CA 95136
75 MOOD MUZAK LLC 7246 P O BOX 71070 CHARLOTTE NC 28272-1070
76 Mr. Freeze, Inc. 5110 186 Cleveland Ave San Jose CA 95128
77 Muscardini cellars llc 4510 9380 Sonoma Highway Kenwood CA 95452
78 Newport Fish Co. 5114 457 South Canal ST. So. San Francisco CA 94080
79 NISSAN MOTOR ACCEPTANCE CORP 7310
80 Office of Tourism 9730 PO Box 101711 Pasadena CA 91189
81 Olsen's Pressure Washing 7450
82 Open table 7250 P.O. Box 8395 Pasadena CA 91109-8395
83 P & R PAPER SUPPLY CO 5910 2000 University Ave. Berkley CA 92373
84 PACIFIC HARVEST SEAFOOD - San Juan 5114 P.O. BOX 788 SAN JUAN BAUTISTA CA 95045
85 PACIFIC PRODUCE 5120 P. O. BOX 879 SOUTH SAN FRANCISCO CA 94080
86 Pacific seafood - Boston 5114 po box 842757 Boston MA 02284-2757
87 Paja Glen 8210
88 Palo Alto Foods 5110
89 PETTY ACCOUNT Groceries 5110
90 PETTY ACCOUNT Hardware 7320
91 Ridge vineyards 4510 p.o.box 742749 los angeles ca 95070
92 Rimon 8110
93 ROBERT'S GARDENING 7415 949 S 11TH ST SAN JOSE CA 95112
94 Rombauer Vineyards 5510 Department 33313 PO Box 39000 San Francisco CA 94139-3313
95 ROYAL SATELITE 7160
96 Ruben sanchez A2110
97 Ruchi Gowda 5510 3550 Marsh Manor Way San Jose CA 95121
98 Ruzz0 scholl & murphy 8120
99 S & S BOOKKEEPING 9315 3160 DE LA CRUZ BLVD STE 226 SANTA CLARA CA 95054
100 S.C.C D.T.A.C. 9730
101 SAFEGUARD BUSINESS SYS. 7510 PO BOX 88043 CHICAGO IL 60680-1043
102 SAN JOSE GIANTS 8210 P.O. BOX 21727 SAN JOSE CA 95151
103 Savannah Chanelle 5510 3600 Congress Spring Rd Saratoga CA 95070
104 SCC Tax Collector 9730 70 West Hedding Street East Wing, 6th Floor San Jose CA 95110-1767
105 SILICON VALLEY CARDIOLOGY 6040 1950 UNIVERSITY AVE, #160 E. PALO ALTO CA 94303
106 Silver mountian winery 5510
107 Silver oak cellars 5510 7370 Highway 128 Healdsburg CA 95448
108 SJP SIGNS 9110 1752 JUNCTION AVE SAN JOSE CA 95112
109 Skurnik Wines West, LLC 4510 P. O. Box 421 Syosset NY 11791-1315
110 Smart plumbers&rooter 7440
111 SOFT SERVE PARTS 7460 3245 E. PATRICK SUITE A LAS VEGAS NV 89120
112 SOOTER CONSULTING INC 8110 PO BOX 2301 MORGAN HILL CA 95038
113 SOUTH BAY REFRIGERATION INC 7460 P O BOX 54323 SAN JOSE CA 95154
114 SOUTHWEST TRADERS, INC. 5110
115 ST. LUCY SCHOOL 9150 76 KENNEDY AVE CAMPBELL CA 95008
116 STATE FARM INSURANCE SUPPORT CENTER 6040 P O BOX 68001 DALLAS TX 75368-001
117 SUNLAND CANDY WHOLESALE 5110 3232 N. FIGUEROA ST LOS ANGELES CA 90065
118 Supernova Spirits Inc. 5610 2350 Mission College Blvd suite 1152 Santa Clara CA 95054
119 Surveillance Solutions 8110 15466 Los Gatos Bvld #109-256 Los Gatos CA 95032
120 TACKTIX GRAPHIX 9110 14938 CAMDEN AVE. #209 SAN JOSE CA 95124
121 THE HARDFORD 9382 LOCKBOX 0234 PO 7247 PHILADELPHIA PA 19170-0234
122 The Iceman 7460 530 Lawrence Expy # 425 Sunnyvale CA 94085
123 TOBIASON AND ROOK BUILDERS 7440 1161 GLENN AVE SAN JOSE CA 95125
124 Troung Gia LLC 8210 1966 Cape Hilda Place San Jose CA 95133
125 UNITED CONTRACT SERVICES 7415 1161 RINGWOOD COURT, STE 170 SAN JOSE CA 95131
126 VALLEY IMAGES 7340 1925 KYLE PARK CT. SAN JOSE CA 95125
127 VERIZON WIRELESS 9380 P O BOX 660108 DALLAS TX 75266-0108
128 WELLS FARGO FINANCIAL CARDS A1298 P O BOX 30358 LOS ANGELES CA 90030-0358
129 WEST VALLEY COLLECTION 8330 PO BOX 60248 LOS ANGELES CA 90060-0248
130 West Valley Collection & Recycling, LLC 7450 1333 Old Oakland San Jose CA 95112
131 Western Freezers Specialty Equipment 7460 42285 Osgood Rd. Unit F Fremont CA 94539
132 Winchester printing 9350 2383 moorpark Ave. San Jose CA 95128

View File

@@ -749,3 +749,15 @@
(defn migrate-users [conn]
[(load-users (users/get-all))])
(defn merge-query [query-part-1 query-part-2]
(-> query-part-1
(update-in [:query :find] into (get-in query-part-2 [:query :find]))
(update-in [:query :in] into (get-in query-part-2 [:query :in]))
(update-in [:query :where] into (get-in query-part-2 [:query :where]))
(update-in [:args] into (get-in query-part-2 [:args]))))

View File

@@ -62,9 +62,11 @@
:auto-ap/add-import-status {:txes auto-ap.datomic.migrate.invoice-converter/add-import-status :requires [:auto-ap/add-default-location-2]}
:auto-ap/add-import-status-existing-invoices {:txes-fn 'auto-ap.datomic.migrate.invoice-converter/add-import-status-existing-invoices :requires [:auto-ap/add-import-status]}
:auto-ap/fix-check-numbers {:txes-fn 'auto-ap.datomic.migrate.check-numbers/fix-check-numbers :requires [:auto-ap/add-import-status-existing-invoices]}
:auto-ap/add-new-vendors {:txes-fn 'auto-ap.datomic.migrate.add-new-vendors/add-new-vendors :requires [:auto-ap/fix-check-numbers]}
}]
(println "Conforming database...")
(println (c/ensure-conforms conn norms-map))
(d/release conn)
(println "Done")))
#_(-main)

View File

@@ -0,0 +1,27 @@
(ns auto-ap.datomic.migrate.add-new-vendors
(:require [datomic.api :as d]
[auto-ap.datomic :refer [uri]]
[clojure.data.csv :as csv]
[clojure.java.io :as io]
[clojure.string :as str])
(:import [org.apache.commons.io.input BOMInputStream]))
(defn add-new-vendors [conn]
(let [[header & rows] (-> "vendor-list.csv" (io/resource) io/input-stream (BOMInputStream.) (io/reader) csv/read-csv)
headers (map read-string header)
new-vendors [(reduce
(fn [rows r]
(conj rows (reduce
(fn [r [header value]]
(condp = header
[:vendor/address] r
[:vendor/default-expense-account] (assoc-in r header (Integer/parseInt (str/replace value #"A" "")))
[:vendor/invoice-reminder-schedule] r
(assoc-in r header value)))
{}
(map vector headers r))))
[]
rows)]]
(println (ffirst new-vendors))
new-vendors
))

View File

@@ -3,11 +3,17 @@
[auto-ap.datomic :refer [uri]]))
(defn get-graphql [args]
(prn (->> (d/q '[:find (pull ?e [*])
:where [?e :vendor/name]]
(d/db (d/connect uri)))
(map first)
(take 5)))
(->> (d/q '[:find (pull ?e [*])
:where [?e :vendor/name]]
(d/db (d/connect uri)))
(->> (d/q '[:find (pull ?e [*])
:where [?e :vendor/name]]
(d/db (d/connect uri)))
(map first)
#_(map (fn [c]
(update c :client/bank-accounts
(fn [bas]

View File

@@ -8,6 +8,9 @@
[buddy.auth :refer [throw-unauthorized]]
[auto-ap.utils :refer [by]]
[auto-ap.graphql.utils :refer [assert-admin can-see-client? assert-can-see-client]]
[auto-ap.datomic :refer [uri merge-query]]
[datomic.api :as d]
[auto-ap.expense-accounts :as e-expense-accounts]
[auto-ap.datomic.clients :as d-clients]
[auto-ap.datomic.checks :as d-checks]
[auto-ap.datomic.users :as d-users]
@@ -199,12 +202,31 @@
:start {:type 'Int}
:end {:type 'Int}}}
:check_result {:fields {:invoices {:type '(list :invoice)}
:pdf_url {:type 'String}}}}
:pdf_url {:type 'String}}}
:expense_account_stat {:fields {:expense_account_id {:type 'Int}
:expense_account_name {:type 'String}
:total {:type 'String}}}
:invoice_stat {:fields {:name {:type 'String}
:paid {:type 'String}
:unpaid {:type 'String}}}
}
:queries
{:invoice_page {:type '(list :invoice_page)
{:expense_account_stats {:type '(list :expense_account_stat)
:args {:client_id {:type :id}}
:resolve :get-expense-account-stats}
:invoice_stats {:type '(list :invoice_stat)
:args {:client_id {:type :id}}
:resolve :get-invoice-stats}
:invoice_page {:type '(list :invoice_page)
:args {:import_status {:type 'String}
:status {:type 'String}
:client_id {:type :id}
@@ -465,6 +487,61 @@
(:bank_account_id args)
(:type args))))
(defn get-expense-account-stats [context {:keys [client_id] } value]
(let [result (cond-> {:query {:find ['?expense-account-id '(sum ?amount)]
:in ['$]
:where []}
:args [(d/db (d/connect uri)) client_id]}
client_id (merge-query {:query {:in ['?c]}
:args [client_id]})
(not client_id) (merge-query {:query {:where ['[?c :client/name]]}})
true (merge-query {:query {:where ['[?i :invoice/client ?c]
'[?i :invoice/expense-accounts ?expense-account]
'[?expense-account :invoice-expense-account/expense-account-id ?expense-account-id]
'[?expense-account :invoice-expense-account/amount ?amount]]}})
true (doto println)
true (d/query ))]
(for [[expense-account-id total] result]
{:expense_account_id expense-account-id :total total :expense_account_name (-> expense-account-id e-expense-accounts/expense-accounts :name)})))
(defn categorize [x]
(cond (<= x 0) :due
(<= x 30 ) :due-30
(<= x 60 ) :due-60
:else :due-later))
(defn get-invoice-stats [context {:keys [client_id] } value]
(let [result (cond-> {:query {:find ['?name '(sum ?outstanding-balance) '(sum ?total)]
:in ['$]
:where []}
:args [(d/db (d/connect uri)) client_id]}
client_id (merge-query {:query {:in ['?c]}
:args [client_id]})
(not client_id) (merge-query {:query {:where ['[?c :client/name]]}})
true (merge-query {:query {:where ['[?i :invoice/client ?c]
'[?i :invoice/outstanding-balance ?outstanding-balance]
'[?i :invoice/total ?total]
'[?i :invoice/date ?date]
'[(.toInstant ^java.util.Date ?date) ?d2]
'[(.between java.time.temporal.ChronoUnit/DAYS (java.time.Instant/now) ?d2 ) ?d3]
'[(+ 30 ?d3) ?d4]
'[(auto-ap.graphql/categorize ?d4) ?name]]}})
true (d/query ))
result (group-by first result)]
(for [[id name] [[:due "Due"] [:due-30 "0-30 days"] [:due-60 "31-60 days"] [:due-later ">60 days"] ]
:let [[[_ outstanding-balance total] ] (id result nil)
outstanding-balance (or outstanding-balance 0)
total (or total 0)]]
{:name name :unpaid outstanding-balance :paid (if (= :due id)
0
(- total outstanding-balance))})))
(def schema
@@ -474,6 +551,8 @@
:get-all-payments get-all-payments
:get-payment-page gq-checks/get-payment-page
:get-transaction-page gq-transactions/get-transaction-page
:get-expense-account-stats get-expense-account-stats
:get-invoice-stats get-invoice-stats
:get-client gq-clients/get-client
:get-user get-user
@@ -523,7 +602,11 @@
([id q v]
(println "executing graphql query" id q v)
(try
(time (simplify (execute schema q v {:id id})))
(let [result (time (simplify (execute schema q v {:id id})))]
(when (seq (:errors result))
(throw (ex-info "GraphQL error" {:result result})))
result)
(catch Exception e
(if-let [v (:validation-error (ex-data e))]
(println "validation error" v)

View File

@@ -14,7 +14,7 @@
:in ['$ '?code]
:where ['[?id :client/code ?code]]}
:args [(d/db (d/connect uri)) code]}))
(throw (ex-info "Client is not unique" {:validation-error "Client is not unique"}))))
(throw (ex-info "Client is not unique" {:validation-error (str "Client code '" code "' is not unique.")}))))
(defn edit-client [context {:keys [edit_client new_bank_accounts] :as args} value]
(assert-admin (:id context))

View File

@@ -21,7 +21,15 @@
:body (pr-str (ql/query (:identity r) (query-params "query") variables ))
:headers {"Content-Type" "application/edn"}})
(catch Exception e
{:status 400
:body (pr-str {:data (merge {:message (.getMessage e)} (ex-data e))})
:headers {"Content-Type" "application/edn"}}))))
(if-let [result (:result (ex-data e))]
{:status 400
:body (pr-str result)
:headers {"Content-Type" "application/edn"}}
(if-let [message (:validation-error (ex-data e) )]
{:status 400
:body (pr-str {:errors [(merge {:message message} (ex-data e))]})
:headers {"Content-Type" "application/edn"}}
{:status 500
:body (pr-str {:errors [(merge {:message (.getMessage e)} (ex-data e))]})
:headers {"Content-Type" "application/edn"}}))))))
wrap-secure))

View File

@@ -28,16 +28,16 @@
(s/def ::bank-accounts (s/coll-of ::bank-account))
(s/def ::location string?)
(s/def ::locations (s/coll-of ::location))
(s/def ::locations (s/coll-of ::location :min-count 1))
(s/def ::email (s/nilable (s/and string? (s/or :is-email #(re-matches email-regex %)
:is-empty #(= % "")))))
(s/def ::client (s/keys :req-un [::name ::code]
(s/def ::client (s/keys :req-un [::name ::code ::locations]
:opt-un [::email
::address
::locations
::bank-accounts
::id]))

View File

@@ -337,6 +337,7 @@
9365 {:name "Office Maintenance - HQ" :parent 9300 :location "HQ" }
9370 {:name "Utilities - HQ" :parent 9300 :location "HQ" }
9380 {:name "Telephone - HQ" :parent 9300 :location "HQ" }
9383 {:name "Storage - HQ" :parent 9380 :location "HQ" }
9500 {:name "HQ Interest and Bank Expenses" :parent nil :location "HQ" }
9510 {:name "Bank Fees - HQ" :parent 9500 :location "HQ" }
9520 {:name "NSF Fees - HQ" :parent 9500 :location "HQ" }

View File

@@ -8,7 +8,8 @@
[auto-ap.effects :as effects]
[pushy.core :as pushy]
[auto-ap.history :as p]
[bidi.bidi :as bidi]))
[bidi.bidi :as bidi]
[cljsjs.recharts]))
(defn dev-setup []
(when true

View File

@@ -132,6 +132,7 @@
(swap! timeouts dissoc key))
time))))
(re-frame/reg-fx
:graphql
(fn [{:keys [query on-success on-error token variables query-obj]}]
@@ -148,7 +149,7 @@
(when on-error
(->> response
:body
:data
:errors
(dates->date-times)
(conj on-error)
(re-frame/dispatch)))

View File

@@ -18,6 +18,7 @@
::initialize-db
(fn [{:keys [db]} [_ token]]
(let [handler (:handler (bidi/match-route routes/routes (.. js/window -location -pathname)))]
(prn (and token (get (jwt->data token) "user/role")))
(cond
(and (not= :login handler) (not token))
{:redirect "/login"
@@ -25,7 +26,7 @@
:active-page :login
:user token)}
(and token (= "none" (get (jwt->data token) "role") ))
(and token (= "none" (or (get (jwt->data token) "role") (get (jwt->data token) "user/role")) ))
{:redirect "/needs-activation"
:db (assoc db/default-db
:active-page :needs-activation
@@ -76,7 +77,8 @@
(fn [db [_ {clients :client vendors :vendor :as x}]]
(-> db
(assoc :clients (by :id clients) )
(assoc :vendors (by :id vendors) ))))
(assoc :vendors (by :id vendors) )
(assoc :client (when (= 1 (count clients)) (->> clients first :id ))))))
(re-frame/reg-event-db
::swap-client

View File

@@ -54,6 +54,12 @@
(fn [db]
(vals (:vendors db))))
(re-frame/reg-sub
::sorted-vendors
:<- [::vendors]
(fn [vendors]
(sort-by :name vendors)))
(re-frame/reg-sub
::admin
(fn [db]

View File

@@ -1,5 +1,7 @@
(ns auto-ap.views.components.layouts
(:require
[cljsjs.react-transition-group]
[reagent.core :as reagent]
[re-frame.core :as re-frame]
[bidi.bidi :as bidi]
[auto-ap.routes :as routes]
@@ -8,7 +10,8 @@
[auto-ap.views.utils :refer [active-when active-when= login-url dispatch-event]]
[auto-ap.views.components.vendor-dialog :refer [vendor-dialog]]))
(def css-transition-group
(reagent/adapt-react-class js/ReactTransitionGroup.CSSTransition))
(defn login-dropdown []
(let [user (re-frame/subscribe [::subs/user])
menu (re-frame/subscribe [::subs/menu])]
@@ -28,7 +31,7 @@
(let [client (re-frame/subscribe [::subs/client])
clients (re-frame/subscribe [::subs/clients])
menu (re-frame/subscribe [::subs/menu])]
[:nav {:class "navbar has-shadow"}
[:nav {:class "navbar has-shadow is-fixed-top"}
[:div {:class "container"}
[:div {:class "navbar-brand"}
[:a {:class "navbar-item", :href "../"}
@@ -52,52 +55,56 @@
[:span]
[:span]]
[:div.navbar-end
[:div { :class (str "navbar-item has-dropdown " (when (get-in @menu [:client :active?]) "is-active"))}
[:a {:class "navbar-link login" :on-click (fn [] (re-frame/dispatch [::events/toggle-menu :client]))} "Client: " (if @client (:name @client)
"All")]
[:div {:class "navbar-dropdown"}
[:a {:class "navbar-item"
:on-click (fn []
(re-frame/dispatch [::events/toggle-menu :client])
(re-frame/dispatch [::events/swap-client nil]))
} "All"]
[:hr {:class "navbar-divider"}]
(for [{:keys [name id] :as client} @clients]
^{:key id }
(when (> (count @clients) 1)
[:div { :class (str "navbar-item has-dropdown " (when (get-in @menu [:client :active?]) "is-active"))}
[:a {:class "navbar-link login" :on-click (fn [] (re-frame/dispatch [::events/toggle-menu :client]))} "Client: " (if @client (:name @client)
"All")]
[:div {:class "navbar-dropdown"}
[:a {:class "navbar-item"
:on-click (fn []
(re-frame/dispatch [::events/toggle-menu :client])
(re-frame/dispatch [::events/swap-client client]))
} name])]]]]
(re-frame/dispatch [::events/swap-client nil]))
} "All"]
[:hr {:class "navbar-divider"}]
(for [{:keys [name id] :as client} @clients]
^{:key id }
[:a {:class "navbar-item"
:on-click (fn []
(re-frame/dispatch [::events/toggle-menu :client])
(re-frame/dispatch [::events/swap-client client]))
} name])]])]]
[login-dropdown]]]))
(defn footer []
[:footer {:class "footer"}
[:div {:class "container"}
[:div {:class "content has-text-centered"}
[:p
[:strong "Integreat"]]
[:p
[:a {:class "icon", :href "https://github.com/dansup/bulma-templates"}
[:i {:class "fa fa-github"}]]]]]])
[:footer {:style {:padding "1em"}}
[:div {:class "content has-text-centered"}
[:p
[:strong "Integreat"] ]]])
(defn side-bar-layout [{:keys [side-bar main ap bottom right-side-bar]}]
(defn appearing-side-bar [{:keys [visible?]} & children ]
(let [final-state (reagent/atom visible?)]
(fn [{:keys [visible?]} & children]
[css-transition-group {:in visible? :class-names {:exitDone "bounce animated" :exit "fadeOutRight animated" :enter "fadeInRight animated"} :timeout 300 :onEnter (fn [] (reset! final-state true )) :onExited (fn [] (reset! final-state false))}
(if (or @final-state visible?)
[:aside {:class "column is-3 aside menu" :style {:height "calc(100vh - 46px)" :overflow "auto"}}
[:div.sub-main {} children ]]
[:div])])))
(defn side-bar-layout [{:keys [side-bar main ap bottom right-side-bar right-side-bar-visible?]}]
(let [ap @(re-frame/subscribe [::subs/active-page])
client @(re-frame/subscribe [::subs/client])]
[:div
[navbar ap]
[:div {:class "columns ", :id "mail-app"}
[:aside {:class "column is-narrow aside menu hero is-fullheight"}
[:div.main.left-nav
side-bar]]
[:div {:class "column messages hero is-fullheight", :id "message-feed"}
[:div {:class "columns has-shadow", :style {:margin-bottom "0px" :height "calc(100vh - 46px)" } :id "mail-app" }
[:aside {:class "column aside menu is-2 " }
[:div.main.left-nav
[:div side-bar
]]]
[:div {:class "column messages hero " :style { :overflow "auto" }, :id "message-feed"}
^{:key (str "active-page-" (:name client))}
[:div.inbox-messages main]]
(when right-side-bar
[:aside.fadeInRight.animated {:class "column aside is-narrow menu hero is-fullheight" :style {:animation-duration "0.75s"}}
[:div.sub-main
right-side-bar]])]
[footer]
[appearing-side-bar {:visible? right-side-bar-visible?} right-side-bar]]
#_[footer]
bottom
[:div#dz-hidden]]))

View File

@@ -10,10 +10,12 @@
[auto-ap.views.pages.unpaid-invoices :refer [unpaid-invoices-page]]
[auto-ap.views.pages.import-invoices :refer [import-invoices-page]]
[auto-ap.views.pages.paid-invoices :refer [paid-invoices-page]]
[auto-ap.views.pages.needs-activation :refer [needs-activation-page]]
[auto-ap.views.pages.transactions :refer [transactions-page]]
[auto-ap.views.pages.login :refer [login-page]]
[auto-ap.views.pages.checks :refer [checks-page]]
[auto-ap.views.pages.admin :refer [admin-page]]
[auto-ap.views.pages.home :refer [home-page]]
[auto-ap.views.pages.admin.clients :refer [admin-clients-page]]
[auto-ap.views.pages.admin.vendors :refer [admin-vendors-page]]
[auto-ap.views.pages.admin.excel-import :refer [admin-excel-import-page]]
@@ -59,12 +61,16 @@
(admin-yodlee-page))
(defmethod page :index [_]
[side-bar-layout {:side-bar [:div]
:main [:h1 "Home"]}])
(home-page)
)
(defmethod page :login [_]
[login-page])
(defmethod page :needs-activation [_]
[needs-activation-page])
(defmethod page :admin-excel-import [_]
[admin-excel-import-page])

View File

@@ -2,6 +2,7 @@
(:require-macros [cljs.core.async.macros :refer [go]]
[clojure.string :as str])
(:require [re-frame.core :as re-frame]
[reagent.core :as reagent]
[clojure.spec.alpha :as s]
[clojure.string :as str]
@@ -17,151 +18,149 @@
[auto-ap.routes :as routes]
[bidi.bidi :as bidi]))
(re-frame/reg-event-fx
(re-frame/reg-sub
::form
(fn [db [_ x]]
(-> db ::forms x)))
(re-frame/reg-sub
::loading-class
(fn [db [_ x]]
(if (= (get-in db [::forms x :status]) "loading")
"is-loading"
"")))
(defn start-form [db form data]
(assoc-in db [::forms form] {:error nil
:status nil
:data data}))
(defn stop-form [db form]
(update db ::forms dissoc form))
(re-frame/reg-event-db
::form-closing
(fn [db [_ f]]
(-> db
(assoc-in [:admin :adding-client?] false)
(stop-form f))))
(re-frame/reg-event-db
::new
(fn [{:keys [db]} [_ client-id]]
{:db (-> db (assoc-in [:admin :adding-client?] true)
(assoc-in [:admin :new-client] {:new-account {:type :check}}))}))
(fn [db [_ client-id]]
(-> db
(assoc-in [:admin :adding-client?] true)
(start-form ::new-client (assoc {} :new-account {:type :check})))))
(re-frame/reg-event-fx
::edit-client-clicked
(fn [{:keys [db]} [_ client-id]]
{:db (-> db
(assoc-in [:admin :new-client] (assoc (get (:clients db) client-id) :new-account {:type :check}))
(start-form ::new-client (assoc (get (:clients db) client-id) :new-account {:type :check}))
(assoc-in [:admin :adding-client? ] true))}))
(re-frame/reg-event-fx
::save
(fn [{:keys [db]} _]
(let [edited-client (-> (:client @(re-frame/subscribe [::subs/admin]))
(dissoc :location))]
{:db (assoc-in db [:admin :client :saving?] true)
:graphql
{:token (-> db :user)
:query-obj {:venia/operation {:operation/type :mutation
:operation/name "EditClient"}
:venia/queries [{:query/data [:edit-client
{:edit-client
(-> edited-client
(update :bank-accounts #(seq (into % (map (fn [ba] (dissoc ba :is-new?)) (:new-bank-accounts edited-client)))))
(dissoc :new-account)
(dissoc :new-bank-accounts)
)}
[:id :name :code :email [:address [:street1 :street2 :city :state :zip]] [:bank-accounts [:id :number :check-number :name :code :bank-code :bank-name :routing]]]]}]}
:on-success [::save-complete]
:on-error [::save-error]}})))
(re-frame/reg-event-fx
::save-new-client
(fn [{:keys [db]} _]
(let [new-client (-> (:new-client @(re-frame/subscribe [::subs/admin]))
(dissoc :location))]
{:db (assoc-in db [:admin :client :saving?] true)
:graphql
{:token (-> db :user)
:query-obj {:venia/operation {:operation/type :mutation
:operation/name "EditClient"}
:venia/queries [{:query/data [:edit-client
{:edit-client
;; TODO - hard code fields we want
(-> new-client
(update :bank-accounts #(seq (into % (map (fn [ba] (dissoc ba :is-new?)) (:new-bank-accounts new-client)))))
(dissoc :new-bank-accounts))
}
[:id :name :code :email [:address [:street1 :street2 :city :state :zip]] [:bank-accounts [:id :number :check-number :name :code :bank-code :bank-name :routing]]]
]}]}
:on-success [::save-complete]
:on-error [::save-error]}})))
[(re-frame/path [::forms ::new-client])]
(fn [{{new-client-data :data :as new-client-form} :db} _]
(re-frame/reg-event-fx
(let [new-client-req {:id (:id new-client-data),
:name (:name new-client-data)
:code (:code new-client-data) ;; TODO add validation can't change
:email (:email new-client-data)
:locations (:locations new-client-data)
:address {:street1 (:street1 (:address new-client-data))
:street2 (:street2 (:address new-client-data)),
:city (:city (:address new-client-data))
:state (:state (:address new-client-data))
:zip (:zip (:address new-client-data))}
:bank-accounts (map (fn [{:keys [number name check-number type id code bank-name routing bank-code]}]
{:number number
:name name
:check-number check-number
:type type
:id id
:code (str (:code new-client-data) "-" code)
:bank-name bank-name
:routing routing
:bank-code bank-code})
(:bank-accounts new-client-data))}
user @(re-frame/subscribe [::subs/token])]
(if (s/valid? ::entity/client new-client-req)
{:db (-> new-client-form
(assoc :status :loading)
(assoc :error nil))
:graphql
{:token user
:query-obj {:venia/operation {:operation/type :mutation
:operation/name "EditClient"}
:venia/queries [{:query/data [:edit-client
{:edit-client new-client-req}
[:id :name :code :email :locations [:address [:street1 :street2 :city :state :zip]] [:bank-accounts [:id :number :check-number :name :code :bank-code :bank-name :routing]]]]}]}
:on-success [::save-complete]
:on-error [::save-error]}}
{:db new-client-form}))))
(re-frame/reg-event-db
::save-complete
(fn [{:keys [db]} [_ client]]
{:dispatch [::events/modal-completed :auto-ap.views.pages.admin.clients/edit]
:db (-> db
(assoc-in [:admin :adding-client?] false)
(update :admin dissoc :new-client)
(assoc-in [:admin :client] nil)
(assoc-in [:clients (:id (:edit-client client))] (:edit-client client)))}))
(fn [db [_ client]]
(-> db
(stop-form ::new-client)
(assoc-in [:admin :adding-client?] false)
(assoc-in [:clients (:id (:edit-client client))] (:edit-client client)))))
(re-frame/reg-event-db
::save-error
(fn [db [_ client]]
[(re-frame/path [::forms ::new-client])]
(fn [db [_ result]]
(-> db
(assoc-in [:admin :client :saving?] false)
(assoc-in [:admin :client :error] true))))
(re-frame/reg-event-db
::change
(fn [db [_ path value]]
(assoc-in db (concat [:admin :client] path)
value)))
(assoc :status :error)
(assoc :error (:message (first result))))))
(re-frame/reg-event-db
::change-new
[(re-frame/path [::forms ::new-client :data])]
(fn [db [_ path value]]
(assoc-in db (concat [:admin :new-client] path)
value)))
(assoc-in db path value)))
(re-frame/reg-event-fx
::add-location
(fn [{:keys [db]} _]
(let [client (:client @(re-frame/subscribe [::subs/admin]))]
{:db (-> db
(update-in [:admin :client :locations] conj (:location client))
(update-in [:admin :client] dissoc :location))})))
(re-frame/reg-event-fx
(re-frame/reg-event-db
::add-new-location
(fn [{:keys [db]} _]
(let [client (:new-client @(re-frame/subscribe [::subs/admin]))]
{:db (-> db
(update-in [:admin :new-client :locations] conj (:location client))
(update-in [:admin :new-client] dissoc :location))})))
[(re-frame/path [::forms ::new-client :data])]
(fn [client _]
(-> client
(update :locations conj (:location client))
(dissoc :location))))
(re-frame/reg-event-fx
(re-frame/reg-event-db
::add-new-bank-account
(fn [{:keys [db]} _]
(let [client (:client @(re-frame/subscribe [::subs/admin]))
_ (prn (s/explain-data ::entity/bank-account (:new-account client)))
new-bank-account (:new-account client)
new-bank-account (-> new-bank-account
(update :code #(str (:code client) "-" %))
(update :check-number #(if (seq %) (js/parseInt %) nil))
(update :yodlee-account-id #(if (seq %) (js/parseInt %) nil))
(assoc :is-new? true))]
{:db (-> db
(update-in [:admin :client :new-bank-accounts] (fn [bank-accounts]
(conj bank-accounts new-bank-account)))
(update-in [:admin :client :new-account] {:type :check}))})))
(re-frame/reg-event-fx
::add-new-new-bank-account
(fn [{:keys [db]} _]
(let [client (:new-client @(re-frame/subscribe [::subs/admin]))
new-bank-account (:new-account client)
new-bank-account (-> new-bank-account
(update :code #(str (:code client) "-" %))
(update :check-number #(if (seq %) (js/parseInt %) nil))
(update :yodlee-account-id #(if (seq %) (js/parseInt %) nil))
(assoc :is-new? true))]
{:db (-> db
(update-in [:admin :new-client :new-bank-accounts] (fn [bank-accounts]
(conj bank-accounts new-bank-account)))
(update-in [:admin :new-client] dissoc :new-account))})))
[(re-frame/path [::forms ::new-client :data])]
(fn [{:keys [new-account] :as client} _]
(let [new-account (-> new-account
(update :check-number #(if (seq %) (js/parseInt %) nil))
(update :yodlee-account-id #(if (seq %) (js/parseInt %) nil)))]
(if ((->> client (:bank-accounts)
(map :code)
set) (:code new-account))
client
(-> client
(update :bank-accounts conj new-account )
(assoc :new-account {:type :check}))))))
(re-frame/reg-event-db
::remove-new-bank-account
(fn [db [_ index]]
(update-in db [:admin :new-client :new-bank-accounts]
[(re-frame/path [::forms ::new-client :data])]
(fn [db [_ code]]
(update db :bank-accounts
(fn [bas]
(vec (concat (take index bas)
(drop (inc index) bas)))))))
(filter #(not= (:code %) code) bas)))))
(defn clients-table []
(let [clients (re-frame/subscribe [::subs/clients])
@@ -182,161 +181,7 @@
[:td (str/join ", " locations)]
[:td email]])]]))
(defn clients-modal []
(let [original-client-code (:code (:client @(re-frame/subscribe [::subs/admin])))]
(fn []
(let [editing-client (:client @(re-frame/subscribe [::subs/admin]))]
[action-modal {:id ::edit
:title (str "Edit " (:name editing-client))
:action-text "Save"
:save-event [::save]}
[horizontal-field
[:label.label "Name"]
[:div.control
[bind-field
[:input.input {:type "text"
:field :name
:spec ::entity/name
:event ::change
:subscription editing-client}]]]]
[horizontal-field
[:label.label "Client code"]
[:div.control
[bind-field
[:input.input {:type "code"
:field :code
:disabled (if (str/blank? original-client-code)
""
"disabled")
:spec ::entity/code
:event ::change
:subscription editing-client}]]]]
[horizontal-field
[:label.label "Email"]
[:div.control
[bind-field
[:input.input {:type "email"
:field :email
:spec ::entity/email
:event ::change
:subscription editing-client}]]]]
[horizontal-field
[:label.label "Locations"]
[:div.control
[:div.field.has-addons
[:p.control
[bind-field
[:input.input {:type "text"
:field :location
:event ::change
:subscription editing-client}]]]
[:p.control [:button.button.is-primary {:on-click (dispatch-event [::add-location])} "Add"]]]
[:ul
(for [location (:locations editing-client)]
^{:key location} [:li location ])]]]
[:h2.subtitle "Address"]
[address-field {:field [:address]
:event ::change
:subscription editing-client}]
[:h2.subtitle "Add account"]
[horizontal-field
[:label.label "Acct code"]
[:div.control
[:div.field.has-addons.is-extended
[:p.control [:a.button.is-static (:code editing-client) "-" ]]
[:p.control
[bind-field
[:input.input {:type "code"
:field [:new-account :code]
:spec ::entity/code
:event ::change
:subscription editing-client}]]]]]]
[horizontal-field
[:label.label "Bank"]
[:div.control
[bind-field
[:input.input {:placeholder "Bank Name"
:type "text"
:field [:new-account :bank-name]
:event ::change
:subscription editing-client}]]]
[:div.control
[bind-field
[:input.input {:placeholder "Routing"
:type "text"
:field [:new-account :routing]
:event ::change
:subscription editing-client}]]]
[:div.control
[bind-field
[:input.input {:placeholder "Code"
:type "text"
:field [:new-account :bank-code]
:event ::change
:subscription editing-client}]]]]
[horizontal-field
[:label.label "Account"]
[:div.control
[bind-field
[:input.input {:placeholder "Nickname"
:type "text"
:field [:new-account :name]
:event ::change
:subscription editing-client}]]]
[:div.control
[bind-field
[:input.input {:placeholder "Acct #"
:type "text"
:field [:new-account :number]
:event ::change
:subscription editing-client}]]]
[:div.control
[bind-field
[:input.input {:placeholder "Check #"
:type "text"
:field [:new-account :check-number]
:event ::change
:subscription editing-client}]]]]
[horizontal-field
[:label.label "Yodlee Account"]
[:div.control
[bind-field
[:input.input {:placeholder "Yodlee Account #"
:type "text"
:field [:new-account :yodlee-account-id]
:event ::change
:subscription editing-client}]]]
[:div.control
[:button.button.is-primary.is-pulled-right {:on-click (dispatch-event [::add-new-bank-account])
:disabled (if (and (s/valid? ::entity/bank-account (:new-account editing-client))
(not ((set (map :code (:bank-accounts editing-client)))
(str (:code editing-client) "-" (-> editing-client :new-account :code)))))
""
"disabled")} "Add"]]]
[:h2.subtitle "Bank Accounts"]
[horizontal-field
nil
[:div.control
[:ul
(for [{:keys [code name number check-number id]} (:bank-accounts editing-client)]
^{:key id} [:li code ": " name])
(for [[index {:keys [name code number check-number]}] (map vector (range) (:new-bank-accounts editing-client))]
^{:key index} [:li [:strong "* " code ": " name] [:button.button {:on-click (dispatch-event [::remove-new-bank-account index])} [:span.icon [:i.fa.fa-times]]]])]]]
(when (:saving? editing-client) [:div.is-overlay {:style {"backgroundColor" "rgba(150,150,150, 0.5)"}}])]))))
(defn admin-clients-content []
[:div
@@ -346,19 +191,20 @@
[:h1.title "Clients"]
[:div.is-pulled-right
[:a.button.is-primary.is-large {:on-click (dispatch-event [::new])} "New client"]]
[clients-table]
(when editing-client
[clients-modal])])])
[clients-table]])])
(defn side-bar-form [_ children]
[:div [:a.delete.is-pulled-right {:on-click (dispatch-event [::form-closing ::new-client])}] [:div children]])
(defn new-client-form []
(let [new-client (:new-client @(re-frame/subscribe [::subs/admin]))]
[:div
[:form
[:section.section {:style {:padding-bottom "0.75em" :padding-top "0.75em"}}
[:h1.title "Add client"]
(let [{error :error new-client :data } @(re-frame/subscribe [::form ::new-client])]
[side-bar-form {}
[:form
[:h1.title.is-2 "Add client"]
[:div.field
[:label.label "Name"]
[:p.help "Name"]
[:div.control
[bind-field
[:input.input {:type "text"
@@ -368,7 +214,7 @@
:subscription new-client}]]]]
[:div.field
[:label.label "Client code"]
[:p.help "Client code"]
[:div.control
[bind-field
[:input.input {:type "code"
@@ -378,7 +224,7 @@
:subscription new-client}]]]]
[:div.field
[:label.label "Email"]
[:p.help "Email"]
[:div.control
[bind-field
[:input.input {:type "email"
@@ -388,7 +234,7 @@
:subscription new-client}]]]]
[:div.field
[:label.label "Locations"]
[:p.help "Locations"]
[:div.control
[:div.field.has-addons
[:p.control
@@ -401,130 +247,149 @@
[:ul
(for [location (:locations new-client)]
^{:key location} [:li location ])]]]
]
[:section.section {:style {:padding-bottom "0.75em" :padding-top "0.75em"}}
[:h2.subtitle "Address"]
[address-field {:field [:address]
:event ::change-new
:subscription new-client}]]
[:div {:style {:padding-bottom "0.75em" :padding-top "0.75em"}}
[:h2.subtitle "Address"]
[address-field {:field [:address]
:event ::change-new
:subscription new-client}]]
[:nav.panel
[:p.panel-heading "Bank accounts"]
(for [{:keys [type code name number check-number id]} (:bank-accounts new-client)]
(if id
^{:key code}
[:a.panel-block {:style {:position "relative"}}
[:span.panel-icon
(if (= type :check)
[:span.icon-check-payment-sign]
[:span.icon-accounting-bill])]
code ": " name]
^{:key code}
[:li [:strong "* " code ": " name] [:button.button {:on-click (dispatch-event [::remove-new-bank-account code])} [:span.icon [:i.fa.fa-times]]]]))
[:div.panel-block
[:nav.level
[:div.level-item.has-text-centered
[:button.button.is-outlined.is-primary.is-fullwidth "Add Checking Account"]]
[:div.level-item.has-text-centered
[:button.button.is-outlined.is-primary.is-fullwidth "Add Cash Account"]]]]
#_(for [[index {:keys [name code number check-number]}] (map vector (range) (:new-bank-accounts new-client))]
^{:key index} [:li [:strong "* " code ": " name] [:button.button {:on-click (dispatch-event [::remove-new-bank-account index])} [:span.icon [:i.fa.fa-times]]]])]
[:section.section {:style {:padding-bottom "0.75em" :padding-top "0.75em" :background "hsl(0, 0%, 96%)"}}
[:h2.subtitle "Add bank account"]
[:label.label "General"]
[horizontal-field
nil
[:div.control
[:p.help "Account Code"]
[:div.field.has-addons.is-extended
[:p.control [:a.button.is-static (:code new-client) "-" ]]
[:p.control
[bind-field
[:input.input {:type "code"
:field [:new-account :code]
:spec ::entity/code
:event ::change-new
:subscription new-client}]]]]]
#_[:h2.subtitle "Add bank account"]
#_[:div {:style {:padding-bottom "0.75em" :padding-top "0.75em" :background "hsl(0, 0%, 96%)"}}
[:label.label "General"]
[horizontal-field
nil
[:div.control
[:p.help "Account Code"]
[:div.field.has-addons.is-extended
[:p.control [:a.button.is-static (:code new-client) "-" ]]
[:p.control
[bind-field
[:input.input {:type "code"
:field [:new-account :code]
:spec ::entity/code
:event ::change-new
:subscription new-client}]]]]]
[:div.control
[:p.help "Nickname"]
[bind-field
[:input.input {:placeholder "BOA Checking #1"
:type "text"
:field [:new-account :name]
:event ::change-new
:subscription new-client}]]]]
[:div.control
[:p.help "Nickname"]
[bind-field
[:input.input {:placeholder "BOA Checking #1"
:type "text"
:field [:new-account :name]
:event ::change-new
:subscription new-client}]]]]
[:label.label "Bank"]
[horizontal-field
nil
[:div.control
[:p.help "Bank Name"]
[bind-field
[:input.input {:placeholder "Bank of America"
:type "text"
:field [:new-account :bank-name]
:event ::change-new
:subscription new-client}]]]
[:div.control
[:p.help "Routing #"]
[bind-field
[:input.input {:placeholder "104819123"
:type "text"
:field [:new-account :routing]
:event ::change-new
:subscription new-client}]]]
[:div.control
[:p.help "Bank code"]
[bind-field
[:input.input {:placeholder "12/10123"
:type "text"
:field [:new-account :bank-code]
:event ::change-new
:subscription new-client}]]]]
[:label.label "Bank"]
[horizontal-field
nil
[:div.control
[:p.help "Bank Name"]
[bind-field
[:input.input {:placeholder "Bank of America"
:type "text"
:field [:new-account :bank-name]
:event ::change-new
:subscription new-client}]]]
[:div.control
[:p.help "Routing #"]
[bind-field
[:input.input {:placeholder "104819123"
:type "text"
:field [:new-account :routing]
:event ::change-new
:subscription new-client}]]]
[:div.control
[:p.help "Bank code"]
[bind-field
[:input.input {:placeholder "12/10123"
:type "text"
:field [:new-account :bank-code]
:event ::change-new
:subscription new-client}]]]]
[:label.label "Checking account"]
[horizontal-field
nil
[:div.control
[:p.help "Account #"]
[bind-field
[:input.input {:placeholder "123456789"
:type "text"
:field [:new-account :number]
:event ::change-new
:subscription new-client}]]]
[:div.control
[:p.help "Check Number"]
[bind-field
[:input.input {:placeholder "10000"
:type "text"
:field [:new-account :check-number]
:event ::change-new
:subscription new-client}]]]]
[:label.label "Checking account"]
[horizontal-field
nil
[:div.control
[:p.help "Account #"]
[bind-field
[:input.input {:placeholder "123456789"
:type "text"
:field [:new-account :number]
:event ::change-new
:subscription new-client}]]]
[:div.control
[:p.help "Check Number"]
[bind-field
[:input.input {:placeholder "10000"
:type "text"
:field [:new-account :check-number]
:event ::change-new
:subscription new-client}]]]]
[:div.field
[:label.label "Yodlee Account"]
[:div.control
[bind-field
[:input.input {:placeholder "Yodlee Account #"
:type "text"
:field [:new-account :yodlee-account-id]
:event ::change-new
:subscription new-client}]]]
]
[:div.field
[:div.control
(println (s/explain-data ::entity/bank-account (:new-account new-client)))
[:button.button.is-primary {:disabled (if (and (doto (s/valid? ::entity/bank-account (:new-account new-client)) println)
(not ((set (map :code (:new-bank-accounts new-client)))
(str (:code new-client) "-" (-> new-client :new-account :code)))))
""
"disabled")
:on-click (dispatch-event [::add-new-new-bank-account])} "Add"]]]]
[:div.field
[:label.label "Yodlee Account"]
[:div.control
[bind-field
[:input.input {:placeholder "Yodlee Account #"
:type "text"
:field [:new-account :yodlee-account-id]
:event ::change-new
:subscription new-client}]]]
]
[:div.field
[:div.control
#_(println (s/explain-data ::entity/bank-account (:new-account new-client)))
[:button.button.is-primary {:disabled (if (and (doto (s/valid? ::entity/bank-account (:new-account new-client)) println)
(not ((set (map :code (:new-bank-accounts new-client)))
(str (:code new-client) "-" (-> new-client :new-account :code)))))
""
"disabled")
:on-click (dispatch-event [::add-new-bank-account])} "Add"]]]]
[:section.section {:style {:padding-bottom "0.75em" :padding-top "0.75em"}}
[:h2.subtitle "Bank Accounts"]
[:div.field
nil
[:div.control
[:ul
(for [{:keys [code name number check-number id]} (:bank-accounts new-client)]
^{:key id} [:li code ": " name])
(for [[index {:keys [name code number check-number]}] (map vector (range) (:new-bank-accounts new-client))]
^{:key index} [:li [:strong "* " code ": " name] [:button.button {:on-click (dispatch-event [::remove-new-bank-account index])} [:span.icon [:i.fa.fa-times]]]])]]]]
#_(when (:saving? new-client) [:div.is-overlay {:style {"backgroundColor" "rgba(150,150,150, 0.5)"}}])
(println (s/explain-data ::entity/client new-client))
[:submit.button.is-large.is-primary {:disabled (if (s/valid? ::entity/client new-client)
""
"disabled")
:on-click (dispatch-event [::save-new-client])} "Save"]]]))
#_(when (:saving? new-client) [:div.is-overlay {:style {"backgroundColor" "rgba(150,150,150, 0.5)"}}])
#_(println (s/explain-data ::entity/client new-client))
(when error
[:div.notification.is-warning.animated.fadeInUp
error])
[:submit.button.is-large.is-primary {:disabled (if (s/valid? ::entity/client new-client)
""
"disabled")
:on-click (dispatch-event [::save-new-client])
:class (str @(re-frame/subscribe [::loading-class ::new-client]) (when error " animated shake"))} "Save"]]]))
(defn admin-clients-page []
(let [{:keys [adding-client?]} @(re-frame/subscribe [::subs/admin])]
[side-bar-layout {:side-bar [admin-side-bar {}]
:main [admin-clients-content]
:right-side-bar (when adding-client?
[new-client-form])}]))
:right-side-bar-visible? adding-client?
:right-side-bar [new-client-form]}]))

View File

@@ -24,7 +24,7 @@
(set (mapcat :in (::s/problems (s/explain-data spec v)))))
(defn vendors-table []
(let [vendors (re-frame/subscribe [::subs/vendors])
(let [vendors (re-frame/subscribe [::subs/sorted-vendors])
editing-vendor (:editing @(re-frame/subscribe [::subs/admin]))]
[:table {:class "table", :style {:width "100%"}}

View File

@@ -0,0 +1,110 @@
(ns auto-ap.views.pages.home
(:require [auto-ap.views.components.layouts :refer [side-bar-layout]]
[re-frame.core :as re-frame]
[auto-ap.subs :as subs]
[reagent.core :as r]))
(def pie-chart (r/adapt-react-class js/Recharts.PieChart))
(def pie (r/adapt-react-class js/Recharts.Pie))
(def bar-chart (r/adapt-react-class js/Recharts.BarChart))
(def x-axis (r/adapt-react-class js/Recharts.XAxis))
(def y-axis (r/adapt-react-class js/Recharts.YAxis))
(def bar (r/adapt-react-class js/Recharts.Bar))
(def legend (r/adapt-react-class js/Recharts.Legend))
(def cell (r/adapt-react-class js/Recharts.Cell))
(def tool-tip (r/adapt-react-class js/Recharts.Tooltip))
(def colors ["hsl(171, 100%, 41%)" "hsl(217, 71%, 53%)" "hsl(141, 71%, 48%)" "hsl(48, 100%, 67%)" "hsl(348, 100%, 61%)" "hsl(217, 71%, 53%)"])
(def light-colors ["hsl(171, 60%, 80%)" "hsl(217, 71%, 53%)" "hsl(141, 71%, 48%)" "hsl(48, 100%, 67%)" "hsl(348, 100%, 61%)" "hsl(217, 71%, 53%)"])
(defn make-pie-chart
[{:keys [width height data]}]
[pie-chart {:width width
:height height}
[pie {:fill "#82ca9d"
:data data
:dataKey "value"
:inner-radius 20}
(map (fn [x y]
^{:key y}
[cell {:key y :fill (colors y)}]) data (range))
]
[tool-tip]
[legend]])
(defn make-bar-chart [{:keys [width height data]}]
[bar-chart {:width width :height height :data data :fill "#FFFFFF"}
[tool-tip]
[bar {:dataKey "paid" :fill (get colors 0) :stackId "a" :name "Paid"}]
[bar {:dataKey "unpaid" :fill (get light-colors 0) :stackId "a" :name "Unpaid"}]
[x-axis {:dataKey "name"}]
[y-axis]
[legend]]
)
(re-frame/reg-event-db
::received
(fn [db [_ {:keys [expense-account-stats invoice-stats]}]]
(let [expense-account-stats (->> expense-account-stats
(map #(update % :total (fn [t] (js/parseFloat t))))
(sort-by :total)
(reverse)
(take 5))
top-5 (vec (take 5 expense-account-stats))
rest (drop 5 expense-account-stats)
other {:expense-account-id 0 :expense-account-name "Other" :total (reduce + 0 (map :total rest))}]
(cond-> db
(seq top-5)
(assoc ::top-expense-categories (conj top-5 other))
(seq invoice-stats)
(assoc ::invoice-stats invoice-stats)
)
)))
(re-frame/reg-sub
::invoice-stats
(fn [db]
(println (::invoice-stats db))
(::invoice-stats db)))
(re-frame/reg-sub
::top-expense-categories
(fn [db]
(::top-expense-categories db)))
(re-frame/reg-event-fx
::mounted
(fn [{:keys [db]} _]
{:db (assoc db ::top-expense-categories nil)
:graphql {:token (-> db :user)
:query-obj {:venia/queries [[:expense_account_stats
{:client-id (:id @(re-frame/subscribe [::subs/client]))}
[:expense-account-id :total :expense-account-name]]
[:invoice_stats
{:client-id (:id @(re-frame/subscribe [::subs/client]))}
[:name :paid :unpaid]]]}
:on-success [::received]}}))
(defn home-content []
(let [client-id (-> @(re-frame/subscribe [::subs/client]) :id)]
^{:key client-id}
[side-bar-layout {:side-bar [:div]
:main [:div [:h1.title "Home"]
[:h1.title.is-4 "Top expense categories"]
(let [expense-categories @(re-frame/subscribe [::top-expense-categories])]
(make-pie-chart {:width 800 :height 500 :data (clj->js
(map (fn [x] {:name (:expense-account-name x) :value (:total x)}) expense-categories))}))
[:h1.title.is-4 "Upcoming Bills"]
(make-bar-chart {:width 800 :height 500 :data (clj->js
@(re-frame/subscribe [::invoice-stats]))})]}]))
(defn home-page []
(let [client-id (-> @(re-frame/subscribe [::subs/client]) :id)]
(re-frame/dispatch [::mounted])
^{:key client-id} [home-content]))

View File

@@ -641,7 +641,10 @@
(let [data @(re-frame/subscribe [::edit-invoice])
change-event [::events/change-form [::edit-invoice]]
locations (get-in @(re-frame/subscribe [::subs/clients-by-id]) [(:client-id data) :locations])
min-total (- (:total (:original data)) (:outstanding-balance (:original data)))
min-total (if (= (:total (:original data)) (:outstanding-balance (:original data)))
nil
(- (:total (:original data)) (:outstanding-balance (:original data))))
should-select-location? (and locations
(> (count locations) 1))]
@@ -650,7 +653,7 @@
:action-text "Save"
:save-event [::edit-invoice-save]
:can-submit? (and #_(s/valid? ::invoice/invoice data)
(>= (:total data) min-total))}
(or (not min-total) (>= (:total data) min-total)))}
[horizontal-field
[:label.label "Date"]
@@ -741,7 +744,14 @@
[:div.dropdown-trigger
[:button.button.is-success {:aria-haspopup true
:on-click (dispatch-event [::print-checks-clicked ])
:disabled (if (seq checked-invoices)
:disabled (if (and (seq checked-invoices)
(->> checked-invoices
vals
(group-by #(get-in % [:vendor :id]))
(reduce-kv (fn [negative? _ invoices]
(or negative? (< (reduce + 0 (map (fn [x] (-> x :outstanding-balance js/parseFloat)) invoices) ) 0)))
false)
not))
""
"disabled")