eboshi 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +28 -0
- data/Rakefile +8 -0
- data/app/assets/config/eboshi_manifest.js +1 -0
- data/app/assets/stylesheets/eboshi/application.css +15 -0
- data/app/controllers/eboshi/adjustments_controller.rb +77 -0
- data/app/controllers/eboshi/application_controller.rb +62 -0
- data/app/controllers/eboshi/assignments_controller.rb +31 -0
- data/app/controllers/eboshi/budgets_controller.rb +43 -0
- data/app/controllers/eboshi/calendar_controller.rb +12 -0
- data/app/controllers/eboshi/clients_controller.rb +41 -0
- data/app/controllers/eboshi/invoices_controller.rb +69 -0
- data/app/controllers/eboshi/line_items_controller.rb +28 -0
- data/app/controllers/eboshi/payments_controller.rb +31 -0
- data/app/controllers/eboshi/user_sessions_controller.rb +25 -0
- data/app/controllers/eboshi/users_controller.rb +41 -0
- data/app/controllers/eboshi/works_controller.rb +83 -0
- data/app/helpers/eboshi/application_helper.rb +15 -0
- data/app/helpers/eboshi/calendar_helper.rb +80 -0
- data/app/helpers/eboshi/shallow_route_helper.rb +68 -0
- data/app/jobs/eboshi/application_job.rb +4 -0
- data/app/mailers/eboshi/application_mailer.rb +6 -0
- data/app/models/eboshi/adjustment.rb +37 -0
- data/app/models/eboshi/application_record.rb +5 -0
- data/app/models/eboshi/assignment.rb +20 -0
- data/app/models/eboshi/budget.rb +33 -0
- data/app/models/eboshi/client.rb +85 -0
- data/app/models/eboshi/invoice.rb +87 -0
- data/app/models/eboshi/line_item.rb +94 -0
- data/app/models/eboshi/payment.rb +20 -0
- data/app/models/eboshi/user.rb +128 -0
- data/app/models/eboshi/user_session.rb +6 -0
- data/app/models/eboshi/work.rb +66 -0
- data/app/views/eboshi/adjustments/_adjustment.html.slim +15 -0
- data/app/views/eboshi/adjustments/_form.html.haml +27 -0
- data/app/views/eboshi/adjustments/edit.html.haml +7 -0
- data/app/views/eboshi/adjustments/new.html.haml +8 -0
- data/app/views/eboshi/assignments/new.html.haml +18 -0
- data/app/views/eboshi/budgets/form.html.haml +22 -0
- data/app/views/eboshi/calendar/index.html.slim +32 -0
- data/app/views/eboshi/clients/_form.html.haml +34 -0
- data/app/views/eboshi/clients/edit.html.haml +4 -0
- data/app/views/eboshi/clients/index.html.haml +19 -0
- data/app/views/eboshi/clients/new.html.haml +4 -0
- data/app/views/eboshi/invoices/_form.html.slim +68 -0
- data/app/views/eboshi/invoices/_full.html.haml +76 -0
- data/app/views/eboshi/invoices/_invoice.html.haml +2 -0
- data/app/views/eboshi/invoices/_mini.html.haml +21 -0
- data/app/views/eboshi/invoices/edit.html.haml +14 -0
- data/app/views/eboshi/invoices/index.html.haml +46 -0
- data/app/views/eboshi/invoices/new.html.haml +11 -0
- data/app/views/eboshi/invoices/show.pdf.haml +118 -0
- data/app/views/eboshi/layouts/application.html.haml +120 -0
- data/app/views/eboshi/payments/_form.html.haml +10 -0
- data/app/views/eboshi/payments/new.html.haml +9 -0
- data/app/views/eboshi/user_sessions/new.html.haml +19 -0
- data/app/views/eboshi/users/_form.html.haml +65 -0
- data/app/views/eboshi/users/edit.html.haml +16 -0
- data/app/views/eboshi/users/index.html.haml +11 -0
- data/app/views/eboshi/users/new.html.haml +13 -0
- data/app/views/eboshi/users/show.html.haml +39 -0
- data/app/views/eboshi/works/_form.html.slim +25 -0
- data/app/views/eboshi/works/_work.html.slim +27 -0
- data/app/views/eboshi/works/edit.html.haml +9 -0
- data/app/views/eboshi/works/new.html.haml +8 -0
- data/app/views/layouts/eboshi/application.html.haml +120 -0
- data/config/routes.rb +35 -0
- data/lib/eboshi/engine.rb +15 -0
- data/lib/eboshi/version.rb +3 -0
- data/lib/eboshi.rb +6 -0
- data/lib/tasks/eboshi_tasks.rake +4 -0
- metadata +253 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 9357ca29543c5d56860ecc82f6adc51d0e35f3a9b75357f03af175209767a4bc
|
4
|
+
data.tar.gz: 9d327178f35dd138e215cf9a4bc3446231db82578809d33513b686ffc3b7e1d3
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f0b4b4d52a165e511aac881851a55dfb3dee206c49877d8914529932cd4a5c9ff3c605edcfdff7f3579b4f4e70ec75a43eb285b42435e7d90937f28243f20a1f
|
7
|
+
data.tar.gz: a21c9d6cf4d5812dcb1ce781912b19813b9df7d72f45cab8347a2633417deaa489b1f7a2e4d1bf24bea39c6248f8aca7eceb01b23670d7fd4b1fdde5c9f823db
|
data/README.md
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# Eboshi
|
2
|
+
Short description and motivation.
|
3
|
+
|
4
|
+
## Usage
|
5
|
+
How to use my plugin.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
gem "eboshi"
|
12
|
+
```
|
13
|
+
|
14
|
+
And then execute:
|
15
|
+
```bash
|
16
|
+
$ bundle
|
17
|
+
```
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
```bash
|
21
|
+
$ gem install eboshi
|
22
|
+
```
|
23
|
+
|
24
|
+
## Contributing
|
25
|
+
Contribution directions go here.
|
26
|
+
|
27
|
+
## License
|
28
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
//= link_directory ../stylesheets/eboshi .css
|
@@ -0,0 +1,15 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
+
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
9
|
+
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
|
10
|
+
* files in this directory. Styles in this file should be added after the last require_* statement.
|
11
|
+
* It is generally better to create a new file per style scope.
|
12
|
+
*
|
13
|
+
*= require_tree .
|
14
|
+
*= require_self
|
15
|
+
*/
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module Eboshi
|
2
|
+
class AdjustmentsController < ApplicationController
|
3
|
+
before_action :get_client
|
4
|
+
before_action :authorized?
|
5
|
+
|
6
|
+
before_action :filter_date, only: [:create, :update]
|
7
|
+
before_action :filter_user, only: [:create, :update]
|
8
|
+
|
9
|
+
def new
|
10
|
+
@adjustment = @client.adjustments.build
|
11
|
+
end
|
12
|
+
|
13
|
+
def create
|
14
|
+
@adjustment = @client.adjustments.build params[:adjustment]
|
15
|
+
if @adjustment.save
|
16
|
+
flash[:notice] = "Adjustment successfully created."
|
17
|
+
redirect_to invoices_path(@client)
|
18
|
+
else
|
19
|
+
render :new
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def edit
|
24
|
+
get_adjustment
|
25
|
+
end
|
26
|
+
|
27
|
+
def update
|
28
|
+
get_adjustment
|
29
|
+
if @adjustment.update params[:adjustment]
|
30
|
+
flash[:notice] = "Successfully updated Adjustment."
|
31
|
+
respond_to do |wants|
|
32
|
+
wants.html { redirect_to invoices_path(@client) }
|
33
|
+
wants.js { head :ok }
|
34
|
+
end
|
35
|
+
else
|
36
|
+
render :edit
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def destroy
|
41
|
+
get_adjustment
|
42
|
+
@adjustment.destroy
|
43
|
+
respond_to do |wants|
|
44
|
+
wants.html { redirect_to invoices_path(@client) }
|
45
|
+
wants.js { render json: @adjustment.invoice_total }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def filter_date
|
52
|
+
a = params[:adjustment]
|
53
|
+
if a.delete(:no_date) == "1"
|
54
|
+
a[:start] = nil
|
55
|
+
a.delete_if { |key, _value| key =~ /^start\(.i\)$/ }
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def filter_user
|
60
|
+
a = params[:adjustment]
|
61
|
+
a[:user_id] = current_user.id if a[:user_id].blank?
|
62
|
+
a[:user_id] = nil if a.delete(:no_user) == "1"
|
63
|
+
end
|
64
|
+
|
65
|
+
def get_adjustment
|
66
|
+
@adjustment ||= Adjustment.find params[:id]
|
67
|
+
end
|
68
|
+
|
69
|
+
def get_client
|
70
|
+
@client = params[:client_id] ? Client.find(params[:client_id]) : get_adjustment.client
|
71
|
+
end
|
72
|
+
|
73
|
+
def authorized?
|
74
|
+
current_user.authorized? @client
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Eboshi
|
2
|
+
class ApplicationController < ActionController::Base
|
3
|
+
helper_method :current_user_session, :current_user
|
4
|
+
|
5
|
+
helper :all
|
6
|
+
include ShallowRouteHelper
|
7
|
+
|
8
|
+
before_action :activate_authlogic
|
9
|
+
before_action :require_user
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def current_user_session
|
14
|
+
@current_user_session ||= UserSession.find
|
15
|
+
end
|
16
|
+
|
17
|
+
def current_user
|
18
|
+
@current_user ||= current_user_session && current_user_session.user
|
19
|
+
end
|
20
|
+
|
21
|
+
def require_admin
|
22
|
+
unless current_user.admin?
|
23
|
+
head :forbidden
|
24
|
+
return false
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def require_user
|
29
|
+
unless current_user
|
30
|
+
store_location
|
31
|
+
flash[:notice] = "You must be logged in to access this page"
|
32
|
+
redirect_to login_path
|
33
|
+
return false
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def require_no_user
|
38
|
+
if current_user
|
39
|
+
flash[:notice] = "You must be logged out to access this page"
|
40
|
+
redirect_to '/'
|
41
|
+
return false
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def store_location
|
46
|
+
session[:return_to] = request.fullpath
|
47
|
+
end
|
48
|
+
|
49
|
+
def redirect_to_back_or_default(default)
|
50
|
+
redirect_to(session[:return_to] || default)
|
51
|
+
session[:return_to] = nil
|
52
|
+
end
|
53
|
+
|
54
|
+
def redirect_to_last_client_or_back_or_default
|
55
|
+
if current_user.last_client
|
56
|
+
redirect_to invoices_path(current_user.last_client)
|
57
|
+
else
|
58
|
+
redirect_to_back_or_default '/'
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Eboshi
|
2
|
+
class AssignmentsController < ApplicationController
|
3
|
+
def new
|
4
|
+
@client = current_user.clients.find params[:client_id]
|
5
|
+
@assignment = @client.assignments.build user: current_user
|
6
|
+
end
|
7
|
+
|
8
|
+
def create
|
9
|
+
@client = current_user.clients.find params[:client_id]
|
10
|
+
user = User.find_by_id(params[:assignment][:user_id]) || User.find_by_email(params[:assignment][:email])
|
11
|
+
if user
|
12
|
+
@client.users << user
|
13
|
+
redirect_to invoices_path(@client), notice: "Successfully created!"
|
14
|
+
else
|
15
|
+
redirect_to({ action: :new }, alert: "A user with that email address does not exist!")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def destroy
|
20
|
+
@assignment = Assignment.find params[:id]
|
21
|
+
raise ActiveRecord::RecordNotFound unless current_user.clients.include? @assignment.client
|
22
|
+
@assignment.destroy
|
23
|
+
if @assignment.user == current_user
|
24
|
+
redirect_to "/"
|
25
|
+
else
|
26
|
+
redirect_back fallback_location: "/"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Eboshi
|
2
|
+
class BudgetsController < ApplicationController
|
3
|
+
before_action :get_client, :authorized?
|
4
|
+
|
5
|
+
def new
|
6
|
+
@budget = @client.budgets.build
|
7
|
+
render :form
|
8
|
+
end
|
9
|
+
|
10
|
+
def create
|
11
|
+
@budget = @client.budgets.build(params[:budget])
|
12
|
+
@budget.save!
|
13
|
+
redirect_to [@client, :invoices], notice: "Budget created"
|
14
|
+
end
|
15
|
+
|
16
|
+
def edit
|
17
|
+
@budget = @client.budgets.find(params[:id])
|
18
|
+
render :form
|
19
|
+
end
|
20
|
+
|
21
|
+
def update
|
22
|
+
@budget = @client.budgets.find(params[:id])
|
23
|
+
@budget.update!(params[:budget])
|
24
|
+
redirect_to [@client, :invoices], notice: "Budget updated"
|
25
|
+
end
|
26
|
+
|
27
|
+
def destroy
|
28
|
+
@client.budgets.destroy(params[:id])
|
29
|
+
redirect_to [@client, :invoices], notice: "Budget destroy"
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def get_client
|
35
|
+
@client = Client.find(params[:client_id])
|
36
|
+
end
|
37
|
+
|
38
|
+
def authorized?
|
39
|
+
current_user.authorized?(@client)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Eboshi
|
2
|
+
class ClientsController < ApplicationController
|
3
|
+
def index
|
4
|
+
@clients = current_user.clients
|
5
|
+
end
|
6
|
+
|
7
|
+
def new
|
8
|
+
@client = Client.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def edit
|
12
|
+
@client = current_user.clients.find(params[:id])
|
13
|
+
end
|
14
|
+
|
15
|
+
def create
|
16
|
+
@client = Client.new(params[:client])
|
17
|
+
if @client.save
|
18
|
+
@client.users << current_user
|
19
|
+
redirect_to clients_path, notice: "Client successfully created."
|
20
|
+
else
|
21
|
+
render :new
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def update
|
26
|
+
@client = current_user.clients.find(params[:id])
|
27
|
+
if @client.update(params[:client])
|
28
|
+
redirect_to clients_path, notice: "Client successfully updated."
|
29
|
+
else
|
30
|
+
render :edit
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def destroy
|
35
|
+
@client = current_user.clients.find params[:id]
|
36
|
+
@client.destroy
|
37
|
+
redirect_to clients_path
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module Eboshi
|
2
|
+
class InvoicesController < ApplicationController
|
3
|
+
before_action :get_client, :authorized?
|
4
|
+
|
5
|
+
def index
|
6
|
+
@invoices = @client.invoices_with_unbilled
|
7
|
+
current_user.update_attribute(:last_client, @client)
|
8
|
+
respond_to do |wants|
|
9
|
+
wants.html
|
10
|
+
wants.js { render @client.invoices.paid }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def show
|
15
|
+
@invoice = @client.invoices.find(params[:id])
|
16
|
+
respond_to do |wants|
|
17
|
+
wants.html { render partial: params.fetch(:type, "full"), locals: { invoice: @invoice } }
|
18
|
+
wants.pdf do
|
19
|
+
filename = "#{current_user.business_name_or_name.parameterize}_invoice-\##{@invoice.id}.pdf"
|
20
|
+
render pdf: filename, show_as_html: params[:debug].present?
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def new
|
26
|
+
@invoice = @client.build_invoice_from_unbilled(params[:line_item_ids])
|
27
|
+
end
|
28
|
+
|
29
|
+
def create
|
30
|
+
@invoice = @client.invoices.build
|
31
|
+
@invoice.attributes = params[:invoice]
|
32
|
+
if @invoice.save
|
33
|
+
redirect_to invoices_path(@client), notice: "Invoice successfully created."
|
34
|
+
else
|
35
|
+
render :new
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def edit
|
40
|
+
@invoice = @client.invoices.find(params[:id])
|
41
|
+
end
|
42
|
+
|
43
|
+
def update
|
44
|
+
@invoice = @client.invoices.find(params[:id])
|
45
|
+
if @invoice.update(params[:invoice])
|
46
|
+
redirect_to invoices_path(@client), notice: "Invoice successfully updated."
|
47
|
+
else
|
48
|
+
render :edit
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def destroy
|
53
|
+
@invoice = @client.invoices.find(params[:id])
|
54
|
+
@invoice.destroy
|
55
|
+
redirect_to invoices_path(@client)
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def get_client
|
61
|
+
@client = Client.includes(:assignments).find(params[:client_id])
|
62
|
+
end
|
63
|
+
|
64
|
+
def authorized?
|
65
|
+
current_user.authorized?(@client)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Eboshi
|
2
|
+
class LineItemsController < ApplicationController
|
3
|
+
before_action :get_client
|
4
|
+
before_action :authorized?
|
5
|
+
|
6
|
+
def update
|
7
|
+
if line_item.timestamp < params[:line_item][:timestamp].to_i
|
8
|
+
line_item.update(params[:line_item])
|
9
|
+
end
|
10
|
+
render json: {}, status: :ok
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def line_item
|
16
|
+
@line_item ||= LineItem.find(params[:id])
|
17
|
+
end
|
18
|
+
|
19
|
+
def get_client
|
20
|
+
@client ||= (line_item.try(:client) || Client.find(params[:client_id]))
|
21
|
+
end
|
22
|
+
|
23
|
+
def authorized?
|
24
|
+
current_user.authorized? @client
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Eboshi
|
2
|
+
class PaymentsController < ApplicationController
|
3
|
+
before_action :get_invoice
|
4
|
+
before_action :authorized?
|
5
|
+
|
6
|
+
def new
|
7
|
+
@payment = @invoice.payments.build(params[:payment] || { total: @invoice.balance })
|
8
|
+
end
|
9
|
+
|
10
|
+
def create
|
11
|
+
@payment = @invoice.payments.build params[:payment]
|
12
|
+
if @payment.save
|
13
|
+
flash[:notice] = "Payment successfully created."
|
14
|
+
redirect_to invoices_path(@invoice.client)
|
15
|
+
else
|
16
|
+
render :new
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
protected
|
21
|
+
|
22
|
+
def get_invoice
|
23
|
+
@invoice = Invoice.find params[:invoice_id]
|
24
|
+
end
|
25
|
+
|
26
|
+
def authorized?
|
27
|
+
current_user.authorized? @invoice
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Eboshi
|
2
|
+
class UserSessionsController < ApplicationController
|
3
|
+
before_action :require_no_user, only: [:new, :create]
|
4
|
+
before_action :require_user, only: :destroy
|
5
|
+
|
6
|
+
def new
|
7
|
+
@user_session = UserSession.new
|
8
|
+
end
|
9
|
+
|
10
|
+
def create
|
11
|
+
@user_session = UserSession.new(params[:user_session].to_h)
|
12
|
+
if @user_session.save
|
13
|
+
flash[:notice] = "Login successful!"
|
14
|
+
redirect_to_last_client_or_back_or_default
|
15
|
+
else
|
16
|
+
render "new"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def destroy
|
21
|
+
current_user_session.destroy
|
22
|
+
redirect_to login_path, notice: "Logout successful!"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Eboshi
|
2
|
+
class UsersController < ApplicationController
|
3
|
+
def index
|
4
|
+
require_admin
|
5
|
+
@users = User.all
|
6
|
+
end
|
7
|
+
|
8
|
+
def show
|
9
|
+
@user = User.find params[:id]
|
10
|
+
end
|
11
|
+
|
12
|
+
def new
|
13
|
+
@user = User.new
|
14
|
+
end
|
15
|
+
|
16
|
+
def create
|
17
|
+
@user = User.new params[:user]
|
18
|
+
if @user.save
|
19
|
+
flash[:notice] = "Account registered!"
|
20
|
+
redirect_to @user
|
21
|
+
else
|
22
|
+
render :new
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def edit
|
27
|
+
@user = User.find params[:id]
|
28
|
+
end
|
29
|
+
|
30
|
+
def update
|
31
|
+
@user = User.find params[:id]
|
32
|
+
if @user.update params[:user]
|
33
|
+
flash[:notice] = "Account updated!"
|
34
|
+
redirect_to_last_client_or_back_or_default
|
35
|
+
else
|
36
|
+
render :edit
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module Eboshi
|
2
|
+
class WorksController < ApplicationController
|
3
|
+
before_action :get_client
|
4
|
+
before_action :authorized?
|
5
|
+
|
6
|
+
def new
|
7
|
+
@work = @client.works.build user: current_user
|
8
|
+
end
|
9
|
+
|
10
|
+
def create
|
11
|
+
@work = @client.works.build params[:work].merge(user: current_user)
|
12
|
+
if @work.save
|
13
|
+
flash[:notice] = "Successfully created Work."
|
14
|
+
redirect_to invoices_path(@client)
|
15
|
+
else
|
16
|
+
render :new
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def edit
|
21
|
+
get_work
|
22
|
+
end
|
23
|
+
|
24
|
+
def update
|
25
|
+
get_work
|
26
|
+
if @work.update params[:work]
|
27
|
+
flash[:notice] = "Successfully updated Work."
|
28
|
+
respond_to do |wants|
|
29
|
+
wants.html { redirect_to invoices_path(@client) }
|
30
|
+
wants.js { head :ok }
|
31
|
+
end
|
32
|
+
else
|
33
|
+
render :edit
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def destroy
|
38
|
+
get_work
|
39
|
+
@work.destroy
|
40
|
+
invoice = @work.invoice || @client.build_invoice_from_unbilled
|
41
|
+
redirect_to invoices_path(@client), status: :see_other
|
42
|
+
end
|
43
|
+
|
44
|
+
def clock_in
|
45
|
+
@work = @client.clock_in current_user
|
46
|
+
redirect_to invoices_path(@client), status: :see_other
|
47
|
+
end
|
48
|
+
|
49
|
+
def clock_out
|
50
|
+
get_work
|
51
|
+
@work.clock_out
|
52
|
+
redirect_to invoices_path(@client), status: :see_other
|
53
|
+
end
|
54
|
+
|
55
|
+
def merge
|
56
|
+
@work = Work.merge_from_ids params[:line_item_ids]
|
57
|
+
@invoice = @work.invoice || @client.build_invoice_from_unbilled
|
58
|
+
render @work
|
59
|
+
end
|
60
|
+
|
61
|
+
def convert
|
62
|
+
get_work
|
63
|
+
@work.to_adjustment!
|
64
|
+
flash[:notice] = "Time item converted to adjustment"
|
65
|
+
redirect_to invoices_path(@client)
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def get_work
|
71
|
+
@work ||= Work.find params[:id]
|
72
|
+
end
|
73
|
+
|
74
|
+
def get_client
|
75
|
+
@client = params[:client_id] ? Client.find(params[:client_id]) : get_work.client
|
76
|
+
end
|
77
|
+
|
78
|
+
def authorized?
|
79
|
+
current_user.authorized? @client
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Eboshi
|
2
|
+
module ApplicationHelper
|
3
|
+
def number_to_per_hour(value)
|
4
|
+
return nil unless value
|
5
|
+
precision = (value.round == value ? 0 : 2)
|
6
|
+
number_to_currency(value, precision: precision) + "/hr"
|
7
|
+
end
|
8
|
+
|
9
|
+
def currency_or_empty(value)
|
10
|
+
return '--' unless value.nonzero?
|
11
|
+
number_to_currency value
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|