dorsale 3.14.11 → 3.19.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 +4 -4
- data/CHANGELOG.md +21 -0
- data/app/assets/javascripts/dorsale/dependencies.coffee +1 -1
- data/app/assets/javascripts/dorsale/engines/billing_machine.coffee.erb +14 -0
- data/app/assets/stylesheets/dorsale/engines/billing_machine.sass +4 -1
- data/app/controllers/dorsale/billing_machine/invoices_controller.rb +14 -9
- data/app/controllers/dorsale/billing_machine/quotations_controller.rb +14 -9
- data/app/controllers/dorsale/expense_gun/expenses_controller.rb +24 -34
- data/app/controllers/dorsale/flyboy/task_comments_controller.rb +2 -2
- data/app/filters/dorsale/expense_gun/small_data/filter_for_expenses.rb +5 -2
- data/app/helpers/dorsale/expense_gun/application_helper.rb +1 -1
- data/app/mailers/dorsale/flyboy/task_mailer.rb +2 -2
- data/app/models/dorsale/billing_machine/invoice.rb +2 -4
- data/app/models/dorsale/billing_machine/invoice_line.rb +1 -1
- data/app/models/dorsale/billing_machine/quotation.rb +1 -1
- data/app/models/dorsale/billing_machine/quotation_line.rb +1 -1
- data/app/models/dorsale/customer_vault/corporation.rb +11 -2
- data/app/models/dorsale/customer_vault/individual.rb +4 -2
- data/app/models/dorsale/customer_vault/person.rb +1 -1
- data/app/models/dorsale/expense_gun/expense.rb +7 -34
- data/app/policies/dorsale/expense_gun/expense_policy_helper.rb +9 -20
- data/app/services/dorsale/flyboy/task/snoozer.rb +1 -1
- data/app/sorters/dorsale/expense_gun/expenses_sorter.rb +8 -0
- data/app/uploaders/dorsale/image_uploader.rb +1 -1
- data/app/uploaders/dorsale/pdf_uploader.rb +1 -1
- data/app/views/dorsale/billing_machine/commons/_form.html.slim +2 -1
- data/app/views/dorsale/billing_machine/commons/_line_fields.html.slim +4 -0
- data/app/views/dorsale/expense_gun/expenses/_filters.html.slim +8 -0
- data/app/views/dorsale/expense_gun/expenses/_form.html.slim +3 -4
- data/app/views/dorsale/expense_gun/expenses/_list.html.slim +62 -20
- data/app/views/dorsale/expense_gun/expenses/_show_actions.html.slim +2 -12
- data/app/views/dorsale/expense_gun/expenses/_state_actions.html.slim +8 -0
- data/app/views/dorsale/expense_gun/expenses/index.html.slim +1 -1
- data/app/views/dorsale/flyboy/task_mailer/new_task.html.slim +1 -1
- data/app/views/dorsale/flyboy/task_mailer/term_email.html.slim +1 -1
- data/config/locales/billing_machine.fr.yml +1 -0
- data/config/locales/expense_gun.fr.yml +12 -10
- data/config/routes.rb +3 -4
- data/db/migrate/20210202100529_billing_machine_add_positions.rb +6 -0
- data/db/migrate/20210311131928_billing_machine_add_missing_unique_indexes.rb +6 -0
- data/db/migrate/20210506070548_expenses_change_states.rb +7 -0
- data/features/expense_gun_expenses.feature +0 -30
- data/features/step_definitions/customer_vault_people_steps.rb +1 -1
- data/features/step_definitions/expense_gun_expenses_steps.rb +1 -16
- data/lib/dorsale/engine.rb +0 -1
- data/lib/dorsale/version.rb +1 -1
- data/spec/controllers/dorsale/expense_gun/expenses_controller_spec.rb +66 -17
- data/spec/controllers/dorsale/flyboy/task_comments_controller_spec.rb +2 -2
- data/spec/factories/customer_vault_individuals.rb +13 -13
- data/spec/factories/expense_gun_categories.rb +3 -3
- data/spec/factories/expense_gun_expense_lines.rb +7 -7
- data/spec/factories/expense_gun_expenses.rb +3 -3
- data/spec/models/dorsale/expense_gun/expense_spec.rb +1 -125
- data/spec/pdfs/dorsale/billing_machine/invoice_multiple_vat_pdf_spec.rb +1 -1
- data/spec/pdfs/dorsale/billing_machine/invoice_single_vat_pdf_spec.rb +1 -1
- data/spec/pdfs/dorsale/billing_machine/quotation_multiple_vat_pdf_spec.rb +1 -1
- data/spec/pdfs/dorsale/billing_machine/quotation_single_vat_pdf_spec.rb +1 -1
- data/spec/rails_helper.rb +0 -1
- data/spec/routing/dorsale/expense_gun/expenses_routing_spec.rb +9 -14
- data/spec/services/dorsale/expense_gun/expense/copy_spec.rb +2 -2
- data/spec/sorters/dorsale/expense_gun/expenses_sorter_spec.rb +20 -0
- metadata +10 -35
- data/app/assets/javascripts/url.min.js +0 -1
- data/app/models/dorsale/customer_vault/corporation_data.rb +0 -10
- data/app/models/dorsale/customer_vault/individual_data.rb +0 -3
- data/app/models/dorsale/customer_vault/person_data.rb +0 -17
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 86af52038f7c9cfc24b17dbcf5229608296a7152f2e4565d3fd415d2dd88ce87
|
|
4
|
+
data.tar.gz: cd7c59ee287a99e1cac77068550f7a0d64451e164cb2e10855fd1dd2d9b5fb12
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 20bc75f4aa3210835d0b8ce2c6e7bb0b43ab7b2a496555df02fc1b6ef9983af553ad586170a5d67c729630905706d6ecea52340811781707520f71a47211e73a
|
|
7
|
+
data.tar.gz: 33809971e1f21d88f6a6d6d110a062cb94b18391dee6c667afa28adc9c7d9690d99806b783f02c8a0f427771e7d9f473b7a693cbba069f339005f5631426fa6d
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
## Next version
|
|
4
4
|
|
|
5
|
+
# 3.19.0
|
|
6
|
+
- Change expenses state machine
|
|
7
|
+
- Change expenses list view
|
|
8
|
+
|
|
9
|
+
# 3.18.0
|
|
10
|
+
- Change uploaders `extension_whitelist` to `extension_allowlist`
|
|
11
|
+
- Rails 6.1 compatibility
|
|
12
|
+
|
|
13
|
+
## 3.17.0
|
|
14
|
+
- Refactor CV models using stores
|
|
15
|
+
- Fix redirect after task comment create
|
|
16
|
+
- Add missing unique indexes on invoices and quotations
|
|
17
|
+
|
|
18
|
+
## 3.16.0
|
|
19
|
+
- Allow to reorder BM lines (require Sorting.js + reimport migrations)
|
|
20
|
+
- Remove unused url.js
|
|
21
|
+
|
|
22
|
+
## 3.15.0
|
|
23
|
+
- Fix Ruby 2.7 warnings
|
|
24
|
+
- Faker 2
|
|
25
|
+
|
|
5
26
|
## 3.14.11
|
|
6
27
|
- Fix BM missing PDFs
|
|
7
28
|
|
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
//= require bootstrap
|
|
5
5
|
//= require cocoon
|
|
6
6
|
//= require accounting
|
|
7
|
-
//= require url.min
|
|
8
7
|
//= require select2
|
|
9
8
|
//= require select2_locale_fr
|
|
10
9
|
//= require bootstrap-datepicker/core
|
|
11
10
|
//= require bootstrap-datepicker/locales/bootstrap-datepicker.fr
|
|
12
11
|
//= require Chart.bundle
|
|
13
12
|
//= require chartkick
|
|
13
|
+
//= require Sortable
|
|
14
14
|
//= require agilibox/all
|
|
@@ -77,6 +77,10 @@ BillingMachine.formatInputs = ->
|
|
|
77
77
|
formatted_number = BillingMachine.num2str BillingMachine.str2num $(this).val()
|
|
78
78
|
$(this).val formatted_number
|
|
79
79
|
|
|
80
|
+
BillingMachine.updatePositions = ->
|
|
81
|
+
i = 0
|
|
82
|
+
$("#billing_machine-form input[name*=position]").map -> this.value = (i = i + 1)
|
|
83
|
+
|
|
80
84
|
# Empty number inputs on focus if value is 0
|
|
81
85
|
$(document).on "focus", "#billing_machine-form input.number", ->
|
|
82
86
|
$(this).val("") if BillingMachine.str2num($(this).val()) == 0
|
|
@@ -96,6 +100,7 @@ $(document).on "click", "#billing_machine-form a.delete", (e) ->
|
|
|
96
100
|
$(document).on "turbolinks:load cocoon:after-insert", ->
|
|
97
101
|
BillingMachine.formatInputs()
|
|
98
102
|
BillingMachine.updateTotals()
|
|
103
|
+
BillingMachine.updatePositions()
|
|
99
104
|
|
|
100
105
|
# Fix Cocoon bug
|
|
101
106
|
$("#billing_machine-form .line textarea").map ->
|
|
@@ -106,3 +111,12 @@ $(document).on "keyup", "#billing_machine-form input.number", ->
|
|
|
106
111
|
|
|
107
112
|
$(document).on "blur", "#billing_machine-form input.number", ->
|
|
108
113
|
BillingMachine.formatInputs()
|
|
114
|
+
|
|
115
|
+
$(document).on "turbolinks:load", ->
|
|
116
|
+
$("#billing_machine-form tbody").map ->
|
|
117
|
+
container = this
|
|
118
|
+
|
|
119
|
+
new Sortable container,
|
|
120
|
+
handle: ".handle"
|
|
121
|
+
animation: 150
|
|
122
|
+
onSort: -> BillingMachine.updatePositions()
|
|
@@ -157,15 +157,20 @@ class Dorsale::BillingMachine::InvoicesController < ::Dorsale::BillingMachine::A
|
|
|
157
157
|
:advance,
|
|
158
158
|
:due_date,
|
|
159
159
|
:comments,
|
|
160
|
-
:lines_attributes =>
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
160
|
+
:lines_attributes => line_permitted_params,
|
|
161
|
+
]
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
def line_permitted_params
|
|
165
|
+
[
|
|
166
|
+
:_destroy,
|
|
167
|
+
:id,
|
|
168
|
+
:label,
|
|
169
|
+
:quantity,
|
|
170
|
+
:unit,
|
|
171
|
+
:unit_price,
|
|
172
|
+
:vat_rate,
|
|
173
|
+
:position,
|
|
169
174
|
]
|
|
170
175
|
end
|
|
171
176
|
|
|
@@ -165,15 +165,20 @@ class Dorsale::BillingMachine::QuotationsController < ::Dorsale::BillingMachine:
|
|
|
165
165
|
:comments,
|
|
166
166
|
:vat_rate,
|
|
167
167
|
:commercial_discount,
|
|
168
|
-
:lines_attributes =>
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
168
|
+
:lines_attributes => line_permitted_params,
|
|
169
|
+
]
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def line_permitted_params
|
|
173
|
+
[
|
|
174
|
+
:_destroy,
|
|
175
|
+
:id,
|
|
176
|
+
:label,
|
|
177
|
+
:quantity,
|
|
178
|
+
:unit,
|
|
179
|
+
:unit_price,
|
|
180
|
+
:vat_rate,
|
|
181
|
+
:position,
|
|
177
182
|
]
|
|
178
183
|
end
|
|
179
184
|
|
|
@@ -1,15 +1,5 @@
|
|
|
1
1
|
class Dorsale::ExpenseGun::ExpensesController < Dorsale::ExpenseGun::ApplicationController
|
|
2
|
-
before_action :set_expense
|
|
3
|
-
:show,
|
|
4
|
-
:edit,
|
|
5
|
-
:update,
|
|
6
|
-
:copy,
|
|
7
|
-
:submit,
|
|
8
|
-
:accept,
|
|
9
|
-
:refuse,
|
|
10
|
-
:cancel,
|
|
11
|
-
]
|
|
12
|
-
|
|
2
|
+
before_action :set_expense
|
|
13
3
|
before_action :set_filters_variables, only: [:index]
|
|
14
4
|
|
|
15
5
|
def index
|
|
@@ -18,7 +8,10 @@ class Dorsale::ExpenseGun::ExpensesController < Dorsale::ExpenseGun::Application
|
|
|
18
8
|
@expenses ||= scope.all.preload(:user, :expense_lines)
|
|
19
9
|
@filters ||= Dorsale::ExpenseGun::SmallData::FilterForExpenses.new(filters_jar)
|
|
20
10
|
@expenses = @filters.apply(@expenses)
|
|
11
|
+
@expenses = Dorsale::ExpenseGun::ExpensesSorter.call(@expenses, params[:sort] ||= "-created_at")
|
|
21
12
|
@expenses = @expenses.page(params[:page]).per(25)
|
|
13
|
+
|
|
14
|
+
@total_payback = @expenses.limit(nil).to_a.sum(&:total_employee_payback)
|
|
22
15
|
end
|
|
23
16
|
|
|
24
17
|
def new
|
|
@@ -34,7 +27,7 @@ class Dorsale::ExpenseGun::ExpensesController < Dorsale::ExpenseGun::Application
|
|
|
34
27
|
@expense ||= scope.new(expense_params_for_create)
|
|
35
28
|
|
|
36
29
|
if @expense.save
|
|
37
|
-
|
|
30
|
+
set_succress_flash
|
|
38
31
|
redirect_to dorsale.expense_gun_expense_path(@expense)
|
|
39
32
|
else
|
|
40
33
|
render :new
|
|
@@ -55,7 +48,7 @@ class Dorsale::ExpenseGun::ExpensesController < Dorsale::ExpenseGun::Application
|
|
|
55
48
|
authorize @expense, :update?
|
|
56
49
|
|
|
57
50
|
if @expense.update(expense_params_for_update)
|
|
58
|
-
|
|
51
|
+
set_succress_flash
|
|
59
52
|
redirect_to dorsale.expense_gun_expense_path(@expense)
|
|
60
53
|
else
|
|
61
54
|
render :edit
|
|
@@ -71,50 +64,47 @@ class Dorsale::ExpenseGun::ExpensesController < Dorsale::ExpenseGun::Application
|
|
|
71
64
|
render :new
|
|
72
65
|
end
|
|
73
66
|
|
|
74
|
-
def
|
|
75
|
-
authorize @expense, :
|
|
67
|
+
def go_to_pending
|
|
68
|
+
authorize @expense, :go_to_pending?
|
|
76
69
|
|
|
77
|
-
@expense.
|
|
78
|
-
|
|
70
|
+
@expense.update!(state: "pending")
|
|
71
|
+
set_succress_flash
|
|
79
72
|
redirect_to dorsale.expense_gun_expenses_path
|
|
80
73
|
end
|
|
81
74
|
|
|
82
|
-
def
|
|
83
|
-
authorize @expense, :
|
|
84
|
-
|
|
85
|
-
@expense.go_to_accepted!
|
|
86
|
-
flash[:success] = t("expense_gun.expense.messages.accepted")
|
|
87
|
-
redirect_to dorsale.expense_gun_expense_path(@expense)
|
|
88
|
-
end
|
|
75
|
+
def go_to_paid
|
|
76
|
+
authorize @expense, :go_to_paid?
|
|
89
77
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
@expense.go_to_refused!
|
|
94
|
-
flash[:success] = t("expense_gun.expense.messages.refused")
|
|
78
|
+
@expense.update!(state: "paid")
|
|
79
|
+
set_succress_flash
|
|
95
80
|
redirect_to dorsale.expense_gun_expenses_path
|
|
96
81
|
end
|
|
97
82
|
|
|
98
|
-
def
|
|
99
|
-
authorize @expense, :
|
|
83
|
+
def go_to_canceled
|
|
84
|
+
authorize @expense, :go_to_canceled?
|
|
100
85
|
|
|
101
|
-
@expense.
|
|
102
|
-
|
|
86
|
+
@expense.update!(state: "canceled")
|
|
87
|
+
set_succress_flash
|
|
103
88
|
redirect_to dorsale.expense_gun_expenses_path
|
|
104
89
|
end
|
|
105
90
|
|
|
106
91
|
private
|
|
107
92
|
|
|
93
|
+
def set_succress_flash
|
|
94
|
+
flash.notice = t("expense_gun.expense.messages.#{action_name}_ok")
|
|
95
|
+
end
|
|
96
|
+
|
|
108
97
|
def model
|
|
109
98
|
::Dorsale::ExpenseGun::Expense
|
|
110
99
|
end
|
|
111
100
|
|
|
112
101
|
def set_expense
|
|
113
|
-
@expense = scope.find(params[:id])
|
|
102
|
+
@expense = scope.find(params[:id]) if params.key?(:id)
|
|
114
103
|
end
|
|
115
104
|
|
|
116
105
|
def permitted_params
|
|
117
106
|
[
|
|
107
|
+
:state,
|
|
118
108
|
:name,
|
|
119
109
|
:date,
|
|
120
110
|
:expense_lines_attributes => [
|
|
@@ -19,9 +19,9 @@ class Dorsale::Flyboy::TaskCommentsController < ::Dorsale::Flyboy::ApplicationCo
|
|
|
19
19
|
|
|
20
20
|
def back_url
|
|
21
21
|
task_path = flyboy_task_path(@task)
|
|
22
|
-
back_url = super
|
|
22
|
+
back_url = super.to_s
|
|
23
23
|
|
|
24
|
-
if back_url.
|
|
24
|
+
if back_url == task_path || back_url.start_with?(task_path + "?")
|
|
25
25
|
back_url
|
|
26
26
|
else
|
|
27
27
|
task_path
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
class Dorsale::ExpenseGun::SmallData::FilterForExpenses < ::Agilibox::SmallData::Filter
|
|
2
2
|
STRATEGIES = {
|
|
3
|
-
"expense_state"
|
|
4
|
-
"expense_user_id"
|
|
3
|
+
"expense_state" => ::Agilibox::SmallData::FilterStrategyByKeyValue.new("state"),
|
|
4
|
+
"expense_user_id" => ::Agilibox::SmallData::FilterStrategyByKeyValue.new("user_id"),
|
|
5
|
+
"expense_time_period" => ::Agilibox::SmallData::FilterStrategyByDatePeriod.new(:date),
|
|
6
|
+
"expense_date_begin" => ::Agilibox::SmallData::FilterStrategyByDateBegin.new(:date),
|
|
7
|
+
"expense_date_end" => ::Agilibox::SmallData::FilterStrategyByDateEnd.new(:date),
|
|
5
8
|
}
|
|
6
9
|
end
|
|
@@ -11,7 +11,7 @@ class Dorsale::Flyboy::TaskMailer < ::Dorsale::ApplicationMailer
|
|
|
11
11
|
|
|
12
12
|
mail(
|
|
13
13
|
:to => task.owner.email,
|
|
14
|
-
:subject => t("task_mailer.new_task.subject",
|
|
14
|
+
:subject => t("task_mailer.new_task.subject", **@locals),
|
|
15
15
|
)
|
|
16
16
|
end
|
|
17
17
|
|
|
@@ -26,7 +26,7 @@ class Dorsale::Flyboy::TaskMailer < ::Dorsale::ApplicationMailer
|
|
|
26
26
|
|
|
27
27
|
mail(
|
|
28
28
|
:to => task.owner.email,
|
|
29
|
-
:subject => t("task_mailer.term_email.subject",
|
|
29
|
+
:subject => t("task_mailer.term_email.subject", **@locals),
|
|
30
30
|
)
|
|
31
31
|
end
|
|
32
32
|
end
|
|
@@ -55,7 +55,7 @@ class Dorsale::BillingMachine::Invoice < ::Dorsale::ApplicationRecord
|
|
|
55
55
|
lines.each(&:update_total)
|
|
56
56
|
apply_vat_rate_to_lines
|
|
57
57
|
|
|
58
|
-
lines_sum = lines.
|
|
58
|
+
lines_sum = lines.sum(&:total).round(2)
|
|
59
59
|
|
|
60
60
|
self.total_excluding_taxes = lines_sum - commercial_discount
|
|
61
61
|
|
|
@@ -109,9 +109,7 @@ class Dorsale::BillingMachine::Invoice < ::Dorsale::ApplicationRecord
|
|
|
109
109
|
def payment_status
|
|
110
110
|
if paid?
|
|
111
111
|
:paid
|
|
112
|
-
elsif due_date.nil?
|
|
113
|
-
:on_alert
|
|
114
|
-
elsif Date.current >= due_date + 15
|
|
112
|
+
elsif due_date.nil? || Date.current >= due_date + 15
|
|
115
113
|
:on_alert
|
|
116
114
|
elsif Date.current > due_date
|
|
117
115
|
:late
|
|
@@ -61,7 +61,7 @@ class Dorsale::BillingMachine::Quotation < ::Dorsale::ApplicationRecord
|
|
|
61
61
|
lines.each(&:update_total)
|
|
62
62
|
apply_vat_rate_to_lines
|
|
63
63
|
|
|
64
|
-
lines_sum = lines.
|
|
64
|
+
lines_sum = lines.sum(&:total)
|
|
65
65
|
|
|
66
66
|
self.total_excluding_taxes = lines_sum - commercial_discount
|
|
67
67
|
|
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
class Dorsale::CustomerVault::Corporation < Dorsale::CustomerVault::Person
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
data_attributes = %i(
|
|
3
|
+
legal_form
|
|
4
|
+
immatriculation_number
|
|
5
|
+
naf
|
|
6
|
+
european_union_vat_number
|
|
7
|
+
societe_com
|
|
8
|
+
capital
|
|
9
|
+
revenue
|
|
10
|
+
number_of_employees
|
|
11
|
+
)
|
|
12
|
+
store :data, accessors: data_attributes, coder: JSON
|
|
4
13
|
|
|
5
14
|
validates :corporation_name, presence: true
|
|
6
15
|
has_many :individuals, dependent: :nullify
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
class Dorsale::CustomerVault::Individual < Dorsale::CustomerVault::Person
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
data_attributes = %i(
|
|
3
|
+
title
|
|
4
|
+
)
|
|
5
|
+
store :data, accessors: data_attributes, coder: JSON
|
|
4
6
|
|
|
5
7
|
validates :first_name, presence: true
|
|
6
8
|
validates :last_name, presence: true
|
|
@@ -10,7 +10,7 @@ class Dorsale::CustomerVault::Person < ::Dorsale::ApplicationRecord
|
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
def verify_class
|
|
13
|
-
if
|
|
13
|
+
if instance_of?(Dorsale::CustomerVault::Person)
|
|
14
14
|
# self.abstract_class does not work with STI
|
|
15
15
|
raise "Cannot directly instantiate Person class"
|
|
16
16
|
end
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
class Dorsale::ExpenseGun::Expense < ::Dorsale::ApplicationRecord
|
|
2
2
|
self.table_name = "dorsale_expense_gun_expenses"
|
|
3
|
-
|
|
3
|
+
|
|
4
|
+
STATES = %w(draft pending paid canceled)
|
|
4
5
|
|
|
5
6
|
has_many :expense_lines, inverse_of: :expense, dependent: :destroy, class_name: "Dorsale::ExpenseGun::ExpenseLine"
|
|
6
7
|
|
|
@@ -12,6 +13,7 @@ class Dorsale::ExpenseGun::Expense < ::Dorsale::ApplicationRecord
|
|
|
12
13
|
belongs_to :user
|
|
13
14
|
validates :user, presence: true
|
|
14
15
|
|
|
16
|
+
validates :state, presence: true, inclusion: {in: STATES}
|
|
15
17
|
validates :name, presence: true
|
|
16
18
|
validates :date, presence: true
|
|
17
19
|
|
|
@@ -24,51 +26,22 @@ class Dorsale::ExpenseGun::Expense < ::Dorsale::ApplicationRecord
|
|
|
24
26
|
}
|
|
25
27
|
|
|
26
28
|
def assign_default_values
|
|
29
|
+
assign_default :state, STATES.first
|
|
27
30
|
assign_default :date, Date.current
|
|
28
31
|
end
|
|
29
32
|
|
|
30
33
|
# Sum of line amounts
|
|
31
34
|
def total_all_taxes
|
|
32
|
-
expense_lines.
|
|
35
|
+
expense_lines.sum(&:total_all_taxes)
|
|
33
36
|
end
|
|
34
37
|
|
|
35
38
|
# Sum of line emplee payback
|
|
36
39
|
def total_employee_payback
|
|
37
|
-
expense_lines.
|
|
40
|
+
expense_lines.sum(&:employee_payback)
|
|
38
41
|
end
|
|
39
42
|
|
|
40
43
|
# Sum of deductible deductible vat
|
|
41
44
|
def total_vat_deductible
|
|
42
|
-
expense_lines.
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
delegate :current_state, to: :aasm
|
|
46
|
-
|
|
47
|
-
aasm(column: :state, whiny_transitions: false) do
|
|
48
|
-
state :draft, initial: true
|
|
49
|
-
state :submitted
|
|
50
|
-
state :accepted
|
|
51
|
-
state :refused
|
|
52
|
-
state :canceled
|
|
53
|
-
|
|
54
|
-
event :go_to_submitted do
|
|
55
|
-
transitions from: :draft, to: :submitted
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
event :go_to_accepted do
|
|
59
|
-
transitions from: :submitted, to: :accepted
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
event :go_to_refused do
|
|
63
|
-
transitions from: :submitted, to: :refused
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
event :go_to_canceled do
|
|
67
|
-
transitions from: [:draft, :submitted, :accepted], to: :canceled
|
|
68
|
-
end
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
def may_edit?
|
|
72
|
-
current_state == :draft
|
|
45
|
+
expense_lines.sum(&:total_vat_deductible)
|
|
73
46
|
end
|
|
74
47
|
end
|