diff --git a/app/helpers/billing_helper.rb b/app/helpers/billing_helper.rb index 26669e38d..e2ada7e86 100644 --- a/app/helpers/billing_helper.rb +++ b/app/helpers/billing_helper.rb @@ -18,4 +18,8 @@ module BillingHelper def non_web_inboxes(account) account.inboxes.where.not(channel_type: Channel::WebWidget.to_s).count end + + def agents(account) + account.users.count + end end diff --git a/app/javascript/dashboard/App.vue b/app/javascript/dashboard/App.vue index ae50055fb..e51958e9e 100644 --- a/app/javascript/dashboard/App.vue +++ b/app/javascript/dashboard/App.vue @@ -4,7 +4,6 @@ import AddAccountModal from '../dashboard/components/layout/sidebarComponents/Ad import LoadingState from './components/widgets/LoadingState.vue'; import NetworkNotification from './components/NetworkNotification.vue'; import UpdateBanner from './components/app/UpdateBanner.vue'; -import UpgradeBanner from './components/app/UpgradeBanner.vue'; import PaymentPendingBanner from './components/app/PaymentPendingBanner.vue'; import PendingEmailVerificationBanner from './components/app/PendingEmailVerificationBanner.vue'; import vueActionCable from './helper/actionCable'; @@ -31,7 +30,6 @@ export default { UpdateBanner, PaymentPendingBanner, WootSnackbarBox, - UpgradeBanner, PendingEmailVerificationBanner, }, setup() { @@ -146,7 +144,6 @@ export default { - diff --git a/app/javascript/dashboard/i18n/locale/en/generalSettings.json b/app/javascript/dashboard/i18n/locale/en/generalSettings.json index 9ad4e4b57..4e28e0b2f 100644 --- a/app/javascript/dashboard/i18n/locale/en/generalSettings.json +++ b/app/javascript/dashboard/i18n/locale/en/generalSettings.json @@ -1,5 +1,11 @@ { "GENERAL_SETTINGS": { + "LIMIT_MESSAGES": { + "CONVERSATION": "You have exceeded the conversation limit. Hacker plan allows only 500 conversations.", + "INBOXES": "You have exceeded the inbox limit. Hacker plan only supports website live-chat. Additional inboxes like email, WhatsApp etc. require a paid plan.", + "AGENTS": "You have exceeded the agent limit. Hacker plan allows only 2 agents.", + "NON_ADMIN": "Please contact your administrator to upgrade the plan and continue using all features." + }, "TITLE": "Account settings", "SUBMIT": "Update settings", "BACK": "Back", @@ -51,6 +57,7 @@ "UPDATE_CHATWOOT": "An update {latestChatwootVersion} for Chatwoot is available. Please update your instance.", "LEARN_MORE": "Learn more", "PAYMENT_PENDING": "Your payment is pending. Please update your payment information to continue using Chatwoot", + "UPGRADE": "Upgrade to continue using Chatwoot", "LIMITS_UPGRADE": "Your account has exceeded the usage limits, please upgrade your plan to continue using Chatwoot", "OPEN_BILLING": "Open billing" }, diff --git a/app/javascript/dashboard/routes/dashboard/Dashboard.vue b/app/javascript/dashboard/routes/dashboard/Dashboard.vue index 4d4c5e8df..7de36102b 100644 --- a/app/javascript/dashboard/routes/dashboard/Dashboard.vue +++ b/app/javascript/dashboard/routes/dashboard/Dashboard.vue @@ -1,6 +1,6 @@ + + + + + + + + + + + + {{ $t('GENERAL_SETTINGS.UPGRADE') }} + + + + + {{ limitExceededMessage }} + + + {{ t('GENERAL_SETTINGS.LIMIT_MESSAGES.NON_ADMIN') }} + + + + + + + + + diff --git a/app/policies/account_policy.rb b/app/policies/account_policy.rb index a74a13a66..5eb80c1ab 100644 --- a/app/policies/account_policy.rb +++ b/app/policies/account_policy.rb @@ -8,7 +8,7 @@ class AccountPolicy < ApplicationPolicy end def limits? - @account_user.administrator? + @account_user.administrator? || @account_user.agent? end def update? diff --git a/enterprise/app/controllers/enterprise/api/v1/accounts_controller.rb b/enterprise/app/controllers/enterprise/api/v1/accounts_controller.rb index f449529b8..86ec2fb55 100644 --- a/enterprise/app/controllers/enterprise/api/v1/accounts_controller.rb +++ b/enterprise/app/controllers/enterprise/api/v1/accounts_controller.rb @@ -13,24 +13,24 @@ class Enterprise::Api::V1::AccountsController < Api::BaseController end def limits - limits = { - 'conversation' => {}, - 'non_web_inboxes' => {}, - 'captain' => @account.usage_limits[:captain] - } - - if default_plan?(@account) - limits = { - 'conversation' => { - 'allowed' => 500, - 'consumed' => conversations_this_month(@account) - }, - 'non_web_inboxes' => { - 'allowed' => 0, - 'consumed' => non_web_inboxes(@account) - } - } - end + limits = if default_plan?(@account) + { + 'conversation' => { + 'allowed' => 500, + 'consumed' => conversations_this_month(@account) + }, + 'non_web_inboxes' => { + 'allowed' => 0, + 'consumed' => non_web_inboxes(@account) + }, + 'agents' => { + 'allowed' => 2, + 'consumed' => agents(@account) + } + } + else + default_limits + end # include id in response to ensure that the store can be updated on the frontend render json: { id: @account.id, limits: limits }, status: :ok @@ -49,6 +49,15 @@ class Enterprise::Api::V1::AccountsController < Api::BaseController private + def default_limits + { + 'conversation' => {}, + 'non_web_inboxes' => {}, + 'agents' => {}, + 'captain' => @account.usage_limits[:captain] + } + end + def fetch_account @account = current_user.accounts.find(params[:id]) @current_account_user = @account.account_users.find_by(user_id: current_user.id) diff --git a/spec/enterprise/controllers/enterprise/api/v1/accounts_controller_spec.rb b/spec/enterprise/controllers/enterprise/api/v1/accounts_controller_spec.rb index 6373bc842..ac26dc525 100644 --- a/spec/enterprise/controllers/enterprise/api/v1/accounts_controller_spec.rb +++ b/spec/enterprise/controllers/enterprise/api/v1/accounts_controller_spec.rb @@ -2,8 +2,8 @@ require 'rails_helper' RSpec.describe 'Enterprise Billing APIs', type: :request do let(:account) { create(:account) } - let(:admin) { create(:user, account: account, role: :administrator) } - let(:agent) { create(:user, account: account, role: :agent) } + let!(:admin) { create(:user, account: account, role: :administrator) } + let!(:agent) { create(:user, account: account, role: :agent) } describe 'POST /enterprise/api/v1/accounts/{account.id}/subscription' do context 'when it is an unauthenticated user' do @@ -121,13 +121,36 @@ RSpec.describe 'Enterprise Billing APIs', type: :request do end context 'when it is an authenticated user' do + before do + InstallationConfig.where(name: 'DEPLOYMENT_ENV').first_or_create(value: 'cloud') + InstallationConfig.where(name: 'CHATWOOT_CLOUD_PLANS').first_or_create(value: [{ 'name': 'Hacker' }]) + end + context 'when it is an agent' do it 'returns unauthorized' do get "/enterprise/api/v1/accounts/#{account.id}/limits", headers: agent.create_new_auth_token, as: :json - expect(response).to have_http_status(:unauthorized) + expect(response).to have_http_status(:success) + json_response = JSON.parse(response.body) + expect(json_response['id']).to eq(account.id) + expect(json_response['limits']).to eq( + { + 'conversation' => { + 'allowed' => 500, + 'consumed' => 0 + }, + 'non_web_inboxes' => { + 'allowed' => 0, + 'consumed' => 0 + }, + 'agents' => { + 'allowed' => 2, + 'consumed' => 2 + } + } + ) end end @@ -155,6 +178,10 @@ RSpec.describe 'Enterprise Billing APIs', type: :request do 'non_web_inboxes' => { 'allowed' => 0, 'consumed' => 1 + }, + 'agents' => { + 'allowed' => 2, + 'consumed' => 2 } } } @@ -172,18 +199,11 @@ RSpec.describe 'Enterprise Billing APIs', type: :request do expected_response = { 'id' => account.id, 'limits' => { + 'agents' => {}, 'conversation' => {}, 'captain' => { - 'documents' => { - 'consumed' => 0, - 'current_available' => ChatwootApp.max_limit, - 'total_count' => ChatwootApp.max_limit - }, - 'responses' => { - 'consumed' => 0, - 'current_available' => ChatwootApp.max_limit, - 'total_count' => ChatwootApp.max_limit - } + 'documents' => { 'consumed' => 0, 'current_available' => ChatwootApp.max_limit, 'total_count' => ChatwootApp.max_limit }, + 'responses' => { 'consumed' => 0, 'current_available' => ChatwootApp.max_limit, 'total_count' => ChatwootApp.max_limit } }, 'non_web_inboxes' => {} } @@ -208,6 +228,10 @@ RSpec.describe 'Enterprise Billing APIs', type: :request do 'non_web_inboxes' => { 'allowed' => 0, 'consumed' => 1 + }, + 'agents' => { + 'allowed' => 2, + 'consumed' => 2 } } }
+ {{ limitExceededMessage }} +
+ {{ t('GENERAL_SETTINGS.LIMIT_MESSAGES.NON_ADMIN') }} +