mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-15 12:20:31 +00:00
feat: retrieve organization subscriptions list api.
feat: subscriptions reducers.
This commit is contained in:
@@ -13,7 +13,6 @@ export default function DashboardLoadingIndicator({
|
||||
<div className={classNames('bigcapital-loading', className)}>
|
||||
<div class="center">
|
||||
<Icon icon="bigcapital" height={37} width={214} />
|
||||
<span class="text">Please wait while resources loading...</span>
|
||||
</div>
|
||||
</div>
|
||||
</Choose.When>
|
||||
|
||||
@@ -13,9 +13,9 @@ function EnsureOrganizationIsReady({
|
||||
redirectTo = '/setup',
|
||||
|
||||
// #withOrganizationByOrgId
|
||||
isOrganizationBuilt,
|
||||
isOrganizationInitialized,
|
||||
}) {
|
||||
return (isOrganizationBuilt) ? children : (
|
||||
return (isOrganizationInitialized) ? children : (
|
||||
<Redirect
|
||||
to={{ pathname: redirectTo }}
|
||||
/>
|
||||
@@ -27,5 +27,5 @@ export default compose(
|
||||
connect((state, props) => ({
|
||||
organizationId: props.currentOrganizationId,
|
||||
})),
|
||||
withOrganization(({ isOrganizationBuilt }) => ({ isOrganizationBuilt })),
|
||||
withOrganization(({ isOrganizationInitialized }) => ({ isOrganizationInitialized })),
|
||||
)(EnsureOrganizationIsReady);
|
||||
@@ -7,6 +7,7 @@ import SetupWizardPage from 'containers/Setup/WizardSetupPage';
|
||||
import DashboardLoadingIndicator from 'components/Dashboard/DashboardLoadingIndicator';
|
||||
|
||||
import withOrganizationActions from 'containers/Organization/withOrganizationActions';
|
||||
import withSubscriptionsActions from 'containers/Subscriptions/withSubscriptionsActions';
|
||||
|
||||
import { compose } from 'utils';
|
||||
|
||||
@@ -17,13 +18,26 @@ function DashboardPrivatePages({
|
||||
|
||||
// #withOrganizationActions
|
||||
requestAllOrganizations,
|
||||
|
||||
// #withSubscriptionsActions
|
||||
requestFetchSubscriptions,
|
||||
}) {
|
||||
// Fetch all user's organizatins.
|
||||
const fetchOrganizations = useQuery(
|
||||
['organizations'], () => requestAllOrganizations(),
|
||||
);
|
||||
|
||||
// Fetchs organization subscriptions.
|
||||
const fetchSuscriptions = useQuery(
|
||||
['susbcriptions'], () => requestFetchSubscriptions(),
|
||||
{ enabled: fetchOrganizations.data },
|
||||
)
|
||||
|
||||
return (
|
||||
<DashboardLoadingIndicator isLoading={fetchOrganizations.isFetching}>
|
||||
<DashboardLoadingIndicator isLoading={
|
||||
fetchOrganizations.isFetching ||
|
||||
fetchSuscriptions.isFetching
|
||||
}>
|
||||
<Switch>
|
||||
<Route path={'/setup'}>
|
||||
<SetupWizardPage />
|
||||
@@ -39,4 +53,5 @@ function DashboardPrivatePages({
|
||||
|
||||
export default compose(
|
||||
withOrganizationActions,
|
||||
withSubscriptionsActions,
|
||||
)(DashboardPrivatePages);
|
||||
@@ -43,14 +43,18 @@ function SetupLeftSection({
|
||||
<p className={'content__text'}>
|
||||
<T id={'you_have_a_bigcapital_account'} />
|
||||
</p>
|
||||
<span class="content__divider"></span>
|
||||
|
||||
<div className={'content__organization'}>
|
||||
<span class="organization-id">Your oragnization ID: <span class="id">{ currentOrganizationId }</span>,</span><br />
|
||||
<span class="signout"><a onClick={onClickLogout} href="#"><T id={'sign_out'} /></a></span>
|
||||
<span class="organization-id">
|
||||
Your oragnization ID: <span class="id">{ currentOrganizationId }</span>,
|
||||
</span>
|
||||
<br />
|
||||
<span class="signout">
|
||||
<a onClick={onClickLogout} href="#"><T id={'sign_out'} /></a>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<span class="content__divider"></span>
|
||||
|
||||
<div className={'content__footer'}>
|
||||
<div className={'content__contact-info'}>
|
||||
<p><T id={'we_re_here_to_help'} /> {'+21892-791-8381'}</p>
|
||||
|
||||
@@ -16,16 +16,20 @@ import classNames from 'classnames';
|
||||
import { TimezonePicker } from '@blueprintjs/timezone';
|
||||
import { FormattedMessage as T, useIntl } from 'react-intl';
|
||||
import { DateInput } from '@blueprintjs/datetime';
|
||||
import { withWizard } from 'react-albus';
|
||||
import { momentFormatter, tansformDateValue } from 'utils';
|
||||
import { ListSelect, ErrorMessage, FieldRequiredHint } from 'components';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
|
||||
import withSettingsActions from 'containers/Settings/withSettingsActions';
|
||||
import withOrganizationActions from 'containers/Organization/withOrganizationActions';
|
||||
|
||||
import { compose, optionsMapToArray } from 'utils';
|
||||
|
||||
function SetupOrganizationForm({ requestSubmitOptions, requestSeedTenant }) {
|
||||
function SetupOrganizationForm({
|
||||
requestSubmitOptions,
|
||||
requestOrganizationSeed,
|
||||
wizard,
|
||||
}) {
|
||||
const { formatMessage } = useIntl();
|
||||
const [selected, setSelected] = useState();
|
||||
|
||||
@@ -130,7 +134,7 @@ function SetupOrganizationForm({ requestSubmitOptions, requestSeedTenant }) {
|
||||
name: Yup.string()
|
||||
.required()
|
||||
.label(formatMessage({ id: 'organization_name_' })),
|
||||
date_start: Yup.date()
|
||||
financial_date_start: Yup.date()
|
||||
.required()
|
||||
.label(formatMessage({ id: 'date_start_' })),
|
||||
base_currency: Yup.string()
|
||||
@@ -148,7 +152,7 @@ function SetupOrganizationForm({ requestSubmitOptions, requestSeedTenant }) {
|
||||
const initialValues = useMemo(
|
||||
() => ({
|
||||
name: '',
|
||||
date_start: moment(new Date()).format('YYYY-MM-DD'),
|
||||
financial_date_start: moment(new Date()).format('YYYY-MM-DD'),
|
||||
base_currency: '',
|
||||
language: '',
|
||||
fiscal_year: '',
|
||||
@@ -176,7 +180,11 @@ function SetupOrganizationForm({ requestSubmitOptions, requestSeedTenant }) {
|
||||
return { key: option.key, ...option, group: 'organization' };
|
||||
});
|
||||
requestSubmitOptions({ options })
|
||||
.then(() => {
|
||||
return requestOrganizationSeed();
|
||||
})
|
||||
.then((response) => {
|
||||
wizard.next();
|
||||
setSubmitting(false);
|
||||
})
|
||||
.catch((erros) => {
|
||||
@@ -220,29 +228,29 @@ function SetupOrganizationForm({ requestSubmitOptions, requestSeedTenant }) {
|
||||
const handleDateChange = useCallback(
|
||||
(date) => {
|
||||
const formatted = moment(date).format('YYYY-MM-DD');
|
||||
setFieldValue('date_start', formatted);
|
||||
setFieldValue('financial_date_start', formatted);
|
||||
},
|
||||
[setFieldValue],
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={'register-organizaton-form'}>
|
||||
<div className={'register-org-title'}>
|
||||
<h2>
|
||||
<div className={'setup-organization'}>
|
||||
<div className={'setup-organization__title-wrap'}>
|
||||
<h1>
|
||||
<T id={'let_s_get_started'} />
|
||||
</h2>
|
||||
<p>
|
||||
</h1>
|
||||
<p class="paragraph">
|
||||
<T id={'tell_the_system_a_little_bit_about_your_organization'} />
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<form onClick={handleSubmit}>
|
||||
<form class="setup-organization__form" onClick={handleSubmit}>
|
||||
<h3>
|
||||
<T id={'organization_details'} />
|
||||
</h3>
|
||||
|
||||
<FormGroup
|
||||
label={<T id={'name'} />}
|
||||
label={<T id={'legal_organization_name'} />}
|
||||
labelInfo={<FieldRequiredHint />}
|
||||
className={'form-group--name'}
|
||||
intent={errors.name && touched.name && Intent.DANGER}
|
||||
@@ -258,15 +266,15 @@ function SetupOrganizationForm({ requestSubmitOptions, requestSeedTenant }) {
|
||||
<FormGroup
|
||||
label={<T id={'financial_starting_date'} />}
|
||||
labelInfo={<FieldRequiredHint />}
|
||||
intent={errors.date_start && touched.date_start && Intent.DANGER}
|
||||
intent={errors.financial_date_start && touched.financial_date_start && Intent.DANGER}
|
||||
helperText={
|
||||
<ErrorMessage name="date_start" {...{ errors, touched }} />
|
||||
<ErrorMessage name="financial_date_start" {...{ errors, touched }} />
|
||||
}
|
||||
className={classNames('form-group--select-list', Classes.FILL)}
|
||||
>
|
||||
<DateInput
|
||||
{...momentFormatter('MMMM Do YYYY')}
|
||||
value={tansformDateValue(values.date_start)}
|
||||
value={tansformDateValue(values.financial_date_start)}
|
||||
onChange={handleDateChange}
|
||||
popoverProps={{ position: Position.BOTTOM, minimal: true }}
|
||||
/>
|
||||
@@ -410,4 +418,5 @@ function SetupOrganizationForm({ requestSubmitOptions, requestSeedTenant }) {
|
||||
export default compose(
|
||||
withSettingsActions,
|
||||
withOrganizationActions,
|
||||
withWizard,
|
||||
)(SetupOrganizationForm);
|
||||
|
||||
@@ -5,6 +5,7 @@ import { useHistory } from "react-router-dom";
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import WizardSetupSteps from './WizardSetupSteps';
|
||||
import withSubscriptions from 'containers/Subscriptions/withSubscriptions';
|
||||
|
||||
import SetupSubscriptionForm from './SetupSubscriptionForm';
|
||||
import SetupOrganizationForm from './SetupOrganizationForm';
|
||||
@@ -23,16 +24,18 @@ function SetupRightSection ({
|
||||
|
||||
// #withOrganization
|
||||
isOrganizationInitialized,
|
||||
isOrganizationSubscribed: hasSubscriptions,
|
||||
isOrganizationSeeded
|
||||
isOrganizationSeeded,
|
||||
|
||||
// #withSubscriptions
|
||||
isSubscriptionActive
|
||||
}) {
|
||||
const history = useHistory();
|
||||
|
||||
const handleSkip = useCallback(({ step, push }) => {
|
||||
const scenarios = [
|
||||
{ condition: !hasSubscriptions, redirectTo: 'subscription' },
|
||||
{ condition: hasSubscriptions && !isOrganizationInitialized, redirectTo: 'initializing' },
|
||||
{ condition: hasSubscriptions && !isOrganizationSeeded, redirectTo: 'organization' },
|
||||
{ condition: !isSubscriptionActive, redirectTo: 'subscription' },
|
||||
{ condition: isSubscriptionActive && !isOrganizationInitialized, redirectTo: 'initializing' },
|
||||
{ condition: isSubscriptionActive && !isOrganizationSeeded, redirectTo: 'organization' },
|
||||
];
|
||||
const scenario = scenarios.find((scenario) => scenario.condition);
|
||||
|
||||
@@ -40,7 +43,7 @@ function SetupRightSection ({
|
||||
push(scenario.redirectTo);
|
||||
}
|
||||
}, [
|
||||
hasSubscriptions,
|
||||
isSubscriptionActive,
|
||||
isOrganizationInitialized,
|
||||
isOrganizationSeeded,
|
||||
]);
|
||||
@@ -92,12 +95,15 @@ export default compose(
|
||||
withOrganization(({
|
||||
organization,
|
||||
isOrganizationInitialized,
|
||||
isOrganizationSubscribed,
|
||||
isOrganizationSeeded,
|
||||
}) => ({
|
||||
organization,
|
||||
isOrganizationInitialized,
|
||||
isOrganizationSubscribed,
|
||||
isOrganizationSeeded,
|
||||
})),
|
||||
withSubscriptions(({
|
||||
isSubscriptionActive,
|
||||
}) => ({
|
||||
isSubscriptionActive
|
||||
}), 'main'),
|
||||
)(SetupRightSection);
|
||||
@@ -3,10 +3,11 @@ import * as Yup from 'yup';
|
||||
import { useFormik } from 'formik';
|
||||
import { FormattedMessage as T, useIntl } from 'react-intl';
|
||||
import { Button, Intent } from '@blueprintjs/core';
|
||||
import { withWizard } from 'react-albus';
|
||||
import withSubscriptionsActions from 'containers/Subscriptions/withSubscriptionsActions';
|
||||
import BillingPlans from 'containers/Subscriptions/billingPlans';
|
||||
import BillingPeriods from 'containers/Subscriptions/billingPeriods';
|
||||
import { BillingPaymentmethod } from 'containers/Subscriptions/billingPaymentmethod';
|
||||
|
||||
import withBillingActions from 'containers/Subscriptions/withBillingActions';
|
||||
import { compose } from 'utils';
|
||||
|
||||
@@ -14,18 +15,23 @@ import { compose } from 'utils';
|
||||
* Subscription step of wizard setup.
|
||||
*/
|
||||
function SetupSubscriptionForm({
|
||||
//#withBillingActions
|
||||
// #withBillingActions
|
||||
requestSubmitBilling,
|
||||
|
||||
// #withWizard
|
||||
wizard,
|
||||
|
||||
// #withSubscriptionsActions
|
||||
requestFetchSubscriptions
|
||||
}) {
|
||||
const { formatMessage } = useIntl();
|
||||
|
||||
const validationSchema = Yup.object().shape({
|
||||
plan_slug: Yup.string()
|
||||
.required()
|
||||
.label(formatMessage({ id: 'plan_slug' })),
|
||||
license_code: Yup.string()
|
||||
.min(7)
|
||||
.max(7)
|
||||
.min(10)
|
||||
.max(10)
|
||||
.required()
|
||||
.label(formatMessage({ id: 'license_code_' }))
|
||||
.trim(),
|
||||
@@ -48,6 +54,10 @@ function SetupSubscriptionForm({
|
||||
onSubmit: (values, { setSubmitting, setErrors }) => {
|
||||
requestSubmitBilling(values)
|
||||
.then((response) => {
|
||||
return requestFetchSubscriptions();
|
||||
})
|
||||
.then(() => {
|
||||
wizard.next();
|
||||
setSubmitting(false);
|
||||
})
|
||||
.catch((errors) => {
|
||||
@@ -76,4 +86,8 @@ function SetupSubscriptionForm({
|
||||
);
|
||||
}
|
||||
|
||||
export default compose(withBillingActions)(SetupSubscriptionForm);
|
||||
export default compose(
|
||||
withBillingActions,
|
||||
withWizard,
|
||||
withSubscriptionsActions,
|
||||
)(SetupSubscriptionForm);
|
||||
|
||||
@@ -45,7 +45,7 @@ function BillingPeriods({ formik, title, selected = 1 }) {
|
||||
|
||||
return (
|
||||
<section class="billing-section">
|
||||
<h1 className={'bg-title'}>
|
||||
<h1>
|
||||
<T id={title} />
|
||||
</h1>
|
||||
<p className='paragraph'>
|
||||
|
||||
@@ -62,7 +62,7 @@ function BillingPlans({ formik, title, selected = 1 }) {
|
||||
|
||||
return (
|
||||
<section class="billing-section">
|
||||
<h1 className={'bg-title'}>
|
||||
<h1>
|
||||
<T id={title} />
|
||||
</h1>
|
||||
<p className='paragraph'>
|
||||
|
||||
22
client/src/containers/Subscriptions/withSubscriptions.js
Normal file
22
client/src/containers/Subscriptions/withSubscriptions.js
Normal file
@@ -0,0 +1,22 @@
|
||||
import { connect } from 'react-redux';
|
||||
import {
|
||||
isSubscriptionOnTrialFactory,
|
||||
isSubscriptionInactiveFactory,
|
||||
isSubscriptionActiveFactory,
|
||||
} from 'store/subscription/subscription.selectors';
|
||||
|
||||
export default (mapState, slug) => {
|
||||
const isSubscriptionOnTrial = isSubscriptionOnTrialFactory(slug);
|
||||
const isSubscriptionInactive = isSubscriptionInactiveFactory(slug);
|
||||
const isSubscriptionActive = isSubscriptionActiveFactory(slug);
|
||||
|
||||
const mapStateToProps = (state, props) => {
|
||||
const mapped = {
|
||||
isSubscriptionOnTrial: isSubscriptionOnTrial(state, props),
|
||||
isSubscriptionInactive: isSubscriptionInactive(state, props),
|
||||
isSubscriptionActive: isSubscriptionActive(state, props),
|
||||
};
|
||||
return (mapState) ? mapState(mapped, state, props) : mapped;
|
||||
};
|
||||
return connect(mapStateToProps);
|
||||
};
|
||||
@@ -0,0 +1,10 @@
|
||||
import { connect } from 'react-redux';
|
||||
import {
|
||||
fetchSubscriptions,
|
||||
} from 'store/subscription/subscription.actions'
|
||||
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
requestFetchSubscriptions: () => dispatch(fetchSubscriptions()),
|
||||
});
|
||||
|
||||
export default connect(null, mapDispatchToProps);
|
||||
@@ -765,4 +765,5 @@ export default {
|
||||
something_wentwrong: 'Something went wrong.',
|
||||
new_password: 'New password',
|
||||
license_code_: 'License code',
|
||||
legal_organization_name: 'Legal Organization Name'
|
||||
};
|
||||
|
||||
@@ -26,10 +26,12 @@ import vendors from './vendors/vendors.reducer';
|
||||
import paymentReceives from './PaymentReceive/paymentReceive.reducer';
|
||||
import paymentMades from './PaymentMades/paymentMade.reducer';
|
||||
import organizations from './organizations/organizations.reducers';
|
||||
import subscriptions from './subscription/subscription.reducer';
|
||||
|
||||
export default combineReducers({
|
||||
authentication,
|
||||
organizations,
|
||||
subscriptions,
|
||||
dashboard,
|
||||
users,
|
||||
accounts,
|
||||
@@ -47,12 +49,11 @@ export default combineReducers({
|
||||
exchangeRates,
|
||||
globalErrors,
|
||||
customers,
|
||||
|
||||
salesEstimates,
|
||||
salesInvoices,
|
||||
salesReceipts,
|
||||
bills,
|
||||
vendors,
|
||||
paymentReceives,
|
||||
paymentMades
|
||||
paymentMades,
|
||||
});
|
||||
|
||||
14
client/src/store/subscription/subscription.actions.js
Normal file
14
client/src/store/subscription/subscription.actions.js
Normal file
@@ -0,0 +1,14 @@
|
||||
import ApiService from 'services/ApiService';
|
||||
import t from 'store/types';
|
||||
|
||||
export const fetchSubscriptions = () => (dispatch) => new Promise((resolve, reject) => {
|
||||
ApiService.get('subscription').then((response) => {
|
||||
dispatch({
|
||||
type: t.SET_PLAN_SUBSCRIPTIONS_LIST,
|
||||
payload: {
|
||||
subscriptions: response.data.subscriptions,
|
||||
},
|
||||
});
|
||||
resolve(response);
|
||||
}).catch((error) => { reject(error); })
|
||||
});
|
||||
19
client/src/store/subscription/subscription.reducer.js
Normal file
19
client/src/store/subscription/subscription.reducer.js
Normal file
@@ -0,0 +1,19 @@
|
||||
import { createReducer } from '@reduxjs/toolkit';
|
||||
import t from 'store/types';
|
||||
|
||||
const initialState = {
|
||||
data: {},
|
||||
};
|
||||
|
||||
export default createReducer(initialState, {
|
||||
|
||||
[t.SET_PLAN_SUBSCRIPTIONS_LIST]: (state, action) => {
|
||||
const { subscriptions } = action.payload;
|
||||
const _data = {};
|
||||
|
||||
subscriptions.forEach((subscription) => {
|
||||
_data[subscription.id] = subscription;
|
||||
});
|
||||
state.data = _data;
|
||||
},
|
||||
});
|
||||
23
client/src/store/subscription/subscription.selectors.js
Normal file
23
client/src/store/subscription/subscription.selectors.js
Normal file
@@ -0,0 +1,23 @@
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
|
||||
const subscriptionSelector = (slug) => (state, props) => {
|
||||
const subscriptions = Object.values(state.subscriptions.data);
|
||||
return subscriptions.find((subscription) => subscription.slug === slug);
|
||||
};
|
||||
|
||||
export const isSubscriptionOnTrialFactory = (slug) => createSelector(
|
||||
subscriptionSelector(slug),
|
||||
(subscription) => !!subscription?.on_trial,
|
||||
);
|
||||
|
||||
export const isSubscriptionActiveFactory = (slug) => createSelector(
|
||||
subscriptionSelector(slug),
|
||||
(subscription) => {
|
||||
return !!subscription?.active;
|
||||
}
|
||||
);
|
||||
|
||||
export const isSubscriptionInactiveFactory = (slug) => createSelector(
|
||||
subscriptionSelector(slug),
|
||||
(subscription) => !!subscription?.inactive,
|
||||
);
|
||||
4
client/src/store/subscription/subscription.types.js
Normal file
4
client/src/store/subscription/subscription.types.js
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
export default {
|
||||
SET_PLAN_SUBSCRIPTIONS_LIST: 'SET_PLAN_SUBSCRIPTIONS_LIST',
|
||||
};
|
||||
@@ -25,6 +25,7 @@ import vendors from './vendors/vendors.types';
|
||||
import paymentReceives from './PaymentReceive/paymentReceive.type';
|
||||
import paymentMades from './PaymentMades/paymentMade.type';
|
||||
import organizations from './organizations/organizations.types';
|
||||
import subscription from './subscription/subscription.types';
|
||||
|
||||
export default {
|
||||
...authentication,
|
||||
@@ -54,4 +55,5 @@ export default {
|
||||
...paymentReceives,
|
||||
...paymentMades,
|
||||
...organizations,
|
||||
...subscription,
|
||||
};
|
||||
|
||||
@@ -20,13 +20,17 @@
|
||||
|
||||
h1{
|
||||
font-size: 22px;
|
||||
}
|
||||
h1,
|
||||
h3{
|
||||
font-weight: 500;
|
||||
color: #6d6d6d;
|
||||
color: #6b7382;
|
||||
}
|
||||
}
|
||||
|
||||
&__content{
|
||||
width: 70%;
|
||||
padding-bottom: 40px;
|
||||
}
|
||||
|
||||
&__left-section {
|
||||
@@ -68,7 +72,7 @@
|
||||
&__text {
|
||||
font-size: 16px;
|
||||
opacity: 0.75;
|
||||
margin-bottom: 18px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
&__organization {
|
||||
@@ -87,7 +91,7 @@
|
||||
height: 3px;
|
||||
width: 100px;
|
||||
background: rgba(255, 255, 255, 0.15);
|
||||
margin: 20px 0;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
&__footer{
|
||||
@@ -190,7 +194,54 @@
|
||||
}
|
||||
}
|
||||
|
||||
//Register Subscription form
|
||||
.register-subscription-form {
|
||||
|
||||
}
|
||||
.setup-organization {
|
||||
width: 580px;
|
||||
margin: 0 auto;
|
||||
padding: 45px 0 20px;
|
||||
|
||||
&__title-wrap{
|
||||
margin-bottom: 20px;
|
||||
|
||||
h1 {
|
||||
margin-top: 0;
|
||||
margin-bottom: 10px;
|
||||
color: #565e6c;
|
||||
}
|
||||
}
|
||||
|
||||
&__form{
|
||||
h3 {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.bp3-form-group {
|
||||
.bp3-input-group {
|
||||
.bp3-input {
|
||||
height: 38px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bp3-button:not([class*='bp3-intent-']):not(.bp3-minimal) {
|
||||
width: 100%;
|
||||
height: 38px;
|
||||
}
|
||||
|
||||
.register-org-note{
|
||||
font-size: 13px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px solid #e1e1e1;
|
||||
margin-bottom: 1.75rem;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.register-org-button {
|
||||
.bp3-button {
|
||||
background-color: #0052cc;
|
||||
min-width: 175px;
|
||||
height: 40px;
|
||||
font-size: 15px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,17 @@
|
||||
import { Router } from 'express'
|
||||
import { Container, Service } from 'typedi';
|
||||
import { Router, Request, Response, NextFunction } from 'express'
|
||||
import { Container, Service, Inject } from 'typedi';
|
||||
import JWTAuth from 'api/middleware/jwtAuth';
|
||||
import TenancyMiddleware from 'api/middleware/TenancyMiddleware';
|
||||
import AttachCurrentTenantUser from 'api/middleware/AttachCurrentTenantUser';
|
||||
import PaymentViaLicenseController from 'api/controllers/Subscription/PaymentViaLicense';
|
||||
import SubscriptionService from 'services/Subscription/SubscriptionService';
|
||||
import asyncMiddleware from 'api/middleware/asyncMiddleware';
|
||||
|
||||
@Service()
|
||||
export default class SubscriptionController {
|
||||
export default class SubscriptionController {
|
||||
@Inject()
|
||||
subscriptionService: SubscriptionService;
|
||||
|
||||
/**
|
||||
* Router constructor.
|
||||
*/
|
||||
@@ -19,6 +24,26 @@ export default class SubscriptionController {
|
||||
|
||||
router.use('/license', Container.get(PaymentViaLicenseController).router());
|
||||
|
||||
router.get('/',
|
||||
asyncMiddleware(this.getSubscriptions.bind(this))
|
||||
);
|
||||
return router;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve all subscriptions of the authenticated user's tenant.
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
* @param {NextFunction} next
|
||||
*/
|
||||
async getSubscriptions(req: Request, res: Response, next: NextFunction) {
|
||||
const { tenantId } = req;
|
||||
|
||||
try {
|
||||
const subscriptions = await this.subscriptionService.getSubscriptions(tenantId);
|
||||
return res.status(200).send({ subscriptions });
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,10 @@ export default {
|
||||
type: 'string',
|
||||
// config: true,
|
||||
},
|
||||
{
|
||||
key: 'financial_date_start',
|
||||
type: 'string',
|
||||
},
|
||||
{
|
||||
key: 'language',
|
||||
type: 'string',
|
||||
|
||||
@@ -100,7 +100,7 @@ export default class OrganizationService {
|
||||
this.logger.info('[organization] trying to list all organizations.', { user });
|
||||
|
||||
const { tenantRepository } = this.sysRepositories;
|
||||
const tenant = await tenantRepository.getByIdWithSubscriptions(user.tenantId);
|
||||
const tenant = await tenantRepository.getById(user.tenantId);
|
||||
|
||||
return [tenant];
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Service, Inject } from 'typedi';
|
||||
import { Plan, Tenant } from 'system/models';
|
||||
import { Plan, PlanSubscription } from 'system/models';
|
||||
import Subscription from 'services/Subscription/Subscription';
|
||||
import LicensePaymentMethod from 'services/Payment/LicensePaymentMethod';
|
||||
import PaymentContext from 'services/Payment';
|
||||
@@ -29,7 +29,7 @@ export default class SubscriptionService {
|
||||
* @param {string} licenseCode
|
||||
* @return {Promise}
|
||||
*/
|
||||
async subscriptionViaLicense(
|
||||
public async subscriptionViaLicense(
|
||||
tenantId: number,
|
||||
planSlug: string,
|
||||
paymentModel?: ILicensePaymentModel,
|
||||
@@ -53,4 +53,15 @@ export default class SubscriptionService {
|
||||
tenantId, paymentModel
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve all subscription of the given tenant.
|
||||
* @param {number} tenantId
|
||||
*/
|
||||
public async getSubscriptions(tenantId: number) {
|
||||
this.logger.info('[subscription] trying to get tenant subscriptions.', { tenantId });
|
||||
const subscriptions = await PlanSubscription.query().where('tenant_id', tenantId);
|
||||
|
||||
return subscriptions;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user