Add some methods to deal with storage limits
This commit is contained in:
@@ -12,7 +12,7 @@ class Admin::AccountsController < AdminController
|
||||
end
|
||||
|
||||
def update
|
||||
@account.override_limits(card_count: overridden_card_count_param)
|
||||
@account.override_limits(**overridden_limits_params.to_h.symbolize_keys)
|
||||
redirect_to saas.edit_admin_account_path(@account.external_account_id), notice: "Account limits updated"
|
||||
end
|
||||
|
||||
@@ -21,7 +21,7 @@ class Admin::AccountsController < AdminController
|
||||
@account = Account.find_by!(external_account_id: params[:id])
|
||||
end
|
||||
|
||||
def overridden_card_count_param
|
||||
params[:account][:overridden_card_count].to_i
|
||||
def overridden_limits_params
|
||||
params.expect(account: [ :card_count, :bytes_used ])
|
||||
end
|
||||
end
|
||||
|
||||
@@ -6,15 +6,20 @@ module Account::Limited
|
||||
end
|
||||
|
||||
NEAR_CARD_LIMIT_THRESHOLD = 100
|
||||
NEAR_STORAGE_LIMIT_THRESHOLD = 500.megabytes
|
||||
|
||||
def override_limits(card_count:)
|
||||
(overridden_limits || build_overridden_limits).update!(card_count:)
|
||||
def override_limits(card_count: nil, bytes_used: nil)
|
||||
(overridden_limits || build_overridden_limits).update!(card_count:, bytes_used:)
|
||||
end
|
||||
|
||||
def billed_cards_count
|
||||
overridden_limits&.card_count || cards_count
|
||||
end
|
||||
|
||||
def billed_bytes_used
|
||||
overridden_limits&.bytes_used || bytes_used
|
||||
end
|
||||
|
||||
def nearing_plan_cards_limit?
|
||||
plan.limit_cards? && remaining_cards_count < NEAR_CARD_LIMIT_THRESHOLD
|
||||
end
|
||||
@@ -23,6 +28,22 @@ module Account::Limited
|
||||
plan.limit_cards? && billed_cards_count > plan.card_limit
|
||||
end
|
||||
|
||||
def nearing_plan_storage_limit?
|
||||
remaining_storage < NEAR_STORAGE_LIMIT_THRESHOLD
|
||||
end
|
||||
|
||||
def exceeding_storage_limit?
|
||||
billed_bytes_used > plan.storage_limit
|
||||
end
|
||||
|
||||
def nearing_limits?
|
||||
nearing_plan_cards_limit? || nearing_plan_storage_limit?
|
||||
end
|
||||
|
||||
def exceeding_limits?
|
||||
exceeding_card_limit? || exceeding_storage_limit?
|
||||
end
|
||||
|
||||
def reset_overridden_limits
|
||||
overridden_limits&.destroy
|
||||
reload_overridden_limits
|
||||
@@ -32,4 +53,8 @@ module Account::Limited
|
||||
def remaining_cards_count
|
||||
plan.card_limit - billed_cards_count
|
||||
end
|
||||
|
||||
def remaining_storage
|
||||
plan.storage_limit - billed_bytes_used
|
||||
end
|
||||
end
|
||||
|
||||
@@ -11,14 +11,21 @@
|
||||
<dt class="font-weight-bold">Actual card count:</dt>
|
||||
<dd class="margin-inline-start-none"><%= @account.cards_count %></dd>
|
||||
</div>
|
||||
<div class="flex gap-half">
|
||||
<dt class="font-weight-bold">Actual bytes used:</dt>
|
||||
<dd class="margin-inline-start-none"><%= storage_to_human_size(@account.bytes_used) %></dd>
|
||||
</div>
|
||||
</dl>
|
||||
|
||||
<%= form_with model: @account, url: saas.admin_account_path(@account.external_account_id), class: "flex flex-column gap" do |form| %>
|
||||
<div class="flex flex-column gap-half">
|
||||
<%= form.label :overridden_card_count, "Override card count", class: "font-weight-bold" %>
|
||||
<div class="flex align-center gap input input--actor">
|
||||
<%= form.number_field :overridden_card_count, value: @account.overridden_limits&.card_count, class: "input full-width" %>
|
||||
</div>
|
||||
<div class="flex align-center gap-half">
|
||||
<%= form.label :card_count, "Override card count", class: "font-weight-bold" %>
|
||||
<%= form.number_field :card_count, value: @account.overridden_limits&.card_count, class: "input" %>
|
||||
</div>
|
||||
|
||||
<div class="flex align-center gap-half">
|
||||
<%= form.label :bytes_used, "Override bytes used", class: "font-weight-bold" %>
|
||||
<%= form.number_field :bytes_used, value: @account.overridden_limits&.bytes_used, class: "input" %>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn--reversed">Save</button>
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
class AddBytesUsedToAccountOverriddenLimits < ActiveRecord::Migration[8.2]
|
||||
def change
|
||||
add_column :account_overridden_limits, :bytes_used, :bigint
|
||||
end
|
||||
end
|
||||
@@ -10,7 +10,7 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema[8.2].define(version: 2025_12_15_170000) do
|
||||
ActiveRecord::Schema[8.2].define(version: 2025_12_16_000000) do
|
||||
create_table "account_billing_waivers", id: :uuid, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.uuid "account_id", null: false
|
||||
t.datetime "created_at", null: false
|
||||
@@ -20,6 +20,7 @@ ActiveRecord::Schema[8.2].define(version: 2025_12_15_170000) do
|
||||
|
||||
create_table "account_overridden_limits", id: :uuid, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.uuid "account_id", null: false
|
||||
t.bigint "bytes_used"
|
||||
t.integer "card_count"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
|
||||
@@ -73,4 +73,45 @@ class Account::LimitedTest < ActiveSupport::TestCase
|
||||
|
||||
assert account.exceeding_card_limit?
|
||||
end
|
||||
|
||||
test "detect nearing storage limit" do
|
||||
# Paid plans have large storage limits
|
||||
accounts(:"37s").update_column(:bytes_used, 4.gigabytes)
|
||||
assert_not accounts(:"37s").nearing_plan_storage_limit?
|
||||
|
||||
# Free plan not near limit
|
||||
accounts(:initech).update_column(:bytes_used, 400.megabytes)
|
||||
assert_not accounts(:initech).nearing_plan_storage_limit?
|
||||
|
||||
# Free plan near limit
|
||||
accounts(:initech).update_column(:bytes_used, 600.megabytes)
|
||||
assert accounts(:initech).nearing_plan_storage_limit?
|
||||
end
|
||||
|
||||
test "detect exceeding storage limit" do
|
||||
# Free plan under limit
|
||||
accounts(:initech).update_column(:bytes_used, 900.megabytes)
|
||||
assert_not accounts(:initech).exceeding_storage_limit?
|
||||
|
||||
# Free plan over limit
|
||||
accounts(:initech).update_column(:bytes_used, 1.1.gigabytes)
|
||||
assert accounts(:initech).exceeding_storage_limit?
|
||||
end
|
||||
|
||||
test "override bytes_used limits" do
|
||||
account = accounts(:initech)
|
||||
account.update_column(:bytes_used, 1.1.gigabytes)
|
||||
|
||||
assert account.exceeding_storage_limit?
|
||||
assert_equal 1.1.gigabytes, account.billed_bytes_used
|
||||
|
||||
account.override_limits bytes_used: 500.megabytes
|
||||
assert_not account.exceeding_storage_limit?
|
||||
assert_equal 500.megabytes, account.billed_bytes_used
|
||||
assert_equal 1.1.gigabytes, account.bytes_used # original unchanged
|
||||
|
||||
account.reset_overridden_limits
|
||||
assert account.exceeding_storage_limit?
|
||||
assert_equal 1.1.gigabytes, account.billed_bytes_used
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user