eboshi 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
|