Skip to content

Commit

Permalink
PR updates
Browse files Browse the repository at this point in the history
  • Loading branch information
volodymyrsy committed Sep 14, 2021
1 parent eb0787e commit f374206
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ public static class Recaptcha {

public static class QuickBooks extends Platform {
public String realmId = "";
public String accountId = "";
public String apiBaseUrl = "";
}

public QuickBooks quickbooks = new QuickBooks();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.impactupgrade.nucleus.service.segment;

import com.google.gson.Gson;
import com.impactupgrade.nucleus.environment.Environment;
import com.impactupgrade.nucleus.model.CrmContact;
import com.impactupgrade.nucleus.model.PaymentGatewayDeposit;
Expand Down Expand Up @@ -31,6 +32,7 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
Expand All @@ -40,24 +42,32 @@
@Slf4j
public class QuickBooksAccountingPlatformService implements AccountingPlatformService {

private String clientId;
private String clientSecret;

private String accessToken;
private String refreshToken;
private Long lastTokenUpdateTimestamp;

private static final String CLIENT_ID = "ABlbf9rOF8Z9M3G5OlStMfi2wmNkB4jJMDXtad6yZpfPkMvVlz";
private static final String CLIENT_SECRET = "HdI0aUhPI7wfmFFP1Wl4MLMtHwn7sLgXf83EkuPu";

private static final String QB_API_BASE_URL = "https://sandbox-quickbooks.api.intuit.com";
private static final String REALM_ID = "4620816365179776870";

private static final Long ACCESS_TOKEN_EXPIRES_IN = 3600l;
private static final Gson GSON = new Gson();

private String realmId;
private String apiBaseUrl;

public String name() {
return "quickbooks";
}

public void init(Environment env) {
// TODO:
public void init(Environment environment) {
this.clientId = environment.getConfig().quickbooks.clientId;
this.clientSecret = environment.getConfig().quickbooks.clientSecret;

this.accessToken = environment.getConfig().quickbooks.accessToken;
this.refreshToken = environment.getConfig().quickbooks.refreshToken;

this.realmId = environment.getConfig().quickbooks.realmId;
this.apiBaseUrl = environment.getConfig().quickbooks.apiBaseUrl;
}

public void addDeposits(List<PaymentGatewayDeposit> paymentGatewayDeposits) {
Expand All @@ -77,7 +87,10 @@ public void addDeposits(List<PaymentGatewayDeposit> paymentGatewayDeposits) {
// Check if some transactions already exist
List<Payment> existingPayments;
try {
log.info("Getting existing payments...");
existingPayments = getExistingPayments();
log.info("Payments found: {}", existingPayments.size());

} catch (Exception e) {
log.error("Failed to get payments info! {}", getExceptionDetails(e));
return;
Expand All @@ -87,10 +100,10 @@ public void addDeposits(List<PaymentGatewayDeposit> paymentGatewayDeposits) {
if (CollectionUtils.isEmpty(existingPayments)) {
transactionsToProcess.addAll(transactions);
} else {
Set<String> existingPaymentsSources = getPaymentSources(existingPayments);
Set<String> existingPaymentsPrivateNotes = getPaymentPrivateNotes(existingPayments);
for (PaymentGatewayEvent transaction : transactions) {
String transactionId = transaction.getTransactionId();
if (existingPaymentsSources.contains(transactionId)) {
if (existingPaymentsPrivateNotes.contains(transactionId)) {
log.info("Transaction id {} already exists. Skipping...", transactionId);
} else {
transactionsToProcess.add(transaction);
Expand All @@ -103,29 +116,34 @@ public void addDeposits(List<PaymentGatewayDeposit> paymentGatewayDeposits) {
return;
}

log.info("Transactions to process: {}", transactionsToProcess.size());

// Get or create contacts
List<Customer> existingCustomers;
try {
log.info("Getting existing customers...");
existingCustomers = getExistingCutomers();
log.info("Customers found: {}", existingCustomers.size());

} catch (Exception e) {
log.error("Failed to get customers info! {}", getExceptionDetails(e));
return;
}
Map<String, Customer> existingCustomerMapped = mapCustomers(existingCustomers);

List<CrmContact> crmContacts = collectCrmContacts(transactions);
Map<String, CrmContact> crmContactMapped = mapCrmContacts(crmContacts);

List<CrmContact> contactsToCreate = new ArrayList<>();

if (CollectionUtils.isEmpty(existingCustomers)) {
// Need to create customer for every crm contact
contactsToCreate.addAll(crmContacts);
} else {
for (CrmContact crmContact : crmContacts) {
if (StringUtils.isEmpty(crmContact.firstName) || StringUtils.isEmpty(crmContact.lastName)) {
log.info("Either first name or last name are empty! Skipping contact {}...", crmContact.id);
continue;
}
String displayName = getCrmContactDisplayName(crmContact);
for (Map.Entry<String, CrmContact> entry : crmContactMapped.entrySet()) {
String displayName = entry.getKey();
CrmContact crmContact = entry.getValue();

if (existingCustomerMapped.containsKey(displayName)) {
log.info("Customer with name {} already exists. Skipping...", displayName);
} else {
Expand Down Expand Up @@ -172,32 +190,50 @@ private List<PaymentGatewayEvent> collectTransactions(List<PaymentGatewayDeposit
.collect(Collectors.toList());
}

private Set<String> getPaymentPrivateNotes(List<Payment> existingPayments) {
if (CollectionUtils.isEmpty(existingPayments)) {
return Collections.emptySet();
}
return existingPayments.stream().map(Payment::getPrivateNote).collect(Collectors.toSet());
}

private List<CrmContact> collectCrmContacts(List<PaymentGatewayEvent> transactions) {
if (CollectionUtils.isEmpty(transactions)) {
return Collections.emptyList();
}
return transactions.stream().map(PaymentGatewayEvent::getCrmContact).collect(Collectors.toList());
}

private Set<String> getPaymentSources(List<Payment> payments) {
if (CollectionUtils.isEmpty(payments)) {
return Collections.emptySet();
private Map<String, Customer> mapCustomers(List<Customer> customers) {
if (CollectionUtils.isEmpty(customers)) {
return Collections.emptyMap();
}
return payments.stream().map(Payment::getTxnSource).collect(Collectors.toSet());
return customers.stream().collect(Collectors.toMap(c -> c.getDisplayName(), c -> c));
}

private static Map<String, Customer> mapCustomers(List<Customer> customers) {
if (CollectionUtils.isEmpty(customers)) {
private Map<String, CrmContact> mapCrmContacts(List<CrmContact> crmContacts) {
if (CollectionUtils.isEmpty(crmContacts)) {
return Collections.emptyMap();
}
return customers.stream().collect(Collectors.toMap(c -> c.getDisplayName(), c -> c));
Map<String, CrmContact> crmContactMapped = new HashMap<>();

for (CrmContact crmContact : crmContacts) {
if (StringUtils.isEmpty(crmContact.firstName) || StringUtils.isEmpty(crmContact.lastName)) {
log.info("Either first name or last name are empty! Skipping contact {}...", crmContact.id);
continue;
}
String displayName = getCrmContactDisplayName(crmContact);
crmContactMapped.computeIfAbsent(displayName, k -> crmContact);
}

return crmContactMapped;
}

private String getCrmContactDisplayName(CrmContact crmContact) {
if (Objects.isNull(crmContact)) {
return null;
}
return crmContact.firstName + " " + crmContact.firstName;
return crmContact.firstName + " " + crmContact.lastName;
}

private String getExceptionDetails(Exception e) {
Expand All @@ -216,7 +252,7 @@ private void getAccessToken() throws OAuthException {
log.info("Token is valid. No need to refresh.");
} else {

OAuth2Config oauth2Config = new OAuth2Config.OAuth2ConfigBuilder(CLIENT_ID, CLIENT_SECRET) //set client id, secret
OAuth2Config oauth2Config = new OAuth2Config.OAuth2ConfigBuilder(clientId, clientSecret) //set client id, secret
.callDiscoveryAPI(com.intuit.oauth2.config.Environment.SANDBOX) // call discovery API to populate urls
.buildConfig();
OAuth2PlatformClient client = new OAuth2PlatformClient(oauth2Config);
Expand Down Expand Up @@ -270,7 +306,9 @@ private Customer asCustomer(CrmContact crmContact) {
Customer customer = new Customer();
customer.setGivenName(crmContact.firstName);
customer.setFamilyName(crmContact.lastName);
customer.setDisplayName(crmContact.firstName + " " + crmContact.lastName);
String displayName = getCrmContactDisplayName(crmContact);
customer.setDisplayName(displayName);
customer.setContactName(displayName);
return customer;
}

Expand Down Expand Up @@ -317,8 +355,10 @@ private Payment asPayment(PaymentGatewayEvent transaction) {
}
Payment payment = new Payment();
// TODO: set all required fields (QB requires only amount and cutomer ref/id)
payment.setTotalAmt(new BigDecimal(transaction.getTransactionOriginalAmountInDollars()));
payment.setTxnSource(transaction.getTransactionId()); // ?
BigDecimal transactionAmount = new BigDecimal(transaction.getTransactionOriginalAmountInDollars());
payment.setTotalAmt(transactionAmount);
payment.setTxnDate(transaction.getTransactionDate().getTime());
payment.setPrivateNote(transaction.getTransactionId());

return payment;
}
Expand All @@ -337,10 +377,10 @@ private List<Payment> createPayments(List<Payment> payments) throws FMSException
}

private QueryResult getQueryResult(String sqlQuery) throws FMSException {
Config.setProperty(Config.BASE_URL_QBO, QB_API_BASE_URL + "/v3/company");
Config.setProperty(Config.BASE_URL_QBO, apiBaseUrl + "/v3/company");
OAuth2Authorizer oauth = new OAuth2Authorizer(accessToken);

Context context = new Context(oauth, ServiceType.QBO, REALM_ID);
Context context = new Context(oauth, ServiceType.QBO, realmId);
DataService service = new DataService(context);
QueryResult queryResult = service.executeQuery(sqlQuery);

Expand All @@ -363,10 +403,10 @@ private <T extends IEntity> List<T> getEntities(Query query) throws FMSException
}

private <T extends IEntity> T addEntity(T entity) throws FMSException {
Config.setProperty(Config.BASE_URL_QBO, QB_API_BASE_URL + "/v3/company"); // ?
Config.setProperty(Config.BASE_URL_QBO, apiBaseUrl + "/v3/company"); // ?

OAuth2Authorizer oauth = new OAuth2Authorizer(accessToken);
Context context = new Context(oauth, ServiceType.QBO, REALM_ID);
Context context = new Context(oauth, ServiceType.QBO, realmId);
DataService service = new DataService(context);
T added = service.add(entity);

Expand Down

0 comments on commit f374206

Please sign in to comment.