dorsale 3.18.0 → 3.19.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (27) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/app/controllers/dorsale/expense_gun/expenses_controller.rb +24 -34
  4. data/app/filters/dorsale/expense_gun/small_data/filter_for_expenses.rb +5 -2
  5. data/app/helpers/dorsale/expense_gun/application_helper.rb +1 -1
  6. data/app/models/dorsale/expense_gun/expense.rb +4 -31
  7. data/app/policies/dorsale/expense_gun/expense_policy_helper.rb +9 -20
  8. data/app/sorters/dorsale/expense_gun/expenses_sorter.rb +8 -0
  9. data/app/views/dorsale/expense_gun/expenses/_filters.html.slim +8 -0
  10. data/app/views/dorsale/expense_gun/expenses/_form.html.slim +3 -4
  11. data/app/views/dorsale/expense_gun/expenses/_list.html.slim +62 -20
  12. data/app/views/dorsale/expense_gun/expenses/_show_actions.html.slim +2 -12
  13. data/app/views/dorsale/expense_gun/expenses/_state_actions.html.slim +8 -0
  14. data/app/views/dorsale/expense_gun/expenses/index.html.slim +1 -1
  15. data/config/locales/expense_gun.fr.yml +12 -10
  16. data/config/routes.rb +3 -4
  17. data/db/migrate/20210506070548_expenses_change_states.rb +7 -0
  18. data/features/expense_gun_expenses.feature +0 -30
  19. data/features/step_definitions/expense_gun_expenses_steps.rb +1 -16
  20. data/lib/dorsale/engine.rb +0 -1
  21. data/lib/dorsale/version.rb +1 -1
  22. data/spec/controllers/dorsale/expense_gun/expenses_controller_spec.rb +66 -17
  23. data/spec/models/dorsale/expense_gun/expense_spec.rb +1 -125
  24. data/spec/routing/dorsale/expense_gun/expenses_routing_spec.rb +9 -14
  25. data/spec/services/dorsale/expense_gun/expense/copy_spec.rb +2 -2
  26. data/spec/sorters/dorsale/expense_gun/expenses_sorter_spec.rb +20 -0
  27. metadata +7 -16
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f967e032d9c4918a372978e3c92216d542751e9e29881843aa029c7d63be401f
4
- data.tar.gz: 35fbc1b26a2dea2067f936674324804b8d02fd6a673adfd92354886060b56ced
3
+ metadata.gz: 86af52038f7c9cfc24b17dbcf5229608296a7152f2e4565d3fd415d2dd88ce87
4
+ data.tar.gz: cd7c59ee287a99e1cac77068550f7a0d64451e164cb2e10855fd1dd2d9b5fb12
5
5
  SHA512:
6
- metadata.gz: b0bb3cf0a9cd7322cc3e6928101ba486c8dddd577fa9962f1c462612d3c876e2df525224acdc6a2a4902510943ca61c500986431a6b1e895313f246c60467826
7
- data.tar.gz: 135ff2e5848baede200b8ab36ba6bed2078f1c56024a8a1e901bcad21b9ae3f0bb700a314d74582006ae9275d6779f082bbcd6d17577af38f9296291fa379c76
6
+ metadata.gz: 20bc75f4aa3210835d0b8ce2c6e7bb0b43ab7b2a496555df02fc1b6ef9983af553ad586170a5d67c729630905706d6ecea52340811781707520f71a47211e73a
7
+ data.tar.gz: 33809971e1f21d88f6a6d6d110a062cb94b18391dee6c667afa28adc9c7d9690d99806b783f02c8a0f427771e7d9f473b7a693cbba069f339005f5631426fa6d
data/CHANGELOG.md CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  ## Next version
4
4
 
5
+ # 3.19.0
6
+ - Change expenses state machine
7
+ - Change expenses list view
8
+
5
9
  # 3.18.0
6
10
  - Change uploaders `extension_whitelist` to `extension_allowlist`
7
11
  - Rails 6.1 compatibility
@@ -1,15 +1,5 @@
1
1
  class Dorsale::ExpenseGun::ExpensesController < Dorsale::ExpenseGun::ApplicationController
2
- before_action :set_expense, only: [
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
- flash[:success] = t("expense_gun.expense.messages.created")
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
- flash[:success] = t("expense_gun.expense.messages.updated")
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 submit
75
- authorize @expense, :submit?
67
+ def go_to_pending
68
+ authorize @expense, :go_to_pending?
76
69
 
77
- @expense.go_to_submitted!
78
- flash[:success] = t("expense_gun.expense.messages.submitted")
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 accept
83
- authorize @expense, :accept?
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
- def refuse
91
- authorize @expense, :refuse?
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 cancel
99
- authorize @expense, :cancel?
83
+ def go_to_canceled
84
+ authorize @expense, :go_to_canceled?
100
85
 
101
- @expense.go_to_canceled!
102
- flash[:success] = t("expense_gun.expense.messages.canceled")
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" => ::Agilibox::SmallData::FilterStrategyByKeyValue.new("state"),
4
- "expense_user_id" => ::Agilibox::SmallData::FilterStrategyByKeyValue.new("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,6 @@
1
1
  module Dorsale::ExpenseGun::ApplicationHelper
2
2
  def expense_states_for_filters_select
3
- Dorsale::ExpenseGun::Expense.aasm.states.map do |state|
3
+ Dorsale::ExpenseGun::Expense::STATES.map do |state|
4
4
  [
5
5
  Dorsale::ExpenseGun::Expense.t("state.#{state}"),
6
6
  state,
@@ -1,6 +1,7 @@
1
1
  class Dorsale::ExpenseGun::Expense < ::Dorsale::ApplicationRecord
2
2
  self.table_name = "dorsale_expense_gun_expenses"
3
- include AASM
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
- :submit?,
9
- :accept?,
10
- :refuse?,
11
- :cancel?,
8
+ :go_to_pending?,
9
+ :go_to_paid?,
10
+ :go_to_canceled?,
12
11
  ]
13
12
 
14
- def update?
15
- return false unless expense.may_edit?
13
+ def go_to_pending?
14
+ return false unless expense.state == "draft"
16
15
  super
17
16
  end
18
17
 
19
- def submit?
20
- return false unless expense.may_go_to_submitted?
18
+ def go_to_paid?
19
+ return false unless expense.state == "pending"
21
20
  super
22
21
  end
23
22
 
24
- def accept?
25
- return false unless expense.may_go_to_accepted?
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
@@ -0,0 +1,8 @@
1
+ class Dorsale::ExpenseGun::ExpensesSorter < Agilibox::Sorter
2
+ def sort
3
+ case column
4
+ when :created_at, :date
5
+ {column => direction}
6
+ end
7
+ end
8
+ 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-6
12
- = f.input :name
13
- .col-md-6
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
- - expenses.each do |expense|
2
- .panel.panel-default.expense
3
- .panel-heading
4
- .pull-right
5
- = read_button dorsale.expense_gun_expense_path(expense)
6
-
7
- - if policy(expense).update?
8
- = update_button dorsale.edit_expense_gun_expense_path(expense)
9
-
10
- .panel-title = expense
11
-
12
- .panel-body
13
- .row
14
- .col-md-6
15
- = info expense, :user
16
- = info expense, :total_all_taxes, helper: :euros
17
- = info expense, :total_employee_payback, helper: :euros
18
- .col-md-6
19
- = info expense, :state
20
- = info expense, :date
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"
@@ -13,7 +13,7 @@
13
13
  - content_for :filters
14
14
  = render "dorsale/expense_gun/expenses/filters"
15
15
 
16
- - content_for :page_body
16
+ - content_for :table
17
17
  = render "dorsale/expense_gun/expenses/list", expenses: @expenses
18
18
 
19
19
  = render_dorsale_page
@@ -2,12 +2,11 @@ fr:
2
2
  expense_gun:
3
3
  expense:
4
4
  messages:
5
- created : "La note de frais a été créée."
6
- updated : "La note de frais a été mise à jour."
7
- submitted : "La note de frais a été soumise."
8
- accepted : "La note de frais a été acceptée."
9
- refused : "La note de frais a été refusée."
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 employé"
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
- submitted : "Soumise"
67
- accepted : "Accepée"
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
- patch :submit
100
- patch :accept
101
- patch :refuse
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
@@ -13,7 +13,6 @@ require "pundit"
13
13
  require "awesome_print"
14
14
  require "kaminari-i18n"
15
15
  require "carrierwave"
16
- require "aasm"
17
16
  require "pdf/reader"
18
17
  require "prawn"
19
18
  require "prawn/table"
@@ -1,3 +1,3 @@
1
1
  module Dorsale
2
- VERSION = "3.18.0"
2
+ VERSION = "3.19.0"
3
3
  end
@@ -9,38 +9,57 @@ RSpec.describe ::Dorsale::ExpenseGun::ExpensesController, type: :controller do
9
9
  describe "filters" do
10
10
  render_views
11
11
 
12
- it "should filter by state" do
13
- expense1 = create(:expense_gun_expense, state: "accepted")
14
- expense2 = create(:expense_gun_expense, state: "refused")
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
- cookies[:filters] = {expense_state: "accepted"}.to_json
21
+ def filter_by(**filters)
22
+ cookies[:filters] = filters.to_json
17
23
  get :index
24
+ assigns :expenses
25
+ end
18
26
 
19
- expect(assigns :expenses).to eq [expense1]
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
- user1 = create(:user)
24
- user2 = create(:user)
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
- cookies[:filters] = {expense_user_id: user1.id}.to_json
29
- get :index
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
- expect(assigns :expenses).to eq [expense1]
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 assigns only users having expenses" do
35
- user1 = create(:user)
36
- user2 = create(:user)
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.current_state).to be :draft
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 "#submit" do
38
- expect(patch "/expense_gun/expenses/1/submit").to \
39
- route_to("dorsale/expense_gun/expenses#submit", id: "1")
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 "#accept" do
43
- expect(patch "/expense_gun/expenses/1/accept").to \
44
- route_to("dorsale/expense_gun/expenses#accept", id: "1")
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 "#refuse" do
48
- expect(patch "/expense_gun/expenses/1/refuse").to \
49
- route_to("dorsale/expense_gun/expenses#refuse", id: "1")
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 => "accepted",
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 "accepted"
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.18.0
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-04-19 00:00:00.000000000 Z
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