├── .gitignore
├── Cakefile
├── LICENSE
├── README.md
├── build
├── client
│ ├── .gitignore
│ ├── app
│ │ ├── application.coffee
│ │ ├── assets
│ │ │ ├── 404.html
│ │ │ ├── asc.gif
│ │ │ ├── bg.gif
│ │ │ ├── crossdomain.xml
│ │ │ ├── desc.gif
│ │ │ ├── favicon.ico
│ │ │ ├── fonts
│ │ │ │ ├── fontawesome
│ │ │ │ │ ├── FontAwesome.ttf
│ │ │ │ │ ├── README.md
│ │ │ │ │ ├── fontawesome-webfont.eot
│ │ │ │ │ ├── fontawesome-webfont.svg
│ │ │ │ │ ├── fontawesome-webfont.ttf
│ │ │ │ │ └── fontawesome-webfont.woff
│ │ │ │ ├── fontello.ttf
│ │ │ │ ├── glyphicons-halflings-regular.eot
│ │ │ │ ├── glyphicons-halflings-regular.svg
│ │ │ │ ├── glyphicons-halflings-regular.ttf
│ │ │ │ ├── glyphicons-halflings-regular.woff
│ │ │ │ ├── maven-pro-light-100.otf
│ │ │ │ ├── maven-pro-light-200.otf
│ │ │ │ ├── maven-pro-light-300.otf
│ │ │ │ ├── signika-bold.ttf
│ │ │ │ ├── signika-light.ttf
│ │ │ │ └── signika-regular.ttf
│ │ │ ├── humans.txt
│ │ │ ├── icons
│ │ │ │ └── main_icon.png
│ │ │ ├── images
│ │ │ │ ├── .gitkeep
│ │ │ │ ├── Melamine-wood-003.png
│ │ │ │ ├── arrow.png
│ │ │ │ └── arrow_vertical.png
│ │ │ ├── index.html
│ │ │ ├── javascripts
│ │ │ │ └── modernizr-2.6.1.js
│ │ │ ├── loader.gif
│ │ │ ├── loader_big_blue.gif
│ │ │ ├── loader_green.gif
│ │ │ ├── loader_inverse.gif
│ │ │ └── robots.txt
│ │ ├── collections
│ │ │ ├── .gitkeep
│ │ │ ├── bank_accesses.coffee
│ │ │ ├── bank_accounts.coffee
│ │ │ ├── bank_alerts.coffee
│ │ │ ├── bank_operations.coffee
│ │ │ └── banks.coffee
│ │ ├── initialize.coffee
│ │ ├── lib
│ │ │ ├── app_helpers.coffee
│ │ │ ├── base_view.coffee
│ │ │ └── view_collection.coffee
│ │ ├── locales
│ │ │ ├── en.coffee
│ │ │ └── fr.coffee
│ │ ├── models
│ │ │ ├── .gitkeep
│ │ │ ├── bank.coffee
│ │ │ ├── bank_access.coffee
│ │ │ ├── bank_account.coffee
│ │ │ ├── bank_alert.coffee
│ │ │ └── bank_operation.coffee
│ │ ├── router.coffee
│ │ └── views
│ │ │ ├── accounts.coffee
│ │ │ ├── accounts_alerts.coffee
│ │ │ ├── accounts_alerts_alert.coffee
│ │ │ ├── accounts_bank.coffee
│ │ │ ├── accounts_bank_account.coffee
│ │ │ ├── app.coffee
│ │ │ ├── balance.coffee
│ │ │ ├── balance_bank.coffee
│ │ │ ├── balance_operation.coffee
│ │ │ ├── balance_operations.coffee
│ │ │ ├── bank_subtitle.coffee
│ │ │ ├── bank_title.coffee
│ │ │ ├── mockup.coffee
│ │ │ ├── navbar.coffee
│ │ │ ├── new_bank.coffee
│ │ │ ├── search.coffee
│ │ │ ├── search_bank.coffee
│ │ │ ├── search_bank_subtitle.coffee
│ │ │ ├── search_bank_title.coffee
│ │ │ ├── search_operations.coffee
│ │ │ ├── search_operations_table.coffee
│ │ │ ├── styles
│ │ │ ├── _base.styl
│ │ │ ├── _colors.styl
│ │ │ ├── _main.styl
│ │ │ ├── _responsive.styl
│ │ │ ├── _states.styl
│ │ │ └── application.styl
│ │ │ └── templates
│ │ │ ├── .gitkeep
│ │ │ ├── accounts.jade
│ │ │ ├── accounts_alerts.jade
│ │ │ ├── accounts_alerts_alert.jade
│ │ │ ├── accounts_bank.jade
│ │ │ ├── accounts_bank_account.jade
│ │ │ ├── app.jade
│ │ │ ├── balance_bank_subtitle.jade
│ │ │ ├── balance_bank_title.jade
│ │ │ ├── balance_banks_empty.jade
│ │ │ ├── balance_operations_element.jade
│ │ │ ├── balance_operations_empty.jade
│ │ │ ├── balance_operations_header.jade
│ │ │ ├── layout-2col.jade
│ │ │ ├── mockup_balance.jade
│ │ │ ├── modal_confirm.jade
│ │ │ ├── navbar.jade
│ │ │ ├── new_bank.jade
│ │ │ ├── search_bank_subtitle.jade
│ │ │ ├── search_bank_title.jade
│ │ │ ├── search_operations.jade
│ │ │ └── search_operations_table_header.jade
│ ├── config.coffee
│ ├── generators
│ │ ├── collection
│ │ │ ├── collection.coffee.hbs
│ │ │ └── generator.json
│ │ ├── collection_test
│ │ │ ├── collection_test.coffee.hbs
│ │ │ └── generator.json
│ │ ├── generator
│ │ │ ├── generated_file.coffee.hbs
│ │ │ ├── generator.json
│ │ │ └── generator.json.hbs
│ │ ├── model
│ │ │ ├── generator.json
│ │ │ └── model.coffee.hbs
│ │ ├── model_test
│ │ │ ├── generator.json
│ │ │ └── model_test.coffee.hbs
│ │ ├── module
│ │ │ ├── collection.coffee.hbs
│ │ │ ├── generator.json
│ │ │ ├── model.coffee.hbs
│ │ │ ├── style.styl.hbs
│ │ │ ├── template.jade.hbs
│ │ │ ├── view.coffee.hbs
│ │ │ └── view_collection.coffee.hbs
│ │ ├── style
│ │ │ ├── generator.json
│ │ │ └── style.styl.hbs
│ │ ├── template
│ │ │ ├── generator.json
│ │ │ └── template.hbs
│ │ ├── view
│ │ │ ├── generator.json
│ │ │ └── view.coffee.hbs
│ │ └── view_test
│ │ │ ├── generator.json
│ │ │ └── view_test.coffee.hbs
│ ├── package.json
│ ├── public
│ │ ├── 404.html
│ │ ├── asc.gif
│ │ ├── bg.gif
│ │ ├── crossdomain.xml
│ │ ├── desc.gif
│ │ ├── favicon.ico
│ │ ├── fonts
│ │ │ ├── fontawesome
│ │ │ │ ├── FontAwesome.ttf
│ │ │ │ ├── README.md
│ │ │ │ ├── fontawesome-webfont.eot
│ │ │ │ ├── fontawesome-webfont.svg
│ │ │ │ ├── fontawesome-webfont.ttf
│ │ │ │ └── fontawesome-webfont.woff
│ │ │ ├── fontello.ttf
│ │ │ ├── glyphicons-halflings-regular.eot
│ │ │ ├── glyphicons-halflings-regular.svg
│ │ │ ├── glyphicons-halflings-regular.ttf
│ │ │ ├── glyphicons-halflings-regular.woff
│ │ │ ├── maven-pro-light-100.otf
│ │ │ ├── maven-pro-light-200.otf
│ │ │ ├── maven-pro-light-300.otf
│ │ │ ├── signika-bold.ttf
│ │ │ ├── signika-light.ttf
│ │ │ └── signika-regular.ttf
│ │ ├── humans.txt
│ │ ├── icons
│ │ │ └── main_icon.png
│ │ ├── images
│ │ │ ├── Melamine-wood-003.png
│ │ │ ├── arrow.png
│ │ │ ├── arrow_vertical.png
│ │ │ ├── glyphicons-halflings-white.png
│ │ │ └── glyphicons-halflings.png
│ │ ├── index.html
│ │ ├── javascripts
│ │ │ ├── app.js
│ │ │ ├── app.js.map
│ │ │ ├── jquery.min.map
│ │ │ ├── modernizr-2.6.1.js
│ │ │ ├── vendor.js
│ │ │ └── vendor.js.map
│ │ ├── loader.gif
│ │ ├── loader_big_blue.gif
│ │ ├── loader_green.gif
│ │ ├── loader_inverse.gif
│ │ ├── robots.txt
│ │ └── stylesheets
│ │ │ ├── app.css
│ │ │ └── app.css.map
│ └── vendor
│ │ ├── scripts
│ │ ├── async.js
│ │ ├── backbone-1.0.0.js
│ │ ├── backbone.mediator.js
│ │ ├── bootstrap.js
│ │ ├── jquery-1.10.2.js
│ │ ├── jquery.nicescroll.js
│ │ ├── moment.min.js
│ │ ├── polyglot.js
│ │ ├── underscore-1.4.4.js
│ │ └── zoomico.png
│ │ └── styles
│ │ ├── bootstrap-theme.css
│ │ ├── bootstrap.css
│ │ ├── font-awesome.css
│ │ ├── helpers.css
│ │ ├── hint.css
│ │ ├── normalize.css
│ │ ├── sort.css
│ │ └── tablesort_blue.css
├── package.json
├── server.js
├── server
│ ├── config.js
│ ├── controllers
│ │ ├── bankaccesses.js
│ │ ├── bankaccounts.js
│ │ ├── bankalerts.js
│ │ ├── bankoperations.js
│ │ ├── banks.js
│ │ └── routes.js
│ ├── init.js
│ ├── lib
│ │ ├── accounts-poller.js
│ │ ├── alert-manager.js
│ │ ├── report-manager.js
│ │ └── weboob-manager.js
│ └── models
│ │ ├── bank.js
│ │ ├── bankaccess.js
│ │ ├── bankaccount.js
│ │ ├── bankalert.js
│ │ ├── bankoperation.js
│ │ ├── cozyinstance.js
│ │ └── requests.js
└── tests
│ ├── controllers
│ ├── bankaccesses.js
│ ├── bankaccounts.js
│ ├── bankalerts.js
│ ├── bankoperations.js
│ └── banks.js
│ ├── fixtures
│ ├── banks-all.json
│ ├── banks-mesinfos.json
│ └── weboob
│ │ ├── accounts.js
│ │ └── operations.js
│ ├── helpers.js
│ └── mock-weboob.js
├── client
├── .gitignore
├── app
│ ├── application.coffee
│ ├── assets
│ │ ├── 404.html
│ │ ├── asc.gif
│ │ ├── bg.gif
│ │ ├── crossdomain.xml
│ │ ├── desc.gif
│ │ ├── favicon.ico
│ │ ├── fonts
│ │ │ ├── fontawesome
│ │ │ │ ├── FontAwesome.ttf
│ │ │ │ ├── README.md
│ │ │ │ ├── fontawesome-webfont.eot
│ │ │ │ ├── fontawesome-webfont.svg
│ │ │ │ ├── fontawesome-webfont.ttf
│ │ │ │ └── fontawesome-webfont.woff
│ │ │ ├── fontello.ttf
│ │ │ ├── glyphicons-halflings-regular.eot
│ │ │ ├── glyphicons-halflings-regular.svg
│ │ │ ├── glyphicons-halflings-regular.ttf
│ │ │ ├── glyphicons-halflings-regular.woff
│ │ │ ├── maven-pro-light-100.otf
│ │ │ ├── maven-pro-light-200.otf
│ │ │ ├── maven-pro-light-300.otf
│ │ │ ├── signika-bold.ttf
│ │ │ ├── signika-light.ttf
│ │ │ └── signika-regular.ttf
│ │ ├── humans.txt
│ │ ├── icons
│ │ │ └── main_icon.png
│ │ ├── images
│ │ │ ├── .gitkeep
│ │ │ ├── Melamine-wood-003.png
│ │ │ ├── arrow.png
│ │ │ └── arrow_vertical.png
│ │ ├── index.html
│ │ ├── javascripts
│ │ │ └── modernizr-2.6.1.js
│ │ ├── loader.gif
│ │ ├── loader_big_blue.gif
│ │ ├── loader_green.gif
│ │ ├── loader_inverse.gif
│ │ ├── pdf
│ │ │ ├── factureSFR.pdf
│ │ │ └── factureSNCF.pdf
│ │ └── robots.txt
│ ├── collections
│ │ ├── .gitkeep
│ │ ├── bank_accesses.coffee
│ │ ├── bank_accounts.coffee
│ │ ├── bank_alerts.coffee
│ │ ├── bank_operations.coffee
│ │ └── banks.coffee
│ ├── initialize.coffee
│ ├── lib
│ │ ├── app_helpers.coffee
│ │ ├── base_view.coffee
│ │ └── view_collection.coffee
│ ├── locales
│ │ ├── en.coffee
│ │ └── fr.coffee
│ ├── models
│ │ ├── .gitkeep
│ │ ├── bank.coffee
│ │ ├── bank_access.coffee
│ │ ├── bank_account.coffee
│ │ ├── bank_alert.coffee
│ │ └── bank_operation.coffee
│ ├── router.coffee
│ └── views
│ │ ├── accounts.coffee
│ │ ├── accounts_alerts.coffee
│ │ ├── accounts_alerts_alert.coffee
│ │ ├── accounts_bank.coffee
│ │ ├── accounts_bank_account.coffee
│ │ ├── app.coffee
│ │ ├── balance.coffee
│ │ ├── balance_bank.coffee
│ │ ├── balance_operation.coffee
│ │ ├── balance_operations.coffee
│ │ ├── bank_subtitle.coffee
│ │ ├── bank_title.coffee
│ │ ├── mockup.coffee
│ │ ├── navbar.coffee
│ │ ├── new_bank.coffee
│ │ ├── search.coffee
│ │ ├── search_bank.coffee
│ │ ├── search_bank_subtitle.coffee
│ │ ├── search_bank_title.coffee
│ │ ├── search_operations.coffee
│ │ ├── search_operations_table.coffee
│ │ ├── styles
│ │ ├── _base.styl
│ │ ├── _colors.styl
│ │ ├── _main.styl
│ │ ├── _responsive.styl
│ │ ├── _states.styl
│ │ └── application.styl
│ │ └── templates
│ │ ├── .gitkeep
│ │ ├── accounts.jade
│ │ ├── accounts_alerts.jade
│ │ ├── accounts_alerts_alert.jade
│ │ ├── accounts_bank.jade
│ │ ├── accounts_bank_account.jade
│ │ ├── app.jade
│ │ ├── balance_bank_subtitle.jade
│ │ ├── balance_bank_title.jade
│ │ ├── balance_banks_empty.jade
│ │ ├── balance_operations_element.jade
│ │ ├── balance_operations_empty.jade
│ │ ├── balance_operations_header.jade
│ │ ├── layout-2col.jade
│ │ ├── mockup_balance.jade
│ │ ├── modal_confirm.jade
│ │ ├── navbar.jade
│ │ ├── new_bank.jade
│ │ ├── search_bank_subtitle.jade
│ │ ├── search_bank_title.jade
│ │ ├── search_operations.jade
│ │ └── search_operations_table_header.jade
├── config.coffee
├── generators
│ ├── collection
│ │ ├── collection.coffee.hbs
│ │ └── generator.json
│ ├── collection_test
│ │ ├── collection_test.coffee.hbs
│ │ └── generator.json
│ ├── generator
│ │ ├── generated_file.coffee.hbs
│ │ ├── generator.json
│ │ └── generator.json.hbs
│ ├── model
│ │ ├── generator.json
│ │ └── model.coffee.hbs
│ ├── model_test
│ │ ├── generator.json
│ │ └── model_test.coffee.hbs
│ ├── module
│ │ ├── collection.coffee.hbs
│ │ ├── generator.json
│ │ ├── model.coffee.hbs
│ │ ├── style.styl.hbs
│ │ ├── template.jade.hbs
│ │ ├── view.coffee.hbs
│ │ └── view_collection.coffee.hbs
│ ├── style
│ │ ├── generator.json
│ │ └── style.styl.hbs
│ ├── template
│ │ ├── generator.json
│ │ └── template.hbs
│ ├── view
│ │ ├── generator.json
│ │ └── view.coffee.hbs
│ └── view_test
│ │ ├── generator.json
│ │ └── view_test.coffee.hbs
├── package.json
├── public
│ ├── 404.html
│ ├── asc.gif
│ ├── bg.gif
│ ├── crossdomain.xml
│ ├── desc.gif
│ ├── favicon.ico
│ ├── fonts
│ │ ├── fontawesome
│ │ │ ├── FontAwesome.ttf
│ │ │ ├── README.md
│ │ │ ├── fontawesome-webfont.eot
│ │ │ ├── fontawesome-webfont.svg
│ │ │ ├── fontawesome-webfont.ttf
│ │ │ └── fontawesome-webfont.woff
│ │ ├── fontello.ttf
│ │ ├── glyphicons-halflings-regular.eot
│ │ ├── glyphicons-halflings-regular.svg
│ │ ├── glyphicons-halflings-regular.ttf
│ │ ├── glyphicons-halflings-regular.woff
│ │ ├── maven-pro-light-100.otf
│ │ ├── maven-pro-light-200.otf
│ │ ├── maven-pro-light-300.otf
│ │ ├── signika-bold.ttf
│ │ ├── signika-light.ttf
│ │ └── signika-regular.ttf
│ ├── humans.txt
│ ├── icons
│ │ └── main_icon.png
│ ├── images
│ │ ├── Melamine-wood-003.png
│ │ ├── arrow.png
│ │ ├── arrow_vertical.png
│ │ ├── glyphicons-halflings-white.png
│ │ └── glyphicons-halflings.png
│ ├── index.html
│ ├── javascripts
│ │ ├── app.js
│ │ ├── app.js.map
│ │ ├── jquery.min.map
│ │ ├── modernizr-2.6.1.js
│ │ ├── vendor.js
│ │ └── vendor.js.map
│ ├── loader.gif
│ ├── loader_big_blue.gif
│ ├── loader_green.gif
│ ├── loader_inverse.gif
│ ├── pdf
│ │ ├── factureSFR.pdf
│ │ └── factureSNCF.pdf
│ ├── robots.txt
│ └── stylesheets
│ │ ├── app.css
│ │ └── app.css.map
└── vendor
│ ├── scripts
│ ├── async.js
│ ├── backbone-1.0.0.js
│ ├── backbone.mediator.js
│ ├── bootstrap.js
│ ├── jquery-1.10.2.js
│ ├── jquery.nicescroll.js
│ ├── moment.min.js
│ ├── polyglot.js
│ ├── underscore-1.4.4.js
│ └── zoomico.png
│ └── styles
│ ├── bootstrap-theme.css
│ ├── bootstrap.css
│ ├── font-awesome.css
│ ├── helpers.css
│ ├── hint.css
│ ├── normalize.css
│ ├── sort.css
│ └── tablesort_blue.css
├── coffeelint.json
├── log
└── production.log
├── package.json
├── server.coffee
├── server
├── config.coffee
├── controllers
│ ├── bankaccesses.coffee
│ ├── bankaccounts.coffee
│ ├── bankalerts.coffee
│ ├── bankoperations.coffee
│ ├── banks.coffee
│ └── routes.coffee
├── init.coffee
├── lib
│ ├── accounts-poller.coffee
│ ├── alert-manager.coffee
│ ├── report-manager.coffee
│ └── weboob-manager.coffee
├── models
│ ├── bank.coffee
│ ├── bankaccess.coffee
│ ├── bankaccount.coffee
│ ├── bankalert.coffee
│ ├── bankoperation.coffee
│ ├── cozyinstance.coffee
│ └── requests.coffee
└── views
│ └── mail-report.jade
└── tests
├── controllers
├── bankaccesses.coffee
├── bankaccounts.coffee
├── bankalerts.coffee
├── bankoperations.coffee
└── banks.coffee
├── fixtures
├── banks-all.json
├── banks-mesinfos.json
└── weboob
│ ├── accounts.coffee
│ └── operations.coffee
├── helpers.coffee
└── mock-weboob.coffee
/.gitignore:
--------------------------------------------------------------------------------
1 | # Numerous always-ignored extensions
2 | *.diff
3 | *.err
4 | *.orig
5 | *.log
6 | *.rej
7 | *.swo
8 | *.swp
9 | *.vi
10 | *~
11 | *.sass-cache
12 |
13 | # OS or Editor folders
14 | .DS_Store
15 | .cache
16 | .project
17 | .settings
18 | .tmproj
19 | nbproject
20 | Thumbs.db
21 |
22 | # Logs folder
23 | logs
24 |
25 | # NPM packages folder.
26 | node_modules/
27 |
28 |
--------------------------------------------------------------------------------
/build/client/.gitignore:
--------------------------------------------------------------------------------
1 | # Numerous always-ignore extensions
2 | *.diff
3 | *.err
4 | *.orig
5 | *.log
6 | *.rej
7 | *.swo
8 | *.swp
9 | *.vi
10 | *~
11 | *.sass-cache
12 |
13 | # OS or Editor folders
14 | .DS_Store
15 | .cache
16 | .project
17 | .settings
18 | .tmproj
19 | nbproject
20 | Thumbs.db
21 |
22 | # NPM packages folder.
23 | node_modules/
24 |
25 | # Brunch folder for temporary files.
26 | tmp/
27 |
--------------------------------------------------------------------------------
/build/client/app/application.coffee:
--------------------------------------------------------------------------------
1 | AppView = require 'views/app'
2 |
3 | BanksCollection = require 'collections/banks'
4 | BankOperationsCollection = require 'collections/bank_operations'
5 |
6 | module.exports =
7 |
8 | initialize: ->
9 |
10 | $.ajax('cozy-locale.json')
11 | .done( (data) => @locale = data.locale )
12 | .fail( () => @locale = 'en' )
13 | .always( () => @step2() )
14 |
15 | step2: ->
16 |
17 | # internationalisation
18 | @polyglot = new Polyglot()
19 | window.polyglot = @polyglot
20 | try
21 | locales = require "locales/#{@locale}"
22 | catch e
23 | locales = require 'locales/en'
24 |
25 | @polyglot.extend locales
26 | window.t = @polyglot.t.bind @polyglot
27 | window.i18n = (key) -> window.polyglot.t key
28 |
29 | # collections, views
30 | window.collections = {}
31 | window.views = {}
32 |
33 | # banks, operations
34 | window.collections.allBanks = new BanksCollection()
35 | window.collections.banks = new BanksCollection()
36 | window.collections.operations = new BankOperationsCollection()
37 |
38 | ###
39 | views
40 | ###
41 | # this one is tricky - it lays down the structure, so it needs to be rendered
42 | # before any other view using that structure
43 | window.views.appView = new AppView()
44 | window.views.appView.render()
45 |
46 | window.activeObjects = {}
47 | _.extend(window.activeObjects, Backbone.Events);
48 |
49 | # Routing management
50 | Router = require 'router'
51 | @router = new Router()
52 | #Backbone.history.start()
53 |
54 | # Makes this object immuable.
55 | Object.freeze this if typeof Object.freeze is 'function'
56 |
--------------------------------------------------------------------------------
/build/client/app/assets/asc.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/app/assets/asc.gif
--------------------------------------------------------------------------------
/build/client/app/assets/bg.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/app/assets/bg.gif
--------------------------------------------------------------------------------
/build/client/app/assets/crossdomain.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
15 |
16 |
--------------------------------------------------------------------------------
/build/client/app/assets/desc.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/app/assets/desc.gif
--------------------------------------------------------------------------------
/build/client/app/assets/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/app/assets/favicon.ico
--------------------------------------------------------------------------------
/build/client/app/assets/fonts/fontawesome/FontAwesome.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/app/assets/fonts/fontawesome/FontAwesome.ttf
--------------------------------------------------------------------------------
/build/client/app/assets/fonts/fontawesome/README.md:
--------------------------------------------------------------------------------
1 | #Font Awesome 2.0
2 | ##the iconic font designed for use with Twitter Bootstrap
3 |
4 | The full suite of pictographic icons, examples, and documentation can be found at:
5 | http://fortawesome.github.com/Font-Awesome/
6 |
7 | ##Contact
8 | - Email: dave@davegandy.com
9 | - Twitter: http://twitter.com/fortaweso_me
10 | - Work: Lead Product Designer @ http://kyru.us
11 |
12 | ##License
13 | Version 2.0 of the Font Awesome font, CSS, and LESS files are licensed under CC BY 3.0:
14 | http://creativecommons.org/licenses/by/3.0/
15 | A mention of 'Font Awesome - http://fortawesome.github.com/Font-Awesome'
16 | in human-readable source code is considered acceptable attribution (most common on the
17 | web). If human readable source code is not available to the end user, a mention in an 'About'
18 | or 'Credits' screen is considered acceptable (most common in desktop or mobile software).
19 |
--------------------------------------------------------------------------------
/build/client/app/assets/fonts/fontawesome/fontawesome-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/app/assets/fonts/fontawesome/fontawesome-webfont.eot
--------------------------------------------------------------------------------
/build/client/app/assets/fonts/fontawesome/fontawesome-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/app/assets/fonts/fontawesome/fontawesome-webfont.ttf
--------------------------------------------------------------------------------
/build/client/app/assets/fonts/fontawesome/fontawesome-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/app/assets/fonts/fontawesome/fontawesome-webfont.woff
--------------------------------------------------------------------------------
/build/client/app/assets/fonts/fontello.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/app/assets/fonts/fontello.ttf
--------------------------------------------------------------------------------
/build/client/app/assets/fonts/glyphicons-halflings-regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/app/assets/fonts/glyphicons-halflings-regular.eot
--------------------------------------------------------------------------------
/build/client/app/assets/fonts/glyphicons-halflings-regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/app/assets/fonts/glyphicons-halflings-regular.ttf
--------------------------------------------------------------------------------
/build/client/app/assets/fonts/glyphicons-halflings-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/app/assets/fonts/glyphicons-halflings-regular.woff
--------------------------------------------------------------------------------
/build/client/app/assets/fonts/maven-pro-light-100.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/app/assets/fonts/maven-pro-light-100.otf
--------------------------------------------------------------------------------
/build/client/app/assets/fonts/maven-pro-light-200.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/app/assets/fonts/maven-pro-light-200.otf
--------------------------------------------------------------------------------
/build/client/app/assets/fonts/maven-pro-light-300.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/app/assets/fonts/maven-pro-light-300.otf
--------------------------------------------------------------------------------
/build/client/app/assets/fonts/signika-bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/app/assets/fonts/signika-bold.ttf
--------------------------------------------------------------------------------
/build/client/app/assets/fonts/signika-light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/app/assets/fonts/signika-light.ttf
--------------------------------------------------------------------------------
/build/client/app/assets/fonts/signika-regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/app/assets/fonts/signika-regular.ttf
--------------------------------------------------------------------------------
/build/client/app/assets/humans.txt:
--------------------------------------------------------------------------------
1 | # humanstxt.org/
2 | # The humans responsible & technology colophon
3 |
4 | # TEAM
5 |
6 | -- --
7 |
8 | # THANKS
9 |
10 |
11 |
12 | # TECHNOLOGY COLOPHON
13 |
14 | HTML5, CSS3
15 | jQuery, Modernizr,
16 | Lodash, Backbone,
17 | Handlebars, Coffeescript,
18 | Stylus, Brunch
19 |
--------------------------------------------------------------------------------
/build/client/app/assets/icons/main_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/app/assets/icons/main_icon.png
--------------------------------------------------------------------------------
/build/client/app/assets/images/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/app/assets/images/.gitkeep
--------------------------------------------------------------------------------
/build/client/app/assets/images/Melamine-wood-003.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/app/assets/images/Melamine-wood-003.png
--------------------------------------------------------------------------------
/build/client/app/assets/images/arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/app/assets/images/arrow.png
--------------------------------------------------------------------------------
/build/client/app/assets/images/arrow_vertical.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/app/assets/images/arrow_vertical.png
--------------------------------------------------------------------------------
/build/client/app/assets/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Cozy PFM
10 |
11 |
12 |
17 |
18 |
19 |
20 |
21 |
22 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/build/client/app/assets/loader.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/app/assets/loader.gif
--------------------------------------------------------------------------------
/build/client/app/assets/loader_big_blue.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/app/assets/loader_big_blue.gif
--------------------------------------------------------------------------------
/build/client/app/assets/loader_green.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/app/assets/loader_green.gif
--------------------------------------------------------------------------------
/build/client/app/assets/loader_inverse.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/app/assets/loader_inverse.gif
--------------------------------------------------------------------------------
/build/client/app/assets/robots.txt:
--------------------------------------------------------------------------------
1 | # robotstxt.org/
2 |
3 | User-agent: *
4 |
--------------------------------------------------------------------------------
/build/client/app/collections/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/app/collections/.gitkeep
--------------------------------------------------------------------------------
/build/client/app/collections/bank_accesses.coffee:
--------------------------------------------------------------------------------
1 | BankAccess = require '../models/bank_access'
2 |
3 | module.exports = class BankAccesses extends Backbone.Collection
4 |
5 | model: BankAccess
6 | url: "bankaccesses"
7 |
--------------------------------------------------------------------------------
/build/client/app/collections/bank_accounts.coffee:
--------------------------------------------------------------------------------
1 | BankAccount = require '../models/bank_account'
2 |
3 | module.exports = class BankAccounts extends Backbone.Collection
4 |
5 | model: BankAccount
6 | url: "bankaccounts"
7 |
8 | constructor: (@bank) ->
9 | @url = "banks/getAccounts/" + @bank.get("id")
10 | super()
11 |
12 | getSum: ->
13 | sum = 0
14 | for account in @models
15 | sum += Number(account.get("amount"))
16 | sum
17 |
--------------------------------------------------------------------------------
/build/client/app/collections/bank_alerts.coffee:
--------------------------------------------------------------------------------
1 | BankAlert = require '../models/bank_alert'
2 |
3 | module.exports = class BankAlerts extends Backbone.Collection
4 |
5 | model: BankAlert
6 | url: "bankalerts"
7 |
--------------------------------------------------------------------------------
/build/client/app/collections/bank_operations.coffee:
--------------------------------------------------------------------------------
1 | BankOperation = require '../models/bank_operation'
2 |
3 | module.exports = class BankOperations extends Backbone.Collection
4 |
5 | model: BankOperation
6 | url: "bankoperations"
7 |
8 | order: "asc"
9 | orderBy: "date"
10 |
11 | setAccount: (@account) ->
12 | @url = "bankaccounts/getOperations/" + @account.get("id")
13 | #console.log @url
14 |
15 | setComparator: (type) ->
16 | if type == "date"
17 | # sorting by date and then title
18 | @comparator = (o1, o2) =>
19 | d1 = new Date(o1.get("date")).getTime()
20 | d2 = new Date(o2.get("date")).getTime()
21 |
22 | t1 = o1.get("title")
23 | t2 = o2.get("title")
24 |
25 | sort = if @order == "asc" then -1 else 1
26 |
27 | if d1 == d2
28 | if t1 > t2 then return sort
29 | if t1 < t2 then return -sort
30 | return 0
31 | else if d1 > d2
32 | return sort
33 | else
34 | return -sort
35 |
36 | else
37 | @orderBy = type
38 | @comparator = (o1, o2) ->
39 |
40 | t1 = o1.get @orderBy
41 | t2 = o2.get @orderBy
42 |
43 | sort = if @order == "asc" then -1 else 1
44 |
45 | if t1 == t2
46 | return 0
47 | else if t1 > t2
48 | return sort
49 | else
50 | return -sort
51 |
52 | toggleSort: (order) ->
53 | if @orderBy == order
54 | @order = if @order == "asc" then "desc" else "asc"
55 | else
56 | @orderBy = order
57 |
58 |
--------------------------------------------------------------------------------
/build/client/app/collections/banks.coffee:
--------------------------------------------------------------------------------
1 | Bank = require '../models/bank'
2 |
3 | module.exports = class Banks extends Backbone.Collection
4 |
5 | model: Bank
6 | url: "banks"
7 |
8 | getSum: ->
9 | sum = 0
10 | for bank in @models
11 | sum += Number(bank.get("amount"))
12 | #console.log Number(bank.get("amount"))
13 | sum
14 |
--------------------------------------------------------------------------------
/build/client/app/initialize.coffee:
--------------------------------------------------------------------------------
1 | app = require 'application'
2 | # The function called from index.html
3 | $ ->
4 | require 'lib/app_helpers'
5 |
6 | # init
7 | ###
8 | global variables
9 | ###
10 | # app, for nasty tricks
11 | window.app = app
12 | app.initialize()
13 |
--------------------------------------------------------------------------------
/build/client/app/lib/app_helpers.coffee:
--------------------------------------------------------------------------------
1 | (() ->
2 | # IIFE to avoid collisions with other variables
3 | (->
4 | # Make it safe to do console.log() always.
5 | console = window.console = window.console or {}
6 | method = undefined
7 | dummy = ->
8 | methods = ('assert,count,debug,dir,dirxml,error,exception,
9 | group,groupCollapsed,groupEnd,info,log,markTimeline,
10 | profile,profileEnd,time,timeEnd,trace,warn').split ','
11 |
12 | console[method] = console[method] or dummy while method = methods.pop()
13 | )()
14 | )()
15 |
16 | Number::formatMoney = (decPlaces, thouSeparator, decSeparator) ->
17 | n = this
18 | decPlaces = (if isNaN(decPlaces = Math.abs(decPlaces)) then 2 else decPlaces)
19 | decSeparator = (if decSeparator is `undefined` then "." else decSeparator)
20 | thouSeparator = (if thouSeparator is `undefined` then "," else thouSeparator)
21 | sign = (if n < 0 then "-" else "")
22 | i = parseInt(n = Math.abs(+n or 0).toFixed(decPlaces)) + ""
23 | j = (if (j = i.length) > 3 then j % 3 else 0)
24 | sign + ((if j then i.substr(0, j) + thouSeparator else "")) + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + thouSeparator) + ((if decPlaces then decSeparator + Math.abs(n - i).toFixed(decPlaces).slice(2) else ""))
25 |
26 | Number::money = ->
27 | @formatMoney(2, " ", ",")
28 |
29 | Date::dateString = ->
30 | addZeros = (num) ->
31 | if Number(num) < 10
32 | "0" + num
33 | else
34 | num
35 | myDate = @
36 | addZeros(myDate.getDate() + 1) + "/" + addZeros(myDate.getMonth() + 1) + "/" + myDate.getFullYear()
37 |
38 | Date::timeString = ->
39 | addZeros = (num) ->
40 | if Number(num) < 10
41 | "0" + num
42 | else
43 | num
44 | myDate = @
45 | addZeros(myDate.getHours()) + ":" + addZeros(myDate.getMinutes())
46 |
--------------------------------------------------------------------------------
/build/client/app/lib/base_view.coffee:
--------------------------------------------------------------------------------
1 | module.exports = class BaseView extends Backbone.View
2 |
3 | template: ->
4 |
5 | initialize: ->
6 |
7 | getRenderData: ->
8 | model: @model
9 |
10 | render: ->
11 | @beforeRender()
12 | @$el.html @template(@getRenderData())
13 | @afterRender()
14 | @
15 |
16 | beforeRender: ->
17 |
18 | afterRender: ->
19 |
20 | destroy: ->
21 | @undelegateEvents()
22 | @$el.removeData().unbind()
23 | @remove()
24 | Backbone.View::remove.call @
25 |
--------------------------------------------------------------------------------
/build/client/app/models/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/app/models/.gitkeep
--------------------------------------------------------------------------------
/build/client/app/models/bank.coffee:
--------------------------------------------------------------------------------
1 | BankAccountsCollection = require '../collections/bank_accounts'
2 |
3 | module.exports = class Bank extends Backbone.Model
4 |
5 | defaults:
6 | amount: 0
7 |
8 | checked: true
9 |
10 | initialize: ->
11 | @accounts = new BankAccountsCollection @
12 | @listenTo @accounts, "add", @updateAmount
13 | @listenTo @accounts, "remove", @updateAmount
14 | @listenTo @accounts, "destroy", @updateAmount
15 | @listenTo @accounts, "change", @updateAmount
16 |
17 | updateAmount: ->
18 | @set("amount", @accounts.getSum())
19 | console.log "updated balance bank " + @get("name") + " is now " + @get("amount")
20 |
--------------------------------------------------------------------------------
/build/client/app/models/bank_access.coffee:
--------------------------------------------------------------------------------
1 | module.exports = class BankAccess extends Backbone.Model
2 |
3 | url: "bankaccesses"
4 |
--------------------------------------------------------------------------------
/build/client/app/models/bank_account.coffee:
--------------------------------------------------------------------------------
1 | BankOperationsCollection = require '../collections/bank_operations'
2 |
3 | module.exports = class BankAccount extends Backbone.Model
4 |
5 | checked: true
6 |
--------------------------------------------------------------------------------
/build/client/app/models/bank_alert.coffee:
--------------------------------------------------------------------------------
1 | module.exports = class BankAlert extends Backbone.Model
2 |
3 | url: "bankalerts"
4 |
--------------------------------------------------------------------------------
/build/client/app/models/bank_operation.coffee:
--------------------------------------------------------------------------------
1 | module.exports = class BankOperation extends Backbone.Model
2 |
--------------------------------------------------------------------------------
/build/client/app/router.coffee:
--------------------------------------------------------------------------------
1 | MockupView = require 'views/mockup'
2 | AppView = require 'views/app'
3 | BalanceView = require 'views/balance'
4 |
5 | module.exports = class Router extends Backbone.Router
6 |
7 | empty: ->
8 | window.views.balanceView?.empty()
9 | window.views.accountsView?.empty()
10 | window.views.searchView?.empty()
11 |
12 | routes:
13 | '': 'balance'
14 | 'accounts': 'accounts'
15 | 'search' : 'search'
16 |
17 | balance: ->
18 | @empty()
19 | window.views.balanceView?.render()
20 | $(".menu-position").removeClass("active")
21 | $(".menu-1").addClass("active")
22 |
23 | search: ->
24 | @empty()
25 | window.views.searchView?.render()
26 | $(".menu-position").removeClass("active")
27 | $(".menu-2").addClass("active")
28 |
29 | accounts: ->
30 | @empty()
31 | window.views.accountsView?.render()
32 | $(".menu-position").removeClass("active")
33 | $(".menu-3").addClass("active")
34 |
--------------------------------------------------------------------------------
/build/client/app/views/accounts.coffee:
--------------------------------------------------------------------------------
1 | BaseView = require '../lib/base_view'
2 | AccountsBankView = require './accounts_bank'
3 |
4 | module.exports = class AccountsView extends BaseView
5 |
6 | template: require('./templates/accounts')
7 |
8 | el: 'div#content'
9 | elBanks: '.content-right-column'
10 |
11 | subViews: []
12 |
13 | render: ->
14 |
15 | # load the template
16 | super()
17 |
18 | # prepare the banks list
19 | for bank in window.collections.banks.models
20 | view = new AccountsBankView bank
21 | @subViews.push view
22 | @$(@elBanks).append view.render().el
23 |
24 | # TODO - fix the compability issue with niceScroll
25 | #@$('#layout-2col-column-right').niceScroll()
26 | @
27 |
28 | empty: ->
29 | for view in @subViews
30 | view.destroy()
--------------------------------------------------------------------------------
/build/client/app/views/accounts_alerts_alert.coffee:
--------------------------------------------------------------------------------
1 | BaseView = require '../lib/base_view'
2 | BankAlert = require '../models/bank_alert'
3 |
4 | module.exports = class AccountsAlertsAlertView extends BaseView
5 |
6 | template: require "./templates/accounts_alerts_alert"
7 |
8 | events:
9 | "click .reports-save" : "save"
10 | "click .reports-cancel" : "destroy"
11 | "click .reports-delete" : "removeAlert"
12 | "click .reports-edit" : "edit"
13 |
14 | constructor: (@alert, @parent) ->
15 | super()
16 |
17 | initialize: ->
18 |
19 | save: ->
20 | view = @
21 |
22 | # get the data
23 | if @alert.get("type") == "report"
24 | @alert.set "frequency", @$(".reports-frequency").val()
25 | else
26 | @alert.set "order", @$(".reports-order").val()
27 | valLimit = @$(".reports-limit").val()
28 | valLimit = valLimit.replace(" ", "").replace(",",".") # stripping all non digits
29 | @alert.set "limit", Number(valLimit)
30 |
31 | # save the report to the server
32 | @alert.save {},
33 | success: ->
34 | console.log "Alert saved to server"
35 | view.render()
36 | error: ->
37 | console.log "error"
38 |
39 | removeAlert: ->
40 |
41 | view = @
42 |
43 | @alert.url = "bankalerts/" + @alert.get("id")
44 | @alert.destroy
45 | success: ->
46 | console.log "Alert deleted from server"
47 | view.destroy()
48 | error: ->
49 | console.log "error"
50 |
51 | render: ->
52 | # lay down the template
53 | @$el.html @template
54 | model: @alert
55 | @
56 |
--------------------------------------------------------------------------------
/build/client/app/views/app.coffee:
--------------------------------------------------------------------------------
1 | BaseView = require '../lib/base_view'
2 |
3 | NavbarView = require 'views/navbar'
4 | NewBankView = require 'views/new_bank'
5 |
6 | AccountsView = require 'views/accounts'
7 | BalanceView = require 'views/balance'
8 | SearchView = require 'views/search'
9 |
10 |
11 | module.exports = class AppView extends BaseView
12 |
13 | template: require('./templates/app')
14 |
15 | el: 'body.application'
16 |
17 | afterRender: ->
18 |
19 | # init - get the necessary data
20 | window.collections.banks.fetch
21 | data:
22 | withAccountOnly: true
23 | success: ->
24 |
25 | window.collections.allBanks.fetch
26 | success: ->
27 | if not @navbarView
28 | @navbarView = new NavbarView()
29 | if not @newbankView
30 | @newbankView = new NewBankView()
31 | if not window.views.balanceView
32 | window.views.balanceView = new BalanceView()
33 | if not window.views.accountsView
34 | window.views.accountsView = new AccountsView()
35 | if not window.views.searchView
36 | window.views.searchView = new SearchView()
37 |
38 | @navbarView.render()
39 | @newbankView.render()
40 |
41 | # start routing
42 | Backbone.history.start()
43 | error: ->
44 |
45 | # could not get banks, or 0 banks available - fatal error
46 | console.log "Fatal error: could not get the banks list"
47 | alert window.i18n "fatal_error"
48 |
49 |
--------------------------------------------------------------------------------
/build/client/app/views/balance_bank.coffee:
--------------------------------------------------------------------------------
1 | BaseView = require '../lib/base_view'
2 | BankTitleView = require './bank_title'
3 | BankSubTitleView = require './bank_subtitle'
4 |
5 | module.exports = class BalanceBankView extends BaseView
6 |
7 | className: 'bank'
8 |
9 | sum: 0
10 |
11 | subViews: []
12 |
13 | constructor: (@bank) ->
14 | super()
15 |
16 | initialize: ->
17 | @listenTo @bank.accounts, "add", @addOne
18 | @listenTo @bank.accounts, "destroy", @render
19 |
20 | addOne: (account) ->
21 | # add the account
22 | viewAccount = new BankSubTitleView account
23 | @subViews.push viewAccount
24 | account.view = viewAccount
25 | @$el.append viewAccount.render().el
26 |
27 | render: ->
28 |
29 | # generate the title
30 | @viewTitle = new BankTitleView @bank
31 | @$el.html @viewTitle.render().el
32 | @viewTitle = null
33 | @sum = 0
34 |
35 | # add accounts
36 | for account in @bank.accounts.models
37 | @addOne account
38 | @
39 |
40 | destroy: ->
41 | @viewTitle?.destroy()
42 | for view in @subViews
43 | view.destroy()
44 | super()
--------------------------------------------------------------------------------
/build/client/app/views/balance_operation.coffee:
--------------------------------------------------------------------------------
1 | BaseView = require '../lib/base_view'
2 |
3 | module.exports = class BalanceOperationView extends BaseView
4 |
5 | template: require './templates/balance_operations_element'
6 |
7 | tagName: 'tr'
8 |
9 | constructor: (@model, @account, @showAccountNum = false) ->
10 | super()
11 |
12 | fakeFeatureLink: ->
13 | if @model.get('title') is "SNCF" and @model.get('amount') is -137.00
14 | return 'pdf/factureSNCF.pdf'
15 | else if @model.get('title') is "SFR Facture"
16 | return 'pdf/factureSFR.pdf'
17 | else return null
18 |
19 | render: ->
20 | if @model.get("amount") > 0
21 | @$el.addClass "success"
22 | @model.account = @account
23 | @model.formattedDate = moment(@model.get('date')).format "DD/MM/YYYY"
24 | formattedAmount = @fakeFeatureLink()
25 | @model.formattedAmount = formattedAmount unless formattedAmount is null
26 |
27 | if @showAccountNum
28 | hint = "#{@model.account.get('title')}, " + \
29 | "n°#{@model.account.get('accountNumber')}"
30 | @model.hint = "#{@model.account.get('title')}, " + \
31 | "n°#{@model.account.get('accountNumber')}"
32 | else
33 | @model.hint = "#{@model.get('raw')}"
34 | super()
35 | @
--------------------------------------------------------------------------------
/build/client/app/views/bank_subtitle.coffee:
--------------------------------------------------------------------------------
1 | BaseView = require '../lib/base_view'
2 |
3 | module.exports = class BankSubTitleView extends BaseView
4 |
5 | template: require('./templates/balance_bank_subtitle')
6 |
7 | constructor: (@model) ->
8 | super()
9 |
10 | events:
11 | "click .row" : "chooseAccount"
12 |
13 | initialize: ->
14 | @listenTo @model, 'change', @render
15 | @listenTo window.activeObjects, 'changeActiveAccount', @checkActive
16 |
17 | chooseAccount: (event) ->
18 | console.log "Account chosen: " + @model.get("title")
19 | window.activeObjects.trigger "changeActiveAccount", @model
20 |
21 | checkActive: (account) ->
22 | @$(".row").removeClass("active")
23 | if account == @model
24 | @$(".row").addClass("active")
25 |
--------------------------------------------------------------------------------
/build/client/app/views/bank_title.coffee:
--------------------------------------------------------------------------------
1 | BaseView = require '../lib/base_view'
2 |
3 | module.exports = class BankTitleView extends BaseView
4 |
5 | template: require('./templates/balance_bank_title')
6 |
7 | constructor: (@model) ->
8 | super()
9 |
10 | initialize: ->
11 | @listenTo @model, 'change', @update
12 | @listenTo @model.accounts, "add", @update
13 | @listenTo @model.accounts, "destroy", @update
14 | @listenTo @model.accounts, "request", @displayLoading
15 | @listenTo @model.accounts, "change", @hideLoading
16 |
17 | displayLoading: ->
18 | @$(".bank-title-loading").show()
19 |
20 | hideLoading: ->
21 | @$(".bank-title-loading").hide()
22 |
23 | update: ->
24 | # update the sum
25 | @model.set("amount", @model.accounts.getSum())
26 | @$(".bank-amount").html Number(@model.get('amount')).money()
27 |
28 | # display or hide the bank title
29 | if @model.accounts.length == 0
30 | @$(".bank-title").hide()
31 | @$(".bank-balance").hide()
32 | else
33 | @$(".bank-title").show()
34 | @$(".bank-balance").show()
35 |
36 | # hide loader
37 | @$(".bank-title-loading").hide()
38 |
39 | render: ->
40 | super()
41 | @update()
42 | @
--------------------------------------------------------------------------------
/build/client/app/views/mockup.coffee:
--------------------------------------------------------------------------------
1 | BaseView = require '../lib/base_view'
2 |
3 |
4 | module.exports = class AppView extends BaseView
5 |
6 | template: require('./templates/mockup_balance')
7 |
8 | el: 'body.application'
9 |
10 | afterRender: ->
11 | $('.content-right-column').niceScroll()
12 |
--------------------------------------------------------------------------------
/build/client/app/views/navbar.coffee:
--------------------------------------------------------------------------------
1 | BaseView = require '../lib/base_view'
2 |
3 |
4 | module.exports = class NavbarView extends BaseView
5 |
6 | template: require('./templates/navbar')
7 |
8 | el: 'div#navbar'
9 |
10 | initialize: ->
11 | @listenTo window.collections.banks, "change", @refreshOverallBalance
12 | @listenTo window.collections.banks, 'destroy', @refreshOverallBalance
13 | @listenTo window.collections.banks, 'update', @refreshOverallBalance
14 | @listenTo window.collections.banks, 'reset', @refreshOverallBalance
15 |
16 | refreshOverallBalance: ->
17 | sum = window.collections.banks.getSum()
18 | console.log "recalculating the overall balance: " + sum
19 | $("span#total-amount").html sum.money()
20 |
--------------------------------------------------------------------------------
/build/client/app/views/search_bank.coffee:
--------------------------------------------------------------------------------
1 | BaseView = require '../lib/base_view'
2 | SearchBankTitleView = require './search_bank_title'
3 | SearchBankSubTitleView = require './search_bank_subtitle'
4 |
5 | module.exports = class SearchBankView extends BaseView
6 |
7 | className: 'bank'
8 |
9 | events:
10 | "change .choice-bank" : "bankChange"
11 |
12 | viewsAccount: []
13 |
14 | constructor: (@bank) ->
15 | super()
16 |
17 | initialize: ->
18 | @listenTo @bank.accounts, "add", @addOne
19 | @listenTo @bank.accounts, "destroy", @render
20 |
21 | bankChange: (event) ->
22 |
23 | enabled = @$(event.target).prop("checked")
24 | console.log "[Search] " + @bank.get("name") + ": " + enabled
25 |
26 | # check/uncheck all
27 | $.each @$("input[type=checkbox].choice-account"), (index, element) ->
28 | $(element).prop "checked", enabled
29 | for account in @bank.accounts.models
30 | account.checked = enabled
31 |
32 | # mark the entire bank as checked
33 | @bank.checked = enabled
34 |
35 | # and fire "update" on accounts
36 | window.collections.banks.trigger "search-update-accounts"
37 |
38 | addOne: (account) ->
39 | # add the account
40 | viewAccount = new SearchBankSubTitleView account
41 | @viewsAccount.push viewAccount
42 | account.view = viewAccount
43 | @$el.append viewAccount.render().el
44 |
45 | render: ->
46 |
47 | # generate the title
48 | @viewTitle = new SearchBankTitleView @bank
49 | @$el.html @viewTitle.render().el
50 | @viewTitle = null
51 | @sum = 0
52 |
53 | # add accounts
54 | for account in @bank.accounts.models
55 | @addOne account
56 | @
57 |
58 | destroy: ->
59 | @viewTitle?.destroy()
60 | for viewAccount in @viewsAccount
61 | viewAccount.destroy()
62 | super()
63 |
--------------------------------------------------------------------------------
/build/client/app/views/search_bank_subtitle.coffee:
--------------------------------------------------------------------------------
1 | BaseView = require '../lib/base_view'
2 |
3 | module.exports = class SearchBankSubTitleView extends BaseView
4 |
5 | template: require('./templates/search_bank_subtitle')
6 |
7 | constructor: (@model) ->
8 | super()
9 |
10 | events:
11 | "change .choice-account" : "accountChange"
12 |
13 | accountChange: (event) ->
14 |
15 | # get the value
16 | enabled = @$(event.target).prop("checked")
17 | console.log "[Search] " + @model.get("title") + ": " + enabled
18 |
19 | # mark the account as checked
20 | @model.checked = enabled
21 |
22 | # and fire "update" on accounts
23 | window.collections.banks.trigger "search-update-accounts"
24 |
25 | initialize: ->
26 | @listenTo @model, 'change', @render
27 |
--------------------------------------------------------------------------------
/build/client/app/views/search_bank_title.coffee:
--------------------------------------------------------------------------------
1 | BaseView = require '../lib/base_view'
2 |
3 | module.exports = class SearchBankTitleView extends BaseView
4 |
5 | template: require('./templates/search_bank_title')
6 |
7 | constructor: (@model) ->
8 | super()
9 |
10 | initialize: ->
11 | @listenTo @model.accounts, "add", @update
12 | @listenTo @model.accounts, "destroy", @update
13 | @listenTo @model.accounts, "request", @displayLoading
14 | @listenTo @model.accounts, "change", @hideLoading
15 |
16 | displayLoading: ->
17 | @$(".bank-title-loading").show()
18 |
19 | hideLoading: ->
20 | @$(".bank-title-loading").hide()
21 |
22 | update: ->
23 |
24 | # display or hide the bank title
25 | if @model.accounts.length == 0
26 | @$(".bank-title").hide()
27 | @$(".bank-title-checkbox").hide()
28 | else
29 | @$(".bank-title").show()
30 | @$(".bank-title-checkbox").show()
31 |
32 | # hide loader
33 | @$(".bank-title-loading").hide()
34 |
35 | render: ->
36 | super()
37 | @update()
38 | @
--------------------------------------------------------------------------------
/build/client/app/views/styles/_base.styl:
--------------------------------------------------------------------------------
1 | // Base Styles
2 |
3 | *
4 | box-sizing: border-box
5 |
6 | html,
7 | body
8 | height 100%
9 | width 100%
10 |
11 | body
12 | text-rendering optimizeLegibility
13 |
14 | body,
15 | input
16 | color #444
17 | font 300 16px Geneva, Verdana, "Lucida Sans", "Lucida Grande", "Lucida Sans Unicode", sans-serif
18 | line-height 1.2
19 |
20 | a,
21 | a:visited
22 | color #0086cc
23 | text-decoration none
24 |
25 | &:hover
26 | text-decoration underline
27 |
--------------------------------------------------------------------------------
/build/client/app/views/styles/_colors.styl:
--------------------------------------------------------------------------------
1 | basecolor = #34A6FF
2 | basecolor-alpha = rgba(49, 156, 256, 0.5)
3 |
4 | contrastcolor = #5C5
5 | contrastcolor-alpha = #5C5
6 |
7 |
8 | actioncolor = #fe8800
9 | actioncolor-alpha = rgba(254,128,0,0.5)
--------------------------------------------------------------------------------
/build/client/app/views/styles/_responsive.styl:
--------------------------------------------------------------------------------
1 | @media screen and (max-width: 480px)
2 | // Landscape phones and down
3 |
4 | body
5 | text-rendering optimizeSpeed
6 |
7 | .content-left-column
8 | height 30%
9 |
10 | .content-right-column
11 | height 70%
12 |
13 | @media screen and (max-width: 767px)
14 | // Landscape phone to portrait tablet
15 |
16 | body
17 | text-rendering optimizeSpeed
18 |
19 | .content-left-column
20 | height 30%
21 |
22 | .content-right-column
23 | height 70%
24 |
25 | @media screen and (min-width: 768px) and (max-width: 1200px)
26 | // Portrait tablet to landscape and desktop
27 |
28 | .content-left-column
29 | height 30%
30 |
31 | .content-right-column
32 | height 70%
33 |
34 | @media screen and (min-width: 1200px)
35 | // Desktop
36 |
37 | .content-left-column, .content-right-column
38 | height 100%
39 |
--------------------------------------------------------------------------------
/build/client/app/views/styles/_states.styl:
--------------------------------------------------------------------------------
1 | [data-state~="default"],
2 | [data-state~="enabled"]
3 | cursor inherit
4 | opacity 1
5 | transition opacity 0.2s linear
6 |
7 | [data-state~="disabled"],
8 | cursor not-allowed
9 | opacity 0.5
10 | transition opacity 0.2s linear
11 |
12 | [data-state~="hidden"]
13 | display none
14 |
15 | [data-state~="visible"]
16 | visibility visible
17 |
18 | [data-state~="invisible"]
19 | visibility hidden
20 |
21 | [data-state~="waiting"],
22 | [data-state~="loading"]
23 | cursor wait
24 |
25 | [data-state~="success"],
26 | [data-state~="valid"]
27 | border-color #82cf82
28 | color #82cf82
29 | transition color 0.2s linear, border-color 0.2s linear
30 |
31 | [data-state~="error"],
32 | [data-state~="invalid"]
33 | border-color #f0dddd
34 | color #f0dddd
35 | transition color 0.2s linear, border-color 0.2s linear
36 |
--------------------------------------------------------------------------------
/build/client/app/views/styles/application.styl:
--------------------------------------------------------------------------------
1 | // nib is a powerful lib for stylus that provides cross-browser css3 mixins.
2 | @import 'nib'
3 |
4 | @import '_responsive'
5 |
6 | @import '_main'
7 |
--------------------------------------------------------------------------------
/build/client/app/views/templates/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/app/views/templates/.gitkeep
--------------------------------------------------------------------------------
/build/client/app/views/templates/accounts.jade:
--------------------------------------------------------------------------------
1 | .row.content-background
2 | .col-lg-12.content-right-column
--------------------------------------------------------------------------------
/build/client/app/views/templates/accounts_alerts.jade:
--------------------------------------------------------------------------------
1 | #reports-dialog.modal.fade
2 | .modal-dialog
3 | .modal-content
4 | .modal-header
5 | button.close(type='button', data-dismiss='modal', aria-hidden='true') x
6 | h4.modal-title
7 | | #{window.i18n("accounts_alerts_title")}
8 | .modal-body
9 | h3
10 | | #{window.i18n("accounts_alerts_title_periodic")}
11 | div#reports-body-periodic
12 | p
13 | a.btn.btn-small.btn-cozy.reports-add-periodic #{window.i18n("accounts_alerts_periodic_add")}
14 |
15 |
16 | h3
17 | | #{window.i18n("accounts_alerts_title_balance")}
18 | div#reports-body-amount
19 | p
20 | a.btn.btn-small.btn-cozy.reports-add-amount #{window.i18n("accounts_alerts_balance_add")}
21 |
22 |
23 | h3
24 | | #{window.i18n("accounts_alerts_title_transaction")}
25 | div#reports-body-transaction
26 | p
27 | a.btn.btn-small.btn-cozy.reports-add-transaction #{window.i18n("accounts_alerts_transaction_add")}
28 |
29 |
--------------------------------------------------------------------------------
/build/client/app/views/templates/accounts_bank.jade:
--------------------------------------------------------------------------------
1 | h2 #{model.get("name")}
2 | a.btn.btn-cozy.pull-right.delete-bank
3 | | #{window.i18n("accounts_delete_bank")}
4 | table.table-accounts.table.table-striped.table-hover.table-bordered
5 | tbody#account-container
6 |
--------------------------------------------------------------------------------
/build/client/app/views/templates/accounts_bank_account.jade:
--------------------------------------------------------------------------------
1 | td.account-title #{model.get("title")}
2 | td.account-title
3 | span.account-details n°#{model.get("accountNumber")}
4 | td
5 | span.text-right
6 | a.btn.btn-small.btn-cozy.pull-right.alert-management
7 | | manage reports and notifications
8 | td
9 | span.text-right
10 | a.btn.btn-small.btn-cozy.pull-right.delete-account
11 | | #{window.i18n("accounts_delete_account")}
--------------------------------------------------------------------------------
/build/client/app/views/templates/app.jade:
--------------------------------------------------------------------------------
1 | // navigation bar
2 | #navbar.navbar.navbar-fixed-top.navbar-inverse
3 |
4 | // modal window to add a new bank
5 | #add-bank-window.modal.fade
6 |
7 | // content
8 | #content.container
9 |
--------------------------------------------------------------------------------
/build/client/app/views/templates/balance_bank_subtitle.jade:
--------------------------------------------------------------------------------
1 | .row.accounts-sub
2 | .pull-left
3 | p.pull-left #{model.get('title')}
4 | br
5 | span.account-details n°#{model.get("accountNumber")}
6 | .pull-right
7 | p.pull-right #{Number(model.get('amount')).money()}
8 | span.euro-sign €
9 |
--------------------------------------------------------------------------------
/build/client/app/views/templates/balance_bank_title.jade:
--------------------------------------------------------------------------------
1 | .row.accounts-top
2 | .col-lg-7
3 | p.pull-left
4 | span.bank-title-loading
5 | img(src="./loader.gif")
6 | span.bank-title #{model.get('name')}
7 | .col-lg-5
8 | p.pull-right.bank-balance
9 | span.bank-amount #{Number(model.get('amount')).money()}
10 | span.euro-sign €
11 |
--------------------------------------------------------------------------------
/build/client/app/views/templates/balance_banks_empty.jade:
--------------------------------------------------------------------------------
1 | p.arrow.text-right
2 | img(src="images/arrow_vertical.png")
3 | p.loading
4 | | #{window.i18n("balance_banks_empty")}
5 |
--------------------------------------------------------------------------------
/build/client/app/views/templates/balance_operations_element.jade:
--------------------------------------------------------------------------------
1 | td.operation-date #{model.formattedDate}
2 | td.operation-title
3 | .hint--top(data-hint="#{model.hint}")
4 | span.infobulle.glyphicon.glyphicon-info-sign
5 | | #{model.get('title')}
6 | td.operation-amount.text-right
7 | - if(model.formattedAmount == null)
8 | | #{Number(model.get('amount')).money()}
9 | - else
10 | a(href="#{model.formattedAmount}", target="_blank")
11 | | #{Number(model.get('amount')).money()}
--------------------------------------------------------------------------------
/build/client/app/views/templates/balance_operations_empty.jade:
--------------------------------------------------------------------------------
1 | br
2 | br
3 | p.loading
4 | | #{window.i18n("balance_please_choose_account")}
--------------------------------------------------------------------------------
/build/client/app/views/templates/balance_operations_header.jade:
--------------------------------------------------------------------------------
1 | h2 #{model.get("title")}
2 | p
3 | span.last-checked #{window.i18n("balance_last_checked")} #{moment(moment(model.get("lastChecked"))).fromNow()}.
4 | a.recheck-button.btn-link #{window.i18n("balance_recheck_now")}
5 |
6 | .text-center.loading.loader-operations
7 | img(src="./loader_big_blue.gif")
8 |
9 | table.table.tablesorter.table-striped.table-hover
10 | thead
11 | tr
12 | th.sort-date.text-left #{window.i18n("header_date")}
13 | th.sort-title.text-center #{window.i18n("header_title")}
14 | th.sort-amount.text-right #{window.i18n("header_amount")}
15 | tbody#table-operations
16 |
--------------------------------------------------------------------------------
/build/client/app/views/templates/layout-2col.jade:
--------------------------------------------------------------------------------
1 | .row.content-background
2 | #layout-2col-column-left.col-lg-4.content-left-column
3 |
4 | #layout-2col-column-right.col-lg-8.content-right-column
5 |
--------------------------------------------------------------------------------
/build/client/app/views/templates/modal_confirm.jade:
--------------------------------------------------------------------------------
1 | #confirmation-dialog.modal.fade
2 | .modal-dialog
3 | .modal-content
4 | .modal-header
5 | button.close(type='button', data-dismiss='modal', aria-hidden='true') x
6 | h4.modal-title
7 | | #{title}
8 | .modal-body
9 | p
10 | | #{body}
11 | .modal-footer
12 | a.btn.btn-link(data-dismiss='modal',href='#') #{window.i18n("cancel")}
13 | a#confirmation-dialog-confirm.btn.btn-cozy(href='#') #{confirm}
14 |
15 |
--------------------------------------------------------------------------------
/build/client/app/views/templates/navbar.jade:
--------------------------------------------------------------------------------
1 | nav.navbar.navbar-inverse.navbar-fixed-top(role='navigation')
2 | .container
3 | // Brand and toggle get grouped for better mobile display
4 | .navbar-header
5 | button.navbar-toggle(type='button', data-toggle='collapse', data-target='.navbar-collapse')
6 | span.sr-only Toggle navigation
7 | span.icon-bar
8 | span.icon-bar
9 | span.icon-bar
10 | // Collect the nav links, forms, and other content for toggling
11 | .collapse.navbar-collapse
12 | ul.nav.navbar-nav
13 | li.menu-position.menu-1
14 | a#menu-pos-balance(href='#') #{window.i18n("menu_balance")}
15 | li.menu-position.menu-2
16 | a#menu-pos-accounts(href='#search') #{window.i18n("menu_search")}
17 | li.menu-position.menu-3
18 | a#menu-pos-accounts(href='#accounts') #{window.i18n("menu_accounts")}
19 | li
20 | a#menu-pos-new-bank(data-toggle='modal', href='#add-bank-window') #{window.i18n("menu_add_bank")}
21 |
22 | ul.nav.navbar-nav.navbar-right
23 | p.navbar-text
24 | | #{window.i18n("overall_balance")}
25 | span#total-amount 0,00
--------------------------------------------------------------------------------
/build/client/app/views/templates/new_bank.jade:
--------------------------------------------------------------------------------
1 | .modal-dialog
2 | .modal-content
3 | .modal-header
4 | button.close(type='button', data-dismiss='modal', aria-hidden='true') x
5 | h4.modal-title
6 | | #{window.i18n("menu_add_bank")}
7 | .modal-body
8 | .message-modal
9 | form
10 | fieldset
11 | legend
12 | | #{window.i18n("add_bank_bank")}
13 | .form-group
14 | select#inputBank.form-control
15 | each bank in banks
16 | option(value=bank.get("uuid"))
17 | =bank.get("name")
18 |
19 | #formInputWebsite.form-group.hide
20 | label(for='inputWebsite')
21 | | #{window.i18n("add_bank_website")}
22 | select#inputWebsite.form-control
23 |
24 | fieldset
25 | legend
26 | | #{window.i18n("add_bank_credentials")}
27 | .form-group
28 | label(for='inputLogin')
29 | | #{window.i18n("add_bank_login")}
30 | input#inputLogin.form-control(type='text', placeholder=window.i18n("add_bank_login_placeholder"))
31 | .form-group
32 | label(for='inputPass')
33 | | #{window.i18n("add_bank_password")}
34 | input#inputPass.form-control(type='password', placeholder=window.i18n("add_bank_password_placeholder"))
35 | h3.important-notice
36 | | #{window.i18n("add_bank_security_notice")}
37 | p
38 | | #{window.i18n("add_bank_security_notice_text")}
39 | .modal-footer
40 | a.btn.btn-link(data-dismiss='modal',href='#') #{window.i18n("add_bank_cancel")}
41 | a#btn-add-bank-save.btn.btn-success(href='#') #{window.i18n("add_bank_ok")}
42 |
--------------------------------------------------------------------------------
/build/client/app/views/templates/search_bank_subtitle.jade:
--------------------------------------------------------------------------------
1 | .row.accounts-sub
2 | .col-lg-7
3 | p.pull-left #{model.get('title')}
4 | .col-lg-5
5 | p.pull-right
6 | if model.checked
7 | input(type="checkbox", checked).choice-account
8 | else
9 | input(type="checkbox").choice-account
10 |
--------------------------------------------------------------------------------
/build/client/app/views/templates/search_bank_title.jade:
--------------------------------------------------------------------------------
1 | .row.accounts-top
2 | .col-lg-7
3 | p.pull-left
4 | span.bank-title-loading
5 | img(src="./loader.gif")
6 | span.bank-title
7 | | #{model.get('name')}
8 | .col-lg-5
9 | p.pull-right.bank-title-checkbox
10 | if model.checked
11 | input(type="checkbox", checked).choice-bank
12 | else
13 | input(type="checkbox").choice-bank
--------------------------------------------------------------------------------
/build/client/app/views/templates/search_operations.jade:
--------------------------------------------------------------------------------
1 | form.form-search
2 | .row
3 | .col-lg-6
4 | .form-group
5 | label(for='search-date-from')
6 | | #{window.i18n("search_date_from")}
7 | input#search-date-from.form-control(type='date')
8 | .col-lg-6
9 | .form-group
10 | label(for='search-date-to')
11 | | #{window.i18n("search_date_to")}
12 | input#search-date-to.form-control(type='date')
13 |
14 | .row
15 | .col-lg-6
16 | .form-group
17 | label(for='search-amount-from')
18 | | #{window.i18n("search_amount_from")}
19 | input#search-amount-from.form-control(type='number')
20 | .col-lg-6
21 | .form-group
22 | label(for='search-amount-to')
23 | | #{window.i18n("search_amount_to")}
24 | input#search-amount-to.form-control(type='number')
25 |
26 | .row
27 | .col-lg-12
28 | label(for='search-text')
29 | | #{window.i18n("search_text")}
30 | input#search-text.form-control(type='text')
31 |
32 | .row
33 | .col-lg-12#search-operations-table
34 |
--------------------------------------------------------------------------------
/build/client/app/views/templates/search_operations_table_header.jade:
--------------------------------------------------------------------------------
1 | br
2 | table#search-table.table.tablesorter.table-striped.table-hover
3 | thead
4 | tr
5 | th.sort-date.text-left #{window.i18n("header_date")}
6 | th.sort-title.text-center #{window.i18n("header_title")}
7 | th.sort-amount.text-right #{window.i18n("header_amount")}
8 | tbody#search-operations-table-body
9 |
--------------------------------------------------------------------------------
/build/client/config.coffee:
--------------------------------------------------------------------------------
1 | exports.config =
2 | # See docs at http://brunch.readthedocs.org/en/latest/config.html.
3 | #coffeelint:
4 | #pattern: /^app\/.*\.coffee$/
5 | #options:
6 | #indentation:
7 | #value: 4
8 | #level: "error"
9 |
10 | files:
11 | javascripts:
12 | joinTo:
13 | 'javascripts/app.js': /^app/
14 | 'javascripts/vendor.js': /^vendor/
15 | order:
16 | # Files in `vendor` directories are compiled before other files
17 | # even if they aren't specified in order.
18 | before: [
19 | 'vendor/scripts/jquery-1.10.2.js'
20 | 'vendor/scripts/underscore-1.4.4.js'
21 | 'vendor/scripts/backbone-1.0.0.js'
22 | 'vendor/scripts/jquery.dataTables.js'
23 | ]
24 |
25 | stylesheets:
26 | joinTo: 'stylesheets/app.css'
27 | order:
28 | before: ['vendor/styles/normalize.css']
29 | after: ['vendor/styles/helpers.css']
30 |
31 | templates:
32 | defaultExtension: 'jade'
33 | joinTo: 'javascripts/app.js'
34 |
--------------------------------------------------------------------------------
/build/client/generators/collection/collection.coffee.hbs:
--------------------------------------------------------------------------------
1 | module.exports = class {{#camelize}}{{pluralName}}{{/camelize}}Collection extends Backbone.Collection
2 | model: require '../models/{{name}}'
3 | url: '{{name}}s/'
4 |
--------------------------------------------------------------------------------
/build/client/generators/collection/generator.json:
--------------------------------------------------------------------------------
1 | {
2 | "files": [{
3 | "from": "collection.coffee.hbs",
4 | "to": "app/collections/{{pluralName}}.coffee"
5 | }],
6 | "dependencies": [{
7 | "name": "collection_test",
8 | "params": "{{pluralName}}"
9 | }]
10 | }
11 |
--------------------------------------------------------------------------------
/build/client/generators/collection_test/collection_test.coffee.hbs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/generators/collection_test/collection_test.coffee.hbs
--------------------------------------------------------------------------------
/build/client/generators/collection_test/generator.json:
--------------------------------------------------------------------------------
1 | {
2 | "files": [{
3 | "from": "collection_test.coffee.hbs",
4 | "to": "test/collections/{{pluralName}}_test.coffee"
5 | }],
6 | "dependencies": []
7 | }
8 |
--------------------------------------------------------------------------------
/build/client/generators/generator/generated_file.coffee.hbs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/generators/generator/generated_file.coffee.hbs
--------------------------------------------------------------------------------
/build/client/generators/generator/generator.json:
--------------------------------------------------------------------------------
1 | {
2 | "files": [
3 | {
4 | "from": "generator.json.hbs",
5 | "to": "generators/{{name}}/generator.json"
6 | },
7 | {
8 | "from": "generated_file.coffee.hbs",
9 | "to": "generators/{{name}}/{{name}}.coffee.hbs"
10 | }
11 | ],
12 | "dependencies": []
13 | }
14 |
--------------------------------------------------------------------------------
/build/client/generators/generator/generator.json.hbs:
--------------------------------------------------------------------------------
1 | {
2 | "files": [{
3 | "from": "{{name}}.coffee.hbs",
4 | "to": "app/file.coffee"
5 | }],
6 | "dependencies": []
7 | }
8 |
--------------------------------------------------------------------------------
/build/client/generators/model/generator.json:
--------------------------------------------------------------------------------
1 | {
2 | "files": [{
3 | "from": "model.coffee.hbs",
4 | "to": "app/models/{{name}}.coffee"
5 | }],
6 | "dependencies": [{
7 | "name": "model_test",
8 | "params": "{{name}}"
9 | }]
10 | }
11 |
--------------------------------------------------------------------------------
/build/client/generators/model/model.coffee.hbs:
--------------------------------------------------------------------------------
1 | module.exports = class {{#camelize}}{{name}}{{/camelize}}Model extends Backbone.Model
2 | rootUrl: "{{name}}s/"
--------------------------------------------------------------------------------
/build/client/generators/model_test/generator.json:
--------------------------------------------------------------------------------
1 | {
2 | "files": [{
3 | "from": "model_test.coffee.hbs",
4 | "to": "test/models/{{name}}.coffee"
5 | }],
6 | "dependencies": []
7 | }
8 |
--------------------------------------------------------------------------------
/build/client/generators/model_test/model_test.coffee.hbs:
--------------------------------------------------------------------------------
1 | {{#camelize}}{{name}}{{/camelize}}Model = require 'models/{{name}}'
2 |
3 | describe '{{#camelize}}{{name}}{{/camelize}}Model', ->
4 | beforeEach ->
5 | @model = new {{#camelize}}{{name}}{{/camelize}}Model()
6 |
--------------------------------------------------------------------------------
/build/client/generators/module/collection.coffee.hbs:
--------------------------------------------------------------------------------
1 | module.exports = class {{#camelize}}{{pluralName}}{{/camelize}}Collection extends Backbone.Collection
2 | model: require '../models/{{name}}'
3 | url: '{{name}}s/'
4 |
--------------------------------------------------------------------------------
/build/client/generators/module/generator.json:
--------------------------------------------------------------------------------
1 | {
2 | "files": [
3 | {
4 | "from": "model.coffee.hbs",
5 | "to": "app/models/{{name}}.coffee"
6 | },
7 | {
8 | "from": "view.coffee.hbs",
9 | "to": "app/views/{{name}}.coffee"
10 | },
11 | {
12 | "from": "collection.coffee.hbs",
13 | "to": "app/collections/{{name}}s.coffee"
14 | },
15 | {
16 | "from": "template.jade.hbs",
17 | "to": "app/views/templates/{{name}}.jade"
18 | },
19 | {
20 | "from": "style.styl.hbs",
21 | "to": "app/views/styles/_{{name}}.styl"
22 | },
23 | {
24 | "from": "view_collection.coffee.hbs",
25 | "to": "app/views/{{name}}s.coffee"
26 | }
27 | ],
28 | "dependencies": []
29 | }
30 |
--------------------------------------------------------------------------------
/build/client/generators/module/model.coffee.hbs:
--------------------------------------------------------------------------------
1 | module.exports = class {{#camelize}}{{name}}{{/camelize}}Model extends Backbone.Model
2 | rootUrl: "{{name}}s/"
--------------------------------------------------------------------------------
/build/client/generators/module/style.styl.hbs:
--------------------------------------------------------------------------------
1 | .{{name}}
2 | // {{#camelize}}{{name}}{{/camelize}} Module
3 |
4 |
--------------------------------------------------------------------------------
/build/client/generators/module/template.jade.hbs:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/build/client/generators/module/view.coffee.hbs:
--------------------------------------------------------------------------------
1 | BaseView = require '../lib/base_view'
2 |
3 | module.exports = class {{#camelize}}{{name}}{{/camelize}}View extends BaseView
4 | template: require './templates/{{name}}'
5 | className: '{{name}}'
6 |
--------------------------------------------------------------------------------
/build/client/generators/module/view_collection.coffee.hbs:
--------------------------------------------------------------------------------
1 | ViewCollection = require '../lib/view_collection'
2 | {{#camelize}}{{name}}{{/camelize}}sCollection = require '../collections/{{name}}s'
3 | {{#camelize}}{{name}}{{/camelize}}View = require './{{name}}'
4 |
5 | module.exports = class {{#camelize}}{{name}}{{/camelize}}sView extends ViewCollection
6 | el: '#{{name}}s'
7 |
8 | collection: new {{#camelize}}{{name}}{{/camelize}}sCollection()
9 | itemview: {{#camelize}}{{name}}{{/camelize}}View
10 |
11 | afterRender: ->
12 | @collection.on 'reset', =>
13 | @renderAll()
14 | @collection.on 'add', (model) =>
15 | @renderOne model
16 |
--------------------------------------------------------------------------------
/build/client/generators/style/generator.json:
--------------------------------------------------------------------------------
1 | {
2 | "files": [{
3 | "from": "style.styl.hbs",
4 | "to": "app/views/styles/_{{name}}.styl"
5 | }],
6 | "dependencies": []
7 | }
8 |
--------------------------------------------------------------------------------
/build/client/generators/style/style.styl.hbs:
--------------------------------------------------------------------------------
1 | .{{name}}
2 | // {{#camelize}}{{name}}{{/camelize}} Module
3 |
--------------------------------------------------------------------------------
/build/client/generators/template/generator.json:
--------------------------------------------------------------------------------
1 | {
2 | "files": [{
3 | "from": "template.hbs.hbs",
4 | "to": "app/views/templates/{{name}}.jade"
5 | }],
6 | "dependencies": []
7 | }
8 |
--------------------------------------------------------------------------------
/build/client/generators/template/template.hbs:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/build/client/generators/view/generator.json:
--------------------------------------------------------------------------------
1 | {
2 | "files": [{
3 | "from": "view.coffee.hbs",
4 | "to": "app/views/{{name}}.coffee"
5 | }],
6 | "dependencies": [{
7 | "name": "view_test",
8 | "params": "{{name}}"
9 | }]
10 | }
11 |
--------------------------------------------------------------------------------
/build/client/generators/view/view.coffee.hbs:
--------------------------------------------------------------------------------
1 | BaseView = require '../lib/base_view'
2 |
3 | module.exports = class {{#camelize}}{{name}}{{/camelize}}View extends BaseView
4 | template: require './templates/{{name}}'
5 | className: '{{name}}'
6 |
--------------------------------------------------------------------------------
/build/client/generators/view_test/generator.json:
--------------------------------------------------------------------------------
1 | {
2 | "files": [
3 | {
4 | "from": "view_test.coffee.hbs",
5 | "to": "test/views/{{name}}.coffee"
6 | }
7 | ],
8 | "dependencies": []
9 | }
10 |
--------------------------------------------------------------------------------
/build/client/generators/view_test/view_test.coffee.hbs:
--------------------------------------------------------------------------------
1 | {{#camelize}}{{name}}{{/camelize}}View = require 'views/{{name}}'
2 |
3 | describe '{{#camelize}}{{name}}{{/camelize}}View', ->
4 | beforeEach ->
5 | @view = new {{#camelize}}{{name}}{{/camelize}}View()
6 |
--------------------------------------------------------------------------------
/build/client/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "author": "Your Name",
3 | "name": "package-name",
4 | "description": "Package description",
5 | "version": "0.0.1",
6 | "homepage": "",
7 | "repository": {
8 | "type": "git",
9 | "url": ""
10 | },
11 | "engines": {
12 | "node": "~0.6.10 || 0.8 || 0.9"
13 | },
14 | "scripts": {
15 | "start": "brunch watch --server"
16 | },
17 | "dependencies": {
18 | "javascript-brunch": "> 1.0 < 1.5",
19 | "coffee-script-brunch": "> 1.0 < 1.5",
20 |
21 | "css-brunch": "> 1.0 < 1.5",
22 | "stylus-brunch": "> 1.0 < 1.5",
23 |
24 | "jade-brunch": "> 1.0 < 1.5",
25 |
26 | "uglify-js-brunch": "> 1.0 < 1.5",
27 | "clean-css-brunch": "> 1.0 < 1.5",
28 |
29 | "auto-reload-brunch": "> 1.0 < 1.5",
30 |
31 | "async": ">= 0"
32 | },
33 | "devDependencies": {
34 | "mocha": "0.14.0",
35 | "expect.js": "0.1.2",
36 | "ws": "0.4.21"
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/build/client/public/asc.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/public/asc.gif
--------------------------------------------------------------------------------
/build/client/public/bg.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/public/bg.gif
--------------------------------------------------------------------------------
/build/client/public/crossdomain.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
15 |
16 |
--------------------------------------------------------------------------------
/build/client/public/desc.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/public/desc.gif
--------------------------------------------------------------------------------
/build/client/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/public/favicon.ico
--------------------------------------------------------------------------------
/build/client/public/fonts/fontawesome/FontAwesome.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/public/fonts/fontawesome/FontAwesome.ttf
--------------------------------------------------------------------------------
/build/client/public/fonts/fontawesome/README.md:
--------------------------------------------------------------------------------
1 | #Font Awesome 2.0
2 | ##the iconic font designed for use with Twitter Bootstrap
3 |
4 | The full suite of pictographic icons, examples, and documentation can be found at:
5 | http://fortawesome.github.com/Font-Awesome/
6 |
7 | ##Contact
8 | - Email: dave@davegandy.com
9 | - Twitter: http://twitter.com/fortaweso_me
10 | - Work: Lead Product Designer @ http://kyru.us
11 |
12 | ##License
13 | Version 2.0 of the Font Awesome font, CSS, and LESS files are licensed under CC BY 3.0:
14 | http://creativecommons.org/licenses/by/3.0/
15 | A mention of 'Font Awesome - http://fortawesome.github.com/Font-Awesome'
16 | in human-readable source code is considered acceptable attribution (most common on the
17 | web). If human readable source code is not available to the end user, a mention in an 'About'
18 | or 'Credits' screen is considered acceptable (most common in desktop or mobile software).
19 |
--------------------------------------------------------------------------------
/build/client/public/fonts/fontawesome/fontawesome-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/public/fonts/fontawesome/fontawesome-webfont.eot
--------------------------------------------------------------------------------
/build/client/public/fonts/fontawesome/fontawesome-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/public/fonts/fontawesome/fontawesome-webfont.ttf
--------------------------------------------------------------------------------
/build/client/public/fonts/fontawesome/fontawesome-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/public/fonts/fontawesome/fontawesome-webfont.woff
--------------------------------------------------------------------------------
/build/client/public/fonts/fontello.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/public/fonts/fontello.ttf
--------------------------------------------------------------------------------
/build/client/public/fonts/glyphicons-halflings-regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/public/fonts/glyphicons-halflings-regular.eot
--------------------------------------------------------------------------------
/build/client/public/fonts/glyphicons-halflings-regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/public/fonts/glyphicons-halflings-regular.ttf
--------------------------------------------------------------------------------
/build/client/public/fonts/glyphicons-halflings-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/public/fonts/glyphicons-halflings-regular.woff
--------------------------------------------------------------------------------
/build/client/public/fonts/maven-pro-light-100.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/public/fonts/maven-pro-light-100.otf
--------------------------------------------------------------------------------
/build/client/public/fonts/maven-pro-light-200.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/public/fonts/maven-pro-light-200.otf
--------------------------------------------------------------------------------
/build/client/public/fonts/maven-pro-light-300.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/public/fonts/maven-pro-light-300.otf
--------------------------------------------------------------------------------
/build/client/public/fonts/signika-bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/public/fonts/signika-bold.ttf
--------------------------------------------------------------------------------
/build/client/public/fonts/signika-light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/public/fonts/signika-light.ttf
--------------------------------------------------------------------------------
/build/client/public/fonts/signika-regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/public/fonts/signika-regular.ttf
--------------------------------------------------------------------------------
/build/client/public/humans.txt:
--------------------------------------------------------------------------------
1 | # humanstxt.org/
2 | # The humans responsible & technology colophon
3 |
4 | # TEAM
5 |
6 | -- --
7 |
8 | # THANKS
9 |
10 |
11 |
12 | # TECHNOLOGY COLOPHON
13 |
14 | HTML5, CSS3
15 | jQuery, Modernizr,
16 | Lodash, Backbone,
17 | Handlebars, Coffeescript,
18 | Stylus, Brunch
19 |
--------------------------------------------------------------------------------
/build/client/public/icons/main_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/public/icons/main_icon.png
--------------------------------------------------------------------------------
/build/client/public/images/Melamine-wood-003.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/public/images/Melamine-wood-003.png
--------------------------------------------------------------------------------
/build/client/public/images/arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/public/images/arrow.png
--------------------------------------------------------------------------------
/build/client/public/images/arrow_vertical.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/public/images/arrow_vertical.png
--------------------------------------------------------------------------------
/build/client/public/images/glyphicons-halflings-white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/public/images/glyphicons-halflings-white.png
--------------------------------------------------------------------------------
/build/client/public/images/glyphicons-halflings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/public/images/glyphicons-halflings.png
--------------------------------------------------------------------------------
/build/client/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Cozy PFM
10 |
11 |
12 |
17 |
18 |
19 |
20 |
21 |
22 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/build/client/public/loader.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/public/loader.gif
--------------------------------------------------------------------------------
/build/client/public/loader_big_blue.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/public/loader_big_blue.gif
--------------------------------------------------------------------------------
/build/client/public/loader_green.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/public/loader_green.gif
--------------------------------------------------------------------------------
/build/client/public/loader_inverse.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/public/loader_inverse.gif
--------------------------------------------------------------------------------
/build/client/public/robots.txt:
--------------------------------------------------------------------------------
1 | # robotstxt.org/
2 |
3 | User-agent: *
4 |
--------------------------------------------------------------------------------
/build/client/vendor/scripts/zoomico.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/build/client/vendor/scripts/zoomico.png
--------------------------------------------------------------------------------
/build/client/vendor/styles/helpers.css:
--------------------------------------------------------------------------------
1 | .chromeframe { margin: 0.2em 0; background: #ccc; color: #000; padding: 0.2em 0; }
2 | .ir { display: block; border: 0; text-indent: -999em; overflow: hidden; background-color: transparent; background-repeat: no-repeat; text-align: left; direction: ltr; *line-height: 0; }
3 | .ir br { display: none; }
4 | .hidden { display: none !important; visibility: hidden; }
5 | .visuallyhidden { border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; }
6 | .visuallyhidden.focusable:active, .visuallyhidden.focusable:focus { clip: auto; height: auto; margin: 0; overflow: visible; position: static; width: auto; }
7 | .invisible { visibility: hidden; }
8 | .clearfix:before, .clearfix:after { content: ""; display: table; }
9 | .clearfix:after { clear: both; }
10 | .clearfix { *zoom: 1; }
11 |
12 | @media print {
13 | * { background: transparent !important; color: black !important; box-shadow:none !important; text-shadow: none !important; filter:none !important; -ms-filter: none !important; }
14 | a, a:visited { text-decoration: underline; }
15 | a[href]:after { content: " (" attr(href) ")"; }
16 | abbr[title]:after { content: " (" attr(title) ")"; }
17 | .ir a:after, a[href^="javascript:"]:after, a[href^="#"]:after { content: ""; }
18 | pre, blockquote { border: 1px solid #999; page-break-inside: avoid; }
19 | thead { display: table-header-group; }
20 | tr, img { page-break-inside: avoid; }
21 | img { max-width: 100% !important; }
22 | @page { margin: 0.5cm; }
23 | p, h2, h3 { orphans: 3; widows: 3; }
24 | h2, h3 { page-break-after: avoid; }
25 | }
26 |
--------------------------------------------------------------------------------
/build/client/vendor/styles/sort.css:
--------------------------------------------------------------------------------
1 | /* table sorter */
2 | table.tablesorter thead tr th {
3 | background-image: url(../bg.gif);
4 | background-repeat: no-repeat;
5 | background-position: center right;
6 | /* background-color: #F7F7F7; */
7 | padding-right: 20px;
8 | cursor: pointer;
9 | }
10 | table.tablesorter thead tr .sorting_asc {
11 | background-image: url(../asc.gif);
12 | }
13 | table.tablesorter thead tr .sorting_desc {
14 | background-image: url(../desc.gif);
15 | }
16 | table.tablesorter thead tr .sorting_asc, table.tablesorter thead tr .sorting_desc {
17 | /* background-color: #dddddd; */
18 | font-weight: bold;
19 | color: #34A6FF;
20 | }
--------------------------------------------------------------------------------
/build/client/vendor/styles/tablesort_blue.css:
--------------------------------------------------------------------------------
1 | /* table sorter */
2 | table.tablesorter thead tr .header {
3 | background-image: url(../bg.gif);
4 | background-repeat: no-repeat;
5 | background-position: center right;
6 | /* background-color: #F7F7F7; */
7 | padding-right: 20px;
8 | cursor: pointer;
9 | }
10 | table.tablesorter thead tr .headerSortUp {
11 | background-image: url(../asc.gif);
12 | }
13 | table.tablesorter thead tr .headerSortDown {
14 | background-image: url(../desc.gif);
15 | }
16 | table.tablesorter thead tr .headerSortDown, table.tablesorter thead tr .headerSortUp {
17 | /* background-color: #dddddd; */
18 | font-weight: bold;
19 | color: #34A6FF;
20 | }
21 |
--------------------------------------------------------------------------------
/build/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "pfm",
3 | "version": "1.0.0",
4 | "engines": [
5 | "node = 0.8.x"
6 | ],
7 | "description": "Personal Finance Manager you own and control",
8 | "license": "MIT",
9 | "repository": {
10 | "type": "git",
11 | "url": "https://github.com/mycozycloud/cozy-pfm.git"
12 | },
13 | "main": "server.coffee",
14 | "dependencies": {
15 | "americano": "0.3.3",
16 | "americano-cozy": "0.2.2",
17 | "async": "0.2.10",
18 | "request-json": "0.4.8",
19 | "moment": "2.5.1",
20 | "cozy-notifications-helper": "1.0.2",
21 | "jade": "1.3.0",
22 | "nock": "0.27.2",
23 | "cozy-i18n-helper": "0.0.4",
24 | "printit": "0.1.3"
25 | },
26 | "devDependencies": {
27 | "should": "3.1.4",
28 | "mocha": "1.18.2",
29 | "cozy-fixtures": "1.1.0",
30 | "coffeelint": "1.1.0"
31 | },
32 | "scripts": {
33 | "test": "cake --use-js tests",
34 | "start": "node build/server.js"
35 | },
36 | "cozy-displayName": "Mes Comptes",
37 | "cozy-permissions": {
38 | "Bank": {
39 | "description": "Les banques auxquelles vous pouvez accéder via l'application."
40 | },
41 | "BankAccess": {
42 | "description": "Vos identifiants d'accès à votre banque sont stockés de façon sécurisée."
43 | },
44 | "BankAccount": {
45 | "description": "Vos différents comptes bancaires."
46 | },
47 | "BankOperation": {
48 | "description": "Une opération bancaire."
49 | },
50 | "BankAlert": {
51 | "description": "Une alerte liée à vos comptes bancaires."
52 | },
53 | "send mail to user": {
54 | "description": "A votre demande, des rapports journaliers, hebdomadaires ou mensuels peuvent vous être envoyés par email."
55 | },
56 | "Notification": {
57 | "description": "Des notifications sont créées lorsque des alertes sont mises en place dans l'application."
58 | },
59 | "CozyInstance": {
60 | "description": "Afin d'afficher le contenu dans votre langue, l'application doit accéder à vos préférences."
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/build/server.js:
--------------------------------------------------------------------------------
1 | // Generated by CoffeeScript 1.8.0
2 | var application;
3 |
4 | application = module.exports = function(callback) {
5 | var americano, initialize, options;
6 | americano = require('americano');
7 | initialize = require('./server/init');
8 | require('./tests/mock-weboob');
9 | options = {
10 | name: 'pfm',
11 | port: process.env.PORT || 9875,
12 | host: process.env.HOST || "127.0.0.1",
13 | root: __dirname
14 | };
15 | return americano.start(options, function(app, server) {
16 | return initialize(app, server, callback);
17 | });
18 | };
19 |
20 | if (!module.parent) {
21 | application();
22 | }
23 |
--------------------------------------------------------------------------------
/build/server/config.js:
--------------------------------------------------------------------------------
1 | // Generated by CoffeeScript 1.8.0
2 | var americano, config;
3 |
4 | americano = require('americano');
5 |
6 | config = {
7 | common: [
8 | americano.bodyParser(), americano.methodOverride(), americano.errorHandler({
9 | dumpExceptions: true,
10 | showStack: true
11 | }), americano["static"](__dirname + '/../client/public', {
12 | maxAge: 86400000
13 | }), require('cozy-i18n-helper').middleware
14 | ],
15 | development: [americano.logger('dev')],
16 | production: [americano.logger('short')],
17 | plugins: ['americano-cozy']
18 | };
19 |
20 | module.exports = config;
21 |
--------------------------------------------------------------------------------
/build/server/init.js:
--------------------------------------------------------------------------------
1 | // Generated by CoffeeScript 1.8.0
2 | module.exports = function(app, server, callback) {
3 | var Bank, poller, reportManager;
4 | Bank = require('./models/bank');
5 | Bank.all(function(err, banks) {
6 | var async, bankList, process;
7 | if (err || (banks != null ? banks.length : void 0) === 0) {
8 | async = require('async');
9 | bankList = require("../tests/fixtures/banks-all.json");
10 | process = function(bank, callback) {
11 | var newBank;
12 | newBank = {
13 | name: bank.name,
14 | uuid: bank.uuid,
15 | websites: bank.websites
16 | };
17 | return Bank.create(newBank, function(err) {
18 | if (err != null) {
19 | return callback(err);
20 | } else {
21 | return callback(null);
22 | }
23 | });
24 | };
25 | return async.each(bankList, process, function(err) {
26 | var msg;
27 | if (err != null) {
28 | msg = "Couldn't add the bank to the database -- " + err;
29 | return console.log(msg);
30 | } else {
31 | msg = "Banks added to the database.";
32 | console.log(msg);
33 | if (callback != null) {
34 | return callback(app, server);
35 | }
36 | }
37 | });
38 | } else {
39 | if (callback != null) {
40 | return callback(app, server);
41 | }
42 | }
43 | });
44 | console.log("Start bank accounts polling...");
45 | poller = require('./lib/accounts-poller');
46 | poller.start();
47 | console.log("Start alert watcher...");
48 | reportManager = require('./lib/report-manager');
49 | return reportManager.start();
50 | };
51 |
--------------------------------------------------------------------------------
/build/server/lib/accounts-poller.js:
--------------------------------------------------------------------------------
1 | // Generated by CoffeeScript 1.8.0
2 | var AccountsPoller, BankAccess, async, moment;
3 |
4 | async = require("async");
5 |
6 | moment = require("moment");
7 |
8 | BankAccess = require("../models/bankaccess");
9 |
10 | AccountsPoller = (function() {
11 | function AccountsPoller() {}
12 |
13 | AccountsPoller.prototype.start = function() {
14 | return this.prepareNextCheck();
15 | };
16 |
17 | AccountsPoller.prototype.prepareNextCheck = function() {
18 | var delta, format, msg, nextUpdate, now;
19 | delta = Math.floor(Math.random() * 120);
20 | now = moment();
21 | nextUpdate = now.clone().add(1, 'days').hours(0).minutes(delta).seconds(0);
22 | format = "DD/MM/YYYY [at] HH:mm:ss";
23 | msg = "> Next check of bank accounts on " + (nextUpdate.format(format));
24 | console.log(msg);
25 | return this.timeout = setTimeout((function(_this) {
26 | return function() {
27 | return _this.checkAllAccesses();
28 | };
29 | })(this), nextUpdate.diff(now));
30 | };
31 |
32 | AccountsPoller.prototype.checkAllAccesses = function() {
33 | console.log("Checking new operations for all bank accesses...");
34 | return BankAccess.retrieveOperationsForAllAccesses((function(_this) {
35 | return function(err) {
36 | if (err != null) {
37 | console.log("An error occurred during access check -- " + err);
38 | }
39 | console.log("Bank accesses checked.");
40 | return _this.prepareNextCheck();
41 | };
42 | })(this));
43 | };
44 |
45 | return AccountsPoller;
46 |
47 | })();
48 |
49 | module.exports = new AccountsPoller;
50 |
--------------------------------------------------------------------------------
/build/server/models/bankalert.js:
--------------------------------------------------------------------------------
1 | // Generated by CoffeeScript 1.8.0
2 | var BankAlert, americano;
3 |
4 | americano = require('americano');
5 |
6 | module.exports = BankAlert = americano.getModel('bankalert', {
7 | bankAccount: String,
8 | type: String,
9 | frequency: String,
10 | limit: Number,
11 | order: String
12 | });
13 |
14 | BankAlert.all = function(callback) {
15 | return BankAlert.request("all", callback);
16 | };
17 |
18 | BankAlert.allFromBankAccount = function(account, callback) {
19 | var params;
20 | params = {
21 | key: account.id
22 | };
23 | return BankAlert.request("allByBankAccount", params, callback);
24 | };
25 |
26 | BankAlert.allByAccountAndType = function(accountID, type, callback) {
27 | var params;
28 | params = {
29 | key: [accountID, type]
30 | };
31 | return BankAlert.request("allByBankAccountAndType", params, callback);
32 | };
33 |
34 | BankAlert.allReportsByFrequency = function(frequency, callback) {
35 | var params;
36 | params = {
37 | key: ["report", frequency]
38 | };
39 | return BankAlert.request("allReportsByFrequency", params, callback);
40 | };
41 |
42 | BankAlert.destroyByAccount = function(id, callback) {
43 | return BankAlert.requestDestroy("allByBankAccount", {
44 | key: id
45 | }, callback);
46 | };
47 |
48 | BankAlert.prototype.testTransaction = function(operation) {
49 | var alertLimit, amount;
50 | if (this.type !== "transaction") {
51 | return false;
52 | } else {
53 | alertLimit = Number(this.limit);
54 | amount = Math.abs(operation.amount);
55 | return (this.order === "lt" && amount <= alertLimit) || (this.order === "gt" && amount >= alertLimit);
56 | }
57 | };
58 |
59 | BankAlert.prototype.testBalance = function(account) {
60 | var alertLimit, balance;
61 | if (this.type !== "balance") {
62 | return false;
63 | } else {
64 | alertLimit = Number(this.limit);
65 | balance = account.getBalance();
66 | return (this.order === "lt" && balance <= alertLimit) || (this.order === "gt" && balance >= alertLimit);
67 | }
68 | };
69 |
--------------------------------------------------------------------------------
/build/server/models/bankoperation.js:
--------------------------------------------------------------------------------
1 | // Generated by CoffeeScript 1.8.0
2 | var BankOperation, americano;
3 |
4 | americano = require('americano');
5 |
6 | module.exports = BankOperation = americano.getModel('bankoperation', {
7 | bankAccount: String,
8 | title: String,
9 | date: Date,
10 | amount: Number,
11 | raw: String,
12 | dateImport: Date
13 | });
14 |
15 | BankOperation.all = function(callback) {
16 | return BankOperation.request("all", callback);
17 | };
18 |
19 | BankOperation.allFromBankAccount = function(account, callback) {
20 | var params;
21 | params = {
22 | key: account.id
23 | };
24 | return BankOperation.request("allByBankAccount", params, callback);
25 | };
26 |
27 | BankOperation.allFromBankAccounts = function(accountNums, callback) {
28 | var params;
29 | params = {
30 | keys: accountNums
31 | };
32 | return BankOperation.request("allByBankAccount", params, callback);
33 | };
34 |
35 | BankOperation.allFromBankAccountDate = function(account, callback) {
36 | var params;
37 | params = {
38 | startkey: [account.accountNumber + "0"],
39 | endkey: [account.accountNumber],
40 | descending: true
41 | };
42 | return BankOperation.request("allByBankAccountAndDate", params, callback);
43 | };
44 |
45 | BankOperation.allLike = function(operation, callback) {
46 | var date, params;
47 | date = new Date(operation.date).toISOString();
48 | params = {
49 | key: [operation.bankAccount, date, operation.amount, operation.raw]
50 | };
51 | return BankOperation.request("allLike", params, callback);
52 | };
53 |
54 | BankOperation.destroyByAccount = function(accountNum, callback) {
55 | return BankOperation.requestDestroy("allByBankAccount", {
56 | key: accountNum
57 | }, callback);
58 | };
59 |
--------------------------------------------------------------------------------
/build/server/models/cozyinstance.js:
--------------------------------------------------------------------------------
1 | // Generated by CoffeeScript 1.8.0
2 | var CozyInstance, americano;
3 |
4 | americano = require('americano');
5 |
6 | module.exports = CozyInstance = americano.getModel('CozyInstance', {
7 | domain: String,
8 | helpUrl: String,
9 | locale: String
10 | });
11 |
12 | CozyInstance.getInstance = function(callback) {
13 | return CozyInstance.request('all', function(err, instances) {
14 | if (err) {
15 | return callback(err, null);
16 | } else if (!((instances != null) && instances.length > 0)) {
17 | return callback(new Error('No instance parameters found', null));
18 | } else {
19 | return callback(null, instances[0]);
20 | }
21 | });
22 | };
23 |
--------------------------------------------------------------------------------
/build/tests/controllers/bankalerts.js:
--------------------------------------------------------------------------------
1 | // Generated by CoffeeScript 1.8.0
2 | var client, fixtures, helpers, path, should;
3 |
4 | should = require('should');
5 |
6 | path = require('path');
7 |
8 | fixtures = require('cozy-fixtures');
9 |
10 | fixtures.setDefaultValues({
11 | dirPath: path.resolve(__dirname, '../fixtures/'),
12 | silent: true,
13 | removeBeforeLoad: false
14 | });
15 |
16 | helpers = require('../helpers');
17 |
18 | client = helpers.getClient();
19 |
20 | describe("Bank Alerts Controller", function() {
21 | before(helpers.cleanDBWithRequests);
22 | before(helpers.startApp);
23 | after(helpers.stopApp);
24 | after(helpers.cleanDBWithRequests);
25 | describe("When I add bank alerts", function() {
26 | describe("When I retrieve them", function() {
27 | it("The response should be a success");
28 | return it("There should be x bank alerts");
29 | });
30 | describe("When I retrieve one of them", function() {
31 | it("The response should be a success");
32 | return it("The alert should have the correct values");
33 | });
34 | describe("When I update one of them", function() {
35 | it("The response should be a success");
36 | return it("The alert in the database should be updated");
37 | });
38 | describe("When I destroy one of them", function() {
39 | it("The response should be a success");
40 | return it("The alert shouldn't be in the database anymore");
41 | });
42 | return describe("When I retrieve the alerts for a given bank account", function() {
43 | it("The response should be a success");
44 | return it("There should be x bank alerts");
45 | });
46 | });
47 | return describe("When I create a bank alert", function() {
48 | it("The response should be a success");
49 | return it("It should be in the database");
50 | });
51 | });
52 |
--------------------------------------------------------------------------------
/build/tests/fixtures/banks-mesinfos.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "docType": "Bank",
4 | "name": "Société Générale",
5 | "uuid": "societegenerale"
6 | },
7 | {
8 | "docType": "Bank",
9 | "name": "La Banque Postale",
10 | "uuid": "bp"
11 | },
12 | {
13 | "docType": "Bank",
14 | "name": "Crédit Coopératif",
15 | "uuid": "creditcooperatif"
16 | }
17 | ]
18 |
--------------------------------------------------------------------------------
/build/tests/fixtures/weboob/accounts.js:
--------------------------------------------------------------------------------
1 | // Generated by CoffeeScript 1.8.0
2 | var bank, banks, output, _i, _len;
3 |
4 | banks = require('../banks-all.json');
5 |
6 | output = {};
7 |
8 | for (_i = 0, _len = banks.length; _i < _len; _i++) {
9 | bank = banks[_i];
10 | output[bank.uuid] = [
11 | {
12 | "accountNumber": "1234567890",
13 | "label": "Compte bancaire",
14 | "balance": "150"
15 | }, {
16 | "accountNumber": "0987654321",
17 | "label": "Livret A",
18 | "balance": "500"
19 | }
20 | ];
21 | }
22 |
23 | module.exports = output;
24 |
--------------------------------------------------------------------------------
/build/tests/helpers.js:
--------------------------------------------------------------------------------
1 | // Generated by CoffeeScript 1.8.0
2 | var Client, client, fixtures, helpers, initializeApplication;
3 |
4 | fixtures = require('cozy-fixtures');
5 |
6 | Client = require('request-json').JsonClient;
7 |
8 | module.exports = helpers = {};
9 |
10 | helpers.options = {};
11 |
12 | helpers.app = null;
13 |
14 | if (process.env.COVERAGE) {
15 | helpers.prefix = '../instrumented/';
16 | } else if (process.env.USE_JS) {
17 | helpers.prefix = '../build/';
18 | } else {
19 | helpers.prefix = '../';
20 | }
21 |
22 | helpers.options = {
23 | serverHost: process.env.HOST || 'localhost',
24 | serverPort: process.env.PORT || 9875
25 | };
26 |
27 | process.env.HOST = helpers.options.serverHost;
28 |
29 | process.env.PORT = helpers.options.serverPort;
30 |
31 | client = new Client("http://" + helpers.options.serverHost + ":" + helpers.options.serverPort + "/", {
32 | jar: true
33 | });
34 |
35 | helpers.getClient = function() {
36 | return client;
37 | };
38 |
39 | initializeApplication = require("" + helpers.prefix + "server");
40 |
41 | helpers.startApp = function(done) {
42 | this.timeout(15000);
43 | return initializeApplication((function(_this) {
44 | return function(app, server) {
45 | _this.app = app;
46 | _this.app.server = server;
47 | return done();
48 | };
49 | })(this));
50 | };
51 |
52 | helpers.stopApp = function(done) {
53 | this.timeout(10000);
54 | return this.app.server.close(done);
55 | };
56 |
57 | helpers.cleanDB = function(done) {
58 | this.timeout(10000);
59 | return fixtures.resetDatabase({
60 | callback: done
61 | });
62 | };
63 |
64 | helpers.cleanDBWithRequests = function(done) {
65 | this.timeout(10000);
66 | return fixtures.resetDatabase({
67 | removeAllRequests: true,
68 | callback: done
69 | });
70 | };
71 |
--------------------------------------------------------------------------------
/build/tests/mock-weboob.js:
--------------------------------------------------------------------------------
1 | // Generated by CoffeeScript 1.8.0
2 | var accounts, nock, operations, options;
3 |
4 | if ((process.env.NODE_ENV == null) || process.env.NODE_ENV !== 'production') {
5 | nock = require('nock');
6 | options = {
7 | allowUnmocked: true
8 | };
9 | accounts = nock('http://localhost:9101', options).persist().log(console.log).defaultReplyHeaders({
10 | 'content-type': 'application/json; charset=utf-8'
11 | }).filteringPath(/bank\/[a-z]+\//g, 'bank/societegenerale/').filteringRequestBody(function(path) {
12 | return {
13 | "login": "12345",
14 | "password": "54321"
15 | };
16 | }).post('/connectors/bank/societegenerale/', {
17 | "login": "12345",
18 | "password": "54321"
19 | }).reply(200, require('./fixtures/weboob/accounts'));
20 | operations = nock('http://localhost:9101', options).persist().log(console.log).defaultReplyHeaders({
21 | 'content-type': 'application/json; charset=utf-8'
22 | }).filteringPath(/bank\/[a-z]+\//g, 'bank/societegenerale/').filteringRequestBody(function(path) {
23 | return {
24 | "login": "12345",
25 | "password": "54321"
26 | };
27 | }).post('/connectors/bank/societegenerale/history', {
28 | "login": "12345",
29 | "password": "54321"
30 | }).reply(200, require('./fixtures/weboob/operations'));
31 | }
32 |
--------------------------------------------------------------------------------
/client/.gitignore:
--------------------------------------------------------------------------------
1 | # Numerous always-ignore extensions
2 | *.diff
3 | *.err
4 | *.orig
5 | *.log
6 | *.rej
7 | *.swo
8 | *.swp
9 | *.vi
10 | *~
11 | *.sass-cache
12 |
13 | # OS or Editor folders
14 | .DS_Store
15 | .cache
16 | .project
17 | .settings
18 | .tmproj
19 | nbproject
20 | Thumbs.db
21 |
22 | # NPM packages folder.
23 | node_modules/
24 |
25 | # Brunch folder for temporary files.
26 | tmp/
27 |
--------------------------------------------------------------------------------
/client/app/application.coffee:
--------------------------------------------------------------------------------
1 | AppView = require 'views/app'
2 |
3 | BanksCollection = require 'collections/banks'
4 | BankOperationsCollection = require 'collections/bank_operations'
5 |
6 | module.exports =
7 |
8 | initialize: ->
9 |
10 | $.ajax('cozy-locale.json')
11 | .done( (data) => @locale = data.locale )
12 | .fail( () => @locale = 'en' )
13 | .always( () => @step2() )
14 |
15 | step2: ->
16 |
17 | # internationalisation
18 | @polyglot = new Polyglot()
19 | window.polyglot = @polyglot
20 | try
21 | locales = require "locales/#{@locale}"
22 | catch e
23 | locales = require 'locales/en'
24 |
25 | @polyglot.extend locales
26 | window.t = @polyglot.t.bind @polyglot
27 | window.i18n = (key) -> window.polyglot.t key
28 |
29 | # collections, views
30 | window.collections = {}
31 | window.views = {}
32 |
33 | # banks, operations
34 | window.collections.allBanks = new BanksCollection()
35 | window.collections.banks = new BanksCollection()
36 | window.collections.operations = new BankOperationsCollection()
37 |
38 | ###
39 | views
40 | ###
41 | # this one is tricky - it lays down the structure, so it needs to be rendered
42 | # before any other view using that structure
43 | window.views.appView = new AppView()
44 | window.views.appView.render()
45 |
46 | window.activeObjects = {}
47 | _.extend(window.activeObjects, Backbone.Events);
48 |
49 | # Routing management
50 | Router = require 'router'
51 | @router = new Router()
52 | #Backbone.history.start()
53 |
54 | # Makes this object immuable.
55 | Object.freeze this if typeof Object.freeze is 'function'
56 |
--------------------------------------------------------------------------------
/client/app/assets/asc.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/app/assets/asc.gif
--------------------------------------------------------------------------------
/client/app/assets/bg.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/app/assets/bg.gif
--------------------------------------------------------------------------------
/client/app/assets/crossdomain.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
15 |
16 |
--------------------------------------------------------------------------------
/client/app/assets/desc.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/app/assets/desc.gif
--------------------------------------------------------------------------------
/client/app/assets/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/app/assets/favicon.ico
--------------------------------------------------------------------------------
/client/app/assets/fonts/fontawesome/FontAwesome.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/app/assets/fonts/fontawesome/FontAwesome.ttf
--------------------------------------------------------------------------------
/client/app/assets/fonts/fontawesome/README.md:
--------------------------------------------------------------------------------
1 | #Font Awesome 2.0
2 | ##the iconic font designed for use with Twitter Bootstrap
3 |
4 | The full suite of pictographic icons, examples, and documentation can be found at:
5 | http://fortawesome.github.com/Font-Awesome/
6 |
7 | ##Contact
8 | - Email: dave@davegandy.com
9 | - Twitter: http://twitter.com/fortaweso_me
10 | - Work: Lead Product Designer @ http://kyru.us
11 |
12 | ##License
13 | Version 2.0 of the Font Awesome font, CSS, and LESS files are licensed under CC BY 3.0:
14 | http://creativecommons.org/licenses/by/3.0/
15 | A mention of 'Font Awesome - http://fortawesome.github.com/Font-Awesome'
16 | in human-readable source code is considered acceptable attribution (most common on the
17 | web). If human readable source code is not available to the end user, a mention in an 'About'
18 | or 'Credits' screen is considered acceptable (most common in desktop or mobile software).
19 |
--------------------------------------------------------------------------------
/client/app/assets/fonts/fontawesome/fontawesome-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/app/assets/fonts/fontawesome/fontawesome-webfont.eot
--------------------------------------------------------------------------------
/client/app/assets/fonts/fontawesome/fontawesome-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/app/assets/fonts/fontawesome/fontawesome-webfont.ttf
--------------------------------------------------------------------------------
/client/app/assets/fonts/fontawesome/fontawesome-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/app/assets/fonts/fontawesome/fontawesome-webfont.woff
--------------------------------------------------------------------------------
/client/app/assets/fonts/fontello.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/app/assets/fonts/fontello.ttf
--------------------------------------------------------------------------------
/client/app/assets/fonts/glyphicons-halflings-regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/app/assets/fonts/glyphicons-halflings-regular.eot
--------------------------------------------------------------------------------
/client/app/assets/fonts/glyphicons-halflings-regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/app/assets/fonts/glyphicons-halflings-regular.ttf
--------------------------------------------------------------------------------
/client/app/assets/fonts/glyphicons-halflings-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/app/assets/fonts/glyphicons-halflings-regular.woff
--------------------------------------------------------------------------------
/client/app/assets/fonts/maven-pro-light-100.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/app/assets/fonts/maven-pro-light-100.otf
--------------------------------------------------------------------------------
/client/app/assets/fonts/maven-pro-light-200.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/app/assets/fonts/maven-pro-light-200.otf
--------------------------------------------------------------------------------
/client/app/assets/fonts/maven-pro-light-300.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/app/assets/fonts/maven-pro-light-300.otf
--------------------------------------------------------------------------------
/client/app/assets/fonts/signika-bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/app/assets/fonts/signika-bold.ttf
--------------------------------------------------------------------------------
/client/app/assets/fonts/signika-light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/app/assets/fonts/signika-light.ttf
--------------------------------------------------------------------------------
/client/app/assets/fonts/signika-regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/app/assets/fonts/signika-regular.ttf
--------------------------------------------------------------------------------
/client/app/assets/humans.txt:
--------------------------------------------------------------------------------
1 | # humanstxt.org/
2 | # The humans responsible & technology colophon
3 |
4 | # TEAM
5 |
6 | -- --
7 |
8 | # THANKS
9 |
10 |
11 |
12 | # TECHNOLOGY COLOPHON
13 |
14 | HTML5, CSS3
15 | jQuery, Modernizr,
16 | Lodash, Backbone,
17 | Handlebars, Coffeescript,
18 | Stylus, Brunch
19 |
--------------------------------------------------------------------------------
/client/app/assets/icons/main_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/app/assets/icons/main_icon.png
--------------------------------------------------------------------------------
/client/app/assets/images/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/app/assets/images/.gitkeep
--------------------------------------------------------------------------------
/client/app/assets/images/Melamine-wood-003.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/app/assets/images/Melamine-wood-003.png
--------------------------------------------------------------------------------
/client/app/assets/images/arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/app/assets/images/arrow.png
--------------------------------------------------------------------------------
/client/app/assets/images/arrow_vertical.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/app/assets/images/arrow_vertical.png
--------------------------------------------------------------------------------
/client/app/assets/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Cozy PFM
10 |
11 |
12 |
17 |
18 |
19 |
20 |
21 |
22 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/client/app/assets/loader.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/app/assets/loader.gif
--------------------------------------------------------------------------------
/client/app/assets/loader_big_blue.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/app/assets/loader_big_blue.gif
--------------------------------------------------------------------------------
/client/app/assets/loader_green.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/app/assets/loader_green.gif
--------------------------------------------------------------------------------
/client/app/assets/loader_inverse.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/app/assets/loader_inverse.gif
--------------------------------------------------------------------------------
/client/app/assets/pdf/factureSFR.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/app/assets/pdf/factureSFR.pdf
--------------------------------------------------------------------------------
/client/app/assets/pdf/factureSNCF.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/app/assets/pdf/factureSNCF.pdf
--------------------------------------------------------------------------------
/client/app/assets/robots.txt:
--------------------------------------------------------------------------------
1 | # robotstxt.org/
2 |
3 | User-agent: *
4 |
--------------------------------------------------------------------------------
/client/app/collections/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/app/collections/.gitkeep
--------------------------------------------------------------------------------
/client/app/collections/bank_accesses.coffee:
--------------------------------------------------------------------------------
1 | BankAccess = require '../models/bank_access'
2 |
3 | module.exports = class BankAccesses extends Backbone.Collection
4 |
5 | model: BankAccess
6 | url: "bankaccesses"
7 |
--------------------------------------------------------------------------------
/client/app/collections/bank_accounts.coffee:
--------------------------------------------------------------------------------
1 | BankAccount = require '../models/bank_account'
2 |
3 | module.exports = class BankAccounts extends Backbone.Collection
4 |
5 | model: BankAccount
6 | url: "bankaccounts"
7 |
8 | constructor: (@bank) ->
9 | @url = "banks/getAccounts/" + @bank.get("id")
10 | super()
11 |
12 | getSum: ->
13 | sum = 0
14 | for account in @models
15 | sum += Number(account.get("amount"))
16 | sum
17 |
--------------------------------------------------------------------------------
/client/app/collections/bank_alerts.coffee:
--------------------------------------------------------------------------------
1 | BankAlert = require '../models/bank_alert'
2 |
3 | module.exports = class BankAlerts extends Backbone.Collection
4 |
5 | model: BankAlert
6 | url: "bankalerts"
7 |
--------------------------------------------------------------------------------
/client/app/collections/bank_operations.coffee:
--------------------------------------------------------------------------------
1 | BankOperation = require '../models/bank_operation'
2 |
3 | module.exports = class BankOperations extends Backbone.Collection
4 |
5 | model: BankOperation
6 | url: "bankoperations"
7 |
8 | order: "asc"
9 | orderBy: "date"
10 |
11 | setAccount: (@account) ->
12 | @url = "bankaccounts/getOperations/" + @account.get("id")
13 | #console.log @url
14 |
15 | setComparator: (type) ->
16 | if type == "date"
17 | # sorting by date and then title
18 | @comparator = (o1, o2) =>
19 | d1 = new Date(o1.get("date")).getTime()
20 | d2 = new Date(o2.get("date")).getTime()
21 |
22 | t1 = o1.get("title")
23 | t2 = o2.get("title")
24 |
25 | sort = if @order == "asc" then -1 else 1
26 |
27 | if d1 == d2
28 | if t1 > t2 then return sort
29 | if t1 < t2 then return -sort
30 | return 0
31 | else if d1 > d2
32 | return sort
33 | else
34 | return -sort
35 |
36 | else
37 | @orderBy = type
38 | @comparator = (o1, o2) ->
39 |
40 | t1 = o1.get @orderBy
41 | t2 = o2.get @orderBy
42 |
43 | sort = if @order == "asc" then -1 else 1
44 |
45 | if t1 == t2
46 | return 0
47 | else if t1 > t2
48 | return sort
49 | else
50 | return -sort
51 |
52 | toggleSort: (order) ->
53 | if @orderBy == order
54 | @order = if @order == "asc" then "desc" else "asc"
55 | else
56 | @orderBy = order
57 |
58 |
--------------------------------------------------------------------------------
/client/app/collections/banks.coffee:
--------------------------------------------------------------------------------
1 | Bank = require '../models/bank'
2 |
3 | module.exports = class Banks extends Backbone.Collection
4 |
5 | model: Bank
6 | url: "banks"
7 |
8 | getSum: ->
9 | sum = 0
10 | for bank in @models
11 | sum += Number(bank.get("amount"))
12 | #console.log Number(bank.get("amount"))
13 | sum
14 |
--------------------------------------------------------------------------------
/client/app/initialize.coffee:
--------------------------------------------------------------------------------
1 | app = require 'application'
2 | # The function called from index.html
3 | $ ->
4 | require 'lib/app_helpers'
5 |
6 | # init
7 | ###
8 | global variables
9 | ###
10 | # app, for nasty tricks
11 | window.app = app
12 | app.initialize()
13 |
--------------------------------------------------------------------------------
/client/app/lib/app_helpers.coffee:
--------------------------------------------------------------------------------
1 | (() ->
2 | # IIFE to avoid collisions with other variables
3 | (->
4 | # Make it safe to do console.log() always.
5 | console = window.console = window.console or {}
6 | method = undefined
7 | dummy = ->
8 | methods = ('assert,count,debug,dir,dirxml,error,exception,
9 | group,groupCollapsed,groupEnd,info,log,markTimeline,
10 | profile,profileEnd,time,timeEnd,trace,warn').split ','
11 |
12 | console[method] = console[method] or dummy while method = methods.pop()
13 | )()
14 | )()
15 |
16 | Number::formatMoney = (decPlaces, thouSeparator, decSeparator) ->
17 | n = this
18 | decPlaces = (if isNaN(decPlaces = Math.abs(decPlaces)) then 2 else decPlaces)
19 | decSeparator = (if decSeparator is `undefined` then "." else decSeparator)
20 | thouSeparator = (if thouSeparator is `undefined` then "," else thouSeparator)
21 | sign = (if n < 0 then "-" else "")
22 | i = parseInt(n = Math.abs(+n or 0).toFixed(decPlaces)) + ""
23 | j = (if (j = i.length) > 3 then j % 3 else 0)
24 | sign + ((if j then i.substr(0, j) + thouSeparator else "")) + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + thouSeparator) + ((if decPlaces then decSeparator + Math.abs(n - i).toFixed(decPlaces).slice(2) else ""))
25 |
26 | Number::money = ->
27 | @formatMoney(2, " ", ",")
28 |
29 | Date::dateString = ->
30 | addZeros = (num) ->
31 | if Number(num) < 10
32 | "0" + num
33 | else
34 | num
35 | myDate = @
36 | addZeros(myDate.getDate() + 1) + "/" + addZeros(myDate.getMonth() + 1) + "/" + myDate.getFullYear()
37 |
38 | Date::timeString = ->
39 | addZeros = (num) ->
40 | if Number(num) < 10
41 | "0" + num
42 | else
43 | num
44 | myDate = @
45 | addZeros(myDate.getHours()) + ":" + addZeros(myDate.getMinutes())
46 |
--------------------------------------------------------------------------------
/client/app/lib/base_view.coffee:
--------------------------------------------------------------------------------
1 | module.exports = class BaseView extends Backbone.View
2 |
3 | template: ->
4 |
5 | initialize: ->
6 |
7 | getRenderData: ->
8 | model: @model
9 |
10 | render: ->
11 | @beforeRender()
12 | @$el.html @template(@getRenderData())
13 | @afterRender()
14 | @
15 |
16 | beforeRender: ->
17 |
18 | afterRender: ->
19 |
20 | destroy: ->
21 | @undelegateEvents()
22 | @$el.removeData().unbind()
23 | @remove()
24 | Backbone.View::remove.call @
25 |
--------------------------------------------------------------------------------
/client/app/models/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/app/models/.gitkeep
--------------------------------------------------------------------------------
/client/app/models/bank.coffee:
--------------------------------------------------------------------------------
1 | BankAccountsCollection = require '../collections/bank_accounts'
2 |
3 | module.exports = class Bank extends Backbone.Model
4 |
5 | defaults:
6 | amount: 0
7 |
8 | checked: true
9 |
10 | initialize: ->
11 | @accounts = new BankAccountsCollection @
12 | @listenTo @accounts, "add", @updateAmount
13 | @listenTo @accounts, "remove", @updateAmount
14 | @listenTo @accounts, "destroy", @updateAmount
15 | @listenTo @accounts, "change", @updateAmount
16 |
17 | updateAmount: ->
18 | @set("amount", @accounts.getSum())
19 | console.log "updated balance bank " + @get("name") + " is now " + @get("amount")
20 |
--------------------------------------------------------------------------------
/client/app/models/bank_access.coffee:
--------------------------------------------------------------------------------
1 | module.exports = class BankAccess extends Backbone.Model
2 |
3 | url: "bankaccesses"
4 |
--------------------------------------------------------------------------------
/client/app/models/bank_account.coffee:
--------------------------------------------------------------------------------
1 | BankOperationsCollection = require '../collections/bank_operations'
2 |
3 | module.exports = class BankAccount extends Backbone.Model
4 |
5 | checked: true
6 |
--------------------------------------------------------------------------------
/client/app/models/bank_alert.coffee:
--------------------------------------------------------------------------------
1 | module.exports = class BankAlert extends Backbone.Model
2 |
3 | url: "bankalerts"
4 |
--------------------------------------------------------------------------------
/client/app/models/bank_operation.coffee:
--------------------------------------------------------------------------------
1 | module.exports = class BankOperation extends Backbone.Model
2 |
--------------------------------------------------------------------------------
/client/app/router.coffee:
--------------------------------------------------------------------------------
1 | MockupView = require 'views/mockup'
2 | AppView = require 'views/app'
3 | BalanceView = require 'views/balance'
4 |
5 | module.exports = class Router extends Backbone.Router
6 |
7 | empty: ->
8 | window.views.balanceView?.empty()
9 | window.views.accountsView?.empty()
10 | window.views.searchView?.empty()
11 |
12 | routes:
13 | '': 'balance'
14 | 'accounts': 'accounts'
15 | 'search' : 'search'
16 |
17 | balance: ->
18 | @empty()
19 | window.views.balanceView?.render()
20 | $(".menu-position").removeClass("active")
21 | $(".menu-1").addClass("active")
22 |
23 | search: ->
24 | @empty()
25 | window.views.searchView?.render()
26 | $(".menu-position").removeClass("active")
27 | $(".menu-2").addClass("active")
28 |
29 | accounts: ->
30 | @empty()
31 | window.views.accountsView?.render()
32 | $(".menu-position").removeClass("active")
33 | $(".menu-3").addClass("active")
34 |
--------------------------------------------------------------------------------
/client/app/views/accounts.coffee:
--------------------------------------------------------------------------------
1 | BaseView = require '../lib/base_view'
2 | AccountsBankView = require './accounts_bank'
3 |
4 | module.exports = class AccountsView extends BaseView
5 |
6 | template: require('./templates/accounts')
7 |
8 | el: 'div#content'
9 | elBanks: '.content-right-column'
10 |
11 | subViews: []
12 |
13 | render: ->
14 |
15 | # load the template
16 | super()
17 |
18 | # prepare the banks list
19 | for bank in window.collections.banks.models
20 | view = new AccountsBankView bank
21 | @subViews.push view
22 | @$(@elBanks).append view.render().el
23 |
24 | # TODO - fix the compability issue with niceScroll
25 | #@$('#layout-2col-column-right').niceScroll()
26 | @
27 |
28 | empty: ->
29 | for view in @subViews
30 | view.destroy()
--------------------------------------------------------------------------------
/client/app/views/accounts_alerts_alert.coffee:
--------------------------------------------------------------------------------
1 | BaseView = require '../lib/base_view'
2 | BankAlert = require '../models/bank_alert'
3 |
4 | module.exports = class AccountsAlertsAlertView extends BaseView
5 |
6 | template: require "./templates/accounts_alerts_alert"
7 |
8 | events:
9 | "click .reports-save" : "save"
10 | "click .reports-cancel" : "destroy"
11 | "click .reports-delete" : "removeAlert"
12 | "click .reports-edit" : "edit"
13 |
14 | constructor: (@alert, @parent) ->
15 | super()
16 |
17 | initialize: ->
18 |
19 | save: ->
20 | view = @
21 |
22 | # get the data
23 | if @alert.get("type") == "report"
24 | @alert.set "frequency", @$(".reports-frequency").val()
25 | else
26 | @alert.set "order", @$(".reports-order").val()
27 | valLimit = @$(".reports-limit").val()
28 | valLimit = valLimit.replace(" ", "").replace(",",".") # stripping all non digits
29 | @alert.set "limit", Number(valLimit)
30 |
31 | # save the report to the server
32 | @alert.save {},
33 | success: ->
34 | console.log "Alert saved to server"
35 | view.render()
36 | error: ->
37 | console.log "error"
38 |
39 | removeAlert: ->
40 |
41 | view = @
42 |
43 | @alert.url = "bankalerts/" + @alert.get("id")
44 | @alert.destroy
45 | success: ->
46 | console.log "Alert deleted from server"
47 | view.destroy()
48 | error: ->
49 | console.log "error"
50 |
51 | render: ->
52 | # lay down the template
53 | @$el.html @template
54 | model: @alert
55 | @
56 |
--------------------------------------------------------------------------------
/client/app/views/app.coffee:
--------------------------------------------------------------------------------
1 | BaseView = require '../lib/base_view'
2 |
3 | NavbarView = require 'views/navbar'
4 | NewBankView = require 'views/new_bank'
5 |
6 | AccountsView = require 'views/accounts'
7 | BalanceView = require 'views/balance'
8 | SearchView = require 'views/search'
9 |
10 |
11 | module.exports = class AppView extends BaseView
12 |
13 | template: require('./templates/app')
14 |
15 | el: 'body.application'
16 |
17 | afterRender: ->
18 |
19 | # init - get the necessary data
20 | window.collections.banks.fetch
21 | data:
22 | withAccountOnly: true
23 | success: ->
24 |
25 | window.collections.allBanks.fetch
26 | success: ->
27 | if not @navbarView
28 | @navbarView = new NavbarView()
29 | if not @newbankView
30 | @newbankView = new NewBankView()
31 | if not window.views.balanceView
32 | window.views.balanceView = new BalanceView()
33 | if not window.views.accountsView
34 | window.views.accountsView = new AccountsView()
35 | if not window.views.searchView
36 | window.views.searchView = new SearchView()
37 |
38 | @navbarView.render()
39 | @newbankView.render()
40 |
41 | # start routing
42 | Backbone.history.start()
43 | error: ->
44 |
45 | # could not get banks, or 0 banks available - fatal error
46 | console.log "Fatal error: could not get the banks list"
47 | alert window.i18n "fatal_error"
48 |
49 |
--------------------------------------------------------------------------------
/client/app/views/balance_bank.coffee:
--------------------------------------------------------------------------------
1 | BaseView = require '../lib/base_view'
2 | BankTitleView = require './bank_title'
3 | BankSubTitleView = require './bank_subtitle'
4 |
5 | module.exports = class BalanceBankView extends BaseView
6 |
7 | className: 'bank'
8 |
9 | sum: 0
10 |
11 | subViews: []
12 |
13 | constructor: (@bank) ->
14 | super()
15 |
16 | initialize: ->
17 | @listenTo @bank.accounts, "add", @addOne
18 | @listenTo @bank.accounts, "destroy", @render
19 |
20 | addOne: (account) ->
21 | # add the account
22 | viewAccount = new BankSubTitleView account
23 | @subViews.push viewAccount
24 | account.view = viewAccount
25 | @$el.append viewAccount.render().el
26 |
27 | render: ->
28 |
29 | # generate the title
30 | @viewTitle = new BankTitleView @bank
31 | @$el.html @viewTitle.render().el
32 | @viewTitle = null
33 | @sum = 0
34 |
35 | # add accounts
36 | for account in @bank.accounts.models
37 | @addOne account
38 | @
39 |
40 | destroy: ->
41 | @viewTitle?.destroy()
42 | for view in @subViews
43 | view.destroy()
44 | super()
--------------------------------------------------------------------------------
/client/app/views/balance_operation.coffee:
--------------------------------------------------------------------------------
1 | BaseView = require '../lib/base_view'
2 |
3 | module.exports = class BalanceOperationView extends BaseView
4 |
5 | template: require './templates/balance_operations_element'
6 |
7 | tagName: 'tr'
8 |
9 | constructor: (@model, @account, @showAccountNum = false) ->
10 | super()
11 |
12 | fakeFeatureLink: ->
13 | if @model.get('title') is "SNCF" and @model.get('amount') is -137.00
14 | return 'pdf/factureSNCF.pdf'
15 | else if @model.get('title') is "SFR Facture"
16 | return 'pdf/factureSFR.pdf'
17 | else return null
18 |
19 | render: ->
20 | if @model.get("amount") > 0
21 | @$el.addClass "success"
22 | @model.account = @account
23 | @model.formattedDate = moment(@model.get('date')).format "DD/MM/YYYY"
24 | formattedAmount = @fakeFeatureLink()
25 | @model.formattedAmount = formattedAmount unless formattedAmount is null
26 |
27 | if @showAccountNum
28 | hint = "#{@model.account.get('title')}, " + \
29 | "n°#{@model.account.get('accountNumber')}"
30 | @model.hint = "#{@model.account.get('title')}, " + \
31 | "n°#{@model.account.get('accountNumber')}"
32 | else
33 | @model.hint = "#{@model.get('raw')}"
34 | super()
35 | @
--------------------------------------------------------------------------------
/client/app/views/bank_subtitle.coffee:
--------------------------------------------------------------------------------
1 | BaseView = require '../lib/base_view'
2 |
3 | module.exports = class BankSubTitleView extends BaseView
4 |
5 | template: require('./templates/balance_bank_subtitle')
6 |
7 | constructor: (@model) ->
8 | super()
9 |
10 | events:
11 | "click .row" : "chooseAccount"
12 |
13 | initialize: ->
14 | @listenTo @model, 'change', @render
15 | @listenTo window.activeObjects, 'changeActiveAccount', @checkActive
16 |
17 | chooseAccount: (event) ->
18 | console.log "Account chosen: " + @model.get("title")
19 | window.activeObjects.trigger "changeActiveAccount", @model
20 |
21 | checkActive: (account) ->
22 | @$(".row").removeClass("active")
23 | if account == @model
24 | @$(".row").addClass("active")
25 |
--------------------------------------------------------------------------------
/client/app/views/bank_title.coffee:
--------------------------------------------------------------------------------
1 | BaseView = require '../lib/base_view'
2 |
3 | module.exports = class BankTitleView extends BaseView
4 |
5 | template: require('./templates/balance_bank_title')
6 |
7 | constructor: (@model) ->
8 | super()
9 |
10 | initialize: ->
11 | @listenTo @model, 'change', @update
12 | @listenTo @model.accounts, "add", @update
13 | @listenTo @model.accounts, "destroy", @update
14 | @listenTo @model.accounts, "request", @displayLoading
15 | @listenTo @model.accounts, "change", @hideLoading
16 |
17 | displayLoading: ->
18 | @$(".bank-title-loading").show()
19 |
20 | hideLoading: ->
21 | @$(".bank-title-loading").hide()
22 |
23 | update: ->
24 | # update the sum
25 | @model.set("amount", @model.accounts.getSum())
26 | @$(".bank-amount").html Number(@model.get('amount')).money()
27 |
28 | # display or hide the bank title
29 | if @model.accounts.length == 0
30 | @$(".bank-title").hide()
31 | @$(".bank-balance").hide()
32 | else
33 | @$(".bank-title").show()
34 | @$(".bank-balance").show()
35 |
36 | # hide loader
37 | @$(".bank-title-loading").hide()
38 |
39 | render: ->
40 | super()
41 | @update()
42 | @
--------------------------------------------------------------------------------
/client/app/views/mockup.coffee:
--------------------------------------------------------------------------------
1 | BaseView = require '../lib/base_view'
2 |
3 |
4 | module.exports = class AppView extends BaseView
5 |
6 | template: require('./templates/mockup_balance')
7 |
8 | el: 'body.application'
9 |
10 | afterRender: ->
11 | $('.content-right-column').niceScroll()
12 |
--------------------------------------------------------------------------------
/client/app/views/navbar.coffee:
--------------------------------------------------------------------------------
1 | BaseView = require '../lib/base_view'
2 |
3 |
4 | module.exports = class NavbarView extends BaseView
5 |
6 | template: require('./templates/navbar')
7 |
8 | el: 'div#navbar'
9 |
10 | initialize: ->
11 | @listenTo window.collections.banks, "change", @refreshOverallBalance
12 | @listenTo window.collections.banks, 'destroy', @refreshOverallBalance
13 | @listenTo window.collections.banks, 'update', @refreshOverallBalance
14 | @listenTo window.collections.banks, 'reset', @refreshOverallBalance
15 |
16 | refreshOverallBalance: ->
17 | sum = window.collections.banks.getSum()
18 | console.log "recalculating the overall balance: " + sum
19 | $("span#total-amount").html sum.money()
20 |
--------------------------------------------------------------------------------
/client/app/views/search_bank.coffee:
--------------------------------------------------------------------------------
1 | BaseView = require '../lib/base_view'
2 | SearchBankTitleView = require './search_bank_title'
3 | SearchBankSubTitleView = require './search_bank_subtitle'
4 |
5 | module.exports = class SearchBankView extends BaseView
6 |
7 | className: 'bank'
8 |
9 | events:
10 | "change .choice-bank" : "bankChange"
11 |
12 | viewsAccount: []
13 |
14 | constructor: (@bank) ->
15 | super()
16 |
17 | initialize: ->
18 | @listenTo @bank.accounts, "add", @addOne
19 | @listenTo @bank.accounts, "destroy", @render
20 |
21 | bankChange: (event) ->
22 |
23 | enabled = @$(event.target).prop("checked")
24 | console.log "[Search] " + @bank.get("name") + ": " + enabled
25 |
26 | # check/uncheck all
27 | $.each @$("input[type=checkbox].choice-account"), (index, element) ->
28 | $(element).prop "checked", enabled
29 | for account in @bank.accounts.models
30 | account.checked = enabled
31 |
32 | # mark the entire bank as checked
33 | @bank.checked = enabled
34 |
35 | # and fire "update" on accounts
36 | window.collections.banks.trigger "search-update-accounts"
37 |
38 | addOne: (account) ->
39 | # add the account
40 | viewAccount = new SearchBankSubTitleView account
41 | @viewsAccount.push viewAccount
42 | account.view = viewAccount
43 | @$el.append viewAccount.render().el
44 |
45 | render: ->
46 |
47 | # generate the title
48 | @viewTitle = new SearchBankTitleView @bank
49 | @$el.html @viewTitle.render().el
50 | @viewTitle = null
51 | @sum = 0
52 |
53 | # add accounts
54 | for account in @bank.accounts.models
55 | @addOne account
56 | @
57 |
58 | destroy: ->
59 | @viewTitle?.destroy()
60 | for viewAccount in @viewsAccount
61 | viewAccount.destroy()
62 | super()
63 |
--------------------------------------------------------------------------------
/client/app/views/search_bank_subtitle.coffee:
--------------------------------------------------------------------------------
1 | BaseView = require '../lib/base_view'
2 |
3 | module.exports = class SearchBankSubTitleView extends BaseView
4 |
5 | template: require('./templates/search_bank_subtitle')
6 |
7 | constructor: (@model) ->
8 | super()
9 |
10 | events:
11 | "change .choice-account" : "accountChange"
12 |
13 | accountChange: (event) ->
14 |
15 | # get the value
16 | enabled = @$(event.target).prop("checked")
17 | console.log "[Search] " + @model.get("title") + ": " + enabled
18 |
19 | # mark the account as checked
20 | @model.checked = enabled
21 |
22 | # and fire "update" on accounts
23 | window.collections.banks.trigger "search-update-accounts"
24 |
25 | initialize: ->
26 | @listenTo @model, 'change', @render
27 |
--------------------------------------------------------------------------------
/client/app/views/search_bank_title.coffee:
--------------------------------------------------------------------------------
1 | BaseView = require '../lib/base_view'
2 |
3 | module.exports = class SearchBankTitleView extends BaseView
4 |
5 | template: require('./templates/search_bank_title')
6 |
7 | constructor: (@model) ->
8 | super()
9 |
10 | initialize: ->
11 | @listenTo @model.accounts, "add", @update
12 | @listenTo @model.accounts, "destroy", @update
13 | @listenTo @model.accounts, "request", @displayLoading
14 | @listenTo @model.accounts, "change", @hideLoading
15 |
16 | displayLoading: ->
17 | @$(".bank-title-loading").show()
18 |
19 | hideLoading: ->
20 | @$(".bank-title-loading").hide()
21 |
22 | update: ->
23 |
24 | # display or hide the bank title
25 | if @model.accounts.length == 0
26 | @$(".bank-title").hide()
27 | @$(".bank-title-checkbox").hide()
28 | else
29 | @$(".bank-title").show()
30 | @$(".bank-title-checkbox").show()
31 |
32 | # hide loader
33 | @$(".bank-title-loading").hide()
34 |
35 | render: ->
36 | super()
37 | @update()
38 | @
--------------------------------------------------------------------------------
/client/app/views/styles/_base.styl:
--------------------------------------------------------------------------------
1 | // Base Styles
2 |
3 | *
4 | box-sizing: border-box
5 |
6 | html,
7 | body
8 | height 100%
9 | width 100%
10 |
11 | body
12 | text-rendering optimizeLegibility
13 |
14 | body,
15 | input
16 | color #444
17 | font 300 16px Geneva, Verdana, "Lucida Sans", "Lucida Grande", "Lucida Sans Unicode", sans-serif
18 | line-height 1.2
19 |
20 | a,
21 | a:visited
22 | color #0086cc
23 | text-decoration none
24 |
25 | &:hover
26 | text-decoration underline
27 |
--------------------------------------------------------------------------------
/client/app/views/styles/_colors.styl:
--------------------------------------------------------------------------------
1 | basecolor = #34A6FF
2 | basecolor-alpha = rgba(49, 156, 256, 0.5)
3 |
4 | contrastcolor = #5C5
5 | contrastcolor-alpha = #5C5
6 |
7 |
8 | actioncolor = #fe8800
9 | actioncolor-alpha = rgba(254,128,0,0.5)
--------------------------------------------------------------------------------
/client/app/views/styles/_responsive.styl:
--------------------------------------------------------------------------------
1 | @media screen and (max-width: 480px)
2 | // Landscape phones and down
3 |
4 | body
5 | text-rendering optimizeSpeed
6 |
7 | .content-left-column
8 | height 30%
9 |
10 | .content-right-column
11 | height 70%
12 |
13 | @media screen and (max-width: 767px)
14 | // Landscape phone to portrait tablet
15 |
16 | body
17 | text-rendering optimizeSpeed
18 |
19 | .content-left-column
20 | height 30%
21 |
22 | .content-right-column
23 | height 70%
24 |
25 | @media screen and (min-width: 768px) and (max-width: 1200px)
26 | // Portrait tablet to landscape and desktop
27 |
28 | .content-left-column
29 | height 30%
30 |
31 | .content-right-column
32 | height 70%
33 |
34 | @media screen and (min-width: 1200px)
35 | // Desktop
36 |
37 | .content-left-column, .content-right-column
38 | height 100%
39 |
--------------------------------------------------------------------------------
/client/app/views/styles/_states.styl:
--------------------------------------------------------------------------------
1 | [data-state~="default"],
2 | [data-state~="enabled"]
3 | cursor inherit
4 | opacity 1
5 | transition opacity 0.2s linear
6 |
7 | [data-state~="disabled"],
8 | cursor not-allowed
9 | opacity 0.5
10 | transition opacity 0.2s linear
11 |
12 | [data-state~="hidden"]
13 | display none
14 |
15 | [data-state~="visible"]
16 | visibility visible
17 |
18 | [data-state~="invisible"]
19 | visibility hidden
20 |
21 | [data-state~="waiting"],
22 | [data-state~="loading"]
23 | cursor wait
24 |
25 | [data-state~="success"],
26 | [data-state~="valid"]
27 | border-color #82cf82
28 | color #82cf82
29 | transition color 0.2s linear, border-color 0.2s linear
30 |
31 | [data-state~="error"],
32 | [data-state~="invalid"]
33 | border-color #f0dddd
34 | color #f0dddd
35 | transition color 0.2s linear, border-color 0.2s linear
36 |
--------------------------------------------------------------------------------
/client/app/views/styles/application.styl:
--------------------------------------------------------------------------------
1 | // nib is a powerful lib for stylus that provides cross-browser css3 mixins.
2 | @import 'nib'
3 |
4 | @import '_responsive'
5 |
6 | @import '_main'
7 |
--------------------------------------------------------------------------------
/client/app/views/templates/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/app/views/templates/.gitkeep
--------------------------------------------------------------------------------
/client/app/views/templates/accounts.jade:
--------------------------------------------------------------------------------
1 | .row.content-background
2 | .col-lg-12.content-right-column
--------------------------------------------------------------------------------
/client/app/views/templates/accounts_alerts.jade:
--------------------------------------------------------------------------------
1 | #reports-dialog.modal.fade
2 | .modal-dialog
3 | .modal-content
4 | .modal-header
5 | button.close(type='button', data-dismiss='modal', aria-hidden='true') x
6 | h4.modal-title
7 | | #{window.i18n("accounts_alerts_title")}
8 | .modal-body
9 | h3
10 | | #{window.i18n("accounts_alerts_title_periodic")}
11 | div#reports-body-periodic
12 | p
13 | a.btn.btn-small.btn-cozy.reports-add-periodic #{window.i18n("accounts_alerts_periodic_add")}
14 |
15 |
16 | h3
17 | | #{window.i18n("accounts_alerts_title_balance")}
18 | div#reports-body-amount
19 | p
20 | a.btn.btn-small.btn-cozy.reports-add-amount #{window.i18n("accounts_alerts_balance_add")}
21 |
22 |
23 | h3
24 | | #{window.i18n("accounts_alerts_title_transaction")}
25 | div#reports-body-transaction
26 | p
27 | a.btn.btn-small.btn-cozy.reports-add-transaction #{window.i18n("accounts_alerts_transaction_add")}
28 |
29 |
--------------------------------------------------------------------------------
/client/app/views/templates/accounts_bank.jade:
--------------------------------------------------------------------------------
1 | h2 #{model.get("name")}
2 | a.btn.btn-cozy.pull-right.delete-bank
3 | | #{window.i18n("accounts_delete_bank")}
4 | table.table-accounts.table.table-striped.table-hover.table-bordered
5 | tbody#account-container
6 |
--------------------------------------------------------------------------------
/client/app/views/templates/accounts_bank_account.jade:
--------------------------------------------------------------------------------
1 | td.account-title #{model.get("title")}
2 | td.account-title
3 | span.account-details n°#{model.get("accountNumber")}
4 | td
5 | span.text-right
6 | a.btn.btn-small.btn-cozy.pull-right.alert-management
7 | | manage reports and notifications
8 | td
9 | span.text-right
10 | a.btn.btn-small.btn-cozy.pull-right.delete-account
11 | | #{window.i18n("accounts_delete_account")}
--------------------------------------------------------------------------------
/client/app/views/templates/app.jade:
--------------------------------------------------------------------------------
1 | // navigation bar
2 | #navbar.navbar.navbar-fixed-top.navbar-inverse
3 |
4 | // modal window to add a new bank
5 | #add-bank-window.modal.fade
6 |
7 | // content
8 | #content.container
9 |
--------------------------------------------------------------------------------
/client/app/views/templates/balance_bank_subtitle.jade:
--------------------------------------------------------------------------------
1 | .row.accounts-sub
2 | .pull-left
3 | p.pull-left #{model.get('title')}
4 | br
5 | span.account-details n°#{model.get("accountNumber")}
6 | .pull-right
7 | p.pull-right #{Number(model.get('amount')).money()}
8 | span.euro-sign €
9 |
--------------------------------------------------------------------------------
/client/app/views/templates/balance_bank_title.jade:
--------------------------------------------------------------------------------
1 | .row.accounts-top
2 | .col-lg-7
3 | p.pull-left
4 | span.bank-title-loading
5 | img(src="./loader.gif")
6 | span.bank-title #{model.get('name')}
7 | .col-lg-5
8 | p.pull-right.bank-balance
9 | span.bank-amount #{Number(model.get('amount')).money()}
10 | span.euro-sign €
11 |
--------------------------------------------------------------------------------
/client/app/views/templates/balance_banks_empty.jade:
--------------------------------------------------------------------------------
1 | p.arrow.text-right
2 | img(src="images/arrow_vertical.png")
3 | p.loading
4 | | #{window.i18n("balance_banks_empty")}
5 |
--------------------------------------------------------------------------------
/client/app/views/templates/balance_operations_element.jade:
--------------------------------------------------------------------------------
1 | td.operation-date #{model.formattedDate}
2 | td.operation-title
3 | .hint--top(data-hint="#{model.hint}")
4 | span.infobulle.glyphicon.glyphicon-info-sign
5 | | #{model.get('title')}
6 | td.operation-amount.text-right
7 | - if(model.formattedAmount == null)
8 | | #{Number(model.get('amount')).money()}
9 | - else
10 | a(href="#{model.formattedAmount}", target="_blank")
11 | | #{Number(model.get('amount')).money()}
--------------------------------------------------------------------------------
/client/app/views/templates/balance_operations_empty.jade:
--------------------------------------------------------------------------------
1 | br
2 | br
3 | p.loading
4 | | #{window.i18n("balance_please_choose_account")}
--------------------------------------------------------------------------------
/client/app/views/templates/balance_operations_header.jade:
--------------------------------------------------------------------------------
1 | h2 #{model.get("title")}
2 | p
3 | span.last-checked #{window.i18n("balance_last_checked")} #{moment(moment(model.get("lastChecked"))).fromNow()}.
4 | a.recheck-button.btn-link #{window.i18n("balance_recheck_now")}
5 |
6 | .text-center.loading.loader-operations
7 | img(src="./loader_big_blue.gif")
8 |
9 | table.table.tablesorter.table-striped.table-hover
10 | thead
11 | tr
12 | th.sort-date.text-left #{window.i18n("header_date")}
13 | th.sort-title.text-center #{window.i18n("header_title")}
14 | th.sort-amount.text-right #{window.i18n("header_amount")}
15 | tbody#table-operations
16 |
--------------------------------------------------------------------------------
/client/app/views/templates/layout-2col.jade:
--------------------------------------------------------------------------------
1 | .row.content-background
2 | #layout-2col-column-left.col-lg-4.content-left-column
3 |
4 | #layout-2col-column-right.col-lg-8.content-right-column
5 |
--------------------------------------------------------------------------------
/client/app/views/templates/modal_confirm.jade:
--------------------------------------------------------------------------------
1 | #confirmation-dialog.modal.fade
2 | .modal-dialog
3 | .modal-content
4 | .modal-header
5 | button.close(type='button', data-dismiss='modal', aria-hidden='true') x
6 | h4.modal-title
7 | | #{title}
8 | .modal-body
9 | p
10 | | #{body}
11 | .modal-footer
12 | a.btn.btn-link(data-dismiss='modal',href='#') #{window.i18n("cancel")}
13 | a#confirmation-dialog-confirm.btn.btn-cozy(href='#') #{confirm}
14 |
15 |
--------------------------------------------------------------------------------
/client/app/views/templates/navbar.jade:
--------------------------------------------------------------------------------
1 | nav.navbar.navbar-inverse.navbar-fixed-top(role='navigation')
2 | .container
3 | // Brand and toggle get grouped for better mobile display
4 | .navbar-header
5 | button.navbar-toggle(type='button', data-toggle='collapse', data-target='.navbar-collapse')
6 | span.sr-only Toggle navigation
7 | span.icon-bar
8 | span.icon-bar
9 | span.icon-bar
10 | // Collect the nav links, forms, and other content for toggling
11 | .collapse.navbar-collapse
12 | ul.nav.navbar-nav
13 | li.menu-position.menu-1
14 | a#menu-pos-balance(href='#') #{window.i18n("menu_balance")}
15 | li.menu-position.menu-2
16 | a#menu-pos-accounts(href='#search') #{window.i18n("menu_search")}
17 | li.menu-position.menu-3
18 | a#menu-pos-accounts(href='#accounts') #{window.i18n("menu_accounts")}
19 | li
20 | a#menu-pos-new-bank(data-toggle='modal', href='#add-bank-window') #{window.i18n("menu_add_bank")}
21 |
22 | ul.nav.navbar-nav.navbar-right
23 | p.navbar-text
24 | | #{window.i18n("overall_balance")}
25 | span#total-amount 0,00
--------------------------------------------------------------------------------
/client/app/views/templates/new_bank.jade:
--------------------------------------------------------------------------------
1 | .modal-dialog
2 | .modal-content
3 | .modal-header
4 | button.close(type='button', data-dismiss='modal', aria-hidden='true') x
5 | h4.modal-title
6 | | #{window.i18n("menu_add_bank")}
7 | .modal-body
8 | .message-modal
9 | form
10 | fieldset
11 | legend
12 | | #{window.i18n("add_bank_bank")}
13 | .form-group
14 | select#inputBank.form-control
15 | each bank in banks
16 | option(value=bank.get("uuid"))
17 | =bank.get("name")
18 |
19 | #formInputWebsite.form-group.hide
20 | label(for='inputWebsite')
21 | | #{window.i18n("add_bank_website")}
22 | select#inputWebsite.form-control
23 |
24 | fieldset
25 | legend
26 | | #{window.i18n("add_bank_credentials")}
27 | .form-group
28 | label(for='inputLogin')
29 | | #{window.i18n("add_bank_login")}
30 | input#inputLogin.form-control(type='text', placeholder=window.i18n("add_bank_login_placeholder"))
31 | .form-group
32 | label(for='inputPass')
33 | | #{window.i18n("add_bank_password")}
34 | input#inputPass.form-control(type='password', placeholder=window.i18n("add_bank_password_placeholder"))
35 | h3.important-notice
36 | | #{window.i18n("add_bank_security_notice")}
37 | p
38 | | #{window.i18n("add_bank_security_notice_text")}
39 | .modal-footer
40 | a.btn.btn-link(data-dismiss='modal',href='#') #{window.i18n("add_bank_cancel")}
41 | a#btn-add-bank-save.btn.btn-success(href='#') #{window.i18n("add_bank_ok")}
42 |
--------------------------------------------------------------------------------
/client/app/views/templates/search_bank_subtitle.jade:
--------------------------------------------------------------------------------
1 | .row.accounts-sub
2 | .col-lg-7
3 | p.pull-left #{model.get('title')}
4 | .col-lg-5
5 | p.pull-right
6 | if model.checked
7 | input(type="checkbox", checked).choice-account
8 | else
9 | input(type="checkbox").choice-account
10 |
--------------------------------------------------------------------------------
/client/app/views/templates/search_bank_title.jade:
--------------------------------------------------------------------------------
1 | .row.accounts-top
2 | .col-lg-7
3 | p.pull-left
4 | span.bank-title-loading
5 | img(src="./loader.gif")
6 | span.bank-title
7 | | #{model.get('name')}
8 | .col-lg-5
9 | p.pull-right.bank-title-checkbox
10 | if model.checked
11 | input(type="checkbox", checked).choice-bank
12 | else
13 | input(type="checkbox").choice-bank
--------------------------------------------------------------------------------
/client/app/views/templates/search_operations.jade:
--------------------------------------------------------------------------------
1 | form.form-search
2 | .row
3 | .col-lg-6
4 | .form-group
5 | label(for='search-date-from')
6 | | #{window.i18n("search_date_from")}
7 | input#search-date-from.form-control(type='date')
8 | .col-lg-6
9 | .form-group
10 | label(for='search-date-to')
11 | | #{window.i18n("search_date_to")}
12 | input#search-date-to.form-control(type='date')
13 |
14 | .row
15 | .col-lg-6
16 | .form-group
17 | label(for='search-amount-from')
18 | | #{window.i18n("search_amount_from")}
19 | input#search-amount-from.form-control(type='number')
20 | .col-lg-6
21 | .form-group
22 | label(for='search-amount-to')
23 | | #{window.i18n("search_amount_to")}
24 | input#search-amount-to.form-control(type='number')
25 |
26 | .row
27 | .col-lg-12
28 | label(for='search-text')
29 | | #{window.i18n("search_text")}
30 | input#search-text.form-control(type='text')
31 |
32 | .row
33 | .col-lg-12#search-operations-table
34 |
--------------------------------------------------------------------------------
/client/app/views/templates/search_operations_table_header.jade:
--------------------------------------------------------------------------------
1 | br
2 | table#search-table.table.tablesorter.table-striped.table-hover
3 | thead
4 | tr
5 | th.sort-date.text-left #{window.i18n("header_date")}
6 | th.sort-title.text-center #{window.i18n("header_title")}
7 | th.sort-amount.text-right #{window.i18n("header_amount")}
8 | tbody#search-operations-table-body
9 |
--------------------------------------------------------------------------------
/client/config.coffee:
--------------------------------------------------------------------------------
1 | exports.config =
2 | # See docs at http://brunch.readthedocs.org/en/latest/config.html.
3 | #coffeelint:
4 | #pattern: /^app\/.*\.coffee$/
5 | #options:
6 | #indentation:
7 | #value: 4
8 | #level: "error"
9 |
10 | files:
11 | javascripts:
12 | joinTo:
13 | 'javascripts/app.js': /^app/
14 | 'javascripts/vendor.js': /^vendor/
15 | order:
16 | # Files in `vendor` directories are compiled before other files
17 | # even if they aren't specified in order.
18 | before: [
19 | 'vendor/scripts/jquery-1.10.2.js'
20 | 'vendor/scripts/underscore-1.4.4.js'
21 | 'vendor/scripts/backbone-1.0.0.js'
22 | 'vendor/scripts/jquery.dataTables.js'
23 | ]
24 |
25 | stylesheets:
26 | joinTo: 'stylesheets/app.css'
27 | order:
28 | before: ['vendor/styles/normalize.css']
29 | after: ['vendor/styles/helpers.css']
30 |
31 | templates:
32 | defaultExtension: 'jade'
33 | joinTo: 'javascripts/app.js'
34 |
--------------------------------------------------------------------------------
/client/generators/collection/collection.coffee.hbs:
--------------------------------------------------------------------------------
1 | module.exports = class {{#camelize}}{{pluralName}}{{/camelize}}Collection extends Backbone.Collection
2 | model: require '../models/{{name}}'
3 | url: '{{name}}s/'
4 |
--------------------------------------------------------------------------------
/client/generators/collection/generator.json:
--------------------------------------------------------------------------------
1 | {
2 | "files": [{
3 | "from": "collection.coffee.hbs",
4 | "to": "app/collections/{{pluralName}}.coffee"
5 | }],
6 | "dependencies": [{
7 | "name": "collection_test",
8 | "params": "{{pluralName}}"
9 | }]
10 | }
11 |
--------------------------------------------------------------------------------
/client/generators/collection_test/collection_test.coffee.hbs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/generators/collection_test/collection_test.coffee.hbs
--------------------------------------------------------------------------------
/client/generators/collection_test/generator.json:
--------------------------------------------------------------------------------
1 | {
2 | "files": [{
3 | "from": "collection_test.coffee.hbs",
4 | "to": "test/collections/{{pluralName}}_test.coffee"
5 | }],
6 | "dependencies": []
7 | }
8 |
--------------------------------------------------------------------------------
/client/generators/generator/generated_file.coffee.hbs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/generators/generator/generated_file.coffee.hbs
--------------------------------------------------------------------------------
/client/generators/generator/generator.json:
--------------------------------------------------------------------------------
1 | {
2 | "files": [
3 | {
4 | "from": "generator.json.hbs",
5 | "to": "generators/{{name}}/generator.json"
6 | },
7 | {
8 | "from": "generated_file.coffee.hbs",
9 | "to": "generators/{{name}}/{{name}}.coffee.hbs"
10 | }
11 | ],
12 | "dependencies": []
13 | }
14 |
--------------------------------------------------------------------------------
/client/generators/generator/generator.json.hbs:
--------------------------------------------------------------------------------
1 | {
2 | "files": [{
3 | "from": "{{name}}.coffee.hbs",
4 | "to": "app/file.coffee"
5 | }],
6 | "dependencies": []
7 | }
8 |
--------------------------------------------------------------------------------
/client/generators/model/generator.json:
--------------------------------------------------------------------------------
1 | {
2 | "files": [{
3 | "from": "model.coffee.hbs",
4 | "to": "app/models/{{name}}.coffee"
5 | }],
6 | "dependencies": [{
7 | "name": "model_test",
8 | "params": "{{name}}"
9 | }]
10 | }
11 |
--------------------------------------------------------------------------------
/client/generators/model/model.coffee.hbs:
--------------------------------------------------------------------------------
1 | module.exports = class {{#camelize}}{{name}}{{/camelize}}Model extends Backbone.Model
2 | rootUrl: "{{name}}s/"
--------------------------------------------------------------------------------
/client/generators/model_test/generator.json:
--------------------------------------------------------------------------------
1 | {
2 | "files": [{
3 | "from": "model_test.coffee.hbs",
4 | "to": "test/models/{{name}}.coffee"
5 | }],
6 | "dependencies": []
7 | }
8 |
--------------------------------------------------------------------------------
/client/generators/model_test/model_test.coffee.hbs:
--------------------------------------------------------------------------------
1 | {{#camelize}}{{name}}{{/camelize}}Model = require 'models/{{name}}'
2 |
3 | describe '{{#camelize}}{{name}}{{/camelize}}Model', ->
4 | beforeEach ->
5 | @model = new {{#camelize}}{{name}}{{/camelize}}Model()
6 |
--------------------------------------------------------------------------------
/client/generators/module/collection.coffee.hbs:
--------------------------------------------------------------------------------
1 | module.exports = class {{#camelize}}{{pluralName}}{{/camelize}}Collection extends Backbone.Collection
2 | model: require '../models/{{name}}'
3 | url: '{{name}}s/'
4 |
--------------------------------------------------------------------------------
/client/generators/module/generator.json:
--------------------------------------------------------------------------------
1 | {
2 | "files": [
3 | {
4 | "from": "model.coffee.hbs",
5 | "to": "app/models/{{name}}.coffee"
6 | },
7 | {
8 | "from": "view.coffee.hbs",
9 | "to": "app/views/{{name}}.coffee"
10 | },
11 | {
12 | "from": "collection.coffee.hbs",
13 | "to": "app/collections/{{name}}s.coffee"
14 | },
15 | {
16 | "from": "template.jade.hbs",
17 | "to": "app/views/templates/{{name}}.jade"
18 | },
19 | {
20 | "from": "style.styl.hbs",
21 | "to": "app/views/styles/_{{name}}.styl"
22 | },
23 | {
24 | "from": "view_collection.coffee.hbs",
25 | "to": "app/views/{{name}}s.coffee"
26 | }
27 | ],
28 | "dependencies": []
29 | }
30 |
--------------------------------------------------------------------------------
/client/generators/module/model.coffee.hbs:
--------------------------------------------------------------------------------
1 | module.exports = class {{#camelize}}{{name}}{{/camelize}}Model extends Backbone.Model
2 | rootUrl: "{{name}}s/"
--------------------------------------------------------------------------------
/client/generators/module/style.styl.hbs:
--------------------------------------------------------------------------------
1 | .{{name}}
2 | // {{#camelize}}{{name}}{{/camelize}} Module
3 |
4 |
--------------------------------------------------------------------------------
/client/generators/module/template.jade.hbs:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/client/generators/module/view.coffee.hbs:
--------------------------------------------------------------------------------
1 | BaseView = require '../lib/base_view'
2 |
3 | module.exports = class {{#camelize}}{{name}}{{/camelize}}View extends BaseView
4 | template: require './templates/{{name}}'
5 | className: '{{name}}'
6 |
--------------------------------------------------------------------------------
/client/generators/module/view_collection.coffee.hbs:
--------------------------------------------------------------------------------
1 | ViewCollection = require '../lib/view_collection'
2 | {{#camelize}}{{name}}{{/camelize}}sCollection = require '../collections/{{name}}s'
3 | {{#camelize}}{{name}}{{/camelize}}View = require './{{name}}'
4 |
5 | module.exports = class {{#camelize}}{{name}}{{/camelize}}sView extends ViewCollection
6 | el: '#{{name}}s'
7 |
8 | collection: new {{#camelize}}{{name}}{{/camelize}}sCollection()
9 | itemview: {{#camelize}}{{name}}{{/camelize}}View
10 |
11 | afterRender: ->
12 | @collection.on 'reset', =>
13 | @renderAll()
14 | @collection.on 'add', (model) =>
15 | @renderOne model
16 |
--------------------------------------------------------------------------------
/client/generators/style/generator.json:
--------------------------------------------------------------------------------
1 | {
2 | "files": [{
3 | "from": "style.styl.hbs",
4 | "to": "app/views/styles/_{{name}}.styl"
5 | }],
6 | "dependencies": []
7 | }
8 |
--------------------------------------------------------------------------------
/client/generators/style/style.styl.hbs:
--------------------------------------------------------------------------------
1 | .{{name}}
2 | // {{#camelize}}{{name}}{{/camelize}} Module
3 |
--------------------------------------------------------------------------------
/client/generators/template/generator.json:
--------------------------------------------------------------------------------
1 | {
2 | "files": [{
3 | "from": "template.hbs.hbs",
4 | "to": "app/views/templates/{{name}}.jade"
5 | }],
6 | "dependencies": []
7 | }
8 |
--------------------------------------------------------------------------------
/client/generators/template/template.hbs:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/client/generators/view/generator.json:
--------------------------------------------------------------------------------
1 | {
2 | "files": [{
3 | "from": "view.coffee.hbs",
4 | "to": "app/views/{{name}}.coffee"
5 | }],
6 | "dependencies": [{
7 | "name": "view_test",
8 | "params": "{{name}}"
9 | }]
10 | }
11 |
--------------------------------------------------------------------------------
/client/generators/view/view.coffee.hbs:
--------------------------------------------------------------------------------
1 | BaseView = require '../lib/base_view'
2 |
3 | module.exports = class {{#camelize}}{{name}}{{/camelize}}View extends BaseView
4 | template: require './templates/{{name}}'
5 | className: '{{name}}'
6 |
--------------------------------------------------------------------------------
/client/generators/view_test/generator.json:
--------------------------------------------------------------------------------
1 | {
2 | "files": [
3 | {
4 | "from": "view_test.coffee.hbs",
5 | "to": "test/views/{{name}}.coffee"
6 | }
7 | ],
8 | "dependencies": []
9 | }
10 |
--------------------------------------------------------------------------------
/client/generators/view_test/view_test.coffee.hbs:
--------------------------------------------------------------------------------
1 | {{#camelize}}{{name}}{{/camelize}}View = require 'views/{{name}}'
2 |
3 | describe '{{#camelize}}{{name}}{{/camelize}}View', ->
4 | beforeEach ->
5 | @view = new {{#camelize}}{{name}}{{/camelize}}View()
6 |
--------------------------------------------------------------------------------
/client/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "author": "Your Name",
3 | "name": "package-name",
4 | "description": "Package description",
5 | "version": "0.0.1",
6 | "homepage": "",
7 | "repository": {
8 | "type": "git",
9 | "url": ""
10 | },
11 | "engines": {
12 | "node": "~0.6.10 || 0.8 || 0.9"
13 | },
14 | "scripts": {
15 | "start": "brunch watch --server"
16 | },
17 | "dependencies": {
18 | "javascript-brunch": "> 1.0 < 1.5",
19 | "coffee-script-brunch": "> 1.0 < 1.5",
20 |
21 | "css-brunch": "> 1.0 < 1.5",
22 | "stylus-brunch": "> 1.0 < 1.5",
23 |
24 | "jade-brunch": "> 1.0 < 1.5",
25 |
26 | "uglify-js-brunch": "> 1.0 < 1.5",
27 | "clean-css-brunch": "> 1.0 < 1.5",
28 |
29 | "auto-reload-brunch": "> 1.0 < 1.5",
30 |
31 | "async": ">= 0"
32 | },
33 | "devDependencies": {
34 | "mocha": "0.14.0",
35 | "expect.js": "0.1.2",
36 | "ws": "0.4.21"
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/client/public/asc.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/public/asc.gif
--------------------------------------------------------------------------------
/client/public/bg.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/public/bg.gif
--------------------------------------------------------------------------------
/client/public/crossdomain.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
15 |
16 |
--------------------------------------------------------------------------------
/client/public/desc.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/public/desc.gif
--------------------------------------------------------------------------------
/client/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/public/favicon.ico
--------------------------------------------------------------------------------
/client/public/fonts/fontawesome/FontAwesome.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/public/fonts/fontawesome/FontAwesome.ttf
--------------------------------------------------------------------------------
/client/public/fonts/fontawesome/README.md:
--------------------------------------------------------------------------------
1 | #Font Awesome 2.0
2 | ##the iconic font designed for use with Twitter Bootstrap
3 |
4 | The full suite of pictographic icons, examples, and documentation can be found at:
5 | http://fortawesome.github.com/Font-Awesome/
6 |
7 | ##Contact
8 | - Email: dave@davegandy.com
9 | - Twitter: http://twitter.com/fortaweso_me
10 | - Work: Lead Product Designer @ http://kyru.us
11 |
12 | ##License
13 | Version 2.0 of the Font Awesome font, CSS, and LESS files are licensed under CC BY 3.0:
14 | http://creativecommons.org/licenses/by/3.0/
15 | A mention of 'Font Awesome - http://fortawesome.github.com/Font-Awesome'
16 | in human-readable source code is considered acceptable attribution (most common on the
17 | web). If human readable source code is not available to the end user, a mention in an 'About'
18 | or 'Credits' screen is considered acceptable (most common in desktop or mobile software).
19 |
--------------------------------------------------------------------------------
/client/public/fonts/fontawesome/fontawesome-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/public/fonts/fontawesome/fontawesome-webfont.eot
--------------------------------------------------------------------------------
/client/public/fonts/fontawesome/fontawesome-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/public/fonts/fontawesome/fontawesome-webfont.ttf
--------------------------------------------------------------------------------
/client/public/fonts/fontawesome/fontawesome-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/public/fonts/fontawesome/fontawesome-webfont.woff
--------------------------------------------------------------------------------
/client/public/fonts/fontello.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/public/fonts/fontello.ttf
--------------------------------------------------------------------------------
/client/public/fonts/glyphicons-halflings-regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/public/fonts/glyphicons-halflings-regular.eot
--------------------------------------------------------------------------------
/client/public/fonts/glyphicons-halflings-regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/public/fonts/glyphicons-halflings-regular.ttf
--------------------------------------------------------------------------------
/client/public/fonts/glyphicons-halflings-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/public/fonts/glyphicons-halflings-regular.woff
--------------------------------------------------------------------------------
/client/public/fonts/maven-pro-light-100.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/public/fonts/maven-pro-light-100.otf
--------------------------------------------------------------------------------
/client/public/fonts/maven-pro-light-200.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/public/fonts/maven-pro-light-200.otf
--------------------------------------------------------------------------------
/client/public/fonts/maven-pro-light-300.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/public/fonts/maven-pro-light-300.otf
--------------------------------------------------------------------------------
/client/public/fonts/signika-bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/public/fonts/signika-bold.ttf
--------------------------------------------------------------------------------
/client/public/fonts/signika-light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/public/fonts/signika-light.ttf
--------------------------------------------------------------------------------
/client/public/fonts/signika-regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/public/fonts/signika-regular.ttf
--------------------------------------------------------------------------------
/client/public/humans.txt:
--------------------------------------------------------------------------------
1 | # humanstxt.org/
2 | # The humans responsible & technology colophon
3 |
4 | # TEAM
5 |
6 | -- --
7 |
8 | # THANKS
9 |
10 |
11 |
12 | # TECHNOLOGY COLOPHON
13 |
14 | HTML5, CSS3
15 | jQuery, Modernizr,
16 | Lodash, Backbone,
17 | Handlebars, Coffeescript,
18 | Stylus, Brunch
19 |
--------------------------------------------------------------------------------
/client/public/icons/main_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/public/icons/main_icon.png
--------------------------------------------------------------------------------
/client/public/images/Melamine-wood-003.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/public/images/Melamine-wood-003.png
--------------------------------------------------------------------------------
/client/public/images/arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/public/images/arrow.png
--------------------------------------------------------------------------------
/client/public/images/arrow_vertical.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/public/images/arrow_vertical.png
--------------------------------------------------------------------------------
/client/public/images/glyphicons-halflings-white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/public/images/glyphicons-halflings-white.png
--------------------------------------------------------------------------------
/client/public/images/glyphicons-halflings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/public/images/glyphicons-halflings.png
--------------------------------------------------------------------------------
/client/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Cozy PFM
10 |
11 |
12 |
17 |
18 |
19 |
20 |
21 |
22 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/client/public/loader.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/public/loader.gif
--------------------------------------------------------------------------------
/client/public/loader_big_blue.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/public/loader_big_blue.gif
--------------------------------------------------------------------------------
/client/public/loader_green.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/public/loader_green.gif
--------------------------------------------------------------------------------
/client/public/loader_inverse.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/public/loader_inverse.gif
--------------------------------------------------------------------------------
/client/public/pdf/factureSFR.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/public/pdf/factureSFR.pdf
--------------------------------------------------------------------------------
/client/public/pdf/factureSNCF.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/public/pdf/factureSNCF.pdf
--------------------------------------------------------------------------------
/client/public/robots.txt:
--------------------------------------------------------------------------------
1 | # robotstxt.org/
2 |
3 | User-agent: *
4 |
--------------------------------------------------------------------------------
/client/vendor/scripts/zoomico.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/client/vendor/scripts/zoomico.png
--------------------------------------------------------------------------------
/client/vendor/styles/helpers.css:
--------------------------------------------------------------------------------
1 | .chromeframe { margin: 0.2em 0; background: #ccc; color: #000; padding: 0.2em 0; }
2 | .ir { display: block; border: 0; text-indent: -999em; overflow: hidden; background-color: transparent; background-repeat: no-repeat; text-align: left; direction: ltr; *line-height: 0; }
3 | .ir br { display: none; }
4 | .hidden { display: none !important; visibility: hidden; }
5 | .visuallyhidden { border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; }
6 | .visuallyhidden.focusable:active, .visuallyhidden.focusable:focus { clip: auto; height: auto; margin: 0; overflow: visible; position: static; width: auto; }
7 | .invisible { visibility: hidden; }
8 | .clearfix:before, .clearfix:after { content: ""; display: table; }
9 | .clearfix:after { clear: both; }
10 | .clearfix { *zoom: 1; }
11 |
12 | @media print {
13 | * { background: transparent !important; color: black !important; box-shadow:none !important; text-shadow: none !important; filter:none !important; -ms-filter: none !important; }
14 | a, a:visited { text-decoration: underline; }
15 | a[href]:after { content: " (" attr(href) ")"; }
16 | abbr[title]:after { content: " (" attr(title) ")"; }
17 | .ir a:after, a[href^="javascript:"]:after, a[href^="#"]:after { content: ""; }
18 | pre, blockquote { border: 1px solid #999; page-break-inside: avoid; }
19 | thead { display: table-header-group; }
20 | tr, img { page-break-inside: avoid; }
21 | img { max-width: 100% !important; }
22 | @page { margin: 0.5cm; }
23 | p, h2, h3 { orphans: 3; widows: 3; }
24 | h2, h3 { page-break-after: avoid; }
25 | }
26 |
--------------------------------------------------------------------------------
/client/vendor/styles/sort.css:
--------------------------------------------------------------------------------
1 | /* table sorter */
2 | table.tablesorter thead tr th {
3 | background-image: url(../bg.gif);
4 | background-repeat: no-repeat;
5 | background-position: center right;
6 | /* background-color: #F7F7F7; */
7 | padding-right: 20px;
8 | cursor: pointer;
9 | }
10 | table.tablesorter thead tr .sorting_asc {
11 | background-image: url(../asc.gif);
12 | }
13 | table.tablesorter thead tr .sorting_desc {
14 | background-image: url(../desc.gif);
15 | }
16 | table.tablesorter thead tr .sorting_asc, table.tablesorter thead tr .sorting_desc {
17 | /* background-color: #dddddd; */
18 | font-weight: bold;
19 | color: #34A6FF;
20 | }
--------------------------------------------------------------------------------
/client/vendor/styles/tablesort_blue.css:
--------------------------------------------------------------------------------
1 | /* table sorter */
2 | table.tablesorter thead tr .header {
3 | background-image: url(../bg.gif);
4 | background-repeat: no-repeat;
5 | background-position: center right;
6 | /* background-color: #F7F7F7; */
7 | padding-right: 20px;
8 | cursor: pointer;
9 | }
10 | table.tablesorter thead tr .headerSortUp {
11 | background-image: url(../asc.gif);
12 | }
13 | table.tablesorter thead tr .headerSortDown {
14 | background-image: url(../desc.gif);
15 | }
16 | table.tablesorter thead tr .headerSortDown, table.tablesorter thead tr .headerSortUp {
17 | /* background-color: #dddddd; */
18 | font-weight: bold;
19 | color: #34A6FF;
20 | }
21 |
--------------------------------------------------------------------------------
/coffeelint.json:
--------------------------------------------------------------------------------
1 | {
2 | "indentation" : {
3 | "value" : 4,
4 | "level" : "error"
5 | },
6 | "no_empty_param_list": {
7 | "level": "warn"
8 | }
9 | }
--------------------------------------------------------------------------------
/log/production.log:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seeker89/cozy-pfm/3e17567625fe81eb879255a4cdbc7d83f374614f/log/production.log
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "pfm",
3 | "version": "1.0.0",
4 | "engines": [
5 | "node = 0.8.x"
6 | ],
7 | "description": "Personal Finance Manager you own and control",
8 | "license": "MIT",
9 | "repository": {
10 | "type": "git",
11 | "url": "https://github.com/mycozycloud/cozy-pfm.git"
12 | },
13 | "main": "server.coffee",
14 | "dependencies": {
15 | "americano": "0.3.3",
16 | "americano-cozy": "0.2.2",
17 | "async": "0.2.10",
18 | "request-json": "0.4.8",
19 | "moment": "2.5.1",
20 | "cozy-notifications-helper": "1.0.2",
21 | "jade": "1.3.0",
22 | "nock": "0.27.2",
23 | "cozy-i18n-helper": "0.0.4",
24 | "printit": "0.1.3"
25 | },
26 | "devDependencies": {
27 | "should": "3.1.4",
28 | "mocha": "1.18.2",
29 | "cozy-fixtures": "1.1.0",
30 | "coffeelint": "1.1.0"
31 | },
32 | "scripts": {
33 | "test": "cake --use-js tests",
34 | "start": "node build/server.js"
35 | },
36 | "cozy-displayName": "Mes Comptes",
37 | "cozy-permissions": {
38 | "Bank": {
39 | "description": "Les banques auxquelles vous pouvez accéder via l'application."
40 | },
41 | "BankAccess": {
42 | "description": "Vos identifiants d'accès à votre banque sont stockés de façon sécurisée."
43 | },
44 | "BankAccount": {
45 | "description": "Vos différents comptes bancaires."
46 | },
47 | "BankOperation": {
48 | "description": "Une opération bancaire."
49 | },
50 | "BankAlert": {
51 | "description": "Une alerte liée à vos comptes bancaires."
52 | },
53 | "send mail to user": {
54 | "description": "A votre demande, des rapports journaliers, hebdomadaires ou mensuels peuvent vous être envoyés par email."
55 | },
56 | "Notification": {
57 | "description": "Des notifications sont créées lorsque des alertes sont mises en place dans l'application."
58 | },
59 | "CozyInstance": {
60 | "description": "Afin d'afficher le contenu dans votre langue, l'application doit accéder à vos préférences."
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/server.coffee:
--------------------------------------------------------------------------------
1 | application = module.exports = (callback) ->
2 |
3 | americano = require 'americano'
4 | initialize = require './server/init'
5 | require './tests/mock-weboob'
6 |
7 | options =
8 | name: 'pfm'
9 | port: process.env.PORT or 9875
10 | host: process.env.HOST or "127.0.0.1"
11 | root: __dirname
12 |
13 | americano.start options, (app, server) ->
14 | initialize app, server, callback
15 |
16 | if not module.parent
17 | application()
18 |
--------------------------------------------------------------------------------
/server/config.coffee:
--------------------------------------------------------------------------------
1 | americano = require 'americano'
2 | config =
3 | common: [
4 | americano.bodyParser()
5 | americano.methodOverride()
6 | americano.errorHandler
7 | dumpExceptions: true
8 | showStack: true
9 | americano.static __dirname + '/../client/public',
10 | maxAge: 86400000
11 | require('cozy-i18n-helper').middleware
12 | ]
13 |
14 | development: [
15 | americano.logger 'dev'
16 | ]
17 |
18 | production: [
19 | americano.logger 'short'
20 | ]
21 |
22 | plugins: [
23 | 'americano-cozy'
24 | ]
25 |
26 | module.exports = config
--------------------------------------------------------------------------------
/server/controllers/bankaccesses.coffee:
--------------------------------------------------------------------------------
1 | BankAccess = require '../models/bankaccess'
2 | BankAccount = require '../models/bankaccount'
3 |
4 | module.exports.loadBankAccess = (req, res, next, bankAccessID) ->
5 | BankAccess.find bankAccessID, (err, access) =>
6 | if err? or not access?
7 | res.send 404, error: "BankAccess not found"
8 | else
9 | delete access.password
10 | req.access = access
11 | next()
12 |
13 | module.exports.index = (req, res) ->
14 | BankAccess.all (err, accesses) ->
15 | if err?
16 | res.send 500, error: 'Server error occurred while retrieving data'
17 | else
18 | res.send 200, accesses
19 |
20 | module.exports.create = (req, res) ->
21 | BankAccess.addNewAccess req.body, (err, access) ->
22 | if err?
23 | if err.alreadyExist?
24 | res.send 409, error: "This bank access already exists"
25 | else
26 | msg = "Server error while creating bank access. -- #{err}"
27 | res.send 500, error: msg
28 | else
29 | res.send 201, access
30 |
31 | module.exports.destroy = (req, res) ->
32 | req.access.destroy (err) ->
33 | if err?
34 | res.send 500, error: "Server error while deleting the bank access"
35 | else
36 | res.send 204, success: true
37 |
38 | module.exports.update = (req, res) ->
39 | req.access.updateAttributes body, (err, access) ->
40 | if err?
41 | res.send 500, error: "Server error while saving bank access"
42 | else
43 | res.send 200, access
44 |
45 | module.exports.show = (req, res) ->
46 | res.send 200, req.access
47 |
48 | module.exports.getAccounts = (req, res) ->
49 | BankAccount.allFromBankAccess req.access, (err, accounts) ->
50 | if err
51 | res.send 500, error: 'Server error occurred while retrieving data'
52 | else
53 | res.send 200, accounts
--------------------------------------------------------------------------------
/server/controllers/bankaccounts.coffee:
--------------------------------------------------------------------------------
1 | BankAccount = require '../models/bankaccount'
2 | BankOperation = require '../models/bankoperation'
3 | BankAccess = require '../models/bankaccess'
4 |
5 | module.exports.loadBankAccount = (req, res, next, accountID) ->
6 | BankAccount.find accountID, (err, account) =>
7 | if err? or not account?
8 | res.send 404, error: "BankAccount not found"
9 | else
10 | req.account = account
11 | next()
12 |
13 | module.exports.index = (req, res) ->
14 | BankAccount.all (err, accounts) ->
15 | if err?
16 | res.send 500, error: 'Server error occurred while retrieving data'
17 | else
18 | res.send 200, accounts
19 |
20 | module.exports.destroy = (req, res) ->
21 | req.account.destroyWithOperations (err) ->
22 | if err?
23 | res.send 500, error: err
24 | else
25 | res.send 204, success: true
26 |
27 | module.exports.show = (req, res) ->
28 | res.send 200, req.account
29 |
30 | module.exports.getOperations = (req, res) ->
31 | BankOperation.allFromBankAccountDate req.account, (err, operations) ->
32 | if err?
33 | res.send 500, error: 'Server error occurred while retrieving data'
34 | else
35 | res.send 200, operations
36 |
37 | module.exports.retrieveOperations = (req, res) ->
38 | BankAccess.find req.account.bankAccess, (err, access) =>
39 | if err?
40 | msg = "Server error occurred while retrieving data -- #{err}"
41 | res.send 500, error: msg
42 | else
43 | access.retrieveOperations (err) =>
44 | if err?
45 | msg = "Server error occurred while retrieving data"
46 | res.send 500, error: "#{msg} -- #{err}"
47 | else
48 | res.send 200, req.account
--------------------------------------------------------------------------------
/server/controllers/bankalerts.coffee:
--------------------------------------------------------------------------------
1 | BankAlert = require '../models/bankalert'
2 |
3 | module.exports.loadAlert = (req, res, next, alertID) ->
4 | BankAlert.find alertID, (err, alert) =>
5 | if err? or not alert?
6 | res.send 404, error: "Bank Alert not found"
7 | else
8 | req.alert = alert
9 | next()
10 |
11 | module.exports.index = (req, res) ->
12 | BankAlert.all (err, alerts) ->
13 | if err?
14 | res.send 500, error: 'Server error occurred while retrieving data'
15 | else
16 | res.send 200, alerts
17 |
18 | module.exports.create = (req, res) ->
19 | BankAlert.create req.body, (err, alert) ->
20 | if err?
21 | res.send 500, error: "Server error while creating bank alert."
22 | else
23 | res.send 201, alert
24 |
25 | module.exports.destroy = (req, res) ->
26 | req.alert.destroy (err) ->
27 | if err?
28 | res.send 500, error: "Server error while deleting the bank alert"
29 | else
30 | res.send 204, success: true
31 |
32 | module.exports.update = (req, res) ->
33 | req.alert.updateAttributes req.body, (err, alert) ->
34 | if err?
35 | res.send 500, error: "Server error while saving bank alert"
36 | else
37 | res.send 200, alert
38 |
39 | module.exports.getForBankAccount = (req, res) ->
40 | BankAlert.allFromBankAccount id: req.params.accountID, (err , alerts) ->
41 | if err?
42 | res.send 500, error: "Server error while getting bank alerts"
43 | else
44 | res.send 200, alerts
45 |
46 | module.exports.show = (req, res) ->
47 | res.send 200, req.alert
48 |
--------------------------------------------------------------------------------
/server/controllers/banks.coffee:
--------------------------------------------------------------------------------
1 | Bank = require '../models/bank'
2 | BankAccess = require '../models/bankaccess'
3 | BankAccount = require '../models/bankaccount'
4 | BankOperation = require '../models/bankoperation'
5 |
6 | module.exports.loadBank = (req, res, next, bankID) ->
7 | Bank.find bankID, (err, bank) =>
8 | if err? or not bank?
9 | res.send 404, error: "Bank not found"
10 | else
11 | req.bank = bank
12 | next()
13 |
14 | module.exports.index = (req, res) ->
15 | doRespond = (err, banks) ->
16 | if err? or not banks?
17 | msg = "Couldn't retrieve banks -- #{err}"
18 | res.send 500, msg
19 | else
20 | res.send 200, banks
21 | if req.query.withAccountOnly?
22 | Bank.getBanksWithAccounts doRespond
23 | else
24 | Bank.all doRespond
25 |
26 | module.exports.show = (req, res) ->
27 | res.send 200, req.bank
28 |
29 | module.exports.getAccesses = (req, res) ->
30 | BankAccess.allFromBank req.bank, (err, accesses) ->
31 | if err?
32 | res.send 500, error: 'Server error occurred while retrieving data'
33 | else
34 | res.send 200, accesses
35 |
36 | module.exports.getAccounts = (req, res) ->
37 | BankAccount.allFromBank req.bank, (err, accounts) ->
38 | if err?
39 | res.send 500, error: 'Server error occurred while retrieving data'
40 | else
41 | res.send 200, accounts
42 |
43 | module.exports.destroy = (req, res) ->
44 | req.bank.destroyBankAccess (err) ->
45 | if err?
46 | msg = "Could not delete accesses for bank #{bank.name}"
47 | res.send 500, error: msg
48 | else
49 | res.send 204, success: true
--------------------------------------------------------------------------------
/server/controllers/routes.coffee:
--------------------------------------------------------------------------------
1 | banks = require './banks'
2 | bankaccesses = require './bankaccesses'
3 | bankaccounts = require './bankaccounts'
4 | bankoperations = require './bankoperations'
5 | bankalerts = require './bankalerts'
6 |
7 | module.exports =
8 | 'banks':
9 | get: banks.index
10 | 'bankID': param: banks.loadBank
11 | 'banks/:bankID':
12 | get: banks.show
13 | delete: banks.destroy
14 | 'banks/getAccesses/:bankID':
15 | get: banks.getAccesses
16 | 'banks/getAccounts/:bankID':
17 | get: banks.getAccounts
18 |
19 | 'bankaccesses':
20 | get: bankaccesses.index
21 | post: bankaccesses.create
22 | 'bankAccessID': param: bankaccesses.loadBankAccess
23 | 'bankaccesses/:bankAccessID':
24 | get: bankaccesses.show
25 | put: bankaccesses.update
26 | delete: bankaccesses.destroy
27 | 'bankaccesses/getAccounts/:bankAccessID':
28 | get: bankaccesses.getAccounts
29 |
30 | 'bankaccounts':
31 | get: bankaccounts.index
32 | 'bankAccountID': param: bankaccounts.loadBankAccount
33 | 'bankaccounts/:bankAccountID':
34 | get: bankaccounts.show
35 | delete: bankaccounts.destroy
36 | 'bankaccounts/getOperations/:bankAccountID':
37 | get: bankaccounts.getOperations
38 | 'bankaccounts/retrieveOperations/:bankAccountID':
39 | get: bankaccounts.retrieveOperations
40 |
41 | 'bankoperations':
42 | get: bankoperations.index
43 | post: bankoperations.create
44 | 'bankOperationID': param: bankoperations.loadBankOperation
45 | 'bankoperations/:bankOperationID':
46 | get: bankoperations.show
47 | 'bankoperations/query':
48 | post: bankoperations.query
49 |
50 | 'bankalerts':
51 | get: bankalerts.index
52 | post: bankalerts.create
53 | 'bankAlertID': param: bankalerts.loadAlert
54 | 'bankalerts/:bankAlertID':
55 | get: bankalerts.show
56 | put: bankalerts.update
57 | delete: bankalerts.destroy
58 | 'bankalerts/getForBankAccount/:accountID':
59 | get: bankalerts.getForBankAccount
60 |
--------------------------------------------------------------------------------
/server/init.coffee:
--------------------------------------------------------------------------------
1 | module.exports = (app, server, callback) ->
2 |
3 | Bank = require './models/bank'
4 |
5 | # Bank initialization
6 | Bank.all (err, banks) ->
7 | if err or banks?.length is 0 # if there aren't any banks
8 | async = require 'async'
9 | bankList = require "../tests/fixtures/banks-all.json"
10 | process = (bank, callback) ->
11 | newBank =
12 | name: bank.name
13 | uuid: bank.uuid
14 | websites: bank.websites
15 | Bank.create newBank, (err) ->
16 | if err?
17 | callback err
18 | else
19 | callback null
20 |
21 | async.each bankList, process, (err) ->
22 | if err?
23 | msg = "Couldn't add the bank to the database -- #{err}"
24 | console.log msg
25 | else
26 | msg = "Banks added to the database."
27 | console.log msg
28 |
29 | callback app, server if callback?
30 |
31 | else
32 | callback app, server if callback?
33 |
34 | # Start bank polling
35 | console.log "Start bank accounts polling..."
36 | poller = require './lib/accounts-poller'
37 | poller.start()
38 |
39 | # manage daily/weekly/monthly report
40 | console.log "Start alert watcher..."
41 | reportManager = require './lib/report-manager'
42 | reportManager.start()
43 |
--------------------------------------------------------------------------------
/server/lib/accounts-poller.coffee:
--------------------------------------------------------------------------------
1 | async = require "async"
2 | moment = require "moment"
3 | BankAccess = require "../models/bankaccess"
4 |
5 | class AccountsPoller
6 |
7 | start: ->
8 | @prepareNextCheck()
9 |
10 | prepareNextCheck: ->
11 | # day after between 00:00am and 02:00am
12 | delta = Math.floor(Math.random() * 120)
13 | now = moment()
14 | nextUpdate = now.clone().add(1, 'days')
15 | .hours(0)
16 | .minutes(delta)
17 | .seconds(0)
18 |
19 | format = "DD/MM/YYYY [at] HH:mm:ss"
20 | msg = "> Next check of bank accounts on #{nextUpdate.format(format)}"
21 | console.log msg
22 | @timeout = setTimeout(
23 | () =>
24 | @checkAllAccesses()
25 | , nextUpdate.diff(now))
26 |
27 | checkAllAccesses: ->
28 | console.log "Checking new operations for all bank accesses..."
29 | BankAccess.retrieveOperationsForAllAccesses (err) =>
30 | if err?
31 | console.log "An error occurred during access check -- #{err}"
32 |
33 | console.log "Bank accesses checked."
34 | @prepareNextCheck()
35 |
36 | module.exports = new AccountsPoller
--------------------------------------------------------------------------------
/server/models/bank.coffee:
--------------------------------------------------------------------------------
1 | americano = require 'americano'
2 | async = require 'async'
3 | BankAccess = require './bankaccess'
4 | BankAccount = require './bankaccount'
5 |
6 | module.exports = Bank = americano.getModel 'bank',
7 | name: String
8 | uuid: String
9 | websites: (x) -> x
10 |
11 | Bank.all = (callback) ->
12 | Bank.request "all", callback
13 |
14 | Bank.getBanksWithAccounts = (callback) ->
15 | params = group: true
16 | BankAccount.rawRequest 'bankWithAccounts', params, (err, banks) ->
17 |
18 | if err?
19 | callback err, null
20 | else if not banks?
21 | callback null, []
22 | else
23 | uuids = []
24 | uuids.push bank.key for bank in banks
25 |
26 | Bank.getManyByUuid uuids, (err, banks) ->
27 | callback err, banks
28 |
29 | Bank.getManyByUuid = (uuids, callback) ->
30 |
31 | uuids = [uuids] if not (uuids instanceof Array)
32 | params = keys: uuids
33 |
34 | Bank.request "byUuid", params, callback
35 |
36 | # Destroy all bank accesses for a given bank
37 | Bank::destroyBankAccess = (callback) ->
38 | console.log "Deleting all accesses for bank #{@uuid}"
39 | BankAccess.allFromBank @, (err, accesses) ->
40 |
41 | if err?
42 | console.log "Could not get BankAccess from bank -- #{@uuid}"
43 | callback err
44 | else
45 | treatment = (access, callback) ->
46 | access.destroyAccounts callback
47 |
48 | async.eachSeries accesses, treatment, (err) ->
49 | callback err
--------------------------------------------------------------------------------
/server/models/bankalert.coffee:
--------------------------------------------------------------------------------
1 | americano = require 'americano'
2 |
3 | module.exports = BankAlert = americano.getModel 'bankalert',
4 | bankAccount: String
5 | type: String # possible options are: report, balance, transaction
6 | frequency: String # only for reports : daily, weekly, monthly
7 | limit: Number # only for balance/transaction
8 | order: String # only for balance/transaction: gt, lt
9 |
10 | BankAlert.all = (callback) ->
11 | BankAlert.request "all", callback
12 |
13 | BankAlert.allFromBankAccount = (account, callback) ->
14 | params = key: account.id
15 | BankAlert.request "allByBankAccount", params, callback
16 |
17 | BankAlert.allByAccountAndType = (accountID, type, callback) ->
18 | params = key: [accountID, type]
19 | BankAlert.request "allByBankAccountAndType", params, callback
20 |
21 | BankAlert.allReportsByFrequency = (frequency, callback) ->
22 | params = key: ["report", frequency]
23 | BankAlert.request "allReportsByFrequency", params, callback
24 |
25 | BankAlert.destroyByAccount = (id, callback) ->
26 | BankAlert.requestDestroy "allByBankAccount", key: id, callback
27 |
28 | BankAlert::testTransaction = (operation) ->
29 | unless @type is "transaction"
30 | return false
31 | else
32 | alertLimit = Number @limit
33 | amount = Math.abs operation.amount
34 | return (@order is "lt" and amount <= alertLimit) or \
35 | (@order is "gt" and amount >= alertLimit)
36 |
37 | BankAlert::testBalance = (account) ->
38 | unless @type is "balance"
39 | return false
40 | else
41 | alertLimit = Number @limit
42 | balance = account.getBalance()
43 | return (@order is "lt" and balance <= alertLimit) or \
44 | (@order is "gt" and balance >= alertLimit)
--------------------------------------------------------------------------------
/server/models/bankoperation.coffee:
--------------------------------------------------------------------------------
1 | americano = require 'americano'
2 |
3 | module.exports = BankOperation = americano.getModel 'bankoperation',
4 | bankAccount: String
5 | title: String
6 | date: Date
7 | amount: Number
8 | raw: String
9 | dateImport: Date
10 |
11 | BankOperation.all = (callback) ->
12 | BankOperation.request "all", callback
13 |
14 | BankOperation.allFromBankAccount = (account, callback) ->
15 | params =
16 | key: account.id
17 | BankOperation.request "allByBankAccount", params, callback
18 |
19 | BankOperation.allFromBankAccounts = (accountNums, callback) ->
20 | params = keys: accountNums
21 | BankOperation.request "allByBankAccount", params, callback
22 |
23 | BankOperation.allFromBankAccountDate = (account, callback) ->
24 | params =
25 | startkey: [account.accountNumber + "0"]
26 | endkey: [account.accountNumber]
27 | descending: true
28 | BankOperation.request "allByBankAccountAndDate", params, callback
29 |
30 | BankOperation.allLike = (operation, callback) ->
31 | date = new Date(operation.date).toISOString()
32 | params =
33 | key: [operation.bankAccount, date, \
34 | operation.amount, operation.raw]
35 | BankOperation.request "allLike", params, callback
36 |
37 | BankOperation.destroyByAccount = (accountNum, callback) ->
38 | BankOperation.requestDestroy "allByBankAccount", key: accountNum, callback
39 |
--------------------------------------------------------------------------------
/server/models/cozyinstance.coffee:
--------------------------------------------------------------------------------
1 | americano = require 'americano'
2 |
3 | module.exports = CozyInstance = americano.getModel 'CozyInstance',
4 | domain: String
5 | helpUrl: String
6 | locale: String
7 |
8 | CozyInstance.getInstance = (callback) ->
9 | CozyInstance.request 'all', (err, instances) ->
10 | if err
11 | callback err, null
12 | else if not(instances? and instances.length > 0)
13 | callback new Error 'No instance parameters found', null
14 | else
15 | callback null, instances[0]
--------------------------------------------------------------------------------
/server/models/requests.coffee:
--------------------------------------------------------------------------------
1 | americano = require 'americano'
2 |
3 | allByName = (doc) -> emit doc.name, doc
4 | byUuid = (doc) -> emit doc.uuid, doc
5 | allByTitle = (doc) -> emit doc.title, doc
6 | allByBank = (doc) -> emit doc.bank, doc
7 | allByBankAccess = (doc) -> emit doc.bankAccess, doc
8 | allByBankAccount = (doc) -> emit doc.bankAccount, doc
9 | allReportsByFrequency = (doc) -> emit [doc.type, doc.frequency], doc
10 | allByBankAccountAndType = (doc) -> emit [doc.bankAccount, doc.type], doc
11 | allByBankAccountAndDate = (doc) -> emit [doc.bankAccount, doc.date], doc
12 | allAccessesLike = (doc) ->
13 | emit [doc.bank, doc.login, doc.password], doc
14 | allOperationsLike = (doc) ->
15 | emit [doc.bankAccount, doc.date, doc.amount.toFixed(2), doc.raw], doc
16 | getBalance =
17 | map: (doc) ->
18 | emit doc.bankAccount, doc.amount
19 | reduce: (keys, values, rereduce) ->
20 | sum values
21 | getBanksWithAccounts =
22 | map: (doc) ->
23 | emit doc.bank, 1
24 | reduce: (keys, values, rereduce) ->
25 | return 1
26 |
27 | module.exports =
28 | bank:
29 | all: allByName
30 | byUuid: byUuid
31 | bankaccess:
32 | all: americano.defaultRequests.all
33 | allByBank: allByBank
34 | allLike: allAccessesLike
35 |
36 | bankaccount:
37 | all: allByTitle
38 | allByBankAccess: allByBankAccess
39 | allByBank: allByBank
40 | bankWithAccounts: getBanksWithAccounts
41 |
42 | bankoperation:
43 | all: americano.defaultRequests.all
44 | allByBankAccount: allByBankAccount
45 | allByBankAccountAndDate: allByBankAccountAndDate
46 | allLike: allOperationsLike
47 | getBalance: getBalance
48 |
49 | bankalert:
50 | all: americano.defaultRequests.all
51 | allByBankAccount: allByBankAccount
52 | allReportsByFrequency: allReportsByFrequency
53 | allByBankAccountAndType: allByBankAccountAndType
54 |
--------------------------------------------------------------------------------
/server/views/mail-report.jade:
--------------------------------------------------------------------------------
1 | html
2 | head
3 | title Votre rapport bancaire du #{today}
4 | body
5 | h1 Votre rapport bancaire du #{today}
6 |
7 | p Solde de vos comptes :
8 | ul
9 | - for(account in accounts) {
10 | li #{accounts[account].title} n°#{accounts[account].accountNumber} (
11 | b #{accounts[account].getBalance()}€
12 | | )
13 | - }
14 |
15 | - if(Object.keys(operationsByAccount).length > 0) {
16 | p Nouvelles opérations importées :
17 | ul
18 | - var accountList = Object.keys(operationsByAccount);
19 | - for(account in accountList) {
20 | li Compte n°#{accountList[account]}
21 | ul
22 | - var operations = operationsByAccount[accountList[account]];
23 | - for(operation in operations) {
24 | li #{operations[operation].title} - #{moment(operation.date).format("DD/MM/YYYY")} (#{operations[operation].amount}€)
25 | - }
26 | - }
27 | - } else {
28 | p Aucune nouvelle opération n'a été importée.
29 | - }
30 |
--------------------------------------------------------------------------------
/tests/controllers/bankalerts.coffee:
--------------------------------------------------------------------------------
1 | should = require 'should'
2 | path = require 'path'
3 | fixtures = require 'cozy-fixtures'
4 |
5 | fixtures.setDefaultValues
6 | dirPath: path.resolve __dirname, '../fixtures/'
7 | silent: true
8 | removeBeforeLoad: false # we clean the DB before tests
9 |
10 | helpers = require '../helpers'
11 | client = helpers.getClient()
12 |
13 | describe "Bank Alerts Controller", ->
14 |
15 | before helpers.cleanDBWithRequests
16 | before helpers.startApp
17 | after helpers.stopApp
18 | after helpers.cleanDBWithRequests
19 |
20 | describe "When I add bank alerts", ->
21 |
22 | describe "When I retrieve them", ->
23 | it "The response should be a success"
24 | it "There should be x bank alerts"
25 |
26 | describe "When I retrieve one of them", ->
27 | it "The response should be a success"
28 | it "The alert should have the correct values"
29 |
30 | describe "When I update one of them", ->
31 | it "The response should be a success"
32 | it "The alert in the database should be updated"
33 |
34 | describe "When I destroy one of them", ->
35 | it "The response should be a success"
36 | it "The alert shouldn't be in the database anymore"
37 |
38 | describe "When I retrieve the alerts for a given bank account", ->
39 | it "The response should be a success"
40 | it "There should be x bank alerts"
41 |
42 | describe "When I create a bank alert", ->
43 | it "The response should be a success"
44 | it "It should be in the database"
45 |
46 |
--------------------------------------------------------------------------------
/tests/fixtures/banks-mesinfos.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "docType": "Bank",
4 | "name": "Société Générale",
5 | "uuid": "societegenerale"
6 | },
7 | {
8 | "docType": "Bank",
9 | "name": "La Banque Postale",
10 | "uuid": "bp"
11 | },
12 | {
13 | "docType": "Bank",
14 | "name": "Crédit Coopératif",
15 | "uuid": "creditcooperatif"
16 | }
17 | ]
18 |
--------------------------------------------------------------------------------
/tests/fixtures/weboob/accounts.coffee:
--------------------------------------------------------------------------------
1 | banks = require '../banks-all.json'
2 | output = {}
3 | for bank in banks
4 | output[bank.uuid] = [
5 | {
6 | "accountNumber": "1234567890",
7 | "label": "Compte bancaire",
8 | "balance": "150"
9 | },
10 | {
11 | "accountNumber": "0987654321",
12 | "label": "Livret A",
13 | "balance": "500"
14 | }
15 | ]
16 |
17 |
18 | module.exports = output
--------------------------------------------------------------------------------
/tests/helpers.coffee:
--------------------------------------------------------------------------------
1 | fixtures = require 'cozy-fixtures'
2 | Client = require('request-json').JsonClient
3 |
4 | module.exports = helpers = {}
5 |
6 | # server management
7 | helpers.options = {}
8 | helpers.app = null
9 |
10 | if process.env.COVERAGE
11 | helpers.prefix = '../instrumented/'
12 | else if process.env.USE_JS
13 | helpers.prefix = '../build/'
14 | else
15 | helpers.prefix = '../'
16 |
17 | # server management
18 | helpers.options =
19 | serverHost: process.env.HOST or 'localhost'
20 | serverPort: process.env.PORT or 9875
21 |
22 | # set the configuration for the server
23 | process.env.HOST = helpers.options.serverHost
24 | process.env.PORT = helpers.options.serverPort
25 |
26 | # default client
27 | client = new Client "http://#{helpers.options.serverHost}:#{helpers.options.serverPort}/", jar: true
28 | helpers.getClient = -> return client
29 |
30 | initializeApplication = require "#{helpers.prefix}server"
31 | helpers.startApp = (done) ->
32 | @timeout 15000
33 | initializeApplication (app, server) =>
34 | @app = app
35 | @app.server = server
36 | done()
37 |
38 | helpers.stopApp = (done) ->
39 | @timeout 10000
40 | @app.server.close done
41 |
42 | # database helper
43 | helpers.cleanDB = (done) ->
44 | @timeout 10000
45 | fixtures.resetDatabase callback: done
46 |
47 | helpers.cleanDBWithRequests = (done) ->
48 | @timeout 10000
49 | fixtures.resetDatabase removeAllRequests: true, callback: done
50 |
--------------------------------------------------------------------------------
/tests/mock-weboob.coffee:
--------------------------------------------------------------------------------
1 | if not process.env.NODE_ENV? or process.env.NODE_ENV isnt 'production'
2 |
3 | nock = require 'nock'
4 |
5 | options =
6 | allowUnmocked: true
7 |
8 | #nock.recorder.rec() # enable or not the request recorder
9 | accounts = nock('http://localhost:9101', options)
10 | .persist()
11 | .log(console.log)
12 | .defaultReplyHeaders({'content-type': 'application/json; charset=utf-8'})
13 | .filteringPath(/bank\/[a-z]+\//g, 'bank/societegenerale/')
14 | .filteringRequestBody((path) -> return {"login":"12345","password":"54321"})
15 | .post('/connectors/bank/societegenerale/', {"login":"12345","password":"54321"})
16 | .reply(200, require('./fixtures/weboob/accounts'))
17 |
18 | operations = nock('http://localhost:9101', options)
19 | .persist()
20 | .log(console.log)
21 | .defaultReplyHeaders({'content-type': 'application/json; charset=utf-8'})
22 | .filteringPath(/bank\/[a-z]+\//g, 'bank/societegenerale/')
23 | .filteringRequestBody((path) -> return {"login":"12345","password":"54321"})
24 | .post('/connectors/bank/societegenerale/history', {"login":"12345","password":"54321"})
25 | .reply(200, require('./fixtures/weboob/operations'))
26 |
--------------------------------------------------------------------------------