Skip to content

Instantly share code, notes, and snippets.

@mlevkovsky
Created January 7, 2022 22:37
Show Gist options
  • Save mlevkovsky/cd22dce90de0442c91fac422f5ec96b0 to your computer and use it in GitHub Desktop.
Save mlevkovsky/cd22dce90de0442c91fac422f5ec96b0 to your computer and use it in GitHub Desktop.
example of service
import Analytics = require('analytics-node');
import { inject, injectable, named } from 'inversify';
import { getRepository } from 'typeorm';
import { ApplicationCharge } from '../entities/ApplicationCharge';
import { ChargeMapper } from '../entities/mappers/ChargeMapper';
import { Merchant } from '../entities/Merchant';
import { MerchantGateway } from '../gateway/MerchantGateway';
export interface Query {
shop: string;
path_prefix: string;
timestamp: number;
signature: string;
}
@injectable()
export class MerchantService {
constructor(@inject('MerchantGateway') @named('Shopify') protected merchantGateway: MerchantGateway,
@inject('Logger') protected logger: any,
@inject('Analytics') @named('Segment') protected analytics: Analytics,
@inject('Cache') protected cache: any) {
}
public async getOne(query: Query, trackAnalytics: boolean = true, fetchRemoteCharges: boolean = false): Promise<Merchant> {
const repository = getRepository(Merchant);
const merchant = await repository.findOne({ domain: query.shop}, {relations: ['status', 'applicationCharge', 'auth']});
if (fetchRemoteCharges) {
try {
const remoteApplicationCharges = await this.merchantGateway.listRecurringCharges(merchant.auth[0].token, merchant.domain);
if (remoteApplicationCharges.recurring_application_charges
&& remoteApplicationCharges.recurring_application_charges.length > 0) {
// if we have an active charge, set that one to update locally
let chargeToSave = remoteApplicationCharges.recurring_application_charges.find((charge: any) => charge.status === 'active');
// if we have neither, set the first one as the one to update
if (!chargeToSave) {
chargeToSave = remoteApplicationCharges.recurring_application_charges[0];
}
merchant.applicationCharge = await MerchantService.updateApplicationCharge(chargeToSave, merchant);
if (trackAnalytics) {
this.analytics.identify({
traits: {
email: merchant.email,
merchant: merchant.domain,
requirementApplicationChargesAccepted: merchant.applicationCharge.status,
},
userId: merchant.id.toString(),
});
}
}
} catch (e) {
this.logger.error(`failed to fetch recurring charge for merchant with error ${e}`,
{ meta: {service: 'MerchantService', merchant: query.shop, stackTrace: e.stack, error: e}});
}
}
return merchant;
}
public async completeOnboarding(query: Query): Promise<Merchant> {
const repository = getRepository(Merchant);
const merchant = await repository.findOne({ domain: query.shop});
merchant.isOnboarded = true;
this.analytics.identify({userId: merchant.id.toString()},
(err, data) => {
if (err) {
this.logger.error(`error sending identify call for merchant ${merchant.email}`,
{message: err.message, name: err.name});
return;
}
this.analytics.track({
event: 'Merchant Onboarded',
properties: {},
userId: merchant.id.toString(),
});
});
return repository.save(merchant);
}
public async disableDummyMode(query: Query): Promise<Merchant> {
const repository = getRepository(Merchant);
const merchant = await repository.findOne({ domain: query.shop});
merchant.isDummyDataModeEnabled = false;
return repository.save(merchant);
}
private static async updateApplicationCharge(remoteApplicationCharge: any, merchant: Merchant): Promise<ApplicationCharge> {
const repository = getRepository(ApplicationCharge);
if (merchant.applicationCharge) {
await repository.delete(merchant.applicationCharge.id);
}
let localApplicationCharge = await repository.findOne(remoteApplicationCharge.id);
if (!localApplicationCharge) {
localApplicationCharge = ChargeMapper.fromShopifyApplicationCharge(remoteApplicationCharge);
localApplicationCharge.merchant = merchant;
return repository.save(localApplicationCharge);
}
localApplicationCharge = ChargeMapper.fromShopifyApplicationCharge(remoteApplicationCharge);
return repository.save(localApplicationCharge);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment