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.
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