dorsale 3.18.0 → 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 +4 -0
- data/app/controllers/dorsale/expense_gun/expenses_controller.rb +24 -34
- 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/models/dorsale/expense_gun/expense.rb +4 -31
- data/app/policies/dorsale/expense_gun/expense_policy_helper.rb +9 -20
- data/app/sorters/dorsale/expense_gun/expenses_sorter.rb +8 -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/config/locales/expense_gun.fr.yml +12 -10
- data/config/routes.rb +3 -4
- data/db/migrate/20210506070548_expenses_change_states.rb +7 -0
- data/features/expense_gun_expenses.feature +0 -30
- 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/models/dorsale/expense_gun/expense_spec.rb +1 -125
- 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 +7 -16
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
|
@@ -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 => [
|
|
@@ -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
|
|
@@ -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,6 +26,7 @@ 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
|
|
|
@@ -41,34 +44,4 @@ class Dorsale::ExpenseGun::Expense < ::Dorsale::ApplicationRecord
|
|
|
41
44
|
def total_vat_deductible
|
|
42
45
|
expense_lines.sum(&:total_vat_deductible)
|
|
43
46
|
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
|
|
73
|
-
end
|
|
74
47
|
end
|
|
@@ -5,34 +5,23 @@ module Dorsale::ExpenseGun::ExpensePolicyHelper
|
|
|
5
5
|
:read?,
|
|
6
6
|
:update?,
|
|
7
7
|
:copy?,
|
|
8
|
-
:
|
|
9
|
-
:
|
|
10
|
-
:
|
|
11
|
-
:cancel?,
|
|
8
|
+
:go_to_pending?,
|
|
9
|
+
:go_to_paid?,
|
|
10
|
+
:go_to_canceled?,
|
|
12
11
|
]
|
|
13
12
|
|
|
14
|
-
def
|
|
15
|
-
return false unless expense.
|
|
13
|
+
def go_to_pending?
|
|
14
|
+
return false unless expense.state == "draft"
|
|
16
15
|
super
|
|
17
16
|
end
|
|
18
17
|
|
|
19
|
-
def
|
|
20
|
-
return false unless expense.
|
|
18
|
+
def go_to_paid?
|
|
19
|
+
return false unless expense.state == "pending"
|
|
21
20
|
super
|
|
22
21
|
end
|
|
23
22
|
|
|
24
|
-
def
|
|
25
|
-
return false unless expense.
|
|
26
|
-
super
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def refuse?
|
|
30
|
-
return false unless expense.may_go_to_refused?
|
|
31
|
-
super
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def cancel?
|
|
35
|
-
return false unless expense.may_go_to_canceled?
|
|
23
|
+
def go_to_canceled?
|
|
24
|
+
return false unless expense.state == "draft"
|
|
36
25
|
super
|
|
37
26
|
end
|
|
38
27
|
end
|
|
@@ -1,3 +1,11 @@
|
|
|
1
1
|
= filters_form do |f|
|
|
2
2
|
= f.input :expense_state, collection: expense_states_for_filters_select, include_blank: t("expense_gun.filters.all_states")
|
|
3
3
|
= f.input :expense_user_id, collection: @users, include_blank: t("expense_gun.filters.all_users")
|
|
4
|
+
|
|
5
|
+
= f.input(:expense_time_period,
|
|
6
|
+
:collection => agilibox_time_periods_for_select,
|
|
7
|
+
:include_blank => false,
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
= f.input :expense_date_begin, input_html: {placeholder: t("filters.date_begin")}
|
|
11
|
+
= f.input :expense_date_end, input_html: {placeholder: t("filters.date_end")}
|
|
@@ -8,10 +8,9 @@
|
|
|
8
8
|
|
|
9
9
|
.panel-body
|
|
10
10
|
.row
|
|
11
|
-
.col-md-
|
|
12
|
-
|
|
13
|
-
.col-md-
|
|
14
|
-
= f.input :date, as: :string, input_html: {type: :date}
|
|
11
|
+
.col-md-4 = f.input :name
|
|
12
|
+
.col-md-4 = f.input :date, as: :string, input_html: {type: :date}
|
|
13
|
+
.col-md-4 = f.input :state, collection: expense_states_for_filters_select, include_blank: false
|
|
15
14
|
|
|
16
15
|
#expense-lines
|
|
17
16
|
= f.simple_fields_for :expense_lines do |line_form|
|
|
@@ -1,20 +1,62 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
.
|
|
5
|
-
=
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
.
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
.
|
|
14
|
-
.
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
1
|
+
table.default
|
|
2
|
+
thead
|
|
3
|
+
tr
|
|
4
|
+
th.expense-created_at
|
|
5
|
+
= sortable_column Dorsale::ExpenseGun::Expense.t(:created_at), :created_at
|
|
6
|
+
|
|
7
|
+
th.expense-date
|
|
8
|
+
= sortable_column Dorsale::ExpenseGun::Expense.t(:date), :date
|
|
9
|
+
|
|
10
|
+
th.expense-name
|
|
11
|
+
= Dorsale::ExpenseGun::Expense.t(:name)
|
|
12
|
+
|
|
13
|
+
th.expense-user
|
|
14
|
+
= Dorsale::ExpenseGun::Expense.t(:user)
|
|
15
|
+
|
|
16
|
+
th.expense-total_employee_payback
|
|
17
|
+
= Dorsale::ExpenseGun::Expense.t(:total_employee_payback)
|
|
18
|
+
|
|
19
|
+
th.expense-total_all_taxes
|
|
20
|
+
= Dorsale::ExpenseGun::Expense.t(:total_all_taxes)
|
|
21
|
+
|
|
22
|
+
th.expense-state
|
|
23
|
+
= Dorsale::ExpenseGun::Expense.t(:state)
|
|
24
|
+
|
|
25
|
+
th.expense-actions.actions
|
|
26
|
+
= ta(:actions)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
tbody
|
|
30
|
+
- @expenses.each do |expense|
|
|
31
|
+
tr.expense
|
|
32
|
+
td.expense-created_at
|
|
33
|
+
= date expense.created_at.to_date
|
|
34
|
+
|
|
35
|
+
td.expense-date
|
|
36
|
+
= date expense.date
|
|
37
|
+
|
|
38
|
+
td.expense-name
|
|
39
|
+
= expense.name
|
|
40
|
+
|
|
41
|
+
td.expense-user
|
|
42
|
+
= expense.user
|
|
43
|
+
|
|
44
|
+
td.expense-total_employee_payback
|
|
45
|
+
= euros expense.total_employee_payback
|
|
46
|
+
|
|
47
|
+
td.expense-total_all_taxes
|
|
48
|
+
= euros expense.total_all_taxes
|
|
49
|
+
|
|
50
|
+
td.expense-state
|
|
51
|
+
= expense.tv(:state)
|
|
52
|
+
|
|
53
|
+
td.expense-actions.actions
|
|
54
|
+
= read_button dorsale.expense_gun_expense_path(expense)
|
|
55
|
+
= render "state_actions", expense: expense
|
|
56
|
+
|
|
57
|
+
tfoot
|
|
58
|
+
tr
|
|
59
|
+
td.text-right colspan=99
|
|
60
|
+
strong
|
|
61
|
+
= "Total remboursements : "
|
|
62
|
+
= euros @total_payback
|
|
@@ -1,21 +1,11 @@
|
|
|
1
|
+
= render "state_actions", expense: @expense
|
|
2
|
+
|
|
1
3
|
- if policy(@expense).update?
|
|
2
4
|
= update_button dorsale.edit_expense_gun_expense_path(@expense)
|
|
3
5
|
|
|
4
6
|
- if policy(@expense).copy?
|
|
5
7
|
= copy_button dorsale.copy_expense_gun_expense_path(@expense)
|
|
6
8
|
|
|
7
|
-
- if policy(@expense).submit?
|
|
8
|
-
= bs_button dorsale.submit_expense_gun_expense_path(@expense), action: :submit, method: "patch", confirm: true, icon: :check, class: "btn btn-xs btn-primary"
|
|
9
|
-
|
|
10
|
-
- if policy(@expense).accept?
|
|
11
|
-
= bs_button dorsale.accept_expense_gun_expense_path(@expense), action: :accept, method: "patch", confirm: true, icon: :check, class: "btn btn-xs btn-success"
|
|
12
|
-
|
|
13
|
-
- if policy(@expense).refuse?
|
|
14
|
-
= bs_button dorsale.refuse_expense_gun_expense_path(@expense), action: :refuse, method: "patch", confirm: true, icon: :ban, class: "btn btn-xs btn-danger"
|
|
15
|
-
|
|
16
|
-
- if policy(@expense).cancel?
|
|
17
|
-
= bs_button dorsale.cancel_expense_gun_expense_path(@expense), action: :cancel, method: "patch", confirm: true, icon: :times, class: "btn btn-xs btn-warning"
|
|
18
|
-
|
|
19
9
|
= download_button url_for(format: :pdf)
|
|
20
10
|
|
|
21
11
|
= print_button
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
- if policy(expense).go_to_pending?
|
|
2
|
+
= bs_button dorsale.go_to_pending_expense_gun_expense_path(expense), text: t("expense_gun.actions.go_to_pending"), method: "post", confirm: true, icon: :check, class: "btn btn-xs btn-success"
|
|
3
|
+
|
|
4
|
+
- if policy(expense).go_to_paid?
|
|
5
|
+
= bs_button dorsale.go_to_paid_expense_gun_expense_path(expense), text: t("expense_gun.actions.go_to_paid"), method: "post", confirm: true, icon: :check, class: "btn btn-xs btn-success"
|
|
6
|
+
|
|
7
|
+
- if policy(expense).go_to_canceled?
|
|
8
|
+
= bs_button dorsale.go_to_canceled_expense_gun_expense_path(expense), text: t("expense_gun.actions.go_to_canceled"), method: "post", confirm: true, icon: :times, class: "btn btn-xs btn-warning"
|
|
@@ -2,12 +2,11 @@ fr:
|
|
|
2
2
|
expense_gun:
|
|
3
3
|
expense:
|
|
4
4
|
messages:
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
canceled : "La note de frais a été annulée."
|
|
5
|
+
create_ok: "La note de frais a été créée."
|
|
6
|
+
update_ok: "La note de frais a été mise à jour."
|
|
7
|
+
go_to_pending_ok: "La note de frais a été marquée comme à payer."
|
|
8
|
+
go_to_paid_ok: "La note de frais a été marquée comme payée."
|
|
9
|
+
go_to_canceled_ok: "La note de frais a été marquée comme annulée."
|
|
11
10
|
|
|
12
11
|
actions:
|
|
13
12
|
create : "Nouvelle note de frais"
|
|
@@ -25,6 +24,10 @@ fr:
|
|
|
25
24
|
all_states: "Tous les états"
|
|
26
25
|
all_users: "Tous les utilisateurs"
|
|
27
26
|
|
|
27
|
+
actions:
|
|
28
|
+
go_to_pending: "Marquer à payer"
|
|
29
|
+
go_to_paid: "Marquer payée"
|
|
30
|
+
go_to_canceled: "Marquer annulée"
|
|
28
31
|
|
|
29
32
|
activerecord:
|
|
30
33
|
models:
|
|
@@ -43,7 +46,7 @@ fr:
|
|
|
43
46
|
attributes:
|
|
44
47
|
dorsale/expense_gun/expense:
|
|
45
48
|
user : "Employé"
|
|
46
|
-
total_employee_payback : "Total remboursement
|
|
49
|
+
total_employee_payback : "Total remboursement"
|
|
47
50
|
vat_deductible : "TVA déductible"
|
|
48
51
|
total_vat_deductible : "Total TVA déductible"
|
|
49
52
|
total_all_taxes : "Total TTC"
|
|
@@ -63,7 +66,6 @@ fr:
|
|
|
63
66
|
dorsale/expense_gun/expense/state:
|
|
64
67
|
all : "Toutes"
|
|
65
68
|
draft : "Brouillon"
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
refused : "Refusée"
|
|
69
|
+
pending : "À payer"
|
|
70
|
+
paid : "Payé"
|
|
69
71
|
canceled : "Annulée"
|
data/config/routes.rb
CHANGED
|
@@ -96,10 +96,9 @@ Dorsale::Engine.routes.draw do
|
|
|
96
96
|
resources :expenses, except: [:destroy] do
|
|
97
97
|
member do
|
|
98
98
|
get :copy
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
patch :cancel
|
|
99
|
+
post :go_to_pending
|
|
100
|
+
post :go_to_paid
|
|
101
|
+
post :go_to_canceled
|
|
103
102
|
end
|
|
104
103
|
end
|
|
105
104
|
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
class ExpensesChangeStates < ActiveRecord::Migration[6.1]
|
|
2
|
+
def change
|
|
3
|
+
Dorsale::ExpenseGun::Expense.where(state: "submitted").update_all(state: "pending")
|
|
4
|
+
Dorsale::ExpenseGun::Expense.where(state: "accepted").update_all(state: "paid")
|
|
5
|
+
Dorsale::ExpenseGun::Expense.where(state: "refused").update_all(state: "canceled")
|
|
6
|
+
end
|
|
7
|
+
end
|
|
@@ -28,33 +28,3 @@ Feature: Expenses
|
|
|
28
28
|
When I copy the expense
|
|
29
29
|
Then an expense copy is created
|
|
30
30
|
And I am redirected on the expense page
|
|
31
|
-
|
|
32
|
-
Scenario: Submit expense
|
|
33
|
-
Given an existing expense
|
|
34
|
-
When I go on the expense page
|
|
35
|
-
And I submit the expense
|
|
36
|
-
Then I am redirect to the expenses page
|
|
37
|
-
And the expense state is "submitted"
|
|
38
|
-
|
|
39
|
-
Scenario: Cancel expense
|
|
40
|
-
Given an existing expense
|
|
41
|
-
When I go on the expense page
|
|
42
|
-
And I cancel the expense
|
|
43
|
-
Then I am redirect to the expenses page
|
|
44
|
-
And the expense state is "canceled"
|
|
45
|
-
|
|
46
|
-
Scenario: Accept expense
|
|
47
|
-
Given an existing expense
|
|
48
|
-
And the expense is submitted
|
|
49
|
-
When I go on the expense page
|
|
50
|
-
And I accept the expense
|
|
51
|
-
Then I am redirect to the expense page
|
|
52
|
-
And the expense state is "accepted"
|
|
53
|
-
|
|
54
|
-
Scenario: Refuse expense
|
|
55
|
-
Given an existing expense
|
|
56
|
-
And the expense is submitted
|
|
57
|
-
When I go on the expense page
|
|
58
|
-
And I refuse the expense
|
|
59
|
-
Then I am redirect to the expenses page
|
|
60
|
-
And the expense state is "refused"
|
|
@@ -61,6 +61,7 @@ When(/^I update the expense$/) do
|
|
|
61
61
|
@expenses_count = Dorsale::ExpenseGun::Expense.count
|
|
62
62
|
@expense_lines_count = Dorsale::ExpenseGun::ExpenseLine.count
|
|
63
63
|
|
|
64
|
+
find(".link_read").click
|
|
64
65
|
find("#main [href$=edit]").click
|
|
65
66
|
|
|
66
67
|
fill_in :expense_name, with: "NewExpenseName"
|
|
@@ -78,10 +79,6 @@ Then(/^the expense is update$/) do
|
|
|
78
79
|
expect(@expense.name).to eq "NewExpenseName"
|
|
79
80
|
end
|
|
80
81
|
|
|
81
|
-
When(/^I submit the expense$/) do
|
|
82
|
-
find("[href$='/submit']").click
|
|
83
|
-
end
|
|
84
|
-
|
|
85
82
|
Then(/^I am redirect to the expenses page$/) do
|
|
86
83
|
wait_for { current_path }.to eq dorsale.expense_gun_expenses_path
|
|
87
84
|
end
|
|
@@ -94,18 +91,6 @@ Given(/^the expense is submitted$/) do
|
|
|
94
91
|
@expense.update_columns(state: "submitted")
|
|
95
92
|
end
|
|
96
93
|
|
|
97
|
-
When(/^I cancel the expense$/) do
|
|
98
|
-
find("[href$='/cancel']").click
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
When(/^I accept the expense$/) do
|
|
102
|
-
find("[href$='/accept']").click
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
When(/^I refuse the expense$/) do
|
|
106
|
-
find("[href$='/refuse']").click
|
|
107
|
-
end
|
|
108
|
-
|
|
109
94
|
Then(/^I am redirect to the expense page$/) do
|
|
110
95
|
wait_for { current_path }.to include dorsale.expense_gun_expense_path(@expense)
|
|
111
96
|
end
|
data/lib/dorsale/engine.rb
CHANGED
data/lib/dorsale/version.rb
CHANGED
|
@@ -9,38 +9,57 @@ RSpec.describe ::Dorsale::ExpenseGun::ExpensesController, type: :controller do
|
|
|
9
9
|
describe "filters" do
|
|
10
10
|
render_views
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
let!(:user1) { create(:user) }
|
|
13
|
+
let!(:user2) { create(:user) }
|
|
14
|
+
let!(:expense1) {
|
|
15
|
+
create(:expense_gun_expense, state: "pending", user: user1, date: "2021-05-10")
|
|
16
|
+
}
|
|
17
|
+
let!(:expense2) {
|
|
18
|
+
create(:expense_gun_expense, state: "canceled", user: user2, date: "2021-05-20")
|
|
19
|
+
}
|
|
15
20
|
|
|
16
|
-
|
|
21
|
+
def filter_by(**filters)
|
|
22
|
+
cookies[:filters] = filters.to_json
|
|
17
23
|
get :index
|
|
24
|
+
assigns :expenses
|
|
25
|
+
end
|
|
18
26
|
|
|
19
|
-
|
|
27
|
+
it "should filter by state" do
|
|
28
|
+
expect(filter_by expense_state: "pending").to eq [expense1]
|
|
20
29
|
end
|
|
21
30
|
|
|
22
31
|
it "should filter by user" do
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
expense1 = create(:expense_gun_expense, user: user1)
|
|
26
|
-
expense2 = create(:expense_gun_expense, user: user2)
|
|
32
|
+
expect(filter_by expense_user_id: user1.id).to eq [expense1]
|
|
33
|
+
end
|
|
27
34
|
|
|
28
|
-
|
|
29
|
-
|
|
35
|
+
it "should filter by date period" do
|
|
36
|
+
Timecop.freeze "2021-05-20"
|
|
37
|
+
expect(filter_by expense_time_period: "this_week").to eq [expense2]
|
|
38
|
+
end
|
|
30
39
|
|
|
31
|
-
|
|
40
|
+
it "should filter by date begin" do
|
|
41
|
+
expect(filter_by expense_date_begin: "2021-05-15").to eq [expense2]
|
|
32
42
|
end
|
|
33
43
|
|
|
34
|
-
it "should
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
expense2 = create(:expense_gun_expense, user: user2)
|
|
44
|
+
it "should filter by date begin" do
|
|
45
|
+
expect(filter_by expense_date_end: "2021-05-15").to eq [expense1]
|
|
46
|
+
end
|
|
38
47
|
|
|
48
|
+
it "should assigns only users having expenses" do
|
|
49
|
+
expense1.destroy!
|
|
39
50
|
get :index
|
|
40
|
-
|
|
41
51
|
expect(assigns :users).to eq [user2]
|
|
42
52
|
end
|
|
43
53
|
end # describe "filters"
|
|
54
|
+
|
|
55
|
+
it "should set total_payback" do
|
|
56
|
+
create(:expense_gun_expense_line, total_all_taxes: 200, company_part: 50)
|
|
57
|
+
.expense.update!(state: "pending")
|
|
58
|
+
create(:expense_gun_expense_line, total_all_taxes: 50, company_part: 100)
|
|
59
|
+
.expense.update!(state: "paid")
|
|
60
|
+
get :index
|
|
61
|
+
expect(assigns :total_payback).to eq 150
|
|
62
|
+
end
|
|
44
63
|
end # describe "#index"
|
|
45
64
|
|
|
46
65
|
describe "#show" do
|
|
@@ -52,4 +71,34 @@ RSpec.describe ::Dorsale::ExpenseGun::ExpensesController, type: :controller do
|
|
|
52
71
|
expect(response).to be_ok
|
|
53
72
|
end
|
|
54
73
|
end # describe "#show"
|
|
74
|
+
|
|
75
|
+
describe "#go_to_pending" do
|
|
76
|
+
it "should go to pending and redirect" do
|
|
77
|
+
expense = create(:expense_gun_expense, user: user, state: "draft")
|
|
78
|
+
post :go_to_pending, params: {id: expense}
|
|
79
|
+
expect(response).to be_redirect
|
|
80
|
+
expect(flash.notice).to be_present
|
|
81
|
+
expect(expense.reload.state).to eq "pending"
|
|
82
|
+
end
|
|
83
|
+
end # describe "#go_to_pending"
|
|
84
|
+
|
|
85
|
+
describe "#go_to_paid" do
|
|
86
|
+
it "should go to paid and redirect" do
|
|
87
|
+
expense = create(:expense_gun_expense, user: user, state: "pending")
|
|
88
|
+
post :go_to_paid, params: {id: expense}
|
|
89
|
+
expect(response).to be_redirect
|
|
90
|
+
expect(flash.notice).to be_present
|
|
91
|
+
expect(expense.reload.state).to eq "paid"
|
|
92
|
+
end
|
|
93
|
+
end # describe "#go_to_pending"
|
|
94
|
+
|
|
95
|
+
describe "#go_to_canceled" do
|
|
96
|
+
it "should go to canceled and redirect" do
|
|
97
|
+
expense = create(:expense_gun_expense, user: user, state: "draft")
|
|
98
|
+
post :go_to_canceled, params: {id: expense}
|
|
99
|
+
expect(response).to be_redirect
|
|
100
|
+
expect(flash.notice).to be_present
|
|
101
|
+
expect(expense.reload.state).to eq "canceled"
|
|
102
|
+
end
|
|
103
|
+
end # describe "#go_to_pending"
|
|
55
104
|
end
|
|
@@ -14,123 +14,7 @@ RSpec.describe Dorsale::ExpenseGun::Expense, type: :model do
|
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
it "new expense should have new state" do
|
|
17
|
-
expect(described_class.new.
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
describe "new state" do
|
|
21
|
-
before :each do
|
|
22
|
-
@expense = build(:expense_gun_expense)
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
it "new expense can be submitted" do
|
|
26
|
-
expect(@expense.go_to_submitted).to be true
|
|
27
|
-
expect(@expense.current_state).to be :submitted
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
it "new expense can't be accepted" do
|
|
31
|
-
expect(@expense.go_to_accepted).to be false
|
|
32
|
-
expect(@expense.current_state).to be :draft
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
it "new expense can't be refused" do
|
|
36
|
-
expect(@expense.go_to_refused).to be false
|
|
37
|
-
expect(@expense.current_state).to be :draft
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
it "new expense can be canceled" do
|
|
41
|
-
expect(@expense.go_to_canceled).to be true
|
|
42
|
-
expect(@expense.current_state).to be :canceled
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
describe "submitted state" do
|
|
47
|
-
before :each do
|
|
48
|
-
@expense = build(:expense_gun_expense)
|
|
49
|
-
@expense.go_to_submitted
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
it "submitted expense can be accepted" do
|
|
53
|
-
expect(@expense.go_to_accepted).to be true
|
|
54
|
-
expect(@expense.current_state).to be :accepted
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
it "submitted expense can be refused" do
|
|
58
|
-
expect(@expense.go_to_refused).to be true
|
|
59
|
-
expect(@expense.current_state).to be :refused
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
it "submitted expense can be canceled" do
|
|
63
|
-
expect(@expense.go_to_canceled).to be true
|
|
64
|
-
expect(@expense.current_state).to be :canceled
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
describe "acceped state" do
|
|
69
|
-
before :each do
|
|
70
|
-
@expense = build(:expense_gun_expense)
|
|
71
|
-
@expense.go_to_submitted
|
|
72
|
-
@expense.go_to_accepted
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
it "acceped expense can't be submitted" do
|
|
76
|
-
expect(@expense.go_to_submitted).to be false
|
|
77
|
-
expect(@expense.current_state).to be :accepted
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
it "acceped expense can't be refused" do
|
|
81
|
-
expect(@expense.go_to_refused).to be false
|
|
82
|
-
expect(@expense.current_state).to be :accepted
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
it "acceped expense can be canceled" do
|
|
86
|
-
expect(@expense.go_to_canceled).to be true
|
|
87
|
-
expect(@expense.current_state).to be :canceled
|
|
88
|
-
end
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
describe "refused state" do
|
|
92
|
-
before :each do
|
|
93
|
-
@expense = build(:expense_gun_expense)
|
|
94
|
-
@expense.go_to_submitted
|
|
95
|
-
@expense.go_to_refused
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
it "refused expense can't be submitted" do
|
|
99
|
-
expect(@expense.go_to_submitted).to be false
|
|
100
|
-
expect(@expense.current_state).to be :refused
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
it "refused expense can't be acceped" do
|
|
104
|
-
expect(@expense.go_to_accepted).to be false
|
|
105
|
-
expect(@expense.current_state).to be :refused
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
it "refused expense can't be canceled" do
|
|
109
|
-
expect(@expense.go_to_canceled).to be false
|
|
110
|
-
expect(@expense.current_state).to be :refused
|
|
111
|
-
end
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
describe "canceled state" do
|
|
115
|
-
before :each do
|
|
116
|
-
@expense = build(:expense_gun_expense)
|
|
117
|
-
@expense.go_to_canceled
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
it "canceled expense can't be submitted" do
|
|
121
|
-
expect(@expense.go_to_submitted).to be false
|
|
122
|
-
expect(@expense.current_state).to be :canceled
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
it "canceled expense can't be acceped" do
|
|
126
|
-
expect(@expense.go_to_accepted).to be false
|
|
127
|
-
expect(@expense.current_state).to be :canceled
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
it "canceled expense can't be refused" do
|
|
131
|
-
expect(@expense.go_to_refused).to be false
|
|
132
|
-
expect(@expense.current_state).to be :canceled
|
|
133
|
-
end
|
|
17
|
+
expect(described_class.new.state).to eq "draft"
|
|
134
18
|
end
|
|
135
19
|
|
|
136
20
|
it "#total_all_taxes should return sum of lines" do
|
|
@@ -165,12 +49,4 @@ RSpec.describe Dorsale::ExpenseGun::Expense, type: :model do
|
|
|
165
49
|
|
|
166
50
|
expect(expense.total_vat_deductible).to eq 5.0
|
|
167
51
|
end
|
|
168
|
-
|
|
169
|
-
it "#may_edit? should return false unless expense is not submitted" do
|
|
170
|
-
expect(described_class.new(state: :draft).may_edit?).to be true
|
|
171
|
-
expect(described_class.new(state: :submitted).may_edit?).to be false
|
|
172
|
-
expect(described_class.new(state: :acceped).may_edit?).to be false
|
|
173
|
-
expect(described_class.new(state: :refused).may_edit?).to be false
|
|
174
|
-
expect(described_class.new(state: :canceled).may_edit?).to be false
|
|
175
|
-
end
|
|
176
52
|
end
|
|
@@ -34,24 +34,19 @@ describe ::Dorsale::ExpenseGun::ExpensesController, type: :routing do
|
|
|
34
34
|
route_to("dorsale/expense_gun/expenses#update", id: "1")
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
-
it "#
|
|
38
|
-
expect(
|
|
39
|
-
route_to("dorsale/expense_gun/expenses#
|
|
37
|
+
it "#go_to_pending" do
|
|
38
|
+
expect(post "/expense_gun/expenses/1/go_to_pending").to \
|
|
39
|
+
route_to("dorsale/expense_gun/expenses#go_to_pending", id: "1")
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
-
it "#
|
|
43
|
-
expect(
|
|
44
|
-
route_to("dorsale/expense_gun/expenses#
|
|
42
|
+
it "#go_to_paid" do
|
|
43
|
+
expect(post "/expense_gun/expenses/1/go_to_paid").to \
|
|
44
|
+
route_to("dorsale/expense_gun/expenses#go_to_paid", id: "1")
|
|
45
45
|
end
|
|
46
46
|
|
|
47
|
-
it "#
|
|
48
|
-
expect(
|
|
49
|
-
route_to("dorsale/expense_gun/expenses#
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
it "#cancel" do
|
|
53
|
-
expect(patch "/expense_gun/expenses/1/cancel").to \
|
|
54
|
-
route_to("dorsale/expense_gun/expenses#cancel", id: "1")
|
|
47
|
+
it "#go_to_canceled" do
|
|
48
|
+
expect(post "/expense_gun/expenses/1/go_to_canceled").to \
|
|
49
|
+
route_to("dorsale/expense_gun/expenses#go_to_canceled", id: "1")
|
|
55
50
|
end
|
|
56
51
|
|
|
57
52
|
it "#copy" do
|
|
@@ -6,7 +6,7 @@ RSpec.describe ::Dorsale::ExpenseGun::Expense::Copy do
|
|
|
6
6
|
:user => create(:user),
|
|
7
7
|
:name => "ExpenseName",
|
|
8
8
|
:date => Date.current,
|
|
9
|
-
:state => "
|
|
9
|
+
:state => "paid",
|
|
10
10
|
)
|
|
11
11
|
|
|
12
12
|
line = create(:expense_gun_expense_line,
|
|
@@ -56,7 +56,7 @@ RSpec.describe ::Dorsale::ExpenseGun::Expense::Copy do
|
|
|
56
56
|
end
|
|
57
57
|
|
|
58
58
|
it "should reset expense state" do
|
|
59
|
-
expect(expense.state).to eq "
|
|
59
|
+
expect(expense.state).to eq "paid"
|
|
60
60
|
expect(copy.state).to eq "draft"
|
|
61
61
|
end
|
|
62
62
|
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require "rails_helper"
|
|
2
|
+
|
|
3
|
+
describe Dorsale::ExpenseGun::ExpensesSorter do
|
|
4
|
+
let!(:expense1) { create(:expense_gun_expense, date: "2021-05-10") }
|
|
5
|
+
let!(:expense2) { create(:expense_gun_expense, date: "2021-05-20") }
|
|
6
|
+
|
|
7
|
+
def sort_by(column)
|
|
8
|
+
described_class.call(Dorsale::ExpenseGun::Expense.all, column)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def self.it_should_sort_by(column)
|
|
12
|
+
it "should sort by #{column}" do
|
|
13
|
+
expect(sort_by column.to_s).to eq [expense1, expense2]
|
|
14
|
+
expect(sort_by "-#{column}").to eq [expense2, expense1]
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it_should_sort_by :created_at
|
|
19
|
+
it_should_sort_by :date
|
|
20
|
+
end # describe "sorting"
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: dorsale
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.
|
|
4
|
+
version: 3.19.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- agilidée
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2021-
|
|
11
|
+
date: 2021-05-06 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rails
|
|
@@ -218,20 +218,6 @@ dependencies:
|
|
|
218
218
|
- - "<"
|
|
219
219
|
- !ruby/object:Gem::Version
|
|
220
220
|
version: '99'
|
|
221
|
-
- !ruby/object:Gem::Dependency
|
|
222
|
-
name: aasm
|
|
223
|
-
requirement: !ruby/object:Gem::Requirement
|
|
224
|
-
requirements:
|
|
225
|
-
- - "<"
|
|
226
|
-
- !ruby/object:Gem::Version
|
|
227
|
-
version: '99'
|
|
228
|
-
type: :runtime
|
|
229
|
-
prerelease: false
|
|
230
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
231
|
-
requirements:
|
|
232
|
-
- - "<"
|
|
233
|
-
- !ruby/object:Gem::Version
|
|
234
|
-
version: '99'
|
|
235
221
|
- !ruby/object:Gem::Dependency
|
|
236
222
|
name: pdf-reader
|
|
237
223
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -589,6 +575,7 @@ files:
|
|
|
589
575
|
- app/services/dorsale/service.rb
|
|
590
576
|
- app/services/dorsale/tag_list_for_model.rb
|
|
591
577
|
- app/sorters/dorsale/alexandrie/attachments_sorter.rb
|
|
578
|
+
- app/sorters/dorsale/expense_gun/expenses_sorter.rb
|
|
592
579
|
- app/sorters/dorsale/flyboy/task_comments_sorter.rb
|
|
593
580
|
- app/sorters/dorsale/flyboy/tasks_sorter.rb
|
|
594
581
|
- app/uploaders/dorsale/alexandrie/file_uploader.rb
|
|
@@ -716,6 +703,7 @@ files:
|
|
|
716
703
|
- app/views/dorsale/expense_gun/expenses/_index_actions.html.slim
|
|
717
704
|
- app/views/dorsale/expense_gun/expenses/_list.html.slim
|
|
718
705
|
- app/views/dorsale/expense_gun/expenses/_show_actions.html.slim
|
|
706
|
+
- app/views/dorsale/expense_gun/expenses/_state_actions.html.slim
|
|
719
707
|
- app/views/dorsale/expense_gun/expenses/edit.html.slim
|
|
720
708
|
- app/views/dorsale/expense_gun/expenses/index.html.slim
|
|
721
709
|
- app/views/dorsale/expense_gun/expenses/new.html.slim
|
|
@@ -819,6 +807,7 @@ files:
|
|
|
819
807
|
- db/migrate/20171115171425_dorsale_customer_vault_people_add_secondary_emails.rb
|
|
820
808
|
- db/migrate/20210202100529_billing_machine_add_positions.rb
|
|
821
809
|
- db/migrate/20210311131928_billing_machine_add_missing_unique_indexes.rb
|
|
810
|
+
- db/migrate/20210506070548_expenses_change_states.rb
|
|
822
811
|
- features/access.feature
|
|
823
812
|
- features/billing_machine_invoices.feature
|
|
824
813
|
- features/billing_machine_multiple_vat.feature
|
|
@@ -951,6 +940,7 @@ files:
|
|
|
951
940
|
- spec/services/dorsale/expense_gun/expense/copy_spec.rb
|
|
952
941
|
- spec/services/dorsale/flyboy/task/copy_spec.rb
|
|
953
942
|
- spec/services/dorsale/flyboy/task/snoozer_spec.rb
|
|
943
|
+
- spec/sorters/dorsale/expense_gun/expenses_sorter_spec.rb
|
|
954
944
|
- spec/spec_helper.rb
|
|
955
945
|
- spec/support/devise.rb
|
|
956
946
|
- spec/support/message_delivery.rb
|
|
@@ -1004,6 +994,7 @@ test_files:
|
|
|
1004
994
|
- spec/models/dorsale/flyboy/task_spec.rb
|
|
1005
995
|
- spec/models/dorsale/flyboy/task_comment_spec.rb
|
|
1006
996
|
- spec/models/dorsale/address_spec.rb
|
|
997
|
+
- spec/sorters/dorsale/expense_gun/expenses_sorter_spec.rb
|
|
1007
998
|
- spec/support/devise.rb
|
|
1008
999
|
- spec/support/message_delivery.rb
|
|
1009
1000
|
- spec/factories/expense_gun_categories.rb
|