Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Renting manager role #916

Open
wants to merge 11 commits into
base: staging
Choose a base branch
from
7 changes: 3 additions & 4 deletions app/controllers/activities_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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]))

Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
8 changes: 5 additions & 3 deletions app/controllers/credit_mutations_controller.rb
Original file line number Diff line number Diff line change
@@ -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
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/invoices_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/orders_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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|
Expand Down
7 changes: 4 additions & 3 deletions app/controllers/price_lists_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
6 changes: 3 additions & 3 deletions app/controllers/users_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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])
Expand Down
9 changes: 9 additions & 0 deletions app/javascript/components/activity/ProductTotals.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@
<td>{{orderTotal.amount}} x</td>
<td class="text-end">{{doubleToCurrency(orderTotal.price)}}</td>
</tr>
<tr>
<th scope="col">Totaal</th>
<td></td>
<td class="text-end">
<strong>{{doubleToCurrency(totalAmount)}}</strong>
</td>
</tr>
</tbody>
</table>
<table v-else class="table table-striped">
Expand Down Expand Up @@ -56,6 +63,7 @@ export default {
return {
user: {},
orderTotals: [],
totalAmount: 0.0,
isLoading: true
};
},
Expand All @@ -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;
});
},
Expand Down
6 changes: 4 additions & 2 deletions app/javascript/components/user/UsersTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@
<tbody class="table-group-divider">
<tr v-for="user in sortedUsers" :key="user.id">
<th class="ps-4" aria-colindex="1">{{ user.id }}</th>
<td><a :href="`/users/${user.id}`" aria-colindex="2">{{ user.name }}</a></td>
<td>
<a :href="`/users/${user.id}`" aria-colindex="2">{{ user.name }}</a>
</td>
<td :class="user.credit < 0 ? 'text-danger' : ''" aria-colindex="3">€ {{parseFloat(user.credit).toFixed(2)}}</td>
</tr>
</tbody>
Expand All @@ -53,7 +55,7 @@ export default {
users: {
type: Array,
required: true
}
},
},

data() {
Expand Down
7 changes: 7 additions & 0 deletions app/javascript/packs/activity.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
});
4 changes: 4 additions & 0 deletions app/models/credit_mutation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 3 additions & 1 deletion app/models/order_row.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions app/models/price_list.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand Down
4 changes: 3 additions & 1 deletion app/models/role.rb
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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
4 changes: 4 additions & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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) }
Expand Down
26 changes: 17 additions & 9 deletions app/policies/activity_policy.rb
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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?
Expand All @@ -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
4 changes: 2 additions & 2 deletions app/policies/application_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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?
Expand All @@ -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
Expand Down
16 changes: 15 additions & 1 deletion app/policies/credit_mutation_policy.rb
Original file line number Diff line number Diff line change
@@ -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
2 changes: 1 addition & 1 deletion app/policies/invoice_policy.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
class InvoicePolicy < ApplicationPolicy
def index?
user&.treasurer?
user&.treasurer? || user&.renting_manager?
end

def send_invoice?
Expand Down
6 changes: 3 additions & 3 deletions app/policies/order_policy.rb
Original file line number Diff line number Diff line change
@@ -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)
Expand All @@ -14,6 +14,6 @@ def index?
end

def create?
user&.treasurer? || user&.main_bartender?
user&.treasurer? || user&.renting_manager? || user&.main_bartender?
end
end
14 changes: 12 additions & 2 deletions app/policies/price_list_policy.rb
Original file line number Diff line number Diff line change
@@ -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?
Expand Down
6 changes: 3 additions & 3 deletions app/policies/user_policy.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
class UserPolicy < ApplicationPolicy
def index?
user&.treasurer?
user&.treasurer? || user&.main_bartender? || user&.renting_manager?
end

def refresh_user_list?
Expand All @@ -12,14 +12,14 @@ def search?
end

def show?
user&.treasurer? || record == user
user&.treasurer? || (user&.renting_manager? && User.manual.exists?(id: record)) || record == user
end

def json?
user&.main_bartender? || show?
end

def activities?
user&.treasurer? || record == user
show?
end
end
Loading
Loading