diff --git a/app/controllers/activities_controller.rb b/app/controllers/activities_controller.rb index 1dacda3f9..45aa76197 100644 --- a/app/controllers/activities_controller.rb +++ b/app/controllers/activities_controller.rb @@ -10,7 +10,7 @@ class ActivitiesController < ApplicationController # rubocop:disable Metrics/Cla def index authorize Activity - @activities = policy_scope(Activity.includes(%i[price_list created_by]) + @activities = policy_scope(Activity.includes(%i[price_list created_by locked_by]) .order(start_time: :desc) .page(params[:page])) @@ -19,7 +19,7 @@ def index end_time: 6.hours.from_now.beginning_of_hour ) - @price_lists_json = PriceList.all.to_json(only: %i[id name]) + @price_lists_json = PriceList.unarchived.to_json(only: %i[id name]) end def create @@ -63,8 +63,7 @@ def destroy def show # rubocop:disable Metrics/AbcSize, Metrics/MethodLength @activity = Activity.includes(:price_list, - { orders: [{ order_rows: :product }, :user, :created_by] }, - credit_mutations: [:user]).find(params[:id]) + { orders: [{ order_rows: :product }, :user, :created_by] }).find(params[:id]) authorize @activity @price_list = @activity.price_list diff --git a/app/controllers/credit_mutations_controller.rb b/app/controllers/credit_mutations_controller.rb index 4ed43df97..ddd09bc0f 100644 --- a/app/controllers/credit_mutations_controller.rb +++ b/app/controllers/credit_mutations_controller.rb @@ -1,12 +1,14 @@ class CreditMutationsController < ApplicationController before_action :authenticate_user! after_action :verify_authorized + after_action :verify_policy_scoped, only: :index def index - @credit_mutations = CreditMutation.includes(model_includes) + authorize CreditMutation + + @credit_mutations = policy_scope(CreditMutation.includes(model_includes) .order(created_at: :desc) - .page params[:page] - authorize @credit_mutations + .page(params[:page])) @new_mutation = CreditMutation.new end diff --git a/app/controllers/invoices_controller.rb b/app/controllers/invoices_controller.rb index 345b36547..ea5c788c2 100644 --- a/app/controllers/invoices_controller.rb +++ b/app/controllers/invoices_controller.rb @@ -6,7 +6,7 @@ class InvoicesController < ApplicationController def index authorize Invoice - @invoices = Invoice.all.order(created_at: :desc) + @invoices = Invoice.includes(:user, :activity, :rows).order(created_at: :desc) @activities_json = Activity.all.to_json(only: %i[id title start_time]) @invoice = Invoice.new @invoice.rows.build diff --git a/app/controllers/orders_controller.rb b/app/controllers/orders_controller.rb index 5a129a31e..73496787d 100644 --- a/app/controllers/orders_controller.rb +++ b/app/controllers/orders_controller.rb @@ -55,7 +55,7 @@ def destroy authorize @order - if @order.activity.locked? + if @order.activity&.locked? render json: {}, status: :forbidden else @order.order_rows.each do |order_row| diff --git a/app/controllers/price_lists_controller.rb b/app/controllers/price_lists_controller.rb index 6a1a02ec3..31783b5ed 100644 --- a/app/controllers/price_lists_controller.rb +++ b/app/controllers/price_lists_controller.rb @@ -2,12 +2,13 @@ class PriceListsController < ApplicationController before_action :authenticate_user! after_action :verify_authorized + after_action :verify_policy_scoped, only: :index def index - price_lists = PriceList.order(created_at: :desc) - products = Product.all.order(:id).includes(:product_prices) + authorize PriceList - authorize price_lists + price_lists = policy_scope(PriceList.order(created_at: :desc)) + products = Product.all.order(:id).includes(:product_prices) @price_list = PriceList.new diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 7255bf066..ba7e6d785 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -6,9 +6,9 @@ class UsersController < ApplicationController # rubocop:disable Metrics/ClassLen def index # rubocop:disable Metrics/AbcSize, Metrics/MethodLength authorize User - @manual_users = User.manual.active.order(:name) - @amber_users = User.in_amber.active.order(:name) - @inactive_users = User.inactive.order(:name) + @manual_users = User.manual.active.order(:name).select { |u| policy(u).show? } + @amber_users = User.in_amber.active.order(:name).select { |u| policy(u).show? } + @inactive_users = User.inactive.order(:name).select { |u| policy(u).show? } @users_credits = User.calculate_credits @manual_users_json = @manual_users.as_json(only: %w[id name]) diff --git a/app/javascript/components/activity/ProductTotals.vue b/app/javascript/components/activity/ProductTotals.vue index 83aa4e142..960c83798 100644 --- a/app/javascript/components/activity/ProductTotals.vue +++ b/app/javascript/components/activity/ProductTotals.vue @@ -23,6 +23,13 @@ {{orderTotal.amount}} x {{doubleToCurrency(orderTotal.price)}} + + Totaal + + + {{doubleToCurrency(totalAmount)}} + + @@ -56,6 +63,7 @@ export default { return { user: {}, orderTotals: [], + totalAmount: 0.0, isLoading: true }; }, @@ -71,6 +79,7 @@ export default { let params = {user: this.user.id, paid_with_cash: this.user.paid_with_cash, paid_with_pin: this.user.paid_with_pin}; this.$http.get('/activities/'+this.activity+'/product_totals', { params }).then((response) => { this.orderTotals = response.body; + this.totalAmount = this.orderTotals.reduce((a, b) => a + parseFloat(b.price), 0.0); this.isLoading = false; }); }, diff --git a/app/javascript/components/user/UsersTable.vue b/app/javascript/components/user/UsersTable.vue index cd648a70b..049919cce 100644 --- a/app/javascript/components/user/UsersTable.vue +++ b/app/javascript/components/user/UsersTable.vue @@ -26,7 +26,9 @@ - + @@ -53,7 +55,7 @@ export default { users: { type: Array, required: true - } + }, }, data() { diff --git a/app/javascript/packs/activity.js b/app/javascript/packs/activity.js index 8a59eeaba..839096a72 100644 --- a/app/javascript/packs/activity.js +++ b/app/javascript/packs/activity.js @@ -12,11 +12,18 @@ document.addEventListener('turbolinks:load', () => { var element = document.getElementById('activity'); if (element !== null) { + // Create a Vue instance for the ProductTotals component new Vue({ el: element, components: { ProductTotals } }); + + // Selects the first visible tab in the activity detail tabs + var firstTabEl = document.querySelector('#activityTabs li:first-child a'); + /* eslint-disable no-undef */ + var firstTab = new bootstrap.Tab(firstTabEl); + firstTab.show(); } }); diff --git a/app/models/credit_mutation.rb b/app/models/credit_mutation.rb index 711c15b5e..6a2f48bb2 100644 --- a/app/models/credit_mutation.rb +++ b/app/models/credit_mutation.rb @@ -8,6 +8,10 @@ class CreditMutation < ApplicationRecord validate :activity_not_locked + scope :linked_to_activity, (lambda { + where.not(activity: nil) + }) + before_destroy -> { throw(:abort) } def activity_not_locked diff --git a/app/models/order_row.rb b/app/models/order_row.rb index 407de1d78..aba802773 100644 --- a/app/models/order_row.rb +++ b/app/models/order_row.rb @@ -18,7 +18,9 @@ def copy_product_price end def no_changes_of_product_count_allowed - errors.add(:product_count, 'cannot be altered') if !new_record? && product_count_changed? && order.activity.locked? + return unless !new_record? && product_count_changed? && order.activity.locked? + + errors.add(:product_count, 'cannot be altered because the activity is locked') end def no_changes_of_price_per_product_allowed diff --git a/app/models/price_list.rb b/app/models/price_list.rb index 0b2fcca5c..dff0a3006 100644 --- a/app/models/price_list.rb +++ b/app/models/price_list.rb @@ -5,6 +5,8 @@ class PriceList < ApplicationRecord validates :name, presence: true + scope :unarchived, (-> { where(archived_at: nil) }) + def product_price_for(product) @product_price ||= ProductPrice.includes(:product).where(price_list: self) @product_price.find { |pp| pp.product == product } diff --git a/app/models/role.rb b/app/models/role.rb index 779a9ad66..55d9a47a2 100644 --- a/app/models/role.rb +++ b/app/models/role.rb @@ -1,5 +1,5 @@ class Role < ApplicationRecord - enum role_type: { treasurer: 0, main_bartender: 1 } + enum role_type: { treasurer: 0, main_bartender: 1, renting_manager: 2 } validates :role_type, :group_uid, presence: true has_many :roles_users, class_name: 'RolesUsers', dependent: :destroy, inverse_of: :role @@ -10,6 +10,8 @@ def name Rails.application.config.x.treasurer_title.capitalize elsif main_bartender? 'Hoofdtapper' + elsif renting_manager? + 'Verhuur manager' end end end diff --git a/app/models/user.rb b/app/models/user.rb index 04a78dc63..086e3d444 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -65,6 +65,10 @@ def main_bartender? @main_bartender ||= roles.where(role_type: :main_bartender).any? end + def renting_manager? + @renting_manager ||= roles.where(role_type: :renting_manager).any? + end + def update_role(groups) roles_to_have = Role.where(group_uid: groups) roles_users_to_have = roles_to_have.map { |role| RolesUsers.find_or_create_by(role: role, user: self) } diff --git a/app/policies/activity_policy.rb b/app/policies/activity_policy.rb index 66a7ce0a1..3ccacd73a 100644 --- a/app/policies/activity_policy.rb +++ b/app/policies/activity_policy.rb @@ -1,7 +1,7 @@ class ActivityPolicy < ApplicationPolicy class Scope < Scope def resolve - if user&.treasurer? + if user&.treasurer? || user&.renting_manager? scope elsif user&.main_bartender? scope.not_locked @@ -10,11 +10,11 @@ def resolve end def create? - user&.treasurer? || user&.main_bartender? + user&.treasurer? || user&.main_bartender? || user&.renting_manager? end def update? - user&.treasurer? || user&.main_bartender? + user&.treasurer? || user&.main_bartender? || user&.renting_manager? end def lock? @@ -26,18 +26,26 @@ def create_invoices? end def destroy? - user&.treasurer? || user&.main_bartender? + user&.treasurer? || user&.renting_manager? || user&.main_bartender? end - def activity_report? - user&.treasurer? + def order_screen? + user&.treasurer? || user&.renting_manager? || user&.main_bartender? end - def order_screen? - user&.treasurer? || user&.main_bartender? + def summary? + user&.treasurer? || user&.renting_manager? || user&.main_bartender? end def product_totals? - user&.treasurer? || user&.main_bartender? + user&.treasurer? || user&.renting_manager? || user&.main_bartender? + end + + def orders? + user&.treasurer? || user&.renting_manager? + end + + def credit_mutations? + user&.treasurer? end end diff --git a/app/policies/application_policy.rb b/app/policies/application_policy.rb index fa8cc4a04..542610763 100644 --- a/app/policies/application_policy.rb +++ b/app/policies/application_policy.rb @@ -7,7 +7,7 @@ def initialize(user, record) end def index? - user&.treasurer? || user&.main_bartender? + user&.treasurer? || user&.main_bartender? || user&.renting_manager? end def show? @@ -31,7 +31,7 @@ def edit? end def destroy? - user&.treasurer? || user&.main_bartender? + user&.treasurer? || user&.main_bartender? || user&.renting_manager? end def scope diff --git a/app/policies/credit_mutation_policy.rb b/app/policies/credit_mutation_policy.rb index cd9124f39..60ab794dc 100644 --- a/app/policies/credit_mutation_policy.rb +++ b/app/policies/credit_mutation_policy.rb @@ -1,5 +1,19 @@ class CreditMutationPolicy < ApplicationPolicy - def create? + class Scope < Scope + def resolve + if user&.treasurer? + scope + elsif user&.main_bartender? + scope.linked_to_activity + end + end + end + + def index? user&.treasurer? || user&.main_bartender? end + + def create? + user&.treasurer? || (user&.main_bartender? && record.activity.present?) + end end diff --git a/app/policies/invoice_policy.rb b/app/policies/invoice_policy.rb index 781bb644f..bbc1f1f13 100644 --- a/app/policies/invoice_policy.rb +++ b/app/policies/invoice_policy.rb @@ -1,6 +1,6 @@ class InvoicePolicy < ApplicationPolicy def index? - user&.treasurer? + user&.treasurer? || user&.renting_manager? end def send_invoice? diff --git a/app/policies/order_policy.rb b/app/policies/order_policy.rb index b75e8b1ce..31b5db26d 100644 --- a/app/policies/order_policy.rb +++ b/app/policies/order_policy.rb @@ -1,7 +1,7 @@ class OrderPolicy < ApplicationPolicy class Scope < Scope - def resolve - if user&.treasurer? || user&.main_bartender? + def resolve # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity + if user&.treasurer? || user&.renting_manager? || user&.main_bartender? scope elsif user scope.orders_for(user) @@ -14,6 +14,6 @@ def index? end def create? - user&.treasurer? || user&.main_bartender? + user&.treasurer? || user&.renting_manager? || user&.main_bartender? end end diff --git a/app/policies/price_list_policy.rb b/app/policies/price_list_policy.rb index a28c98dec..7d77eceb3 100644 --- a/app/policies/price_list_policy.rb +++ b/app/policies/price_list_policy.rb @@ -1,10 +1,20 @@ class PriceListPolicy < ApplicationPolicy + class Scope < Scope + def resolve + if user&.treasurer? + scope + elsif user&.renting_manager? || user&.main_bartender? + scope.unarchived + end + end + end + def index? - user&.treasurer? || user&.main_bartender? + user&.treasurer? || user&.main_bartender? || user&.renting_manager? end def show? - user&.treasurer? || user&.main_bartender? + user&.treasurer? || user&.main_bartender? || user&.renting_manager? end def create? diff --git a/app/policies/user_policy.rb b/app/policies/user_policy.rb index 80b8604e3..835d2e394 100644 --- a/app/policies/user_policy.rb +++ b/app/policies/user_policy.rb @@ -1,6 +1,6 @@ class UserPolicy < ApplicationPolicy def index? - user&.treasurer? + user&.treasurer? || user&.main_bartender? || user&.renting_manager? end def refresh_user_list? @@ -12,7 +12,7 @@ def search? end def show? - user&.treasurer? || record == user + user&.treasurer? || (user&.renting_manager? && User.manual.exists?(id: record)) || record == user end def json? @@ -20,6 +20,6 @@ def json? end def activities? - user&.treasurer? || record == user + show? end end diff --git a/app/views/activities/index.html.erb b/app/views/activities/index.html.erb index b2693cf2d..96cfa8e34 100644 --- a/app/views/activities/index.html.erb +++ b/app/views/activities/index.html.erb @@ -47,7 +47,11 @@ <%= activity.price_list.name %> <% end %> diff --git a/app/views/activities/show.html.erb b/app/views/activities/show.html.erb index 46d429286..24a97315c 100644 --- a/app/views/activities/show.html.erb +++ b/app/views/activities/show.html.erb @@ -3,7 +3,7 @@ <%= render 'edit_modal' %> <% end %> - @@ -87,172 +93,188 @@
-
-
- <% if @credit_mutations.empty? && @orders.empty? %> -
-
{{ user.id }}{{ user.name }} + {{ user.name }} + € {{parseFloat(user.credit).toFixed(2)}}
- <%= link_to activity.created_by.name, activity.created_by %> + <% if policy(activity.created_by).show? %> + <%= link_to activity.created_by.name, activity.created_by %> + <% else %> + <%= activity.created_by.name %> + <% end%>
- + <% if policy(Activity).summary? %> +
+
+ <% if @credit_mutations.empty? && @orders.empty? %> +
+
+ + + + + +
+

+ + Er zijn nog geen bestellingen en er is nog niet ingelegd + +

+
+ + <% else %> +
+ + + + + + + + + + <% Product.categories.each do |category| %> + <% if Rails.application.config.x.codes[category.first.to_sym] != nil %> + + + + + + <% end %> + <% end %> + + + + + + +
ResultaatCodeCredit
<%= t(category.first).capitalize %> + <%= Rails.application.config.x.codes[category.first.to_sym] %> + + <%= number_to_currency(@revenue_by_category[category[0]] || 0, unit: '€') %> +
Totaal opbrengsten + <%= number_to_currency(@revenue_total, unit: '€') %> + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BalansCodeDebitCredit
Inleg Zatladder Inlegsysteem<%= Rails.application.config.x.codes[:credit_mutation] %> + <%= number_to_currency(@credit_mutations_total, unit: '€') %> +
Contante bestellingen<%= number_to_currency(@revenue_with_cash, unit: '€') %>
+ + Totaal kas + + <%= Rails.application.config.x.codes[:cash] %><%= number_to_currency(@cash_total, unit: '€') %>
Omzet Pin<%= Rails.application.config.x.codes[:pin] %><%= number_to_currency(@revenue_with_pin, unit: '€') %>
Omzet Zatladder Inlegsysteem<%= Rails.application.config.x.codes[:credit_mutation] %><%= number_to_currency(@revenue_with_credit, unit: '€') %>
+
+ <% end %> + + <% end %> + <% if policy(Activity).credit_mutations? %> +
+
+ + <% if @credit_mutations.empty? %> - -

- Er zijn nog geen bestellingen en er is nog niet ingelegd + Er zijn nog geen correcties en er is nog niet ingelegd

-
- <% else %> -
- + <% else %> - - - + + + + - <% Product.categories.each do |category| %> - <% if Rails.application.config.x.codes[category.first.to_sym] != nil %> - - - - - - <% end %> + <% @credit_mutations.each do |mutation| %> + + + + + + <% end %> - - - - - -
ResultaatCodeCredit#TijdGebruikerBedrag
<%= t(category.first).capitalize %> - <%= Rails.application.config.x.codes[category.first.to_sym] %> - - <%= number_to_currency(@revenue_by_category[category[0]] || 0, unit: '€') %> -
<%= mutation.id %><%= l mutation.created_at, format: :time_only %> + <% if policy(User).show? %> + <%= link_to mutation.user.name, mutation.user %> + <% else %> + <%= mutation.user.name %> + <% end %> + <%= number_to_currency(mutation.amount, unit: '€') %>
Totaal opbrengsten - <%= number_to_currency(@revenue_total, unit: '€') %> - -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
BalansCodeDebitCredit
Inleg Zatladder Inlegsysteem<%= Rails.application.config.x.codes[:credit_mutation] %> - <%= number_to_currency(@credit_mutations_total, unit: '€') %> -
Contante bestellingen<%= number_to_currency(@revenue_with_cash, unit: '€') %>
- - Totaal kas - - <%= Rails.application.config.x.codes[:cash] %><%= number_to_currency(@cash_total, unit: '€') %>
Omzet Pin<%= Rails.application.config.x.codes[:pin] %><%= number_to_currency(@revenue_with_pin, unit: '€') %>
Omzet Zatladder Inlegsysteem<%= Rails.application.config.x.codes[:credit_mutation] %><%= number_to_currency(@revenue_with_credit, unit: '€') %>
-
- <% end %>
- -
-
- - <% if @credit_mutations.empty? %> - - - - <% else %> - - - - - - - - - - <% @credit_mutations.each do |mutation| %> - - - - - - <% end %> - - <% end %> -
-

- - Er zijn nog geen correcties en er is nog niet ingelegd - -

-
#TijdGebruikerBedrag
<%= mutation.id %><%= l mutation.created_at, format: :time_only %><%= link_to mutation.user.name, mutation.user %><%= number_to_currency(mutation.amount, unit: '€') %>
+ +
- - <% if current_user.treasurer? %> + <% end %> + <% if policy(Activity).orders? %>
@@ -301,7 +323,7 @@ <% order.order_rows.each_with_index do |order_row, i| %> <%= order_row.product.name %> <% if order_row.product_count > 1 %> - ( <%= order_row.product_count %> x) + (<%= order_row.product_count %>x) <% end %> <% if i < order.order_rows.size - 1 %> , @@ -316,13 +338,15 @@ <% end %> -
-
-
- + <% if policy(Activity).product_totals? %> +
+
+
+ +
-
+ <% end %>
diff --git a/app/views/index/index.html.erb b/app/views/index/index.html.erb index 45247a974..1232f83cd 100644 --- a/app/views/index/index.html.erb +++ b/app/views/index/index.html.erb @@ -3,7 +3,7 @@
- <% if current_user&.treasurer? || current_user&.main_bartender? %> + <% if current_user&.treasurer? || current_user&.main_bartender? || current_user&.renting_manager? %>
Welkom, <%= current_user.name %> @@ -49,7 +49,7 @@ <% end %> - <% if @current_activities&.any? %> + <% if policy(Activity).order_screen? && @current_activities&.any? %>

Direct naar het streepscherm diff --git a/app/views/invoices/index.html.erb b/app/views/invoices/index.html.erb index 6d0ff1c2d..1cdd42f29 100644 --- a/app/views/invoices/index.html.erb +++ b/app/views/invoices/index.html.erb @@ -10,9 +10,11 @@

Facturen

- + <% if policy(Invoice).create? %> + + <% end %>
@@ -27,7 +29,9 @@
- + <% if policy(Invoice).send_invoice? %> + + <% end %> @@ -40,7 +44,11 @@ <%= link_to invoice.human_id, invoice %> - + + <% end %> <% end %> diff --git a/app/views/invoices/show.html.erb b/app/views/invoices/show.html.erb index bfcd4daa1..546dc80a4 100644 --- a/app/views/invoices/show.html.erb +++ b/app/views/invoices/show.html.erb @@ -63,7 +63,7 @@
Naam Mailadres StatusVerstuurVerstuur
- <%= link_to invoice.user.name, invoice.user %> + <% if policy(invoice.user).show? %> + <%= link_to invoice.user.name, invoice.user %> + <% else %> + <%= invoice.user.name %> + <% end%> <%= link_to invoice.activity.title, invoice.activity %> @@ -57,13 +65,15 @@ <%= t(invoice.status).humanize %> - <% if invoice.pending? %> - <%= simple_form_for invoice, wrapper: :horizontal_form, url: send_invoice_invoice_path(id: invoice.id), method: :post do |f| %> - <%= f.button :submit, 'Factuur versturen', class: 'btn btn-primary' %> + <% if policy(Invoice).send_invoice? %> + + <% if invoice.pending? %> + <%= simple_form_for invoice, wrapper: :horizontal_form, url: send_invoice_invoice_path(id: invoice.id), method: :post do |f| %> + <%= f.button :submit, 'Factuur versturen', class: 'btn btn-primary' %> + <% end %> <% end %> - <% end %> -
- <% unless @invoice.paid? %> + <% unless !policy(Invoice).send_invoice? || @invoice.paid? %> <%= link_to pay_invoice_url @invoice.token do %> <% end %> diff --git a/app/views/partials/_navigation_bar.html.erb b/app/views/partials/_navigation_bar.html.erb index a70b5f94b..e4ebdf08f 100644 --- a/app/views/partials/_navigation_bar.html.erb +++ b/app/views/partials/_navigation_bar.html.erb @@ -13,14 +13,14 @@ <%= fa_icon 'home', class: 'me-2', text: 'Home' %> <% end %> - <% if current_user&.main_bartender? || current_user&.treasurer? %> + <% if policy(Activity).index? %> <% end %> - <% if current_user&.treasurer? %> + <% if current_user&.treasurer? || current_user&.renting_manager? %> + <% end %> + <% if current_user&.treasurer? %> + <% end %> + <% if policy(:zatladder).index? %> + <% end %> + <% if policy(Invoice).index? %> - <% if policy(Payment).index? %> - - <% end %> + <% end %> + <% if policy(Payment).index? %> + + <% end %> + <% if policy(:finance_overview).index? %>
-
- - + <% if policy(PriceList).create? %> + + <% end %>
+ <% if policy(PriceList).archive? %> +
+ + +
+ <% end %> - +
@@ -39,7 +43,7 @@ - @@ -91,7 +95,7 @@ {{ productPriceToCurrency(findPrice(product, priceList)) }} - diff --git a/app/views/users/index.html.erb b/app/views/users/index.html.erb index d43f11001..9617f796c 100644 --- a/app/views/users/index.html.erb +++ b/app/views/users/index.html.erb @@ -9,23 +9,27 @@ <%= content_tag :div, id: 'users-index', data: {manual_users: @manual_users_json, amber_users: @amber_users_json, inactive_users: @inactive_users_json} do %>

Handmatig aangemaakte gebruikers

- + <% if policy(User).create? %> + + <% end %>

<%= Rails.application.config.x.site_association %> gebruikers

- - <%= link_to refresh_user_list_users_path, class: 'btn btn-primary btn-sm me-1' do %> - <%= fa_icon 'refresh' %> - Synchroniseer gebruikers - <% end %> - + <% if policy(User).refresh_user_list? %> + + <%= link_to refresh_user_list_users_path, class: 'btn btn-primary btn-sm me-1' do %> + <%= fa_icon 'refresh' %> + Synchroniseer gebruikers + <% end %> + + <% end %>
diff --git a/db/seeds.rb b/db/seeds.rb index a307eeab8..3043c9a22 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -42,7 +42,7 @@ FactoryBot.create_list(:invoice, 3, :with_rows) p 'Seeding roles...' -Role.create(role_type: :treasurer, group_uid: 3) -Role.create(role_type: :main_bartender, group_uid: 3) -Role.create(role_type: :main_bartender, group_uid: 2) +Role.create(role_type: :treasurer, group_uid: 4) +Role.create(role_type: :renting_manager, group_uid: 5) +Role.create(role_type: :main_bartender, group_uid: 6) # rubocop:enable Rails/Output diff --git a/spec/controllers/activities_controller/create_invoices_spec.rb b/spec/controllers/activities_controller/create_invoices_spec.rb index 5bc9c24b7..95ee573cb 100644 --- a/spec/controllers/activities_controller/create_invoices_spec.rb +++ b/spec/controllers/activities_controller/create_invoices_spec.rb @@ -21,6 +21,13 @@ expect(request.status).to eq 403 end + it 'unauthenticated when as renting-manager' do + sign_in create(:user, :renting_manager) + request + + expect(request.status).to eq 403 + end + context 'when as treasurer' do let(:user) { create(:user, :treasurer) } diff --git a/spec/controllers/activities_controller/create_spec.rb b/spec/controllers/activities_controller/create_spec.rb index b138e9701..91c31f2c3 100644 --- a/spec/controllers/activities_controller/create_spec.rb +++ b/spec/controllers/activities_controller/create_spec.rb @@ -9,11 +9,26 @@ post :create, params: { activity: activity.attributes } end - it 'creates a new activity' do + it 'treasurer creates a new activity' do sign_in create(:user, :treasurer) expect { request }.to(change(Activity, :count).by(1)) end + it 'renting-manager creates a new activity' do + sign_in create(:user, :renting_manager) + expect { request }.to(change(Activity, :count).by(1)) + end + + it 'main-bartender creates a new activity' do + sign_in create(:user, :main_bartender) + expect { request }.to(change(Activity, :count).by(1)) + end + + it 'user cannot create a new activity' do + sign_in create(:user) + expect { request }.not_to change(Activity, :count) + end + it 'redirects after create' do sign_in create(:user, :treasurer) request diff --git a/spec/controllers/activities_controller/destroy_spec.rb b/spec/controllers/activities_controller/destroy_spec.rb index 43b89c29f..7333ef35c 100644 --- a/spec/controllers/activities_controller/destroy_spec.rb +++ b/spec/controllers/activities_controller/destroy_spec.rb @@ -23,7 +23,7 @@ it { expect(request.status).to eq 403 } end - describe 'when as main bartender' do + describe 'when as main-bartender' do let(:user) { create(:user, :main_bartender) } context 'when with empty activity' do @@ -39,6 +39,22 @@ end end + describe 'when as renting-manager' do + let(:user) { create(:user, :renting_manager) } + + context 'when with empty activity' do + it { expect(request.status).to eq 302 } + it { expect(Activity.count).to eq 0 } + end + + context 'when with non-empty activity' do + let(:additional_records) { create(:order, activity: activity) } + + it { expect(request.status).to eq 302 } + it { expect(Activity.count).to eq 1 } + end + end + describe 'when as treasurer' do let(:user) { create(:user, :treasurer) } diff --git a/spec/controllers/activities_controller/index_spec.rb b/spec/controllers/activities_controller/index_spec.rb index a0222d81d..ca837556f 100644 --- a/spec/controllers/activities_controller/index_spec.rb +++ b/spec/controllers/activities_controller/index_spec.rb @@ -32,6 +32,17 @@ end end + describe 'when as renting-manager' do + let(:user) { create(:user, :renting_manager) } + + it do + expect(request.status).to eq 200 + expect(assigns(:activities).size).to eq 3 + expect(assigns(:price_lists_json)).to eq PriceList.all.to_json(only: %i[id name]) + expect(assigns(:activity)).to be_an_instance_of(Activity) + end + end + describe 'when as treasurer' do let(:user) { create(:user, :treasurer) } diff --git a/spec/controllers/activities_controller/lock_spec.rb b/spec/controllers/activities_controller/lock_spec.rb index 416f14bd9..e12c328db 100644 --- a/spec/controllers/activities_controller/lock_spec.rb +++ b/spec/controllers/activities_controller/lock_spec.rb @@ -21,6 +21,13 @@ expect(request.status).to eq 403 end + it 'unauthenticated when as renting-manager' do + sign_in create(:user, :renting_manager) + request + + expect(request.status).to eq 403 + end + context 'when as treasurer' do let(:user) { create(:user, :treasurer) } diff --git a/spec/controllers/activities_controller/product_totals_spec.rb b/spec/controllers/activities_controller/product_totals_spec.rb index 57d0cfb1c..1b5838c3a 100644 --- a/spec/controllers/activities_controller/product_totals_spec.rb +++ b/spec/controllers/activities_controller/product_totals_spec.rb @@ -33,6 +33,76 @@ expect(json.find { |item| item['name'] == products.first[:name] }['amount']).to eq 6 expect(json.find { |item| item['name'] == products.last[:name] }['amount']).to eq 3 end + + context 'when filtering for user' do + let(:order) { create(:order, activity: activity, user: user) } + let(:params) { { id: activity.id, user: user.id } } + + it do + expect(json.find { |item| item['name'] == products.first[:name] }['amount']).to eq 2 + expect(json.find { |item| item['name'] == products.last[:name] }['amount']).to eq 3 + end + end + + context 'when filtering for cash' do + let(:order) { create(:order, activity: activity, paid_with_cash: true) } + let(:params) { { id: activity.id, paid_with_cash: true } } + + it do + expect(json.find { |item| item['name'] == products.first[:name] }['amount']).to eq 2 + expect(json.find { |item| item['name'] == products.last[:name] }['amount']).to eq 3 + end + end + + context 'when filtering for pin' do + let(:order) { create(:order, activity: activity, paid_with_pin: true) } + let(:params) { { id: activity.id, paid_with_pin: true } } + + it do + expect(json.find { |item| item['name'] == products.first[:name] }['amount']).to eq 2 + expect(json.find { |item| item['name'] == products.last[:name] }['amount']).to eq 3 + end + end + end + + describe 'when as renting-manager' do + let(:user) { create(:user, :renting_manager) } + + it do + expect(request.status).to eq 200 + expect(json.find { |item| item['name'] == products.first[:name] }['amount']).to eq 6 + expect(json.find { |item| item['name'] == products.last[:name] }['amount']).to eq 3 + end + + context 'when filtering for user' do + let(:order) { create(:order, activity: activity, user: user) } + let(:params) { { id: activity.id, user: user.id } } + + it do + expect(json.find { |item| item['name'] == products.first[:name] }['amount']).to eq 2 + expect(json.find { |item| item['name'] == products.last[:name] }['amount']).to eq 3 + end + end + + context 'when filtering for cash' do + let(:order) { create(:order, activity: activity, paid_with_cash: true) } + let(:params) { { id: activity.id, paid_with_cash: true } } + + it do + expect(json.find { |item| item['name'] == products.first[:name] }['amount']).to eq 2 + expect(json.find { |item| item['name'] == products.last[:name] }['amount']).to eq 3 + end + end + + context 'when filtering for pin' do + let(:order) { create(:order, activity: activity, paid_with_pin: true) } + let(:params) { { id: activity.id, paid_with_pin: true } } + + it do + expect(json.find { |item| item['name'] == products.first[:name] }['amount']).to eq 2 + expect(json.find { |item| item['name'] == products.last[:name] }['amount']).to eq 3 + end + end end describe 'when as treasurer' do diff --git a/spec/controllers/activities_controller/update_spec.rb b/spec/controllers/activities_controller/update_spec.rb index cb0472769..f9bf95e37 100644 --- a/spec/controllers/activities_controller/update_spec.rb +++ b/spec/controllers/activities_controller/update_spec.rb @@ -29,6 +29,13 @@ it { expect(activity.title).to eq 'New Title' } end + describe 'when as renting-manager' do + let(:user) { create(:user, :renting_manager) } + + it { expect(request.status).to eq 302 } + it { expect(activity.title).to eq 'New Title' } + end + describe 'when as treasurer' do let(:user) { create(:user, :treasurer) } diff --git a/spec/controllers/credit_mutations_controller/create_spec.rb b/spec/controllers/credit_mutations_controller/create_spec.rb new file mode 100644 index 000000000..df987739f --- /dev/null +++ b/spec/controllers/credit_mutations_controller/create_spec.rb @@ -0,0 +1,67 @@ +require 'rails_helper' + +describe CreditMutationsController, type: :controller do + describe 'POST create' do + let(:user) { create(:user) } + let(:credit_mutation) do + build(:credit_mutation, user: user) + end + let(:credit_mutation_with_activity) do + build(:credit_mutation, activity: create(:activity), user: user) + end + let(:request1) do + post :create, params: { credit_mutation: credit_mutation.attributes, format: :json } + end + let(:request2) do + post :create, params: { credit_mutation: credit_mutation_with_activity.attributes, format: :json } + end + + context 'when as treasurer' do + it 'creates a new credit_mutation' do + sign_in create(:user, :treasurer) + expect { request1 }.to(change(CreditMutation, :count).by(1)) + end + + it 'creates a new credit_mutation linked to an activity' do + sign_in create(:user, :treasurer) + expect { request2 }.to(change(CreditMutation, :count).by(1)) + end + end + + context 'when as renting-manager' do + it 'creates a new credit_mutation' do + sign_in create(:user, :renting_manager) + expect { request1 }.not_to change(CreditMutation, :count) + end + + it 'creates a new credit_mutation linked to an activity' do + sign_in create(:user, :renting_manager) + expect { request2 }.not_to change(CreditMutation, :count) + end + end + + context 'when as main-bartender' do + it 'creates a new credit_mutation' do + sign_in create(:user, :main_bartender) + expect { request1 }.not_to change(CreditMutation, :count) + end + + it 'creates a new credit_mutation linked to an activity' do + sign_in create(:user, :main_bartender) + expect { request2 }.to(change(CreditMutation, :count).by(1)) + end + end + + context 'when as user' do + it 'creates a new credit_mutation' do + sign_in create(:user) + expect { request1 }.not_to change(CreditMutation, :count) + end + + it 'creates a new credit_mutation linked to an activity' do + sign_in create(:user) + expect { request2 }.not_to change(CreditMutation, :count) + end + end + end +end diff --git a/spec/controllers/credit_mutations_controller/index_spec.rb b/spec/controllers/credit_mutations_controller/index_spec.rb new file mode 100644 index 000000000..088cedf93 --- /dev/null +++ b/spec/controllers/credit_mutations_controller/index_spec.rb @@ -0,0 +1,50 @@ +require 'rails_helper' + +describe CreditMutationsController, type: :controller do + describe 'GET index' do + let(:credit_mutation) { create(:credit_mutation, user: create(:user)) } + let(:credit_mutation_with_activity) { create(:credit_mutation, activity: create(:activity), user: create(:user)) } + let(:request) { get :index } + + before do + credit_mutation + credit_mutation_with_activity + sign_in user + request + end + + describe 'when as treasurer' do + let(:user) { create(:user, :treasurer) } + + it 'shows credit_mutations' do + expect(request.status).to eq 200 + expect(assigns(:credit_mutations).size).to eq 2 + end + end + + describe 'when as renting-manager' do + let(:user) { create(:user, :renting_manager) } + + it 'shows credit_mutations' do + expect(response).to have_http_status(:forbidden) + end + end + + describe 'when as main-bartender' do + let(:user) { create(:user, :main_bartender) } + + it 'shows credit_mutations' do + expect(request.status).to eq 200 + expect(assigns(:credit_mutations).size).to eq 1 + end + end + + describe 'when as user' do + let(:user) { create(:user) } + + it 'shows credit_mutations' do + expect(response).to have_http_status(:forbidden) + end + end + end +end diff --git a/spec/controllers/invoices_controller/create_spec.rb b/spec/controllers/invoices_controller/create_spec.rb new file mode 100644 index 000000000..892eec3f2 --- /dev/null +++ b/spec/controllers/invoices_controller/create_spec.rb @@ -0,0 +1,38 @@ +require 'rails_helper' + +describe InvoicesController, type: :controller do + describe 'POST create' do + let(:invoice) do + build(:invoice, user: create(:user), activity: create(:activity, :locked)) + end + let(:request) do + post :create, params: { invoice: invoice.attributes } + end + + it 'treasurer creates a new invoice' do + sign_in create(:user, :treasurer) + expect { request }.to(change(Invoice, :count).by(1)) + end + + it 'renting-manager cannot create a new invoice' do + sign_in create(:user, :renting_manager) + expect { request }.not_to change(Invoice, :count) + end + + it 'main-bartender cannot create a new invoice' do + sign_in create(:user, :main_bartender) + expect { request }.not_to change(Invoice, :count) + end + + it 'user cannot create a new invoice' do + sign_in create(:user) + expect { request }.not_to change(Invoice, :count) + end + + it 'redirects after create' do + sign_in create(:user, :treasurer) + request + expect(response).to be_redirect + end + end +end diff --git a/spec/controllers/invoices_controller/index_spec.rb b/spec/controllers/invoices_controller/index_spec.rb index afe2d4101..ab7fad4e9 100644 --- a/spec/controllers/invoices_controller/index_spec.rb +++ b/spec/controllers/invoices_controller/index_spec.rb @@ -17,6 +17,24 @@ end end + context 'when as renting-manager' do + it 'shows invoices' do + sign_in create(:user, :renting_manager) + get :index + + expect(assigns(:invoices).size).to eq invoices.size + end + end + + context 'when as main-bartender' do + it 'forbids' do + sign_in create(:user, :main_bartender) + get :index + + expect(response).to have_http_status(:forbidden) + end + end + context 'when as user' do it 'forbids' do sign_in create(:user) diff --git a/spec/controllers/invoices_controller/show_spec.rb b/spec/controllers/invoices_controller/show_spec.rb index e6cfc6453..a18763cd2 100644 --- a/spec/controllers/invoices_controller/show_spec.rb +++ b/spec/controllers/invoices_controller/show_spec.rb @@ -17,6 +17,24 @@ end end + context 'when as renting-manager' do + it 'shows invoice' do + sign_in create(:user, :renting_manager) + get :show, params: { id: invoice.id } + + expect(response).to have_http_status(:ok) + end + end + + context 'when as main-bartender' do + it 'forbids' do + sign_in create(:user, :main_bartender) + get :show, params: { id: invoice.id } + + expect(response).to have_http_status(:forbidden) + end + end + context 'when as user' do it 'forbids' do sign_in create(:user) diff --git a/spec/controllers/orders_controller/create_spec.rb b/spec/controllers/orders_controller/create_spec.rb new file mode 100644 index 000000000..d863db985 --- /dev/null +++ b/spec/controllers/orders_controller/create_spec.rb @@ -0,0 +1,74 @@ +require 'rails_helper' + +describe OrdersController, type: :controller do + describe 'POST create' do + let(:activity) { create(:activity) } + let(:locked_activity) { create(:activity) } + let(:order) do + build(:order, activity: activity, user: create(:user)) + end + let(:order_on_locked_activity) do + build(:order, activity: locked_activity, user: create(:user)) + end + let(:request) do + post :create, params: { order: order.attributes } + end + let(:request_on_locked_activity) do + post :create, params: { order: order_on_locked_activity.attributes } + end + + before do + locked_activity.update(locked_by: create(:user)) + + sign_in user + end + + describe 'when as treasurer' do + let(:user) { create(:user, :treasurer) } + + it 'when with order on activity' do + expect { request }.to(change(Order, :count).by(1)) + end + + it 'when with order on locked activty' do + expect { request_on_locked_activity }.not_to change(Order, :count) + end + end + + describe 'when as renting-manager' do + let(:user) { create(:user, :renting_manager) } + + it 'when with order on activity' do + expect { request }.to(change(Order, :count).by(1)) + end + + it 'when with order on locked activty' do + expect { request_on_locked_activity }.not_to change(Order, :count) + end + end + + describe 'when as main-bartender' do + let(:user) { create(:user, :main_bartender) } + + it 'when with order on activity' do + expect { request }.to(change(Order, :count).by(1)) + end + + it 'when with order on locked activty' do + expect { request_on_locked_activity }.not_to change(Order, :count) + end + end + + describe 'when as user' do + let(:user) { create(:user) } + + it 'when with order on activity' do + expect { request }.not_to change(Order, :count) + end + + it 'when with order on locked activty' do + expect { request_on_locked_activity }.not_to change(Order, :count) + end + end + end +end diff --git a/spec/controllers/orders_controller/destroy_spec.rb b/spec/controllers/orders_controller/destroy_spec.rb new file mode 100644 index 000000000..6a5ef5beb --- /dev/null +++ b/spec/controllers/orders_controller/destroy_spec.rb @@ -0,0 +1,101 @@ +require 'rails_helper' + +describe OrdersController, type: :controller do + describe 'DELETE destroy' do + let(:activity) { create(:activity) } + let(:locked_activity) { create(:activity) } + let(:order) do + create(:order, activity: activity, user: create(:user)) + end + let(:order_on_locked_activity) do + create(:order, activity: locked_activity, user: create(:user)) + end + let(:products) { activity.price_list.products.sample(2) } + let(:request) do + delete :destroy, params: { id: order.id } + end + let(:request_on_locked_activity) do + delete :destroy, params: { id: order_on_locked_activity.id } + end + + before do + create(:order_row, order: order, product_count: 2, product: activity.price_list.products.first) + create(:order_row, order: order_on_locked_activity, product_count: 2, product: locked_activity.price_list.products.first) + locked_activity.update(locked_by: create(:user)) + + sign_in user + end + + describe 'when without permission' do + let(:user) { create(:user) } + + it 'when with order on activity' do + request + expect(request.status).to eq 403 + expect(Order.count).to eq 2 + expect(Order.first.order_rows.first.product_count).to eq 2 + end + + it 'when with order on locked activty' do + request_on_locked_activity + expect(request_on_locked_activity.status).to eq 403 + expect(Order.count).to eq 2 + expect(Order.first.order_rows.last.product_count).to eq 2 + end + end + + describe 'when as main-bartender' do + let(:user) { create(:user, :main_bartender) } + + it 'when with order on activity' do + request + expect(request.status).to eq 200 + expect(Order.count).to eq 2 + expect(Order.first.order_rows.first.product_count).to eq 0 + end + + it 'when with order on locked activity' do + request_on_locked_activity + expect(response).to have_http_status(:forbidden) + expect(Order.count).to eq 2 + expect(Order.first.order_rows.last.product_count).to eq 2 + end + end + + describe 'when as renting-manager' do + let(:user) { create(:user, :renting_manager) } + + it 'when with order on activity' do + request + expect(request.status).to eq 200 + expect(Order.count).to eq 2 + expect(Order.first.order_rows.first.product_count).to eq 0 + end + + it 'when with order on locked activity' do + request_on_locked_activity + expect(response).to have_http_status(:forbidden) + expect(Order.count).to eq 2 + expect(Order.first.order_rows.last.product_count).to eq 2 + end + end + + describe 'when as treasurer' do + let(:user) { create(:user, :treasurer) } + + it 'when with order on activity' do + request + expect(request.status).to eq 200 + expect(Order.count).to eq 2 + expect(Order.first.order_rows.first.product_count).to eq 0 + end + + it 'when with order on locked activity' do + request_on_locked_activity + expect(response).to have_http_status(:forbidden) + expect(Order.count).to eq 2 + expect(Order.first.order_rows.last.product_count).to eq 2 + end + end + end +end diff --git a/spec/controllers/orders_controller/index_spec.rb b/spec/controllers/orders_controller/index_spec.rb index 8164c9cfc..46974cc6e 100644 --- a/spec/controllers/orders_controller/index_spec.rb +++ b/spec/controllers/orders_controller/index_spec.rb @@ -3,13 +3,18 @@ describe OrdersController, type: :controller do describe 'GET index' do let(:alice) { create(:user, :treasurer) } + let(:bob) { create(:user, :renting_manager) } + let(:carl) { create(:user, :main_bartender) } + let(:amber) { create(:user, :from_amber) } let(:eve) { create(:user) } let(:orders_alice) { create_list(:order, 2, user: alice) } + let(:orders_amber) { create_list(:order, 2, user: amber) } let(:orders_eve) { create_list(:order, 2, user: eve) } before do orders_alice + orders_amber orders_eve end @@ -21,12 +26,65 @@ expect(Order.where(user: alice)).to match_array assigns(:orders) end - it 'show other users orders' do + it 'show other manual users orders' do sign_in alice get :index, params: { user_id: eve.id, format: :json } expect(Order.where(user: eve)).to match_array assigns(:orders) end + + it 'shows other amber users orders' do + sign_in alice + get :index, params: { user_id: amber.id, format: :json } + + expect(Order.where(user: amber)).to match_array assigns(:orders) + end + end + + context 'when as renting-manager' do + it 'shows own orders' do + sign_in bob + get :index, params: { user_id: bob.id, format: :json } + + expect(Order.where(user: bob)).to match_array assigns(:orders) + end + + it 'shows other manual users orders' do + sign_in bob + get :index, params: { user_id: eve.id, format: :json } + + expect(Order.where(user: eve)).to match_array assigns(:orders) + end + + it 'shows other amber users orders' do + sign_in bob + get :index, params: { user_id: amber.id, format: :json } + + expect(Order.where(user: amber)).to match_array assigns(:orders) + end + end + + context 'when as main-bartender' do + it 'shows own orders' do + sign_in carl + get :index, params: { user_id: carl.id, format: :json } + + expect(Order.where(user: carl)).to match_array assigns(:orders) + end + + it 'shows other manual users orders' do + sign_in carl + get :index, params: { user_id: eve.id, format: :json } + + expect(Order.where(user: eve)).to match_array assigns(:orders) + end + + it 'shows other amber users orders' do + sign_in carl + get :index, params: { user_id: amber.id, format: :json } + + expect(Order.where(user: amber)).to match_array assigns(:orders) + end end context 'when as normal user' do @@ -37,12 +95,19 @@ expect(Order.where(user: eve)).to match_array assigns(:orders) end - it 'user cannot see other users orders' do + it 'user cannot see other manual users orders' do sign_in eve get :index, params: { user_id: alice.id, format: :json } expect(assigns(:orders)).to be_empty end + + it 'user cannot see other amber users orders' do + sign_in eve + get :index, params: { user_id: amber.id, format: :json } + + expect(assigns(:orders)).to be_empty + end end end end diff --git a/spec/controllers/orders_controller/update_spec.rb b/spec/controllers/orders_controller/update_spec.rb new file mode 100644 index 000000000..1da12b7ad --- /dev/null +++ b/spec/controllers/orders_controller/update_spec.rb @@ -0,0 +1,95 @@ +require 'rails_helper' + +describe OrdersController, type: :controller do + describe 'PUT update' do + let(:activity) { create(:activity) } + let(:locked_activity) { create(:activity) } + let(:order) do + create(:order, activity: activity, user: create(:user)) + end + let(:order_on_locked_activity) do + create(:order, activity: locked_activity, user: create(:user)) + end + let(:products) { activity.price_list.products.sample(2) } + let(:request) do + put :update, params: { id: order.id, order_rows_attributes: [{ id: order.order_rows.first.id, product_count: 3 }] } + end + let(:request_on_locked_activity) do + put :update, + params: { id: order_on_locked_activity.id, + order_rows_attributes: [{ id: order_on_locked_activity.order_rows.first.id, product_count: 3 }] } + end + + before do + create(:order_row, order: order, product_count: 2, product: activity.price_list.products.first) + create(:order_row, order: order_on_locked_activity, product_count: 2, product: locked_activity.price_list.products.first) + locked_activity.update(locked_by: create(:user)) + + sign_in user + end + + describe 'when without permission' do + let(:user) { create(:user) } + + it 'when with order on activity' do + request + expect(request.status).to eq 403 + expect(Order.first.order_rows.first.product_count).to eq 2 + end + + it 'when with order on locked activty' do + request_on_locked_activity + expect(request_on_locked_activity.status).to eq 403 + expect(Order.first.order_rows.first.product_count).to eq 2 + end + end + + describe 'when as main-bartender' do + let(:user) { create(:user, :main_bartender) } + + it 'when with order on activity' do + request + expect(request.status).to eq 200 + expect(Order.first.order_rows.first.product_count).to eq 3 + end + + it 'when with order on locked activity' do + request_on_locked_activity + expect(response).to have_http_status(:unprocessable_entity) + expect(Order.first.order_rows.last.product_count).to eq 2 + end + end + + describe 'when as renting-manager' do + let(:user) { create(:user, :renting_manager) } + + it 'when with order on activity' do + request + expect(request.status).to eq 200 + expect(Order.first.order_rows.first.product_count).to eq 3 + end + + it 'when with order on locked activity' do + request_on_locked_activity + expect(response).to have_http_status(:unprocessable_entity) + expect(Order.first.order_rows.last.product_count).to eq 2 + end + end + + describe 'when as treasurer' do + let(:user) { create(:user, :treasurer) } + + it 'when with order on activity' do + request + expect(request.status).to eq 200 + expect(Order.first.order_rows.first.product_count).to eq 3 + end + + it 'when with order on locked activity' do + request_on_locked_activity + expect(response).to have_http_status(:unprocessable_entity) + expect(Order.first.order_rows.last.product_count).to eq 2 + end + end + end +end diff --git a/spec/controllers/payments_controller/index_spec.rb b/spec/controllers/payments_controller/index_spec.rb index 1290c97b5..495c5ec7d 100644 --- a/spec/controllers/payments_controller/index_spec.rb +++ b/spec/controllers/payments_controller/index_spec.rb @@ -17,6 +17,24 @@ end end + context 'when as renting-manager' do + it 'forbids' do + sign_in create(:user, :renting_manager) + get :index + + expect(response).to have_http_status(:forbidden) + end + end + + context 'when as main-bartender' do + it 'forbids' do + sign_in create(:user, :main_bartender) + get :index + + expect(response).to have_http_status(:forbidden) + end + end + context 'when as user' do it 'forbids' do sign_in create(:user) diff --git a/spec/controllers/price_lists_controller/archive_spec.rb b/spec/controllers/price_lists_controller/archive_spec.rb new file mode 100644 index 000000000..d50a8d4d8 --- /dev/null +++ b/spec/controllers/price_lists_controller/archive_spec.rb @@ -0,0 +1,43 @@ +require 'rails_helper' + +describe PriceListsController, type: :controller do + describe 'POST /:id/archive' do + let(:price_list) do + create(:price_list) + end + let(:request) do + post :archive, params: { id: price_list.id, format: :json } + end + + before do + sign_in user + request + price_list.reload + end + + describe 'treasurer can archive a price_list' do + let(:user) { create(:user, :treasurer) } + + it { expect(request.status).to eq 200 } + it { expect(price_list.archived_at.today?).to be true } + end + + describe 'renting-manager cannot archive a price_list' do + let(:user) { create(:user, :renting_manager) } + + it { expect(request.status).to eq 403 } + end + + describe 'main-bartender cannot archive a price_list' do + let(:user) { create(:user, :main_bartender) } + + it { expect(request.status).to eq 403 } + end + + describe 'user cannot archive a price_list' do + let(:user) { create(:user) } + + it { expect(request.status).to eq 403 } + end + end +end diff --git a/spec/controllers/price_lists_controller/create_spec.rb b/spec/controllers/price_lists_controller/create_spec.rb new file mode 100644 index 000000000..fe2c49559 --- /dev/null +++ b/spec/controllers/price_lists_controller/create_spec.rb @@ -0,0 +1,38 @@ +require 'rails_helper' + +describe PriceListsController, type: :controller do + describe 'POST create' do + let(:price_list) do + build(:price_list) + end + let(:request) do + post :create, params: { price_list: price_list.attributes } + end + + it 'treasurer cna create a new price_list' do + sign_in create(:user, :treasurer) + expect { request }.to(change(PriceList, :count).by(1)) + end + + it 'renting-manager cannot create a new price_list' do + sign_in create(:user, :renting_manager) + expect { request }.not_to change(PriceList, :count) + end + + it 'main-bartender cannot create a new price_list' do + sign_in create(:user, :main_bartender) + expect { request }.not_to change(PriceList, :count) + end + + it 'user cannot create a new price_list' do + sign_in create(:user) + expect { request }.not_to change(PriceList, :count) + end + + it 'redirects after create' do + sign_in create(:user, :treasurer) + request + expect(response).to be_redirect + end + end +end diff --git a/spec/controllers/price_lists_controller/index_spec.rb b/spec/controllers/price_lists_controller/index_spec.rb new file mode 100644 index 000000000..dbf3f234a --- /dev/null +++ b/spec/controllers/price_lists_controller/index_spec.rb @@ -0,0 +1,52 @@ +require 'rails_helper' + +describe PriceListsController, type: :controller do + describe 'GET index' do + let(:archived_price_lists) { create_list(:price_list, 3, :archived) } + let(:unarchived_price_lists) { create_list(:price_list, 3) } + + before do + archived_price_lists + unarchived_price_lists + end + + context 'when as treasurer' do + it 'shows all price_lists' do + sign_in create(:user, :treasurer) + get :index + + expect(assigns(:price_lists_json)).to eq PriceList.all.order(created_at: :desc).to_json(except: %i[created_at updated_at + deleted_at]) + end + end + + context 'when as renting-manager' do + it 'shows unarchived price_lists' do + sign_in create(:user, :renting_manager) + get :index + + expect(assigns(:price_lists_json)).to eq PriceList.unarchived.order(created_at: :desc).to_json(except: %i[created_at updated_at + deleted_at]) + end + end + + context 'when as main-bartender' do + it 'shows unarchived price_lists' do + sign_in create(:user, :main_bartender) + get :index + + expect(assigns(:price_lists_json)).to eq PriceList.unarchived.order(created_at: :desc).to_json(except: %i[created_at updated_at + deleted_at]) + end + end + + context 'when as user' do + it 'forbids' do + sign_in create(:user) + get :index + + expect(response).to have_http_status(:forbidden) + end + end + end +end diff --git a/spec/controllers/price_lists_controller/unarchive_spec.rb b/spec/controllers/price_lists_controller/unarchive_spec.rb new file mode 100644 index 000000000..796728f49 --- /dev/null +++ b/spec/controllers/price_lists_controller/unarchive_spec.rb @@ -0,0 +1,43 @@ +require 'rails_helper' + +describe PriceListsController, type: :controller do + describe 'POST /:id/unarchive' do + let(:price_list) do + create(:price_list) + end + let(:request) do + post :unarchive, params: { id: price_list.id, format: :json } + end + + before do + sign_in user + request + price_list.reload + end + + describe 'treasurer can unarchive a price_list' do + let(:user) { create(:user, :treasurer) } + + it { expect(request.status).to eq 200 } + it { expect(price_list.archived_at).to be_nil } + end + + describe 'renting-manager cannot unarchive a price_list' do + let(:user) { create(:user, :renting_manager) } + + it { expect(request.status).to eq 403 } + end + + describe 'main-bartender cannot unarchive a price_list' do + let(:user) { create(:user, :main_bartender) } + + it { expect(request.status).to eq 403 } + end + + describe 'user cannot unarchive a price_list' do + let(:user) { create(:user) } + + it { expect(request.status).to eq 403 } + end + end +end diff --git a/spec/controllers/price_lists_controller/update_spec.rb b/spec/controllers/price_lists_controller/update_spec.rb new file mode 100644 index 000000000..7cb136db8 --- /dev/null +++ b/spec/controllers/price_lists_controller/update_spec.rb @@ -0,0 +1,44 @@ +require 'rails_helper' + +describe PriceListsController, type: :controller do + describe 'PUT update' do + let(:price_list) do + create(:price_list) + end + let(:request) do + put :update, params: { id: price_list.id, price_list: price_list.attributes } + end + + before do + sign_in user + price_list.name = 'New Name' + request + price_list.reload + end + + describe 'when without permission' do + let(:user) { create(:user) } + + it { expect(request.status).to eq 403 } + end + + describe 'when as main-bartender' do + let(:user) { create(:user, :main_bartender) } + + it { expect(request.status).to eq 403 } + end + + describe 'when as renting-manager' do + let(:user) { create(:user, :renting_manager) } + + it { expect(request.status).to eq 403 } + end + + describe 'when as treasurer' do + let(:user) { create(:user, :treasurer) } + + it { expect(request.status).to eq 302 } + it { expect(price_list.name).to eq 'New Name' } + end + end +end diff --git a/spec/controllers/products_controller/create_spec.rb b/spec/controllers/products_controller/create_spec.rb new file mode 100644 index 000000000..51101e35b --- /dev/null +++ b/spec/controllers/products_controller/create_spec.rb @@ -0,0 +1,32 @@ +require 'rails_helper' + +describe ProductsController, type: :controller do + describe 'POST create' do + let(:product) do + build(:product) + end + let(:request) do + post :create, params: { product: product.attributes } + end + + it 'treasurer can create a new product' do + sign_in create(:user, :treasurer) + expect { request }.to(change(Product, :count).by(1)) + end + + it 'renting-manager cannot create a new product' do + sign_in create(:user, :renting_manager) + expect { request }.not_to change(Product, :count) + end + + it 'main-bartender cannot create a new product' do + sign_in create(:user, :main_bartender) + expect { request }.not_to change(Product, :count) + end + + it 'user cannot create a new product' do + sign_in create(:user) + expect { request }.not_to change(Product, :count) + end + end +end diff --git a/spec/controllers/products_controller/update_spec.rb b/spec/controllers/products_controller/update_spec.rb new file mode 100644 index 000000000..8c5c6de7d --- /dev/null +++ b/spec/controllers/products_controller/update_spec.rb @@ -0,0 +1,46 @@ +require 'rails_helper' + +describe ProductsController, type: :controller do + describe 'PUT update' do + let(:product) do + create(:product, product_prices: [create(:product_price)]) + end + let(:request) do + put :update, + params: { id: product.id, + product: product.attributes.merge({ product_prices_attributes: [product.product_prices.first.attributes] }) } + end + + before do + sign_in user + product.product_prices.first.price = 10.00 + request + product.reload + end + + describe 'when without permission' do + let(:user) { create(:user) } + + it { expect(request.status).to eq 403 } + end + + describe 'when as main-bartender' do + let(:user) { create(:user, :main_bartender) } + + it { expect(request.status).to eq 403 } + end + + describe 'when as renting-manager' do + let(:user) { create(:user, :renting_manager) } + + it { expect(request.status).to eq 403 } + end + + describe 'when as treasurer' do + let(:user) { create(:user, :treasurer) } + + it { expect(request.status).to eq 200 } + it { expect(product.product_prices.first.price).to eq 10.00 } + end + end +end diff --git a/spec/controllers/users_controller/create_spec.rb b/spec/controllers/users_controller/create_spec.rb new file mode 100644 index 000000000..b2de00877 --- /dev/null +++ b/spec/controllers/users_controller/create_spec.rb @@ -0,0 +1,38 @@ +require 'rails_helper' + +describe UsersController, type: :controller do + describe 'POST create' do + let(:user) do + build(:user, :manual) + end + let(:request) do + post :create, params: { user: user.attributes } + end + + it 'treasurer can create a new user' do + sign_in create(:user, :treasurer) + expect { request }.to(change(User, :count).by(1)) + end + + it 'renting-manager cannot create a new user' do + sign_in create(:user, :renting_manager) + expect { request }.not_to change(User, :count) + end + + it 'main-bartender cannot create a new user' do + sign_in create(:user, :main_bartender) + expect { request }.not_to change(User, :count) + end + + it 'user cannot create a new user' do + sign_in create(:user) + expect { request }.not_to change(User, :count) + end + + it 'redirects after create' do + sign_in create(:user, :treasurer) + request + expect(response).to be_redirect + end + end +end diff --git a/spec/controllers/users_controller/index_spec.rb b/spec/controllers/users_controller/index_spec.rb new file mode 100644 index 000000000..4d2b37dba --- /dev/null +++ b/spec/controllers/users_controller/index_spec.rb @@ -0,0 +1,58 @@ +require 'rails_helper' + +describe UsersController, type: :controller do + describe 'GET index' do + let(:alice) { create(:user, :treasurer, :manual) } + let(:bob) { create(:user, :renting_manager, :manual) } + let(:carl) { create(:user, :main_bartender, :manual) } + let(:amber) { create(:user, :from_amber) } + let(:eve) { create(:user, :manual) } + + before do + alice + bob + carl + amber + eve + end + + context 'when as treasurer' do + it 'shows all users' do + sign_in alice + get :index + + expect(assigns(:manual_users).size).to eq 4 + expect(assigns(:amber_users).size).to eq 1 + end + end + + context 'when as renting-manager' do + it 'shows manual users' do + sign_in bob + get :index + + expect(assigns(:manual_users).size).to eq 4 + expect(assigns(:amber_users).size).to eq 0 + end + end + + context 'when as main-bartender' do + it 'shows own user' do + sign_in carl + get :index + + expect(assigns(:manual_users).size).to eq 1 + expect(assigns(:amber_users).size).to eq 0 + end + end + + context 'when as user' do + it 'forbids' do + sign_in eve + get :index + + expect(response).to have_http_status(:forbidden) + end + end + end +end diff --git a/spec/controllers/users_controller/show_spec.rb b/spec/controllers/users_controller/show_spec.rb new file mode 100644 index 000000000..b1b383987 --- /dev/null +++ b/spec/controllers/users_controller/show_spec.rb @@ -0,0 +1,77 @@ +require 'rails_helper' + +describe UsersController, type: :controller do + describe 'GET show' do + let(:amber) { create(:user, :from_amber) } + let(:eve) { create(:user, :manual) } + + before do + amber + eve + end + + context 'when as treasurer' do + it 'shows manual user' do + sign_in create(:user, :treasurer) + get :show, params: { id: eve.id } + + expect(response).to have_http_status(:ok) + end + + it 'shows amber user' do + sign_in create(:user, :treasurer) + get :show, params: { id: amber.id } + + expect(response).to have_http_status(:ok) + end + end + + context 'when as renting-manager' do + it 'shows manual user' do + sign_in create(:user, :renting_manager) + get :show, params: { id: eve.id } + + expect(response).to have_http_status(:ok) + end + + it 'forbids showing amber user' do + sign_in create(:user, :renting_manager) + get :show, params: { id: amber.id } + + expect(response).to have_http_status(:forbidden) + end + end + + context 'when as main-bartender' do + it 'forbids showing manual user' do + sign_in create(:user, :main_bartender) + get :show, params: { id: eve.id } + + expect(response).to have_http_status(:forbidden) + end + + it 'forbids showing amber user' do + sign_in create(:user, :main_bartender) + get :show, params: { id: amber.id } + + expect(response).to have_http_status(:forbidden) + end + end + + context 'when as user' do + it 'forbids showing manual user' do + sign_in create(:user) + get :show, params: { id: eve.id } + + expect(response).to have_http_status(:forbidden) + end + + it 'forbids showing amber user' do + sign_in create(:user) + get :show, params: { id: amber.id } + + expect(response).to have_http_status(:forbidden) + end + end + end +end diff --git a/spec/controllers/users_controller/update_spec.rb b/spec/controllers/users_controller/update_spec.rb new file mode 100644 index 000000000..3d3d6a2ef --- /dev/null +++ b/spec/controllers/users_controller/update_spec.rb @@ -0,0 +1,44 @@ +require 'rails_helper' + +describe UsersController, type: :controller do + describe 'PUT update' do + let(:user) do + create(:user, :manual) + end + let(:request) do + put :update, params: { id: user.id, user: user.attributes } + end + + before do + sign_in user + user.name = 'New Name' + request + user.reload + end + + describe 'when as user' do + let(:user) { create(:user) } + + it { expect(request.status).to eq 403 } + end + + describe 'when as main-bartender' do + let(:user) { create(:user, :main_bartender) } + + it { expect(request.status).to eq 403 } + end + + describe 'when as renting-manager' do + let(:user) { create(:user, :renting_manager) } + + it { expect(request.status).to eq 403 } + end + + describe 'when as treasurer' do + let(:user) { create(:user, :treasurer) } + + it { expect(request.status).to eq 302 } + it { expect(user.name).to eq 'New Name' } + end + end +end diff --git a/spec/factories/price_list.rb b/spec/factories/price_list.rb index 9960d1804..2044f8c6d 100644 --- a/spec/factories/price_list.rb +++ b/spec/factories/price_list.rb @@ -16,6 +16,10 @@ with_specific_products { true } end + trait :archived do + archived_at { 1.day.ago } + end + after(:create) do |price_list, evaluator| if evaluator.with_all_products Product.all.each do |product| diff --git a/spec/factories/role.rb b/spec/factories/role.rb index 6deb8d414..4f59d06b0 100644 --- a/spec/factories/role.rb +++ b/spec/factories/role.rb @@ -1,6 +1,6 @@ FactoryBot.define do factory :role do - role_type { %i[treasurer main_bartender].sample } + role_type { %i[treasurer main_bartender renting_manager].sample } group_uid { rand(1...100) } end end diff --git a/spec/factories/user.rb b/spec/factories/user.rb index 6beb9806d..5ead18872 100644 --- a/spec/factories/user.rb +++ b/spec/factories/user.rb @@ -15,5 +15,19 @@ user.roles = [FactoryBot.create(:role, role_type: :main_bartender)] end end + + trait(:renting_manager) do + after :create do |user, _evaluator| + user.roles = [FactoryBot.create(:role, role_type: :renting_manager)] + end + end + + trait(:from_amber) do + provider { 'amber_oauth2' } + end + + trait(:manual) do + provider { nil } + end end end diff --git a/spec/models/role_spec.rb b/spec/models/role_spec.rb index 1e782d2f7..7e16e5980 100644 --- a/spec/models/role_spec.rb +++ b/spec/models/role_spec.rb @@ -26,7 +26,13 @@ it { expect(role.name).to eq Rails.application.config.x.treasurer_title.capitalize } end - context 'when main bartender' do + context 'when renting-manager' do + subject(:role) { build_stubbed(:role, role_type: :renting_manager) } + + it { expect(role.name).to eq 'Verhuur manager' } + end + + context 'when main-bartender' do subject(:role) { build_stubbed(:role, role_type: :main_bartender) } it { expect(role.name).to eq 'Hoofdtapper' }
ID +
+ @@ -101,19 +105,22 @@
- + <% if policy(Product).create? %> + + <% end %>
- - + + +