Skip to content

Commit 8e2939a

Browse files
Vaibhav  BhallaVaibhav  Bhalla
authored andcommitted
refactor(all-services): remove extra code from controller and used by injecting service
GH-88 GH-88 GH-88 GH-88 GH-88 GH-88 GH-88
1 parent f4fc54d commit 8e2939a

27 files changed

Lines changed: 734 additions & 473 deletions

services/subscription-service/src/component.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,13 @@ import {BillingCustomerController} from './controllers/billing-customer.controll
7979
import {BillingInvoiceController} from './controllers/billing-invoice.controller';
8080
import {BillingPaymentSourceController} from './controllers/billing-payment-source.controller';
8181
import {WebhookController} from './controllers/webhook.controller';
82+
import {
83+
BillingCustomerService,
84+
BillingInvoiceService,
85+
BillingPaymentSourceService,
86+
PlanFeaturesService,
87+
SubscriptionService,
88+
} from './services';
8289

8390
export class SubscriptionServiceComponent implements Component {
8491
constructor(
@@ -143,6 +150,17 @@ export class SubscriptionServiceComponent implements Component {
143150
Binding.bind(WEBHOOK_VERIFIER).toProvider(WebhookVerifierProvider),
144151

145152
Binding.bind(SYSTEM_USER).toProvider(SystemUserProvider),
153+
Binding.bind('services.BillingPaymentSourceService').toClass(
154+
BillingPaymentSourceService,
155+
),
156+
Binding.bind('services.BillingInvoiceService').toClass(
157+
BillingInvoiceService,
158+
),
159+
Binding.bind('services.SubscriptionService').toClass(SubscriptionService),
160+
Binding.bind('services.PlanFeaturesService').toClass(PlanFeaturesService),
161+
Binding.bind('services.BillingCustomerService').toClass(
162+
BillingCustomerService,
163+
),
146164
];
147165

148166
this.controllers = [
Lines changed: 9 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
import {BillingComponentBindings, IService} from 'loopback4-billing';
21
import {inject} from '@loopback/core';
3-
import {Filter, repository} from '@loopback/repository';
2+
import {Filter} from '@loopback/repository';
43
import {
54
del,
65
get,
@@ -13,22 +12,16 @@ import {
1312
import {OPERATION_SECURITY_SPEC, STATUS_CODE} from '@sourceloop/core';
1413
import {authenticate, STRATEGY} from 'loopback4-authentication';
1514
import {authorize} from 'loopback4-authorization';
16-
import {AddressDto} from '../models';
1715
import {BillingCustomer} from '../models/billing-customer.model';
1816
import {CustomerDto} from '../models/dto/customer-dto.model';
1917
import {PermissionKey} from '../permissions';
20-
import {InvoiceRepository} from '../repositories';
21-
import {BillingCustomerRepository} from '../repositories/billing-customer.repository';
18+
import {BillingCustomerService} from '../services/billing-customer.service';
2219

2320
const basePath = '/billing-customer';
2421
export class BillingCustomerController {
2522
constructor(
26-
@repository(BillingCustomerRepository)
27-
public billingCustomerRepository: BillingCustomerRepository,
28-
@repository(InvoiceRepository)
29-
public invoiceRepository: InvoiceRepository,
30-
@inject(BillingComponentBindings.BillingProvider)
31-
private readonly billingProvider: IService,
23+
@inject('services.BillingCustomerService')
24+
private readonly billingCustomerService: BillingCustomerService,
3225
) {}
3326

3427
@authorize({
@@ -66,32 +59,7 @@ export class BillingCustomerController {
6659
customerDto: Omit<CustomerDto, 'id'>,
6760
@param.header.string('tenantId') tenantId: string,
6861
): Promise<CustomerDto> {
69-
const customer = await this.billingProvider.createCustomer(customerDto);
70-
await this.billingCustomerRepository.create(
71-
new BillingCustomer({
72-
tenantId,
73-
customerId: customer.id,
74-
}),
75-
);
76-
return new CustomerDto({
77-
id: customer.id,
78-
firstName: customer.firstName,
79-
lastName: customer.lastName,
80-
email: customer.email,
81-
company: customer.company,
82-
phone: customer.phone,
83-
billingAddress: new AddressDto({
84-
firstName: customer.billingAddress?.firstName,
85-
lastName: customer.billingAddress?.lastName,
86-
email: customer.billingAddress?.email,
87-
company: customer.billingAddress?.company,
88-
phone: customer.billingAddress?.phone,
89-
city: customer.billingAddress?.city,
90-
state: customer.billingAddress?.state,
91-
zip: customer.billingAddress?.zip,
92-
country: customer.billingAddress?.country,
93-
}),
94-
});
62+
return this.billingCustomerService.createCustomer(customerDto, tenantId);
9563
}
9664

9765
@authorize({
@@ -112,35 +80,7 @@ export class BillingCustomerController {
11280
async getCustomer(
11381
@param.filter(BillingCustomer) filter?: Filter<BillingCustomer>,
11482
): Promise<{customerDetails: CustomerDto; info: BillingCustomer}> {
115-
const customers = await this.billingCustomerRepository.find(filter);
116-
if (customers.length === 0) {
117-
throw new Error('Customer is not present');
118-
}
119-
120-
const customer = await this.billingProvider.getCustomers(
121-
customers[0].customerId,
122-
);
123-
return {
124-
customerDetails: new CustomerDto({
125-
firstName: customer.firstName,
126-
lastName: customer.lastName,
127-
email: customer.email,
128-
company: customer.company,
129-
phone: customer.phone,
130-
billingAddress: new AddressDto({
131-
firstName: customer.billingAddress?.firstName,
132-
lastName: customer.billingAddress?.lastName,
133-
email: customer.billingAddress?.email,
134-
company: customer.billingAddress?.company,
135-
phone: customer.billingAddress?.phone,
136-
city: customer.billingAddress?.city,
137-
state: customer.billingAddress?.state,
138-
zip: customer.billingAddress?.zip,
139-
country: customer.billingAddress?.country,
140-
}),
141-
}),
142-
info: customers[0],
143-
};
83+
return this.billingCustomerService.getCustomer(filter);
14484
}
14585

14686
@authorize({
@@ -168,15 +108,8 @@ export class BillingCustomerController {
168108
})
169109
customerDto: Partial<CustomerDto>,
170110
): Promise<void> {
171-
const customers = await this.billingCustomerRepository.find({
172-
where: {tenantId: tenantId},
173-
});
174-
175-
if (customers.length === 0) {
176-
throw new Error(`Customer with tenantId ${tenantId} is not present`);
177-
}
178-
await this.billingProvider.updateCustomerById(
179-
customers[0].customerId,
111+
return this.billingCustomerService.updateCustomerByTenantId(
112+
tenantId,
180113
customerDto,
181114
);
182115
}
@@ -198,14 +131,6 @@ export class BillingCustomerController {
198131
async deleteById(
199132
@param.path.string('tenantId') tenantId: string,
200133
): Promise<void> {
201-
const customer = await this.billingCustomerRepository.find({
202-
where: {tenantId: tenantId},
203-
});
204-
if (customer.length === 0) {
205-
throw new Error(' Customer with tenantId is not present');
206-
}
207-
await this.billingProvider.deleteCustomer(customer[0].customerId);
208-
await this.invoiceRepository.deleteAll({billingCustomerId: customer[0].id});
209-
await this.billingCustomerRepository.deleteById(customer[0].id);
134+
return this.billingCustomerService.deleteCustomerByTenantId(tenantId);
210135
}
211136
}

services/subscription-service/src/controllers/billing-invoice.controller.ts

Lines changed: 7 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import {BillingComponentBindings, IService} from 'loopback4-billing';
22
import {inject} from '@loopback/core';
3-
import {repository} from '@loopback/repository';
43
import {
54
del,
65
get,
@@ -13,22 +12,18 @@ import {
1312
import {OPERATION_SECURITY_SPEC, STATUS_CODE} from '@sourceloop/core';
1413
import {authenticate, STRATEGY} from 'loopback4-authentication';
1514
import {authorize} from 'loopback4-authorization';
16-
import {AddressDto, ChargeDto} from '../models';
1715
import {InvoiceDto} from '../models/dto/invoice-dto.model';
1816
import {TransactionDto} from '../models/dto/transaction-dto.model';
1917
import {PermissionKey} from '../permissions';
20-
import {InvoiceRepository} from '../repositories';
21-
import {BillingCustomerRepository} from '../repositories/billing-customer.repository';
18+
import {BillingInvoiceService} from '../services/billing-invoice.service';
2219

2320
const basePath = '/billing-invoice';
2421
export class BillingInvoiceController {
2522
constructor(
26-
@repository(BillingCustomerRepository)
27-
public billingCustomerRepository: BillingCustomerRepository,
28-
@repository(InvoiceRepository)
29-
public invoiceRepository: InvoiceRepository,
3023
@inject(BillingComponentBindings.BillingProvider)
3124
private readonly billingProvider: IService,
25+
@inject('services.BillingInvoiceService')
26+
private readonly billingInvoiceService: BillingInvoiceService,
3227
) {}
3328

3429
@authorize({
@@ -59,43 +54,7 @@ export class BillingInvoiceController {
5954
})
6055
invoiceDto: Omit<InvoiceDto, 'id' | 'status'>,
6156
): Promise<InvoiceDto> {
62-
const customer = await this.billingCustomerRepository.find({
63-
where: {customerId: invoiceDto.customerId},
64-
});
65-
66-
if (customer.length === 0) {
67-
throw new Error(' Customer with tenantId is not present');
68-
}
69-
const invoice = await this.billingProvider.createInvoice(invoiceDto);
70-
const charges = invoice.charges?.map(
71-
charge =>
72-
new ChargeDto({amount: charge.amount, description: charge.description}),
73-
);
74-
75-
const invoiceInfo = await this.invoiceRepository.create({
76-
invoiceId: invoice.id,
77-
invoiceStatus: invoice.status,
78-
billingCustomerId: customer[0].id,
79-
});
80-
return new InvoiceDto({
81-
id: invoiceInfo.id, // passed the id of invoice info created in our db, to setup relation between subscription and invoice
82-
customerId: invoice.customerId,
83-
charges: charges,
84-
status: invoice.status,
85-
shippingAddress: new AddressDto({
86-
firstName: invoice.shippingAddress?.firstName ?? '',
87-
lastName: invoice.shippingAddress?.lastName ?? '',
88-
email: invoice.shippingAddress?.email ?? '',
89-
company: invoice.shippingAddress?.company,
90-
phone: invoice.shippingAddress?.phone,
91-
city: invoice.shippingAddress?.city ?? '',
92-
state: invoice.shippingAddress?.state ?? '',
93-
zip: invoice.shippingAddress?.zip ?? '',
94-
country: invoice.shippingAddress?.country ?? '',
95-
}),
96-
options: invoice.options,
97-
currencyCode: invoice.currencyCode,
98-
});
57+
return this.billingInvoiceService.createInvoice(invoiceDto);
9958
}
10059

10160
@authorize({
@@ -116,28 +75,7 @@ export class BillingInvoiceController {
11675
async getInvoice(
11776
@param.path.string('invoiceId') invoiceId: string,
11877
): Promise<InvoiceDto> {
119-
const invoice = await this.billingProvider.retrieveInvoice(invoiceId);
120-
const charges = invoice.charges?.map(
121-
charge =>
122-
new ChargeDto({amount: charge.amount, description: charge.description}),
123-
);
124-
return new InvoiceDto({
125-
customerId: invoice.customerId,
126-
charges: charges,
127-
status: invoice.status,
128-
shippingAddress: new AddressDto({
129-
firstName: invoice.shippingAddress?.firstName ?? '',
130-
lastName: invoice.shippingAddress?.lastName ?? '',
131-
email: invoice.shippingAddress?.email ?? '',
132-
company: invoice.shippingAddress?.company,
133-
phone: invoice.shippingAddress?.phone,
134-
city: invoice.shippingAddress?.city ?? '',
135-
state: invoice.shippingAddress?.state ?? '',
136-
zip: invoice.shippingAddress?.zip ?? '',
137-
country: invoice.shippingAddress?.country ?? '',
138-
}),
139-
options: invoice.options,
140-
});
78+
return this.billingInvoiceService.getInvoice(invoiceId);
14179
}
14280

14381
@authorize({
@@ -193,11 +131,7 @@ export class BillingInvoiceController {
193131
})
194132
transactionDto: TransactionDto,
195133
): Promise<void> {
196-
const invoiceInfo = await this.invoiceRepository.findById(invoiceId);
197-
await this.billingProvider.applyPaymentSourceForInvoice(
198-
invoiceInfo.invoiceId,
199-
transactionDto,
200-
);
134+
return this.billingInvoiceService.applyPayment(invoiceId, transactionDto);
201135
}
202136

203137
@authorize({
@@ -217,12 +151,6 @@ export class BillingInvoiceController {
217151
async deleteById(
218152
@param.path.string('invoiceId') invoiceId: string,
219153
): Promise<void> {
220-
const invoice = await this.invoiceRepository.find({
221-
where: {invoiceId: invoiceId},
222-
});
223-
if (invoice.length === 0)
224-
throw new Error(' invoice with invoiceId is not present');
225-
await this.billingProvider.deleteInvoice(invoiceId);
226-
await this.invoiceRepository.deleteById(invoice[0].id);
154+
return this.billingInvoiceService.deleteInvoice(invoiceId);
227155
}
228156
}

services/subscription-service/src/controllers/billing-payment-source.controller.ts

Lines changed: 10 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
import {BillingComponentBindings, IService} from 'loopback4-billing';
21
import {inject} from '@loopback/core';
3-
import {repository} from '@loopback/repository';
42
import {
53
del,
64
get,
@@ -14,18 +12,13 @@ import {authenticate, STRATEGY} from 'loopback4-authentication';
1412
import {authorize} from 'loopback4-authorization';
1513
import {PaymentSourceDto} from '../models/dto/payment-dto.model';
1614
import {PermissionKey} from '../permissions';
17-
import {InvoiceRepository} from '../repositories';
18-
import {BillingCustomerRepository} from '../repositories/billing-customer.repository';
15+
import {BillingPaymentSourceService} from '../services/billing-payment-source.service';
1916

2017
const basePath = '/billing-payment-source';
2118
export class BillingPaymentSourceController {
2219
constructor(
23-
@repository(BillingCustomerRepository)
24-
public billingCustomerRepository: BillingCustomerRepository,
25-
@repository(InvoiceRepository)
26-
public invoiceRepository: InvoiceRepository,
27-
@inject(BillingComponentBindings.BillingProvider)
28-
private readonly billingProvider: IService,
20+
@inject('services.BillingPaymentSourceService')
21+
private readonly billingPaymentSourceService: BillingPaymentSourceService,
2922
) {}
3023

3124
@authorize({
@@ -58,23 +51,9 @@ export class BillingPaymentSourceController {
5851
})
5952
paymentSourceDto: PaymentSourceDto,
6053
): Promise<PaymentSourceDto> {
61-
const customer = await this.billingCustomerRepository.find({
62-
where: {customerId: paymentSourceDto.customerId},
63-
});
64-
65-
if (customer.length === 0) {
66-
throw new Error(' Customer with tenantId is not present');
67-
}
68-
const paymentSource =
69-
await this.billingProvider.createPaymentSource(paymentSourceDto);
70-
await this.billingCustomerRepository.updateById(customer[0].id, {
71-
paymentSourceId: paymentSource.id,
72-
});
73-
return new PaymentSourceDto({
74-
id: paymentSource.id,
75-
customerId: paymentSource.customerId,
76-
card: paymentSource.card,
77-
});
54+
return this.billingPaymentSourceService.createPaymentSource(
55+
paymentSourceDto,
56+
);
7857
}
7958

8059
@authorize({
@@ -97,13 +76,7 @@ export class BillingPaymentSourceController {
9776
async getPaymentSource(
9877
@param.path.string('paymentSourceId') paymentSourceId: string,
9978
): Promise<PaymentSourceDto> {
100-
const paymentSource =
101-
await this.billingProvider.retrievePaymentSource(paymentSourceId);
102-
return new PaymentSourceDto({
103-
id: paymentSource.id,
104-
customerId: paymentSource.customerId,
105-
card: paymentSource.card,
106-
});
79+
return this.billingPaymentSourceService.getPaymentSource(paymentSourceId);
10780
}
10881

10982
@authorize({
@@ -123,16 +96,8 @@ export class BillingPaymentSourceController {
12396
async deleteById(
12497
@param.path.string('paymentSourceId') paymentSourceId: string,
12598
): Promise<void> {
126-
const customer = await this.billingCustomerRepository.find({
127-
where: {paymentSourceId: paymentSourceId},
128-
});
129-
130-
if (customer.length === 0) {
131-
throw new Error(' Customer with tenantId is not present');
132-
}
133-
await this.billingProvider.deletePaymentSource(paymentSourceId);
134-
await this.billingCustomerRepository.updateById(customer[0].id, {
135-
paymentSourceId: undefined,
136-
});
99+
return this.billingPaymentSourceService.deletePaymentSource(
100+
paymentSourceId,
101+
);
137102
}
138103
}

0 commit comments

Comments
 (0)