Add system to comp accounts

This commit is contained in:
Jorge Manrubia
2025-12-15 16:44:53 +01:00
parent 3ef5e4eeef
commit 8dd31e3635
13 changed files with 143 additions and 7 deletions
@@ -0,0 +1,13 @@
class Admin::BillingWaiversController < AdminController
include Admin::AccountScoped
def create
@account.comp
redirect_to saas.edit_admin_account_path(@account.external_account_id), notice: "Account comped"
end
def destroy
@account.uncomp
redirect_to saas.edit_admin_account_path(@account.external_account_id), notice: "Account uncomped"
end
end
+24 -1
View File
@@ -3,6 +3,7 @@ module Account::Billing
included do
has_one :subscription, class_name: "Account::Subscription", dependent: :destroy
has_one :billing_waiver, class_name: "Account::BillingWaiver", dependent: :destroy
end
def plan
@@ -10,10 +11,32 @@ module Account::Billing
end
def active_subscription
subscription if subscription&.active?
if comped?
comped_subscription
else
subscription if subscription&.active?
end
end
def subscribed?
subscription.present?
end
def comped?
billing_waiver.present?
end
def comp
create_billing_waiver unless billing_waiver
end
def uncomp
billing_waiver&.destroy
reload_billing_waiver
end
private
def comped_subscription
@comped_subscription ||= billing_waiver&.subscription
end
end
@@ -0,0 +1,7 @@
class Account::BillingWaiver < SaasRecord
belongs_to :account
def subscription
@subscription ||= Account::Subscription.new(plan_key: Plan.paid.key)
end
end
+1 -1
View File
@@ -8,7 +8,7 @@ class Account::Subscription < SaasRecord
delegate :paid?, to: :plan
def plan
Plan.find(plan_key)
@plan ||= Plan.find(plan_key)
end
def to_be_canceled?
+2 -2
View File
@@ -12,11 +12,11 @@ class Plan
end
def free
@free ||= all.find(&:free?)
@free ||= find(:free_v1)
end
def paid
@paid ||= all.find(&:paid?)
@paid ||= find(:monthly_v1)
end
def find(key)
@@ -1,4 +1,4 @@
<% if Current.user.admin? %>
<% if Current.user.admin? && !Current.account.comped? %>
<section class="panel panel--wide settings-subscription__panel shadow center margin-block-double">
<h2 id="subscription" class="divider settings-subscription__divider txt-small txt-uppercase margin-none">Subscription</h2>
@@ -28,6 +28,12 @@
<%= button_to "Reset limits", saas.admin_account_overridden_limits_path(@account.external_account_id), method: :delete, class: "btn btn--negative" %>
<% end %>
<% if @account.comped? %>
<%= button_to "Uncomp account", saas.admin_account_billing_waiver_path(@account.external_account_id), method: :delete, class: "btn btn--negative" %>
<% else %>
<%= button_to "Comp account", saas.admin_account_billing_waiver_path(@account.external_account_id), method: :post, class: "btn btn--positive" %>
<% end %>
<%= link_to "Back to accounts", saas.admin_accounts_path, class: "btn btn--plain txt-link" %>
</div>
</div>
+1
View File
@@ -7,6 +7,7 @@ Fizzy::Saas::Engine.routes.draw do
resource :account_search, only: :create
resources :accounts do
resource :overridden_limits, only: :destroy
resource :billing_waiver, only: [ :create, :destroy ]
end
end
end
@@ -0,0 +1,9 @@
class CreateAccountBillingWaivers < ActiveRecord::Migration[8.2]
def change
create_table :account_billing_waivers, id: :uuid do |t|
t.references :account, null: false, type: :uuid, index: { unique: true }
t.timestamps
end
end
end
+8 -1
View File
@@ -10,7 +10,14 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[8.2].define(version: 2025_12_15_140000) do
ActiveRecord::Schema[8.2].define(version: 2025_12_15_160000) 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
t.datetime "updated_at", null: false
t.index ["account_id"], name: "index_account_billing_waivers_on_account_id", unique: true
end
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.integer "card_count"
@@ -0,0 +1,32 @@
require "test_helper"
class Admin::BillingWaiversControllerTest < ActionDispatch::IntegrationTest
test "staff can comp an account" do
sign_in_as :david
account = accounts(:"37s")
assert_not account.comped?
untenanted do
post saas.admin_account_billing_waiver_path(account.external_account_id)
assert_redirected_to saas.edit_admin_account_path(account.external_account_id)
end
assert account.reload.comped?
end
test "staff can uncomp an account" do
sign_in_as :david
account = accounts(:"37s")
account.comp
assert account.comped?
untenanted do
delete saas.admin_account_billing_waiver_path(account.external_account_id)
assert_redirected_to saas.edit_admin_account_path(account.external_account_id)
end
assert_not account.reload.comped?
end
end
+14 -1
View File
@@ -2,7 +2,7 @@ require "test_helper"
class Account::BillingTest < ActiveSupport::TestCase
test "active subscription" do
account = Account.create!(name: "Test")
account = accounts(:initech)
# No subscription
assert_nil account.active_subscription
@@ -15,4 +15,17 @@ class Account::BillingTest < ActiveSupport::TestCase
account.subscription.update!(status: "active")
assert_equal account.subscription, account.active_subscription
end
test "comped account" do
account = accounts(:"37s")
assert_not account.comped?
account.comp
assert account.comped?
# Calling comp again does not create duplicate
account.comp
assert_equal 1, Account::BillingWaiver.where(account: account).count
end
end
+25
View File
@@ -48,4 +48,29 @@ class Account::LimitedTest < ActiveSupport::TestCase
assert account.exceeding_card_limit?
assert_equal 1001, account.billed_cards_count
end
test "comped accounts are never limited" do
account = accounts(:initech)
account.update_column(:cards_count, 1_000_000)
assert account.exceeding_card_limit?
assert account.nearing_plan_cards_limit?
account.comp
assert_not account.exceeding_card_limit?
assert_not account.nearing_plan_cards_limit?
end
test "uncomping an account restores limits" do
account = accounts(:initech)
account.update_column(:cards_count, 1_000_000)
account.comp
assert_not account.exceeding_card_limit?
account.uncomp
assert account.exceeding_card_limit?
end
end