Chore: Remove dead code related to billing (#935)
- remove subscription model - remove billing-related code
This commit is contained in:
parent
051871a3cd
commit
52d28105e4
84 changed files with 27 additions and 1240 deletions
|
@ -89,15 +89,6 @@ TWITTER_ENVIRONMENT=
|
|||
## Mobile app env variables
|
||||
IOS_APP_ID=6C953F3RX2.com.chatwoot.app
|
||||
|
||||
#### This environment variables are only required in hosted version which has billing
|
||||
ENABLE_BILLING=
|
||||
|
||||
## chargebee settings
|
||||
CHARGEBEE_API_KEY=
|
||||
CHARGEBEE_SITE=
|
||||
CHARGEBEE_WEBHOOK_USERNAME=
|
||||
CHARGEBEE_WEBHOOK_PASSWORD=
|
||||
|
||||
## Push Notification
|
||||
## generate a new key value here : https://d3v.one/vapid-key-generator/
|
||||
# VAPID_PUBLIC_KEY=
|
||||
|
|
|
@ -65,7 +65,6 @@ Style/GuardClause:
|
|||
- 'app/builders/account_builder.rb'
|
||||
- 'app/models/attachment.rb'
|
||||
- 'app/models/message.rb'
|
||||
- 'lib/webhooks/chargebee.rb'
|
||||
- 'db/migrate/20190819005836_add_missing_indexes_on_taggings.acts_as_taggable_on_engine.rb'
|
||||
Metrics/AbcSize:
|
||||
Exclude:
|
||||
|
|
|
@ -88,7 +88,6 @@ Naming/MemoizedInstanceVariableName:
|
|||
- 'app/controllers/application_controller.rb'
|
||||
- 'app/models/message.rb'
|
||||
- 'lib/integrations/widget/outgoing_message_builder.rb'
|
||||
- 'lib/webhooks/chargebee.rb'
|
||||
|
||||
# Offense count: 4
|
||||
# Cop supports --auto-correct.
|
||||
|
@ -187,7 +186,6 @@ Rails/EnumHash:
|
|||
- 'app/models/attachment.rb'
|
||||
- 'app/models/conversation.rb'
|
||||
- 'app/models/message.rb'
|
||||
- 'app/models/subscription.rb'
|
||||
- 'app/models/user.rb'
|
||||
|
||||
# Offense count: 1
|
||||
|
@ -226,7 +224,6 @@ Rails/Output:
|
|||
Rails/TimeZone:
|
||||
Exclude:
|
||||
- 'app/builders/report_builder.rb'
|
||||
- 'app/models/subscription.rb'
|
||||
- 'lib/reports/update_account_identity.rb'
|
||||
- 'lib/reports/update_agent_identity.rb'
|
||||
- 'lib/reports/update_identity.rb'
|
||||
|
|
3
Gemfile
3
Gemfile
|
@ -56,9 +56,6 @@ gem 'administrate'
|
|||
# https://karolgalanciak.com/blog/2019/11/30/from-activerecord-callbacks-to-publish-slash-subscribe-pattern-and-event-driven-design/
|
||||
gem 'wisper', '2.0.0'
|
||||
|
||||
##--- gems for billing ---##
|
||||
gem 'chargebee'
|
||||
|
||||
##--- gems for channels ---##
|
||||
gem 'facebook-messenger'
|
||||
gem 'telegram-bot-ruby'
|
||||
|
|
|
@ -138,9 +138,6 @@ GEM
|
|||
bundler (>= 1.2.0, < 3)
|
||||
thor (~> 0.18)
|
||||
byebug (11.1.3)
|
||||
chargebee (2.7.5)
|
||||
json_pure (~> 2.1)
|
||||
rest-client (>= 1.8, < 3.0)
|
||||
coderay (1.1.2)
|
||||
coercible (1.0.0)
|
||||
descendants_tracker (~> 0.0.1)
|
||||
|
@ -249,7 +246,6 @@ GEM
|
|||
railties (>= 4.2.0)
|
||||
thor (>= 0.14, < 2.0)
|
||||
json (2.3.0)
|
||||
json_pure (2.3.0)
|
||||
jwt (2.2.1)
|
||||
kaminari (1.2.1)
|
||||
activesupport (>= 4.1.0)
|
||||
|
@ -542,7 +538,6 @@ DEPENDENCIES
|
|||
bullet
|
||||
bundle-audit
|
||||
byebug
|
||||
chargebee
|
||||
devise
|
||||
devise_token_auth
|
||||
dotenv-rails
|
||||
|
|
|
@ -10,8 +10,4 @@ class Api::BaseController < ApplicationController
|
|||
def authenticate_by_access_token?
|
||||
request.headers[:api_access_token].present? || request.headers[:HTTP_API_ACCESS_TOKEN].present?
|
||||
end
|
||||
|
||||
def check_billing_enabled
|
||||
raise ActionController::RoutingError, 'Not Found' unless ENV['BILLING_ENABLED']
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
class Api::V1::Accounts::SubscriptionsController < Api::V1::Accounts::BaseController
|
||||
skip_before_action :check_subscription
|
||||
|
||||
before_action :check_billing_enabled
|
||||
|
||||
def index
|
||||
render json: Current.account.subscription_data
|
||||
end
|
||||
|
||||
def status
|
||||
render json: Current.account.subscription.summary
|
||||
end
|
||||
end
|
|
@ -2,7 +2,7 @@ class Api::V1::AccountsController < Api::BaseController
|
|||
include AuthHelper
|
||||
|
||||
skip_before_action :verify_authenticity_token, only: [:create]
|
||||
skip_before_action :authenticate_user!, :set_current_user, :check_subscription, :handle_with_exception,
|
||||
skip_before_action :authenticate_user!, :set_current_user, :handle_with_exception,
|
||||
only: [:create], raise: false
|
||||
before_action :check_signup_enabled, only: [:create]
|
||||
before_action :fetch_account, except: [:create]
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
class Api::V1::AgentBotsController < Api::BaseController
|
||||
skip_before_action :authenticate_user!
|
||||
skip_before_action :check_subscription
|
||||
|
||||
def index
|
||||
render json: AgentBot.all
|
||||
|
|
|
@ -1,18 +1,6 @@
|
|||
class Api::V1::WebhooksController < ApplicationController
|
||||
skip_before_action :authenticate_user!, raise: false
|
||||
skip_before_action :set_current_user
|
||||
skip_before_action :check_subscription
|
||||
|
||||
before_action :login_from_basic_auth, only: [:chargebee]
|
||||
before_action :check_billing_enabled, only: [:chargebee]
|
||||
|
||||
def chargebee
|
||||
chargebee_consumer.consume
|
||||
head :ok
|
||||
rescue StandardError => e
|
||||
Raven.capture_exception(e)
|
||||
head :ok
|
||||
end
|
||||
|
||||
def twitter_crc
|
||||
render json: { response_token: "sha256=#{twitter_client.generate_crc(params[:crc_token])}" }
|
||||
|
@ -34,16 +22,6 @@ class Api::V1::WebhooksController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
def login_from_basic_auth
|
||||
authenticate_or_request_with_http_basic do |username, password|
|
||||
username == ENV['CHARGEBEE_WEBHOOK_USERNAME'] && password == ENV['CHARGEBEE_WEBHOOK_PASSWORD']
|
||||
end
|
||||
end
|
||||
|
||||
def chargebee_consumer
|
||||
@chargebee_consumer ||= ::Webhooks::Chargebee.new(params)
|
||||
end
|
||||
|
||||
def twitter_consumer
|
||||
@twitter_consumer ||= ::Webhooks::Twitter.new(params)
|
||||
end
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
class ApiController < ApplicationController
|
||||
skip_before_action :set_current_user, only: [:index]
|
||||
skip_before_action :check_subscription, only: [:index]
|
||||
|
||||
def index
|
||||
render json: { version: Chatwoot.config[:version], timestamp: Time.now.utc.to_formatted_s(:db) }
|
||||
|
|
|
@ -5,7 +5,6 @@ class ApplicationController < ActionController::Base
|
|||
protect_from_forgery with: :null_session
|
||||
|
||||
before_action :set_current_user, unless: :devise_controller?
|
||||
before_action :check_subscription, unless: :devise_controller?
|
||||
around_action :handle_with_exception, unless: :devise_controller?
|
||||
|
||||
# after_action :verify_authorized
|
||||
|
@ -68,18 +67,6 @@ class ApplicationController < ActionController::Base
|
|||
I18n.locale = locale || I18n.default_locale
|
||||
end
|
||||
|
||||
def check_subscription
|
||||
# This block is left over from the initial version of chatwoot
|
||||
# We might reuse this later in the hosted version of chatwoot.
|
||||
return if !ENV['BILLING_ENABLED'] || !current_user
|
||||
|
||||
if current_subscription.trial? && current_subscription.expiry < Date.current
|
||||
render json: { error: 'Trial Expired' }, status: :trial_expired
|
||||
elsif current_subscription.cancelled?
|
||||
render json: { error: 'Account Suspended' }, status: :account_suspended
|
||||
end
|
||||
end
|
||||
|
||||
def pundit_user
|
||||
{
|
||||
user: Current.user,
|
||||
|
|
|
@ -10,7 +10,6 @@ class AsyncDispatcher < BaseDispatcher
|
|||
|
||||
def listeners
|
||||
listeners = [EventListener.instance, WebhookListener.instance]
|
||||
listeners << SubscriptionListener.instance if ENV['BILLING_ENABLED']
|
||||
listeners
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
module Api::V1::SubscriptionsHelper
|
||||
end
|
|
@ -1,20 +0,0 @@
|
|||
/* global axios */
|
||||
|
||||
import endPoints from './endPoints';
|
||||
|
||||
export default {
|
||||
getSubscription() {
|
||||
const urlData = endPoints('subscriptions').get();
|
||||
const fetchPromise = new Promise((resolve, reject) => {
|
||||
axios
|
||||
.get(urlData.url)
|
||||
.then(response => {
|
||||
resolve(response);
|
||||
})
|
||||
.catch(error => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
return fetchPromise;
|
||||
},
|
||||
};
|
|
@ -33,14 +33,6 @@ const endPoints = {
|
|||
},
|
||||
params: { omniauth_token: '' },
|
||||
},
|
||||
|
||||
subscriptions: {
|
||||
get() {
|
||||
return {
|
||||
url: '/api/v1/subscriptions',
|
||||
};
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default page => {
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
@import 'animations';
|
||||
|
||||
@import 'foundation-custom';
|
||||
@import 'widgets/billing';
|
||||
@import 'widgets/buttons';
|
||||
@import 'widgets/conv-header';
|
||||
@import 'widgets/conversation-card';
|
||||
|
|
|
@ -1,75 +0,0 @@
|
|||
.billing {
|
||||
@include full-height;
|
||||
|
||||
.row {
|
||||
@include full-height;
|
||||
}
|
||||
|
||||
.billing__stats {
|
||||
@include flex;
|
||||
}
|
||||
|
||||
.billing__form {
|
||||
@include thin-border($color-border-light);
|
||||
@include margin($zero - $space-micro);
|
||||
@include full-height;
|
||||
background: $color-white;
|
||||
|
||||
iframe {
|
||||
@include full-height;
|
||||
border: 0;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.account-row {
|
||||
@include padding($space-normal);
|
||||
@include flex;
|
||||
flex-direction: column;
|
||||
// @include thin-border($color-border-light);
|
||||
// @include margin(-$space-micro $zero);
|
||||
background: $color-white;
|
||||
font-size: $font-size-small;
|
||||
|
||||
.title {
|
||||
color: $color-heading;
|
||||
font-weight: $font-weight-medium;
|
||||
}
|
||||
|
||||
.value {
|
||||
font-size: $font-size-mega;
|
||||
font-weight: $font-weight-light;
|
||||
text-transform: capitalize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.account-locked {
|
||||
@include background-gray;
|
||||
@include margin(0);
|
||||
}
|
||||
|
||||
.lock-message {
|
||||
@include flex;
|
||||
@include full-height;
|
||||
flex-direction: column;
|
||||
@include flex-align(center, middle);
|
||||
|
||||
div {
|
||||
@include flex;
|
||||
@include full-height;
|
||||
flex-direction: column;
|
||||
@include flex-align(center, middle);
|
||||
|
||||
img {
|
||||
@include margin($space-normal);
|
||||
width: 10rem;
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: $font-size-small;
|
||||
font-weight: $font-weight-medium;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -21,18 +21,6 @@
|
|||
</transition-group>
|
||||
</div>
|
||||
|
||||
<!-- this block is only required in the hosted version with billing enabled -->
|
||||
<transition name="fade" mode="out-in">
|
||||
<woot-status-bar
|
||||
v-if="shouldShowStatusBox"
|
||||
:message="trialMessage"
|
||||
:button-text="$t('APP_GLOBAL.TRAIL_BUTTON')"
|
||||
:button-route="{ name: 'billing' }"
|
||||
:type="statusBarClass"
|
||||
:show-button="isAdmin"
|
||||
/>
|
||||
</transition>
|
||||
|
||||
<div class="bottom-nav">
|
||||
<transition name="menu-slide">
|
||||
<div
|
||||
|
@ -108,7 +96,6 @@ import { mixin as clickaway } from 'vue-clickaway';
|
|||
import adminMixin from '../../mixins/isAdmin';
|
||||
import Auth from '../../api/auth';
|
||||
import SidebarItem from './SidebarItem';
|
||||
import WootStatusBar from '../widgets/StatusBar';
|
||||
import { frontendURL } from '../../helper/URLHelper';
|
||||
import Thumbnail from '../widgets/Thumbnail';
|
||||
import { getSidebarItems } from '../../i18n/default-sidebar';
|
||||
|
@ -116,7 +103,6 @@ import { getSidebarItems } from '../../i18n/default-sidebar';
|
|||
export default {
|
||||
components: {
|
||||
SidebarItem,
|
||||
WootStatusBar,
|
||||
Thumbnail,
|
||||
},
|
||||
mixins: [clickaway, adminMixin],
|
||||
|
@ -138,7 +124,6 @@ export default {
|
|||
daysLeft: 'getTrialLeft',
|
||||
globalConfig: 'globalConfig/get',
|
||||
inboxes: 'inboxes/getInboxes',
|
||||
subscriptionData: 'getSubscription',
|
||||
accountId: 'getCurrentAccountId',
|
||||
currentRole: 'getCurrentRole',
|
||||
}),
|
||||
|
@ -160,10 +145,6 @@ export default {
|
|||
}
|
||||
}
|
||||
|
||||
if (!window.chatwootConfig.billingEnabled) {
|
||||
menuItems = this.filterBillingRoutes(menuItems);
|
||||
}
|
||||
|
||||
return this.filterMenuItemsByRole(menuItems);
|
||||
},
|
||||
currentRoute() {
|
||||
|
@ -193,35 +174,11 @@ export default {
|
|||
dashboardPath() {
|
||||
return frontendURL(`accounts/${this.accountId}/dashboard`);
|
||||
},
|
||||
shouldShowStatusBox() {
|
||||
return (
|
||||
window.chatwootConfig.billingEnabled &&
|
||||
(this.subscriptionData.state === 'trial' ||
|
||||
this.subscriptionData.state === 'cancelled')
|
||||
);
|
||||
},
|
||||
statusBarClass() {
|
||||
if (this.subscriptionData.state === 'trial') {
|
||||
return 'warning';
|
||||
}
|
||||
if (this.subscriptionData.state === 'cancelled') {
|
||||
return 'danger';
|
||||
}
|
||||
return '';
|
||||
},
|
||||
trialMessage() {
|
||||
return `${this.daysLeft} ${this.$t('APP_GLOBAL.TRIAL_MESSAGE')}`;
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.$store.dispatch('inboxes/get');
|
||||
},
|
||||
methods: {
|
||||
filterBillingRoutes(menuItems) {
|
||||
return menuItems.filter(
|
||||
menuItem => !menuItem.toState.includes('billing')
|
||||
);
|
||||
},
|
||||
filterMenuItemsByRole(menuItems) {
|
||||
if (!this.currentRole) {
|
||||
return [];
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
<template>
|
||||
<div class="status-bar" :class="type">
|
||||
<p class="message">{{message}}</p>
|
||||
<router-link
|
||||
:to="buttonRoute"
|
||||
class="button small warning nice"
|
||||
v-if="showButton"
|
||||
>
|
||||
{{buttonText}}
|
||||
</router-link>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
message: String,
|
||||
buttonRoute: Object,
|
||||
buttonText: String,
|
||||
showButton: Boolean,
|
||||
type: String, // Danger, Info, Success, Warning
|
||||
},
|
||||
};
|
||||
</script>
|
|
@ -1,15 +1,8 @@
|
|||
/* eslint no-console: 0 */
|
||||
import constants from '../constants';
|
||||
import Auth from '../api/auth';
|
||||
import router from '../routes';
|
||||
|
||||
const parseErrorCode = error => {
|
||||
const errorStatus = error.response ? error.response.status : undefined;
|
||||
// 901, 902 are used to identify billing related issues
|
||||
if ([901, 902].includes(errorStatus)) {
|
||||
const name = Auth.isAdmin() ? 'billing' : 'billing_deactivated';
|
||||
router.push({ name });
|
||||
}
|
||||
return Promise.reject(error);
|
||||
};
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@ export const getSidebarItems = accountId => ({
|
|||
'inbox_conversation',
|
||||
'conversation_through_inbox',
|
||||
'settings_account_reports',
|
||||
'billing_deactivated',
|
||||
'profile_settings',
|
||||
'profile_settings_index',
|
||||
],
|
||||
|
@ -51,7 +50,6 @@ export const getSidebarItems = accountId => ({
|
|||
'settings_inboxes_page_channel',
|
||||
'settings_inboxes_add_agents',
|
||||
'settings_inbox_finish',
|
||||
'billing',
|
||||
'settings_integrations',
|
||||
'settings_integrations_webhook',
|
||||
'general_settings',
|
||||
|
@ -88,13 +86,6 @@ export const getSidebarItems = accountId => ({
|
|||
),
|
||||
toStateName: 'canned_list',
|
||||
},
|
||||
billing: {
|
||||
icon: 'ion-card',
|
||||
label: 'BILLING',
|
||||
hasSubMenu: false,
|
||||
toState: frontendURL(`accounts/${accountId}/settings/billing`),
|
||||
toStateName: 'billing',
|
||||
},
|
||||
settings_integrations: {
|
||||
icon: 'ion-flash',
|
||||
label: 'INTEGRATIONS',
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
{
|
||||
"BILLING": {
|
||||
"HEADER": "Facturació",
|
||||
"LOADING": "S'estan obtenin les suscripcions",
|
||||
"ACCOUNT_STATE": "Estat del compte",
|
||||
"AGENT_COUNT": "Compte d'agent",
|
||||
"PER_AGENT_COST": "Per cost d'agent",
|
||||
"TOTAL_COST": "Cost total",
|
||||
"BUTTON": {
|
||||
"ADD": "Afegir mètode de pagament",
|
||||
"EDIT": "EDITAR Mètode de pagament"
|
||||
},
|
||||
"TRIAL": {
|
||||
"TITLE": "S'ha acabat el període de prova",
|
||||
"MESSAGE": "Afegiu un mètode de pagament per continuar utilitzant Chatwoot."
|
||||
},
|
||||
"ACCOUNT_LOCKED": "El seu compte no està disponible de moment. <br>Poseu-vos en contacte amb l'administrador per reactivar-lo."
|
||||
}
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
/* eslint-disable */
|
||||
import { default as _agentMgmt } from './agentMgmt.json';
|
||||
import { default as _billing } from './billing.json';
|
||||
import { default as _cannedMgmt } from './cannedMgmt.json';
|
||||
import { default as _chatlist } from './chatlist.json';
|
||||
import { default as _contact } from './contact.json';
|
||||
|
@ -17,7 +16,6 @@ import { default as _generalSettings } from './generalSettings.json';
|
|||
|
||||
export default {
|
||||
..._agentMgmt,
|
||||
..._billing,
|
||||
..._cannedMgmt,
|
||||
..._chatlist,
|
||||
..._contact,
|
||||
|
|
|
@ -87,7 +87,6 @@
|
|||
"AGENTS": "Agents",
|
||||
"INBOXES": "Safates d'entrada",
|
||||
"CANNED_RESPONSES": "Respostes Predeterminades",
|
||||
"BILLING": "Facturació",
|
||||
"INTEGRATIONS": "Integracions",
|
||||
"ACCOUNT_SETTINGS": "Configuració del compte"
|
||||
}
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
{
|
||||
"BILLING": {
|
||||
"HEADER": "Fakturace",
|
||||
"LOADING": "Načítání předplatného",
|
||||
"ACCOUNT_STATE": "Stav účtu",
|
||||
"AGENT_COUNT": "Počet agentů",
|
||||
"PER_AGENT_COST": "Náklady na jednoho agenta",
|
||||
"TOTAL_COST": "Celkové náklady",
|
||||
"BUTTON": {
|
||||
"ADD": "Přidat způsob platby",
|
||||
"EDIT": "Metoda platby EDIT"
|
||||
},
|
||||
"TRIAL": {
|
||||
"TITLE": "Vaše zkušební období skončilo",
|
||||
"MESSAGE": "Přidejte platební metodu a pokračujte v používání Chatwoot."
|
||||
},
|
||||
"ACCOUNT_LOCKED": "Váš účet není momentálně k dispozici. <br>Obraťte se na správce pro opětovné aktivaci."
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
{
|
||||
"BILLING": {
|
||||
"HEADER": "Abrechnung",
|
||||
"LOADING": "Abonnements abrufen",
|
||||
"ACCOUNT_STATE": "Kontostatus",
|
||||
"AGENT_COUNT": "Anzahl der Agenten",
|
||||
"PER_AGENT_COST": "Kosten pro Agent",
|
||||
"TOTAL_COST": "Gesamtkosten",
|
||||
"BUTTON": {
|
||||
"ADD": "Zahlungsmethode hinzufügen",
|
||||
"EDIT": "Zahlungsmethode BEARBEITEN"
|
||||
},
|
||||
"TRIAL": {
|
||||
"TITLE": "Ihre Probezeit ist vorbei",
|
||||
"MESSAGE": "Fügen Sie eine Zahlungsmethode hinzu, um Chatwoot weiterhin zu verwenden."
|
||||
},
|
||||
"ACCOUNT_LOCKED": "Ihr Konto ist derzeit nicht verfügbar. <br> Bitte wenden Sie sich zur Reaktivierung an Ihren Administrator."
|
||||
}
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
/* eslint-disable */
|
||||
import { default as _agentMgmt } from './agentMgmt.json';
|
||||
import { default as _billing } from './billing.json';
|
||||
import { default as _cannedMgmt } from './cannedMgmt.json';
|
||||
import { default as _chatlist } from './chatlist.json';
|
||||
import { default as _contact } from './contact.json';
|
||||
|
@ -17,7 +16,6 @@ import { default as _generalSettings } from './generalSettings.json';
|
|||
|
||||
export default {
|
||||
..._agentMgmt,
|
||||
..._billing,
|
||||
..._cannedMgmt,
|
||||
..._chatlist,
|
||||
..._contact,
|
||||
|
|
|
@ -90,7 +90,6 @@
|
|||
"AGENTS": "Agenten",
|
||||
"INBOXES": "Posteingänge",
|
||||
"CANNED_RESPONSES": "Vorgefertigte Antworten",
|
||||
"BILLING": "Abrechnung",
|
||||
"INTEGRATIONS": "Integrationen",
|
||||
"ACCOUNT_SETTINGS": "Kontoeinstellungen"
|
||||
}
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
{
|
||||
"BILLING": {
|
||||
"HEADER": "Χρεώσεις",
|
||||
"LOADING": "Λήψη Συνδρομών",
|
||||
"ACCOUNT_STATE": "Κατάσταση Λογαριασμού",
|
||||
"AGENT_COUNT": "Αριθμός Πρακτόρων",
|
||||
"PER_AGENT_COST": "Κόστος ανά πράκτορα",
|
||||
"TOTAL_COST": "Συνολικό κόστος",
|
||||
"BUTTON": {
|
||||
"ADD": "Προσθήκη μεθόδου πληρωμής",
|
||||
"EDIT": "Επεξεργασία μεθόδου πληρωμής"
|
||||
},
|
||||
"TRIAL": {
|
||||
"TITLE": "Η δοκιμαστική περίοδος ολοκληρώθηκε",
|
||||
"MESSAGE": "Προσθέστε μια μέθοδο πληρωμής για να συνεχίσετε την χρήση του Chatwoot."
|
||||
},
|
||||
"ACCOUNT_LOCKED": "O Λογαριασμός σας δεν είναι ενεργός αυτήν τη στιγμή. <br>Παρακαλώ απευθυνθείτε στον διαχειριστή για ενεργοποίηση."
|
||||
}
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
/* eslint-disable */
|
||||
import { default as _agentMgmt } from './agentMgmt.json';
|
||||
import { default as _billing } from './billing.json';
|
||||
import { default as _cannedMgmt } from './cannedMgmt.json';
|
||||
import { default as _chatlist } from './chatlist.json';
|
||||
import { default as _contact } from './contact.json';
|
||||
|
@ -17,7 +16,6 @@ import { default as _generalSettings } from './generalSettings.json';
|
|||
|
||||
export default {
|
||||
..._agentMgmt,
|
||||
..._billing,
|
||||
..._cannedMgmt,
|
||||
..._chatlist,
|
||||
..._contact,
|
||||
|
|
|
@ -102,7 +102,6 @@
|
|||
"AGENTS": "Πράκτορες",
|
||||
"INBOXES": "Κιβώτια Εισερχομένων",
|
||||
"CANNED_RESPONSES": "Έτοιμες Απαντήσεις",
|
||||
"BILLING": "Χρεώσεις",
|
||||
"INTEGRATIONS": "Ενοποιήσεις",
|
||||
"ACCOUNT_SETTINGS": "Ρυθμίσεις Λογαριασμού"
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"HEADER": "Agents",
|
||||
"HEADER_BTN_TXT": "Add Agent",
|
||||
"LOADING": "Fetching Agent List",
|
||||
"SIDEBAR_TXT": "<p><b>Agents</b></p> <p> An <b>Agent</b> is a member of your Customer Support team. </p><p> Agents will be able to view and reply to messages from your users. The list shows all agents currently in your account. </p><p> Click on <b>Add Agent</b> to add a new agent. Agent you add will receive an email with a confirmation link to activate their account, after which they can access Chatwoot and respond to messages. </p><p> Access to Chatwoot's features are based on following roles. </p><p> <b>Agent</b> - Agents with this role can only access inboxes, reports and conversations. They can assign conversations to other agents or themselves and resolve conversations.</p><p> <b>Administrator</b> - Administrator will have access to all Chatwoot features enabled for your account, including settings and billing, along with all of a normal agents' privileges.</p>",
|
||||
"SIDEBAR_TXT": "<p><b>Agents</b></p> <p> An <b>Agent</b> is a member of your Customer Support team. </p><p> Agents will be able to view and reply to messages from your users. The list shows all agents currently in your account. </p><p> Click on <b>Add Agent</b> to add a new agent. Agent you add will receive an email with a confirmation link to activate their account, after which they can access Chatwoot and respond to messages. </p><p> Access to Chatwoot's features are based on following roles. </p><p> <b>Agent</b> - Agents with this role can only access inboxes, reports and conversations. They can assign conversations to other agents or themselves and resolve conversations.</p><p> <b>Administrator</b> - Administrator will have access to all Chatwoot features enabled for your account, including settings, along with all of a normal agents' privileges.</p>",
|
||||
"AGENT_TYPES": [
|
||||
{
|
||||
"name": "administrator",
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
{
|
||||
"BILLING": {
|
||||
"HEADER": "Billing",
|
||||
"LOADING": "Fetching Subscriptions",
|
||||
"ACCOUNT_STATE": "Account State",
|
||||
"AGENT_COUNT": "Agent Count",
|
||||
"PER_AGENT_COST": "Per Agent Cost",
|
||||
"TOTAL_COST": "Total Cost",
|
||||
"BUTTON": {
|
||||
"ADD": "Add Payment Method",
|
||||
"EDIT": "EDIT Payment Method"
|
||||
},
|
||||
"TRIAL": {
|
||||
"TITLE": "Your Trial period is over",
|
||||
"MESSAGE": "Add a payment method to continue using Chatwoot."
|
||||
},
|
||||
"ACCOUNT_LOCKED": "Your account is not available at the moment. <br>Please contact your administrator for reactivation."
|
||||
}
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
/* eslint-disable */
|
||||
import { default as _agentMgmt } from './agentMgmt.json';
|
||||
import { default as _billing } from './billing.json';
|
||||
import { default as _cannedMgmt } from './cannedMgmt.json';
|
||||
import { default as _chatlist } from './chatlist.json';
|
||||
import { default as _contact } from './contact.json';
|
||||
|
@ -17,7 +16,6 @@ import { default as _generalSettings } from './generalSettings.json';
|
|||
|
||||
export default {
|
||||
..._agentMgmt,
|
||||
..._billing,
|
||||
..._cannedMgmt,
|
||||
..._chatlist,
|
||||
..._contact,
|
||||
|
|
|
@ -102,7 +102,6 @@
|
|||
"AGENTS": "Agents",
|
||||
"INBOXES": "Inboxes",
|
||||
"CANNED_RESPONSES": "Canned Responses",
|
||||
"BILLING": "Billing",
|
||||
"INTEGRATIONS": "Integrations",
|
||||
"ACCOUNT_SETTINGS": "Account Settings"
|
||||
}
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
{
|
||||
"BILLING": {
|
||||
"HEADER": "Facturación",
|
||||
"LOADING": "Obteniendo suscripciones",
|
||||
"ACCOUNT_STATE": "Estado de cuenta",
|
||||
"AGENT_COUNT": "Contador de agentes",
|
||||
"PER_AGENT_COST": "Coste por agente",
|
||||
"TOTAL_COST": "Coste total",
|
||||
"BUTTON": {
|
||||
"ADD": "Añadir método de pago",
|
||||
"EDIT": "Método de pago EDIT"
|
||||
},
|
||||
"TRIAL": {
|
||||
"TITLE": "Su período de prueba ha terminado",
|
||||
"MESSAGE": "Añadir un método de pago para seguir usando Chatwoot."
|
||||
},
|
||||
"ACCOUNT_LOCKED": "Su cuenta no está disponible en este momento. <br>Póngase en contacto con su administrador para reactivación."
|
||||
}
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
/* eslint-disable */
|
||||
import { default as _agentMgmt } from './agentMgmt.json';
|
||||
import { default as _billing } from './billing.json';
|
||||
import { default as _cannedMgmt } from './cannedMgmt.json';
|
||||
import { default as _chatlist } from './chatlist.json';
|
||||
import { default as _contact } from './contact.json';
|
||||
|
@ -17,7 +16,6 @@ import { default as _generalSettings } from './generalSettings.json';
|
|||
|
||||
export default {
|
||||
..._agentMgmt,
|
||||
..._billing,
|
||||
..._cannedMgmt,
|
||||
..._chatlist,
|
||||
..._contact,
|
||||
|
|
|
@ -102,7 +102,6 @@
|
|||
"AGENTS": "Agentes",
|
||||
"INBOXES": "Entradas",
|
||||
"CANNED_RESPONSES": "Respuestas predefinidas",
|
||||
"BILLING": "Facturación",
|
||||
"INTEGRATIONS": "Integraciones",
|
||||
"ACCOUNT_SETTINGS": "Configuración de la cuenta"
|
||||
}
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
{
|
||||
"BILLING": {
|
||||
"HEADER": "Facturation",
|
||||
"LOADING": "Récupération des abonnements",
|
||||
"ACCOUNT_STATE": "État du compte",
|
||||
"AGENT_COUNT": "Nombre d'agents",
|
||||
"PER_AGENT_COST": "Coût par agent",
|
||||
"TOTAL_COST": "Coût total",
|
||||
"BUTTON": {
|
||||
"ADD": "Ajouter une méthode de paiement",
|
||||
"EDIT": "MODIFIER la méthode de paiement"
|
||||
},
|
||||
"TRIAL": {
|
||||
"TITLE": "Votre période d'essai est terminée",
|
||||
"MESSAGE": "Ajoutez une méthode de paiement pour continuer à utiliser Chatwoot."
|
||||
},
|
||||
"ACCOUNT_LOCKED": "Votre compte n'est pas disponible pour le moment. <br>Veuillez contacter votre administrateur pour la réactivation."
|
||||
}
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
/* eslint-disable */
|
||||
import { default as _agentMgmt } from './agentMgmt.json';
|
||||
import { default as _billing } from './billing.json';
|
||||
import { default as _cannedMgmt } from './cannedMgmt.json';
|
||||
import { default as _chatlist } from './chatlist.json';
|
||||
import { default as _contact } from './contact.json';
|
||||
|
@ -17,7 +16,6 @@ import { default as _generalSettings } from './generalSettings.json';
|
|||
|
||||
export default {
|
||||
..._agentMgmt,
|
||||
..._billing,
|
||||
..._cannedMgmt,
|
||||
..._chatlist,
|
||||
..._contact,
|
||||
|
|
|
@ -102,7 +102,6 @@
|
|||
"AGENTS": "Agents",
|
||||
"INBOXES": "Boîtes de réception",
|
||||
"CANNED_RESPONSES": "Réponses standardisées",
|
||||
"BILLING": "Facturation",
|
||||
"INTEGRATIONS": "Intégrations",
|
||||
"ACCOUNT_SETTINGS": "Paramètres du compte"
|
||||
}
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
{
|
||||
"BILLING": {
|
||||
"HEADER": "Fatturazione",
|
||||
"LOADING": "Recupero Iscrizioni",
|
||||
"ACCOUNT_STATE": "Stato del conto",
|
||||
"AGENT_COUNT": "Conteggio Agente",
|
||||
"PER_AGENT_COST": "Costo per agente",
|
||||
"TOTAL_COST": "Costo totale",
|
||||
"BUTTON": {
|
||||
"ADD": "Aggiungi metodo di pagamento",
|
||||
"EDIT": "Metodo di pagamento EDIT"
|
||||
},
|
||||
"TRIAL": {
|
||||
"TITLE": "Il tuo periodo di prova è finito",
|
||||
"MESSAGE": "Aggiungi un metodo di pagamento per continuare a utilizzare Chatwoot."
|
||||
},
|
||||
"ACCOUNT_LOCKED": "Il tuo account non è al momento disponibile. <br>Si prega di contattare l'amministratore per la riattivazione."
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
{
|
||||
"BILLING": {
|
||||
"HEADER": "ബില്ലിംഗ്",
|
||||
"LOADING": "സബ്സ്ക്രിപ്ഷനുകൾ ലഭ്യമാക്കുന്നു",
|
||||
"ACCOUNT_STATE": "അക്കൗണ്ടിന്റെ അവസ്ഥ",
|
||||
"AGENT_COUNT": "ഏജന്റിന്റെ എണ്ണം ",
|
||||
"PER_AGENT_COST": "ഓരോ ഏജന്റിന്റെ വില",
|
||||
"TOTAL_COST": "ആകെ ചെലവ്",
|
||||
"BUTTON": {
|
||||
"ADD": "പേയ്മെന്റ് രീതി ചേർക്കുക",
|
||||
"EDIT": "പേയ്മെന്റ് രീതി എഡിറ്റുചെയ്യുക"
|
||||
},
|
||||
"TRIAL": {
|
||||
"TITLE": "നിങ്ങളുടെ ട്രയൽ കാലയളവ് അവസാനിച്ചു",
|
||||
"MESSAGE": "ചാറ്റ് വൂട്ട് ഉപയോഗിക്കുന്നത് തുടരാൻ ഒരു പേയ്മെന്റ് രീതി ചേർക്കുക."
|
||||
},
|
||||
"ACCOUNT_LOCKED": "നിങ്ങളുടെ അക്കൗണ്ട് ഇപ്പോൾ ലഭ്യമല്ല. <br> വീണ്ടും സജീവമാക്കുന്നതിന് ദയവായി നിങ്ങളുടെ അഡ്മിനിസ്ട്രേറ്ററുമായി ബന്ധപ്പെടുക."
|
||||
}
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
/* eslint-disable */
|
||||
import { default as _agentMgmt } from './agentMgmt.json';
|
||||
import { default as _billing } from './billing.json';
|
||||
import { default as _cannedMgmt } from './cannedMgmt.json';
|
||||
import { default as _chatlist } from './chatlist.json';
|
||||
import { default as _contact } from './contact.json';
|
||||
|
@ -17,7 +16,6 @@ import { default as _generalSettings } from './generalSettings.json';
|
|||
|
||||
export default {
|
||||
..._agentMgmt,
|
||||
..._billing,
|
||||
..._cannedMgmt,
|
||||
..._chatlist,
|
||||
..._contact,
|
||||
|
|
|
@ -90,7 +90,6 @@
|
|||
"AGENTS": "ഏജന്റുമാർ",
|
||||
"INBOXES": "ഇൻബോക്സുകൾ",
|
||||
"CANNED_RESPONSES": "ക്യാൻഡ് പ്രതികരണങ്ങൾ",
|
||||
"BILLING": "ബില്ലിംഗ്",
|
||||
"INTEGRATIONS": "സംയോജനങ്ങൾ",
|
||||
"ACCOUNT_SETTINGS": "അക്കൗണ്ട് ക്രമീകരണങ്ങൾ"
|
||||
}
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
{
|
||||
"BILLING": {
|
||||
"HEADER": "Facturatie",
|
||||
"LOADING": "Ophalen Abonnementen",
|
||||
"ACCOUNT_STATE": "Accountstatus",
|
||||
"AGENT_COUNT": "Aantal Medewerkers",
|
||||
"PER_AGENT_COST": "Kosten per medewerker",
|
||||
"TOTAL_COST": "Totale kosten",
|
||||
"BUTTON": {
|
||||
"ADD": "Betaalmethode toevoegen",
|
||||
"EDIT": "Betalingsmethode bewerken"
|
||||
},
|
||||
"TRIAL": {
|
||||
"TITLE": "Uw proefperiode is voorbij",
|
||||
"MESSAGE": "Voeg een betaalmethode toe om Chatwoot te blijven gebruiken."
|
||||
},
|
||||
"ACCOUNT_LOCKED": "Uw account is op dit moment niet beschikbaar. <br>Neem contact op met uw beheerder voor heractivatie."
|
||||
}
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
/* eslint-disable */
|
||||
import { default as _agentMgmt } from './agentMgmt.json';
|
||||
import { default as _billing } from './billing.json';
|
||||
import { default as _cannedMgmt } from './cannedMgmt.json';
|
||||
import { default as _chatlist } from './chatlist.json';
|
||||
import { default as _contact } from './contact.json';
|
||||
|
@ -17,7 +16,6 @@ import { default as _generalSettings } from './generalSettings.json';
|
|||
|
||||
export default {
|
||||
..._agentMgmt,
|
||||
..._billing,
|
||||
..._cannedMgmt,
|
||||
..._chatlist,
|
||||
..._contact,
|
||||
|
|
|
@ -102,7 +102,6 @@
|
|||
"AGENTS": "Medewerkers",
|
||||
"INBOXES": "Inboxen",
|
||||
"CANNED_RESPONSES": "Standaard antwoorden",
|
||||
"BILLING": "Facturatie",
|
||||
"INTEGRATIONS": "Integraties",
|
||||
"ACCOUNT_SETTINGS": "Accountinstellingen"
|
||||
}
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
{
|
||||
"BILLING": {
|
||||
"HEADER": "Płatność",
|
||||
"LOADING": "Pobieranie subskrypcji",
|
||||
"ACCOUNT_STATE": "Stan konta",
|
||||
"AGENT_COUNT": "Liczba agentów",
|
||||
"PER_AGENT_COST": "Koszt za agenta",
|
||||
"TOTAL_COST": "Całkowity koszt",
|
||||
"BUTTON": {
|
||||
"ADD": "Dodaj metodę płatności",
|
||||
"EDIT": "Metoda płatności EDIT"
|
||||
},
|
||||
"TRIAL": {
|
||||
"TITLE": "Twój okres próbny minął",
|
||||
"MESSAGE": "Dodaj metodę płatności, aby kontynuować korzystanie z Chatwoot."
|
||||
},
|
||||
"ACCOUNT_LOCKED": "Twoje konto nie jest obecnie dostępne. <br>Skontaktuj się z administratorem, aby reaktywować."
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
{
|
||||
"BILLING": {
|
||||
"HEADER": "Faturamento",
|
||||
"LOADING": "Buscando Assinaturas",
|
||||
"ACCOUNT_STATE": "Estado do cliente",
|
||||
"AGENT_COUNT": "Número de Representantes",
|
||||
"PER_AGENT_COST": "Custo por agente",
|
||||
"TOTAL_COST": "Custo Total",
|
||||
"BUTTON": {
|
||||
"ADD": "Adicionar método de pagamento",
|
||||
"EDIT": "EDIT Método de Pagamento"
|
||||
},
|
||||
"TRIAL": {
|
||||
"TITLE": "Seu período de avaliação terminou",
|
||||
"MESSAGE": "Adicione um método de pagamento para continuar usando o Chatwoot."
|
||||
},
|
||||
"ACCOUNT_LOCKED": "Sua conta não está disponível no momento. <br>Por favor, entre em contato com o administrador para reativação."
|
||||
}
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
/* eslint-disable */
|
||||
import { default as _agentMgmt } from './agentMgmt.json';
|
||||
import { default as _billing } from './billing.json';
|
||||
import { default as _cannedMgmt } from './cannedMgmt.json';
|
||||
import { default as _chatlist } from './chatlist.json';
|
||||
import { default as _contact } from './contact.json';
|
||||
|
@ -17,7 +16,6 @@ import { default as _generalSettings } from './generalSettings.json';
|
|||
|
||||
export default {
|
||||
..._agentMgmt,
|
||||
..._billing,
|
||||
..._cannedMgmt,
|
||||
..._chatlist,
|
||||
..._contact,
|
||||
|
|
|
@ -67,7 +67,6 @@
|
|||
"AGENTS": "Agentes",
|
||||
"INBOXES": "Caixas de entrada",
|
||||
"CANNED_RESPONSES": "Respostas Enlatadas",
|
||||
"BILLING": "Faturamento",
|
||||
"INTEGRATIONS": "Integrações",
|
||||
"ACCOUNT_SETTINGS": "Configurações da conta"
|
||||
}
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
{
|
||||
"BILLING": {
|
||||
"HEADER": "Faturamento",
|
||||
"LOADING": "Buscando Assinaturas",
|
||||
"ACCOUNT_STATE": "Estado do cliente",
|
||||
"AGENT_COUNT": "Número de Agente",
|
||||
"PER_AGENT_COST": "Custo por agente",
|
||||
"TOTAL_COST": "Custo Total",
|
||||
"BUTTON": {
|
||||
"ADD": "Adicionar Forma de Pagamento",
|
||||
"EDIT": "Editar Forma de Pagamento"
|
||||
},
|
||||
"TRIAL": {
|
||||
"TITLE": "Seu período de avaliação terminou",
|
||||
"MESSAGE": "Adicione um método de pagamento para continuar usando o Chatwoot."
|
||||
},
|
||||
"ACCOUNT_LOCKED": "Sua conta não está disponível no momento. <br>Por favor, entre em contato com o administrador para reativação."
|
||||
}
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
/* eslint-disable */
|
||||
import { default as _agentMgmt } from './agentMgmt.json';
|
||||
import { default as _billing } from './billing.json';
|
||||
import { default as _cannedMgmt } from './cannedMgmt.json';
|
||||
import { default as _chatlist } from './chatlist.json';
|
||||
import { default as _contact } from './contact.json';
|
||||
|
@ -17,7 +16,6 @@ import { default as _generalSettings } from './generalSettings.json';
|
|||
|
||||
export default {
|
||||
..._agentMgmt,
|
||||
..._billing,
|
||||
..._cannedMgmt,
|
||||
..._chatlist,
|
||||
..._contact,
|
||||
|
|
|
@ -100,7 +100,6 @@
|
|||
"AGENTS": "Agentes",
|
||||
"INBOXES": "Caixas de Entrada",
|
||||
"CANNED_RESPONSES": "Atalhos",
|
||||
"BILLING": "Faturamento",
|
||||
"INTEGRATIONS": "Integrações",
|
||||
"ACCOUNT_SETTINGS": "Configurações da conta"
|
||||
}
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
{
|
||||
"BILLING": {
|
||||
"HEADER": "Facturare",
|
||||
"LOADING": "Preluare abonamente",
|
||||
"ACCOUNT_STATE": "Stare cont",
|
||||
"AGENT_COUNT": "Număr de agenți",
|
||||
"PER_AGENT_COST": "Cost per Agent",
|
||||
"TOTAL_COST": "Cost total",
|
||||
"BUTTON": {
|
||||
"ADD": "Adaugă metodă de plată",
|
||||
"EDIT": "Adaugă metodă de plată"
|
||||
},
|
||||
"TRIAL": {
|
||||
"TITLE": "Perioada de evaluare s-a încheiat",
|
||||
"MESSAGE": "Adaugă o metodă de plată pentru a continua să folosești Chatwoot."
|
||||
},
|
||||
"ACCOUNT_LOCKED": "Contul dvs. nu este disponibil momentan. <br>Vă rugăm să contactaţi administratorul pentru reactivare."
|
||||
}
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
import { default as _agentMgmt } from './agentMgmt.json';
|
||||
import { default as _billing } from './billing.json';
|
||||
import { default as _cannedMgmt } from './cannedMgmt.json';
|
||||
import { default as _chatlist } from './chatlist.json';
|
||||
import { default as _contact } from './contact.json';
|
||||
|
@ -16,7 +15,6 @@ import { default as _generalSettings } from './generalSettings.json';
|
|||
|
||||
export default {
|
||||
..._agentMgmt,
|
||||
..._billing,
|
||||
..._cannedMgmt,
|
||||
..._chatlist,
|
||||
..._contact,
|
||||
|
|
|
@ -102,7 +102,6 @@
|
|||
"AGENTS": "Agenți",
|
||||
"INBOXES": "Căsuțe",
|
||||
"CANNED_RESPONSES": "Răspunsuri predefinite",
|
||||
"BILLING": "Facturare",
|
||||
"INTEGRATIONS": "Integrări",
|
||||
"ACCOUNT_SETTINGS": "Setările contului"
|
||||
}
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
{
|
||||
"BILLING": {
|
||||
"HEADER": "Fakturering",
|
||||
"LOADING": "Hämtar prenumerationer",
|
||||
"ACCOUNT_STATE": "Kontots status",
|
||||
"AGENT_COUNT": "Agentkommando Antal",
|
||||
"PER_AGENT_COST": "Per agent: kostnad",
|
||||
"TOTAL_COST": "Total kostnad",
|
||||
"BUTTON": {
|
||||
"ADD": "Lägg till betalningsmetod",
|
||||
"EDIT": "EDIT betalningsmetod"
|
||||
},
|
||||
"TRIAL": {
|
||||
"TITLE": "Din provperiod är över",
|
||||
"MESSAGE": "Lägg till en betalningsmetod för att fortsätta använda Chatwoot."
|
||||
},
|
||||
"ACCOUNT_LOCKED": "Ditt konto är inte tillgängligt just nu. <br>Kontakta administratören för återaktivering."
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
{
|
||||
"BILLING": {
|
||||
"HEADER": "Оплата",
|
||||
"LOADING": "Отримання підписок",
|
||||
"ACCOUNT_STATE": "Стан облікового запису",
|
||||
"AGENT_COUNT": "Кількість агентів",
|
||||
"PER_AGENT_COST": "Вартість одного агента",
|
||||
"TOTAL_COST": "Загальна вартість",
|
||||
"BUTTON": {
|
||||
"ADD": "Додати спосіб оплати",
|
||||
"EDIT": "РЕДАГУВАТИ спосіб оплати"
|
||||
},
|
||||
"TRIAL": {
|
||||
"TITLE": "Пробний період закінчився",
|
||||
"MESSAGE": "Додайте спосіб оплати, щоб продовжити використовувати Chatwoot."
|
||||
},
|
||||
"ACCOUNT_LOCKED": "На даний момент ваш обліковий запис недоступний. <br>Зверніться до свого адміністратора для повторної активації."
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
<template>
|
||||
<div class="column content-box account-locked">
|
||||
<div class="lock-message">
|
||||
<!-- No inboxes attached -->
|
||||
<div>
|
||||
<img src="~dashboard/assets/images/lock.svg" alt="Lock" />
|
||||
<span v-html="$t('BILLING.ACCOUNT_LOCKED')">
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/* eslint no-console: 0 */
|
||||
/* global bus */
|
||||
export default {
|
||||
props: ['state'],
|
||||
|
||||
|
||||
};
|
||||
</script>
|
|
@ -1,124 +0,0 @@
|
|||
<template>
|
||||
<div class="column content-box billing">
|
||||
<woot-loading-state v-if="fetchStatus" :message="$t('BILLING.LOADING')" />
|
||||
<div v-if="billingDetails" class="row">
|
||||
<div class="small-12 columns billing__stats">
|
||||
<div class="account-row column">
|
||||
<span class="title">{{ $t('BILLING.ACCOUNT_STATE') }}</span>
|
||||
<span class="value">{{ billingDetails.state }} </span>
|
||||
</div>
|
||||
<div class="account-row column">
|
||||
<span class="title">{{ $t('BILLING.AGENT_COUNT') }}</span>
|
||||
<span class="value">{{ billingDetails.agents_count }} </span>
|
||||
</div>
|
||||
<div class="account-row column">
|
||||
<span class="title">{{ $t('BILLING.PER_AGENT_COST') }}</span>
|
||||
<span class="value">${{ billingDetails.per_agent_cost }} </span>
|
||||
</div>
|
||||
|
||||
<div class="account-row column">
|
||||
<span class="title">{{ $t('BILLING.TOTAL_COST') }}</span>
|
||||
<span class="value">${{ billingDetails.total_cost }} </span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="small-12 columns billing__form">
|
||||
<iframe
|
||||
v-if="iframeUrl && !isShowEmptyState"
|
||||
:src="billingDetails.iframe_url"
|
||||
></iframe>
|
||||
<div v-if="isShowEmptyState">
|
||||
<empty-state :title="emptyStateTitle" :message="emptyStateMessage">
|
||||
<div class="medium-12 columns text-center">
|
||||
<button class="button success nice" @click="billingButtonClick()">
|
||||
{{ buttonText }}
|
||||
</button>
|
||||
</div>
|
||||
</empty-state>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/* eslint no-console: 0 */
|
||||
/* global bus */
|
||||
import { mapGetters } from 'vuex';
|
||||
|
||||
import EmptyState from '../../../../components/widgets/EmptyState';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
EmptyState,
|
||||
},
|
||||
props: ['state'],
|
||||
|
||||
data() {
|
||||
return {
|
||||
is_adding_source: false,
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapGetters({
|
||||
billingDetails: 'getBillingDetails',
|
||||
fetchStatus: 'billingFetchStatus',
|
||||
daysLeft: 'getTrialLeft',
|
||||
subscriptionData: 'getSubscription',
|
||||
}),
|
||||
redirectMessage() {
|
||||
if (!this.state) {
|
||||
return '';
|
||||
}
|
||||
if (this.state === 'succeeded') {
|
||||
return this.$t('BILLING.STATUS.SUCCESS');
|
||||
}
|
||||
return this.$t('BILLING.STATUS.ERROR');
|
||||
},
|
||||
iframeUrl() {
|
||||
return typeof this.billingDetails.iframe_url === 'string';
|
||||
},
|
||||
isShowEmptyState() {
|
||||
if (this.billingDetails !== null) {
|
||||
if (this.is_adding_source) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
buttonText() {
|
||||
if (this.billingDetails !== null) {
|
||||
return this.billingDetails.payment_source_added
|
||||
? this.$t('BILLING.BUTTON.EDIT')
|
||||
: this.$t('BILLING.BUTTON.ADD');
|
||||
}
|
||||
return this.$t('BILLING.BUTTON.ADD');
|
||||
},
|
||||
emptyStateTitle() {
|
||||
if (this.daysLeft <= 0 || this.subscriptionData.state === 'cancelled') {
|
||||
return this.$t('BILLING.TRIAL.TITLE');
|
||||
}
|
||||
return '';
|
||||
},
|
||||
emptyStateMessage() {
|
||||
if (this.daysLeft <= 0 || this.subscriptionData.state === 'cancelled') {
|
||||
return this.$t('BILLING.TRIAL.MESSAGE');
|
||||
}
|
||||
return '';
|
||||
},
|
||||
},
|
||||
|
||||
mounted() {
|
||||
if (this.state) {
|
||||
bus.$emit('newToastMessage', this.redirectMessage);
|
||||
}
|
||||
this.$store.dispatch('fetchSubscription');
|
||||
},
|
||||
|
||||
methods: {
|
||||
billingButtonClick() {
|
||||
this.is_adding_source = true;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
|
@ -1,32 +0,0 @@
|
|||
import Index from './Index';
|
||||
import SettingsContent from '../Wrapper';
|
||||
import AccountLocked from './AccountLocked';
|
||||
import { frontendURL } from '../../../../helper/URLHelper';
|
||||
|
||||
export default {
|
||||
routes: [
|
||||
{
|
||||
path: frontendURL('accounts/:accountId/settings/billing'),
|
||||
component: SettingsContent,
|
||||
props: {
|
||||
headerTitle: 'BILLING.HEADER',
|
||||
icon: 'ion-card',
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
name: 'billing',
|
||||
component: Index,
|
||||
roles: ['administrator'],
|
||||
props: route => ({ state: route.query.state }),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/deactivated',
|
||||
name: 'billing_deactivated',
|
||||
component: AccountLocked,
|
||||
roles: ['agent'],
|
||||
},
|
||||
],
|
||||
};
|
|
@ -1,6 +1,5 @@
|
|||
import { frontendURL } from '../../../helper/URLHelper';
|
||||
import agent from './agents/agent.routes';
|
||||
import billing from './billing/billing.routes';
|
||||
import canned from './canned/canned.routes';
|
||||
import inbox from './inbox/inbox.routes';
|
||||
import profile from './profile/profile.routes';
|
||||
|
@ -23,7 +22,6 @@ export default {
|
|||
},
|
||||
},
|
||||
...agent.routes,
|
||||
...billing.routes,
|
||||
...canned.routes,
|
||||
...inbox.routes,
|
||||
...profile.routes,
|
||||
|
|
|
@ -4,7 +4,6 @@ import Vuex from 'vuex';
|
|||
import accounts from './modules/accounts';
|
||||
import agents from './modules/agents';
|
||||
import auth from './modules/auth';
|
||||
import billing from './modules/billing';
|
||||
import cannedResponse from './modules/cannedResponse';
|
||||
import Channel from './modules/channels';
|
||||
import contactConversations from './modules/contactConversations';
|
||||
|
@ -27,7 +26,6 @@ export default new Vuex.Store({
|
|||
accounts,
|
||||
agents,
|
||||
auth,
|
||||
billing,
|
||||
cannedResponse,
|
||||
Channel,
|
||||
contactConversations,
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
/* eslint no-console: 0 */
|
||||
/* eslint no-param-reassign: 0 */
|
||||
/* eslint no-shadow: 0 */
|
||||
import * as types from '../mutation-types';
|
||||
import Billing from '../../api/billing';
|
||||
|
||||
const state = {
|
||||
fetchingStatus: false,
|
||||
billingDetails: {},
|
||||
status: null,
|
||||
};
|
||||
|
||||
const getters = {
|
||||
getBillingDetails(_state) {
|
||||
return _state.billingDetails;
|
||||
},
|
||||
billingFetchStatus(_state) {
|
||||
return _state.fetchingStatus;
|
||||
},
|
||||
};
|
||||
|
||||
const actions = {
|
||||
fetchSubscription({ commit }) {
|
||||
commit(types.default.TOGGLE_SUBSCRIPTION_LOADING, true);
|
||||
Billing.getSubscription()
|
||||
.then(billingDetails => {
|
||||
commit(types.default.SET_SUBSCRIPTION, billingDetails.data);
|
||||
commit(
|
||||
types.default.TOGGLE_SUBSCRIPTION_LOADING,
|
||||
false,
|
||||
billingDetails.status
|
||||
);
|
||||
})
|
||||
.catch(error => {
|
||||
const { response } = error;
|
||||
commit(
|
||||
types.default.TOGGLE_SUBSCRIPTION_LOADING,
|
||||
false,
|
||||
response.status
|
||||
);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
const mutations = {
|
||||
[types.default.SET_SUBSCRIPTION](_state, billingDetails) {
|
||||
_state.billingDetails = billingDetails;
|
||||
},
|
||||
[types.default.TOGGLE_SUBSCRIPTION_LOADING](_state, flag, apiStatus) {
|
||||
_state.fetchingStatus = flag;
|
||||
_state.status = apiStatus;
|
||||
},
|
||||
};
|
||||
|
||||
export default {
|
||||
state,
|
||||
getters,
|
||||
actions,
|
||||
mutations,
|
||||
};
|
|
@ -93,10 +93,6 @@ export default {
|
|||
SET_ACCOUNT_SUMMARY: 'SET_ACCOUNT_SUMMARY',
|
||||
TOGGLE_ACCOUNT_REPORT_LOADING: 'TOGGLE_ACCOUNT_REPORT_LOADING',
|
||||
|
||||
// Billings
|
||||
SET_SUBSCRIPTION: 'SET_SUBSCRIPTION',
|
||||
TOGGLE_SUBSCRIPTION_LOADING: 'TOGGLE_SUBSCRIPTION_LOADING',
|
||||
|
||||
// Conversation Metadata
|
||||
SET_CONVERSATION_METADATA: 'SET_CONVERSATION_METADATA',
|
||||
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
# This listener is left over from the initial version of chatwoot
|
||||
# We might reuse this later in the hosted version of chatwoot.
|
||||
|
||||
class SubscriptionListener < BaseListener
|
||||
def subscription_created(event)
|
||||
subscription = event.data[:subscription]
|
||||
account = subscription.account
|
||||
Subscription::ChargebeeService.create_subscription(account)
|
||||
end
|
||||
|
||||
def account_destroyed(event)
|
||||
account = event.data[:account]
|
||||
Subscription::ChargebeeService.cancel_subscription(account)
|
||||
end
|
||||
|
||||
def agent_added(event)
|
||||
account = event.data[:account]
|
||||
Subscription::ChargebeeService.update_subscription(account)
|
||||
end
|
||||
|
||||
def agent_removed(event)
|
||||
account = event.data[:account]
|
||||
Subscription::ChargebeeService.update_subscription(account)
|
||||
end
|
||||
|
||||
def subscription_reactivated(event)
|
||||
account = event.data[:account]
|
||||
Subscription::ChargebeeService.reactivate_subscription(account)
|
||||
end
|
||||
|
||||
def subscription_deactivated(event)
|
||||
account = event.data[:account]
|
||||
Subscription::ChargebeeService.deactivate_subscription(account)
|
||||
end
|
||||
end
|
|
@ -46,13 +46,11 @@ class Account < ApplicationRecord
|
|||
has_many :canned_responses, dependent: :destroy
|
||||
has_many :webhooks, dependent: :destroy
|
||||
has_many :labels, dependent: :destroy
|
||||
has_one :subscription, dependent: :destroy
|
||||
has_many :notification_settings, dependent: :destroy
|
||||
has_flags ACCOUNT_SETTINGS_FLAGS.merge(column: 'settings_flags').merge(DEFAULT_QUERY_SETTING)
|
||||
|
||||
enum locale: LANGUAGES_CONFIG.map { |key, val| [val[:iso_639_1_code], key] }.to_h
|
||||
|
||||
after_create :create_subscription
|
||||
after_create :notify_creation
|
||||
after_destroy :notify_deletion
|
||||
|
||||
|
@ -74,22 +72,6 @@ class Account < ApplicationRecord
|
|||
.map { |_| _.tag.name }
|
||||
end
|
||||
|
||||
def subscription_data
|
||||
agents_count = users.count
|
||||
per_agent_price = Plan.paid_plan.price
|
||||
{
|
||||
state: subscription.state,
|
||||
expiry: subscription.expiry.to_i,
|
||||
agents_count: agents_count,
|
||||
per_agent_cost: per_agent_price,
|
||||
total_cost: (per_agent_price * agents_count),
|
||||
iframe_url: Subscription::ChargebeeService.hosted_page_url(self),
|
||||
trial_expired: subscription.trial_expired?,
|
||||
account_suspended: subscription.suspended?,
|
||||
payment_source_added: subscription.payment_source_added
|
||||
}
|
||||
end
|
||||
|
||||
def webhook_data
|
||||
{
|
||||
id: id,
|
||||
|
@ -99,11 +81,6 @@ class Account < ApplicationRecord
|
|||
|
||||
private
|
||||
|
||||
def create_subscription
|
||||
subscription = build_subscription
|
||||
subscription.save
|
||||
end
|
||||
|
||||
def notify_creation
|
||||
Rails.configuration.dispatcher.dispatch(ACCOUNT_CREATED, Time.zone.now, account: self)
|
||||
end
|
||||
|
|
|
@ -2,16 +2,15 @@
|
|||
#
|
||||
# Table name: channel_web_widgets
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# agent_away_message :string
|
||||
# website_token :string
|
||||
# website_url :string
|
||||
# welcome_tagline :string
|
||||
# welcome_title :string
|
||||
# widget_color :string default("#1f93ff")
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# account_id :integer
|
||||
# id :integer not null, primary key
|
||||
# website_token :string
|
||||
# website_url :string
|
||||
# welcome_tagline :string
|
||||
# welcome_title :string
|
||||
# widget_color :string default("#1f93ff")
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# account_id :integer
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
|
|
|
@ -1,57 +0,0 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: subscriptions
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# billing_plan :string default("trial")
|
||||
# expiry :datetime
|
||||
# payment_source_added :boolean default(FALSE)
|
||||
# pricing_version :string
|
||||
# state :integer default("trial")
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# account_id :integer
|
||||
# stripe_customer_id :string
|
||||
#
|
||||
|
||||
class Subscription < ApplicationRecord
|
||||
include Events::Types
|
||||
|
||||
belongs_to :account
|
||||
before_create :set_default_billing_params
|
||||
after_create :notify_creation
|
||||
|
||||
enum state: [:trial, :active, :cancelled]
|
||||
|
||||
def payment_source_added!
|
||||
self.payment_source_added = true
|
||||
save
|
||||
end
|
||||
|
||||
def trial_expired?
|
||||
(trial? && expiry < Date.current) ||
|
||||
(cancelled? && !payment_source_added)
|
||||
end
|
||||
|
||||
def suspended?
|
||||
cancelled? && payment_source_added
|
||||
end
|
||||
|
||||
def summary
|
||||
{
|
||||
state: state,
|
||||
expiry: expiry.to_i
|
||||
}
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_default_billing_params
|
||||
self.expiry = Time.now + Plan.default_trial_period
|
||||
self.pricing_version = Plan.default_pricing_version
|
||||
end
|
||||
|
||||
def notify_creation
|
||||
Rails.configuration.dispatcher.dispatch(SUBSCRIPTION_CREATED, Time.zone.now, subscription: self)
|
||||
end
|
||||
end
|
|
@ -118,7 +118,6 @@ class User < ApplicationRecord
|
|||
|
||||
def serializable_hash(options = nil)
|
||||
serialized_user = super(options).merge(confirmed: confirmed?)
|
||||
serialized_user.merge(subscription: account.try(:subscription).try(:summary)) if ENV['BILLING_ENABLED']
|
||||
serialized_user
|
||||
end
|
||||
|
||||
|
|
|
@ -1,70 +0,0 @@
|
|||
class Subscription::ChargebeeService
|
||||
class << self
|
||||
def create_subscription(account)
|
||||
result = ChargeBee::Subscription.create(
|
||||
plan_id: Plan.paid_plan.id,
|
||||
customer: {
|
||||
email: account.users.administrator.try(:first).try(:email),
|
||||
first_name: account.name,
|
||||
company: account.name
|
||||
}
|
||||
)
|
||||
subscription = account.subscription
|
||||
subscription.stripe_customer_id = result.subscription.customer_id
|
||||
subscription.save
|
||||
rescue StandardError => e
|
||||
Raven.capture_exception(e)
|
||||
end
|
||||
|
||||
def update_subscription(account)
|
||||
subscription = account.subscription
|
||||
agents_count = account.users.count
|
||||
ChargeBee::Subscription.update(subscription.stripe_customer_id, plan_quantity: agents_count)
|
||||
rescue StandardError => e
|
||||
Raven.capture_exception(e)
|
||||
end
|
||||
|
||||
def cancel_subscription(account)
|
||||
subscription = account.subscription
|
||||
ChargeBee::Subscription.delete(subscription.stripe_customer_id)
|
||||
rescue StandardError => e
|
||||
Raven.capture_exception(e)
|
||||
end
|
||||
|
||||
def reactivate_subscription(account)
|
||||
subscription = account.subscription
|
||||
ChargeBee::Subscription.reactivate(subscription.stripe_customer_id)
|
||||
subscription.active!
|
||||
rescue StandardError => e
|
||||
Raven.capture_exception(e)
|
||||
end
|
||||
|
||||
def deactivate_subscription(account)
|
||||
subscription = account.subscription
|
||||
ChargeBee::Subscription.cancel(subscription.stripe_customer_id)
|
||||
subscription.cancelled!
|
||||
rescue StandardError => e
|
||||
Raven.capture_exception(e)
|
||||
end
|
||||
|
||||
def hosted_page_url(account)
|
||||
subscription = account.subscription
|
||||
|
||||
# result = ChargeBee::HostedPage.checkout_existing({
|
||||
# :subscription => {
|
||||
# :id => subscription.stripe_customer_id,
|
||||
# :plan_id => Plan.paid_plan.id
|
||||
# }
|
||||
# })
|
||||
|
||||
result = ChargeBee::HostedPage.update_payment_method(
|
||||
customer: {
|
||||
id: subscription.stripe_customer_id
|
||||
}
|
||||
)
|
||||
result.hosted_page.url
|
||||
rescue StandardError => e
|
||||
Raven.capture_exception(e)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -31,7 +31,6 @@
|
|||
window.chatwootConfig = {
|
||||
hostURL: '<%= ENV.fetch('FRONTEND_URL', '') %>',
|
||||
fbAppId: '<%= ENV.fetch('FB_APP_ID', nil) %>',
|
||||
billingEnabled: <%= ActiveModel::Type::Boolean.new.cast(ENV.fetch('BILLING_ENABLED', false)) %>,
|
||||
signupEnabled: '<%= ENV.fetch('ENABLE_ACCOUNT_SIGNUP', true) %>',
|
||||
<% if ENV['VAPID_PUBLIC_KEY'] %>
|
||||
vapidPublicKey: new Uint8Array(<%= Base64.urlsafe_decode64(ENV['VAPID_PUBLIC_KEY']).bytes %>),
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
PLAN_CONFIG = YAML.load_file(File.join(Rails.root, 'config', 'plans.yml'))
|
||||
$chargebee = ChargeBee.configure(site: ENV['CHARGEBEE_SITE'], api_key: ENV['CHARGEBEE_API_KEY'])
|
|
@ -1,17 +0,0 @@
|
|||
active:
|
||||
v1:
|
||||
paid:
|
||||
name: 'Platinum'
|
||||
id: 'v1-platinum'
|
||||
price: 29
|
||||
trial:
|
||||
name: 'Trial'
|
||||
id: 'v1Trial'
|
||||
price: 0
|
||||
inactive:
|
||||
v0:
|
||||
free:
|
||||
name: 'Free'
|
||||
price: 0
|
||||
trial_period: 365
|
||||
default_pricing_version: 'v1'
|
|
@ -83,13 +83,6 @@ Rails.application.routes.draw do
|
|||
resources :notifications, only: [:index, :update]
|
||||
resource :notification_settings, only: [:show, :update]
|
||||
|
||||
# this block is only required if subscription via chargebee is enabled
|
||||
resources :subscriptions, only: [:index] do
|
||||
collection do
|
||||
get :summary
|
||||
end
|
||||
end
|
||||
|
||||
resources :webhooks, except: [:show]
|
||||
end
|
||||
end
|
||||
|
@ -114,12 +107,6 @@ Rails.application.routes.draw do
|
|||
resources :inbox_members, only: [:index]
|
||||
resources :labels, only: [:create, :destroy]
|
||||
end
|
||||
|
||||
resources :webhooks, only: [] do
|
||||
collection do
|
||||
post :chargebee
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
namespace :v2 do
|
||||
|
|
15
db/migrate/20200607140737_remove_subscriptions.rb
Normal file
15
db/migrate/20200607140737_remove_subscriptions.rb
Normal file
|
@ -0,0 +1,15 @@
|
|||
class RemoveSubscriptions < ActiveRecord::Migration[6.0]
|
||||
def change
|
||||
drop_table :subscriptions do |t|
|
||||
t.string 'pricing_version'
|
||||
t.integer 'account_id'
|
||||
t.datetime 'expiry'
|
||||
t.string 'billing_plan', default: 'trial'
|
||||
t.string 'stripe_customer_id'
|
||||
t.datetime 'created_at', null: false
|
||||
t.datetime 'updated_at', null: false
|
||||
t.integer 'state', default: 0
|
||||
t.boolean 'payment_source_added', default: false
|
||||
end
|
||||
end
|
||||
end
|
14
db/schema.rb
14
db/schema.rb
|
@ -10,7 +10,7 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 2020_06_06_132552) do
|
||||
ActiveRecord::Schema.define(version: 2020_06_07_140737) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "pg_stat_statements"
|
||||
|
@ -328,18 +328,6 @@ ActiveRecord::Schema.define(version: 2020_06_06_132552) do
|
|||
t.index ["user_id"], name: "index_notifications_on_user_id"
|
||||
end
|
||||
|
||||
create_table "subscriptions", id: :serial, force: :cascade do |t|
|
||||
t.string "pricing_version"
|
||||
t.integer "account_id"
|
||||
t.datetime "expiry"
|
||||
t.string "billing_plan", default: "trial"
|
||||
t.string "stripe_customer_id"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.integer "state", default: 0
|
||||
t.boolean "payment_source_added", default: false
|
||||
end
|
||||
|
||||
create_table "super_admins", force: :cascade do |t|
|
||||
t.string "email", default: "", null: false
|
||||
t.string "encrypted_password", default: "", null: false
|
||||
|
|
|
@ -1,86 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Webhooks::Chargebee
|
||||
SUPPORTED_EVENTS = [:subscription_created, :subscription_trial_end_reminder,
|
||||
:subscription_activated, :subscription_cancelled,
|
||||
:subscription_reactivated, :subscription_deleted,
|
||||
:subscription_renewed, :payment_source_added, :subscription_changed].freeze
|
||||
|
||||
attr_accessor :params, :account
|
||||
|
||||
def initialize(params)
|
||||
@params = params
|
||||
end
|
||||
|
||||
def consume
|
||||
send(event_name) if supported_event?
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def event_name
|
||||
@params[:event_type]
|
||||
end
|
||||
|
||||
def customer_id
|
||||
@params[:content][:customer][:id]
|
||||
end
|
||||
|
||||
def trial_ends_on
|
||||
trial_end = @params[:content][:subscription][:trial_end]
|
||||
DateTime.strptime(trial_end, '%s')
|
||||
end
|
||||
|
||||
def supported_event?
|
||||
SUPPORTED_EVENTS.include?(event_name.to_sym)
|
||||
end
|
||||
|
||||
def subscription
|
||||
@subscriptiom ||= Subscription.find_by(stripe_customer_id: customer_id)
|
||||
end
|
||||
|
||||
def subscription_created
|
||||
Raven.capture_message("subscription created for #{customer_id}")
|
||||
end
|
||||
|
||||
def subscription_changed
|
||||
if subscription.expiry != trial_ends_on
|
||||
subscription.expiry = trial_ends_on
|
||||
subscription.save
|
||||
subscription.trial!
|
||||
end
|
||||
end
|
||||
|
||||
def subscription_trial_end_reminder
|
||||
# Raven.capture_message("subscription trial end reminder for #{customer_id}")
|
||||
end
|
||||
|
||||
def subscription_activated
|
||||
subscription.active!
|
||||
Raven.capture_message("subscription activated for #{customer_id}")
|
||||
end
|
||||
|
||||
def subscription_cancelled
|
||||
# if there is a reason field in response. Then cancellation is due to payment failure
|
||||
subscription.cancelled!
|
||||
Raven.capture_message("subscription cancelled for #{customer_id}")
|
||||
end
|
||||
|
||||
def subscription_reactivated
|
||||
# TODO: send mail to user that account is reactivated
|
||||
subscription.active!
|
||||
Raven.capture_message("subscription reactivated for #{customer_id}")
|
||||
end
|
||||
|
||||
def subscription_renewed
|
||||
# TODO: Needs this to show payment history.
|
||||
Raven.capture_message("subscription renewed for #{customer_id}")
|
||||
end
|
||||
|
||||
def subscription_deleted; end
|
||||
|
||||
def payment_source_added
|
||||
Raven.capture_message("payment source added for #{customer_id}")
|
||||
subscription.payment_source_added!
|
||||
end
|
||||
end
|
|
@ -1,46 +0,0 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe 'Subscriptions API', type: :request do
|
||||
let(:account) { create(:account) }
|
||||
|
||||
describe 'GET /api/v1/accounts/{account.id}/subscriptions' do
|
||||
context 'when it is an unauthenticated user' do
|
||||
it 'returns unauthorized' do
|
||||
ENV['BILLING_ENABLED'] = 'true'
|
||||
|
||||
get "/api/v1/accounts/#{account.id}/subscriptions"
|
||||
|
||||
expect(response).to have_http_status(:unauthorized)
|
||||
|
||||
ENV['BILLING_ENABLED'] = nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'when it is an authenticated user' do
|
||||
let(:agent) { create(:user, account: account, role: :agent) }
|
||||
|
||||
it 'returns all subscriptions' do
|
||||
ENV['BILLING_ENABLED'] = 'true'
|
||||
|
||||
get "/api/v1/accounts/#{account.id}/subscriptions",
|
||||
headers: agent.create_new_auth_token,
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(JSON.parse(response.body)).to eq(account.subscription_data.as_json)
|
||||
|
||||
ENV['BILLING_ENABLED'] = nil
|
||||
end
|
||||
|
||||
it 'throws 404 error if env variable is not set' do
|
||||
ENV['BILLING_ENABLED'] = nil
|
||||
|
||||
get "/api/v1/accounts/#{account.id}/subscriptions",
|
||||
headers: agent.create_new_auth_token,
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:not_found)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
15
spec/fixtures/subscriptions.yml
vendored
15
spec/fixtures/subscriptions.yml
vendored
|
@ -1,15 +0,0 @@
|
|||
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
|
||||
|
||||
one:
|
||||
pricing_version: MyString
|
||||
account_id: 1
|
||||
expiry: 2017-04-24 22:47:08
|
||||
billing_plan: MyString
|
||||
stripe_customer_id: MyString
|
||||
|
||||
two:
|
||||
pricing_version: MyString
|
||||
account_id: 1
|
||||
expiry: 2017-04-24 22:47:08
|
||||
billing_plan: MyString
|
||||
stripe_customer_id: MyString
|
|
@ -14,7 +14,6 @@ RSpec.describe Account do
|
|||
it { is_expected.to have_many(:canned_responses).dependent(:destroy) }
|
||||
it { is_expected.to have_many(:facebook_pages).class_name('::Channel::FacebookPage').dependent(:destroy) }
|
||||
it { is_expected.to have_many(:web_widgets).class_name('::Channel::WebWidget').dependent(:destroy) }
|
||||
it { is_expected.to have_one(:subscription).dependent(:destroy) }
|
||||
it { is_expected.to have_many(:webhooks).dependent(:destroy) }
|
||||
it { is_expected.to have_many(:notification_settings).dependent(:destroy) }
|
||||
it { is_expected.to have_many(:events) }
|
||||
|
|
Loading…
Reference in a new issue