From b24677ee3bc1a1605088c4ddfae2bf35a4affbb6 Mon Sep 17 00:00:00 2001
From: lishouyi <linlangsur163@163.com>
Date: 星期四, 25 五月 2023 18:54:05 +0800
Subject: [PATCH] 卡车公司——财务——上传发票信息接口

---
 src/main/java/com/stylefeng/guns/core/common/exception/BizExceptionEnum.java           |    3 
 src/main/java/com/stylefeng/guns/modular/system/dao/TOrderMapper.java                  |    2 
 src/main/java/com/stylefeng/guns/modular/system/controller/FinanceController.java      |   36 ++++
 src/main/java/com/stylefeng/guns/modular/system/service/impl/TOrderServiceImpl.java    |    5 
 src/main/java/com/stylefeng/guns/modular/system/utils/InvoicesDataUploadUtil.java      |  106 +++++++++++++
 src/main/java/com/stylefeng/guns/modular/system/utils/OAuth2PlatformClientFactory.java |   56 +++++++
 src/main/java/com/stylefeng/guns/modular/system/dao/mapping/TOrderMapper.xml           |   12 +
 pom.xml                                                                                |   23 ++
 src/main/java/com/stylefeng/guns/modular/system/service/ITOrderService.java            |    4 
 src/main/java/com/stylefeng/guns/modular/api/ApiController.java                        |  199 ++++++++++++++++++++++++
 10 files changed, 441 insertions(+), 5 deletions(-)

diff --git a/pom.xml b/pom.xml
index 96181f6..1d0ee39 100644
--- a/pom.xml
+++ b/pom.xml
@@ -91,6 +91,29 @@
         </dependency>
 
 
+        <!-- Intuit's QuickBooks Java SDK -->
+        <dependency>
+            <groupId> com.intuit.quickbooks-online </groupId>
+            <artifactId> ipp-v3-java-data </artifactId>
+            <version> 6.0.7 </version>
+        </dependency>
+
+        <!-- devkit jar with dependencies-->
+        <dependency>
+            <groupId>com.intuit.quickbooks-online</groupId>
+            <artifactId>ipp-v3-java-devkit</artifactId>
+            <classifier>jar-with-dependencies</classifier>
+            <version> 6.0.7 </version>
+        </dependency>
+
+        <!-- oauth jar with dependencies-->
+        <dependency>
+            <groupId>com.intuit.quickbooks-online</groupId>
+            <artifactId>oauth2-platform-api</artifactId>
+            <classifier>jar-with-dependencies</classifier>
+            <version> 6.0.7 </version>
+        </dependency>
+
 
         <!--需要分布式session的话需要放开注释-->
         <!--<dependency>-->
diff --git a/src/main/java/com/stylefeng/guns/core/common/exception/BizExceptionEnum.java b/src/main/java/com/stylefeng/guns/core/common/exception/BizExceptionEnum.java
index 2f1812b..ae1bc3e 100644
--- a/src/main/java/com/stylefeng/guns/core/common/exception/BizExceptionEnum.java
+++ b/src/main/java/com/stylefeng/guns/core/common/exception/BizExceptionEnum.java
@@ -69,7 +69,8 @@
     /**
      * 其他
      */
-    AUTH_REQUEST_ERROR(400, "账号密码错误");
+    AUTH_REQUEST_ERROR(400, "账号密码错误"),
+    CALLBACK_ERROR(400, "FAIL TO CALLBACK");
 
     BizExceptionEnum(int code, String message) {
         this.code = code;
diff --git a/src/main/java/com/stylefeng/guns/modular/api/ApiController.java b/src/main/java/com/stylefeng/guns/modular/api/ApiController.java
index 47287f9..422fef6 100644
--- a/src/main/java/com/stylefeng/guns/modular/api/ApiController.java
+++ b/src/main/java/com/stylefeng/guns/modular/api/ApiController.java
@@ -1,9 +1,23 @@
 package com.stylefeng.guns.modular.api;
 
 import com.baomidou.mybatisplus.mapper.EntityWrapper;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.gson.Gson;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.intuit.ipp.core.IEntity;
+import com.intuit.ipp.data.*;
+import com.intuit.ipp.exception.FMSException;
+import com.intuit.ipp.services.DataService;
+import com.intuit.ipp.services.QueryResult;
+import com.intuit.oauth2.data.BearerTokenResponse;
+import com.intuit.oauth2.exception.OAuthException;
 import com.stylefeng.guns.core.base.controller.BaseController;
 import com.stylefeng.guns.core.base.tips.ErrorTip;
 import com.stylefeng.guns.core.common.constant.factory.ConstantFactory;
+import com.stylefeng.guns.core.common.exception.BizExceptionEnum;
+import com.stylefeng.guns.core.exception.GunsException;
 import com.stylefeng.guns.core.shiro.ShiroUser;
 import com.stylefeng.guns.core.util.Convert;
 import com.stylefeng.guns.core.util.JwtTokenUtil;
@@ -15,17 +29,24 @@
 import com.stylefeng.guns.modular.system.model.User;
 import com.stylefeng.guns.modular.system.model.UserInfo;
 import com.stylefeng.guns.modular.system.utils.EmailUtil;
+import com.stylefeng.guns.modular.system.utils.InvoicesDataUploadUtil;
 import com.stylefeng.guns.modular.system.utils.RedisUtil;
 import com.stylefeng.guns.modular.system.utils.tips.SuccessTip;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiImplicitParam;
 import io.swagger.annotations.ApiImplicitParams;
 import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang.RandomStringUtils;
+import org.json.JSONObject;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
+import javax.servlet.http.HttpSession;
+import java.math.BigDecimal;
 import java.util.*;
 
 /**
@@ -37,6 +58,7 @@
 @RestController
 @Api(tags = "登录")
 @RequestMapping("/gunsApi")
+@Slf4j
 public class ApiController extends BaseController {
 
     @Autowired
@@ -47,6 +69,10 @@
 
     @Autowired
     private RedisUtil redisUtil;
+
+    private final String  INVOICE_DATA = "CARINVOICE:";
+
+    private static final String ACCOUNT_QUERY = "select * from Account where AccountType='%s' maxresults 1";
 
     /**
      * api登录接口,通过账号密码获取token
@@ -188,4 +214,177 @@
         return sb.toString();
     }
 
+    @ApiOperation(value = "redirectURL接口",notes="redirectURL接口")
+    @GetMapping(value = "/oauth2redirectOfCar")
+    @ResponseBody
+    @Transactional
+    public String callbackIntuit(@RequestParam("code") String authCode,
+                                 @RequestParam("state") String state,
+                                 @RequestParam(value = "realmId", required = false) String realmId, HttpSession session) throws OAuthException {
+        String accessToken = "";
+        if (com.stylefeng.guns.core.util.ToolUtil.isEmpty(realmId)) {
+            return new JSONObject().put("response","No realm ID.  QBO calls only work if the accounting scope was passed!").toString();
+        }
+        try {
+            session.setAttribute("realmId", realmId);
+            session.setAttribute("auth_code", authCode);
+
+            // OAuth2PlatformClient client = factory.getOAuth2PlatformClient();
+            // String redirectUri = factory.getRedirectUrl();
+
+            BearerTokenResponse bearerTokenResponse = InvoicesDataUploadUtil.callBackFromOAuth(authCode);
+            accessToken = bearerTokenResponse.getAccessToken();
+            session.setAttribute("access_token", bearerTokenResponse.getAccessToken());
+            session.setAttribute("refresh_token", bearerTokenResponse.getRefreshToken());
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+        try {
+
+            String value = redisUtil.getValue(INVOICE_DATA);
+            log.info("value:{}",value);
+            if (ToolUtil.isEmpty(value)){
+                return "ERROR";
+            }
+            Gson gson = new Gson();
+            JsonArray jsonArray = gson.fromJson(value, JsonArray.class);
+            for (JsonElement jsonElement : jsonArray) {
+                JsonObject asJsonObject = jsonElement.getAsJsonObject();
+                String name = asJsonObject.get("name").getAsString();
+                String amount = asJsonObject.get("amount").getAsString();
+                String unitPrice = asJsonObject.get("unitPrice").getAsString();
+                DataService service = InvoicesDataUploadUtil.getDataService(realmId, accessToken);
+                Customer customer = getCustomerWithAllFields(name,"testconceptsample@mailinator.com");
+                Customer savedCustomer = service.add(customer);
+                Item item = getItemFields(service, unitPrice == null || unitPrice == "ABC Corporations" ? "0" : unitPrice );
+                Item savedItem = service.add(item);
+                Invoice invoice = getInvoiceFields(savedCustomer, savedItem, amount == null || amount == "" ? "0" : amount);
+                Invoice savedInvoice = service.add(invoice);
+                service.sendEmail(savedInvoice, customer.getPrimaryEmailAddr().getAddress());
+                Payment payment = getPaymentFields(savedCustomer, savedInvoice);
+                Payment savedPayment = service.add(payment);
+                createResponse(savedPayment);
+            }
+
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new GunsException(BizExceptionEnum.CALLBACK_ERROR);
+        }
+        return "SUCCESS";
+    }
+
+
+
+
+    private Customer getCustomerWithAllFields(String companyName,String mailAddr) {
+        Customer customer = new Customer();
+        customer.setDisplayName(RandomStringUtils.randomAlphanumeric(6));
+        customer.setCompanyName(companyName);
+
+        EmailAddress emailAddr = new EmailAddress();
+        emailAddr.setAddress(mailAddr);
+        customer.setPrimaryEmailAddr(emailAddr);
+
+        return customer;
+    }
+
+    private Item getItemFields(DataService service,String unitPrice) throws FMSException {
+
+        Item item = new Item();
+        item.setName("Item" + RandomStringUtils.randomAlphanumeric(5));
+        item.setTaxable(false);
+        item.setUnitPrice(unitPrice == null || unitPrice == "" ? BigDecimal.ZERO :new BigDecimal(unitPrice));
+        item.setType(ItemTypeEnum.SERVICE);
+
+        Account incomeAccount = getIncomeBankAccount(service);
+        item.setIncomeAccountRef(createRef(incomeAccount));
+
+        return item;
+    }
+
+    private Account getIncomeBankAccount(DataService service) throws FMSException {
+        QueryResult queryResult = service.executeQuery(String.format(ACCOUNT_QUERY, AccountTypeEnum.INCOME.value()));
+        List<? extends IEntity> entities = queryResult.getEntities();
+        if(!entities.isEmpty()) {
+            return (Account)entities.get(0);
+        }
+        return createIncomeBankAccount(service);
+    }
+
+    private ReferenceType createRef(IntuitEntity entity) {
+        ReferenceType referenceType = new ReferenceType();
+        referenceType.setValue(entity.getId());
+        return referenceType;
+    }
+    private Account createIncomeBankAccount(DataService service) throws FMSException {
+        Account account = new Account();
+        account.setName("Incom" + RandomStringUtils.randomAlphabetic(5));
+        account.setAccountType(AccountTypeEnum.INCOME);
+
+        return service.add(account);
+    }
+
+    private Invoice getInvoiceFields(Customer customer, Item item,String amount) {
+
+        Invoice invoice = new Invoice();
+        invoice.setCustomerRef(createRef(customer));
+        BigDecimal balance = invoice.getBalance();
+        log.info("balance:{}",balance);
+
+        List<Line> invLine = new ArrayList<Line>();
+        Line line = new Line();
+        line.setAmount(amount == null || amount == "" ? BigDecimal.ZERO : new BigDecimal(amount));
+        line.setDetailType(LineDetailTypeEnum.SALES_ITEM_LINE_DETAIL);
+
+        SalesItemLineDetail silDetails = new SalesItemLineDetail();
+        silDetails.setItemRef(createRef(item));
+
+        line.setSalesItemLineDetail(silDetails);
+        invLine.add(line);
+        invoice.setLine(invLine);
+
+        return invoice;
+    }
+
+    private Payment getPaymentFields(Customer customer, Invoice invoice) {
+
+        Payment payment = new Payment();
+        payment.setCustomerRef(createRef(customer));
+
+        payment.setTotalAmt(invoice.getTotalAmt());
+
+        List<LinkedTxn> linkedTxnList = new ArrayList<LinkedTxn>();
+        LinkedTxn linkedTxn = new LinkedTxn();
+        linkedTxn.setTxnId(invoice.getId());
+        linkedTxn.setTxnType(TxnTypeEnum.INVOICE.value());
+        linkedTxnList.add(linkedTxn);
+
+        Line line1 = new Line();
+        line1.setAmount(invoice.getTotalAmt());
+        line1.setLinkedTxn(linkedTxnList);
+
+        List<Line> lineList = new ArrayList<Line>();
+        lineList.add(line1);
+        payment.setLine(lineList);
+
+        return payment;
+    }
+
+
+    private String createResponse(Object entity) {
+        ObjectMapper mapper = new ObjectMapper();
+        String jsonInString;
+        try {
+            jsonInString = mapper.writeValueAsString(entity);
+        } catch (Exception e) {
+            return createErrorResponse(e);
+        }
+        return jsonInString;
+    }
+
+    private String createErrorResponse(Exception e) {
+        log.error("Exception while calling QBO ", e);
+        return new JSONObject().put("response","Failed").toString();
+    }
+
 }
diff --git a/src/main/java/com/stylefeng/guns/modular/system/controller/FinanceController.java b/src/main/java/com/stylefeng/guns/modular/system/controller/FinanceController.java
index ec41f12..6b24ff2 100644
--- a/src/main/java/com/stylefeng/guns/modular/system/controller/FinanceController.java
+++ b/src/main/java/com/stylefeng/guns/modular/system/controller/FinanceController.java
@@ -3,8 +3,11 @@
 import cn.hutool.core.date.DateUtil;
 import com.baomidou.mybatisplus.mapper.EntityWrapper;
 import com.baomidou.mybatisplus.plugins.Page;
+import com.intuit.oauth2.exception.InvalidRequestException;
 import com.stylefeng.guns.core.util.ToolUtil;
 import com.stylefeng.guns.modular.system.service.ITPriceService;
+import com.stylefeng.guns.modular.system.utils.InvoicesDataUploadUtil;
+import com.stylefeng.guns.modular.system.utils.RedisUtil;
 import com.stylefeng.guns.modular.system.utils.tips.ErrorTip;
 import com.stylefeng.guns.modular.system.model.*;
 import com.stylefeng.guns.modular.system.service.ITOrderService;
@@ -13,28 +16,33 @@
 import io.swagger.annotations.ApiImplicitParam;
 import io.swagger.annotations.ApiImplicitParams;
 import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.ibatis.annotations.Param;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.autoconfigure.cache.CacheProperties;
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.*;
+import org.springframework.web.servlet.View;
 
 import javax.annotation.Resource;
 import java.math.BigDecimal;
 import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.List;
+import java.util.*;
 
 @Controller
 @Api(tags = "财务信息")
 @RequestMapping("/api/tFinance")
+@Slf4j
 public class FinanceController {
 
 
     @Autowired
     private ITOrderService orderService;
+
+    @Autowired
+    private RedisUtil redisUtil;
+
+    private final String  INVOICE_DATA = "CARINVOICE:";
 
 
     @ApiOperation(value = "卡车公司-应收报表列表",notes="卡车公司-应收报表列表")
@@ -92,6 +100,26 @@
         return new SuccessTip(receivableVoPage);
     }
 
+    @ApiOperation(value = "应收款票据quickBooks",notes="应收款票据quickBooks")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "Authorization", value = "用户token(Bearer +token)", required = true, dataType = "String", paramType = "header", defaultValue = "Bearer eyJhbGciOiJIUzUxMiJ9....."),
+    })
+    @GetMapping(value = "/exportQuickBook")
+    @ResponseBody
+    public Object exportQuickBooks(){
+        List<Map<String,Object>> orders = orderService.queryAllOrderDatas();
+        redisUtil.setStrValue(INVOICE_DATA+"",orders.toString());
+        try {
+            View view = InvoicesDataUploadUtil.connectToQuickBooks();
+            log.info("view:{}",view);
+        } catch (InvalidRequestException e) {
+            e.printStackTrace();
+        }
+        return new com.stylefeng.guns.core.base.tips.SuccessTip();
+    }
+
+
+
     @ApiOperation(value = "应收款票据详情",notes="应收款票据详情")
     @ApiImplicitParams({
             @ApiImplicitParam(name = "Authorization", value = "用户token(Bearer +token)", required = true, dataType = "String", paramType = "header", defaultValue = "Bearer eyJhbGciOiJIUzUxMiJ9....."),
diff --git a/src/main/java/com/stylefeng/guns/modular/system/dao/TOrderMapper.java b/src/main/java/com/stylefeng/guns/modular/system/dao/TOrderMapper.java
index 43cb8a4..282fd0c 100644
--- a/src/main/java/com/stylefeng/guns/modular/system/dao/TOrderMapper.java
+++ b/src/main/java/com/stylefeng/guns/modular/system/dao/TOrderMapper.java
@@ -8,6 +8,7 @@
 
 import java.math.BigDecimal;
 import java.util.List;
+import java.util.Map;
 
 /**
  * <p>
@@ -58,4 +59,5 @@
 
     Double getCompanyIncome(@Param("companyId") Integer companyId, @Param("sTime") String sTime, @Param("eTime") String eTime);
 
+    List<Map<String, Object>> queryAllOrderDatas();
 }
diff --git a/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/TOrderMapper.xml b/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/TOrderMapper.xml
index c62711f..86e5398 100644
--- a/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/TOrderMapper.xml
+++ b/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/TOrderMapper.xml
@@ -212,5 +212,17 @@
             and success_time BETWEEN #{sTime} and #{eTime}
         </if>
     </select>
+    <select id="queryAllOrderDatas" resultType="java.util.Map">
+        SELECT too.id,
+               tc.`name`,
+               too.s_email as mailAddr,
+               tp.car_price    as amount,
+               too.paid    as unitPrice
+        FROM `t_order` AS too
+                 JOIN t_user tu ON too.user_id = tu.id
+                 JOIN t_company tc ON too.company_id = tc.id
+                 join t_price tp on too.id = tp.order_id
+        WHERE too.STATUS = 1
+    </select>
 
 </mapper>
diff --git a/src/main/java/com/stylefeng/guns/modular/system/service/ITOrderService.java b/src/main/java/com/stylefeng/guns/modular/system/service/ITOrderService.java
index 71f8f86..90a9064 100644
--- a/src/main/java/com/stylefeng/guns/modular/system/service/ITOrderService.java
+++ b/src/main/java/com/stylefeng/guns/modular/system/service/ITOrderService.java
@@ -5,6 +5,7 @@
 import com.baomidou.mybatisplus.service.IService;
 
 import java.util.List;
+import java.util.Map;
 
 /**
  * <p>
@@ -44,4 +45,7 @@
 
     Boolean addOrderFile(Long orderId, String url, String name);
 
+    List<Map<String, Object>> queryAllOrderDatas();
+
+
 }
diff --git a/src/main/java/com/stylefeng/guns/modular/system/service/impl/TOrderServiceImpl.java b/src/main/java/com/stylefeng/guns/modular/system/service/impl/TOrderServiceImpl.java
index ee0ad1b..5a0be84 100644
--- a/src/main/java/com/stylefeng/guns/modular/system/service/impl/TOrderServiceImpl.java
+++ b/src/main/java/com/stylefeng/guns/modular/system/service/impl/TOrderServiceImpl.java
@@ -540,6 +540,11 @@
             return this.baseMapper.addOrderFile(orderId,url,name);
         }
 
+        @Override
+        public List<Map<String, Object>> queryAllOrderDatas() {
+            return this.baseMapper.queryAllOrderDatas();
+        }
+
 
         public static void main(String[] args) throws ParseException {
 
diff --git a/src/main/java/com/stylefeng/guns/modular/system/utils/InvoicesDataUploadUtil.java b/src/main/java/com/stylefeng/guns/modular/system/utils/InvoicesDataUploadUtil.java
new file mode 100644
index 0000000..8e7cec3
--- /dev/null
+++ b/src/main/java/com/stylefeng/guns/modular/system/utils/InvoicesDataUploadUtil.java
@@ -0,0 +1,106 @@
+package com.stylefeng.guns.modular.system.utils;
+
+import com.intuit.ipp.core.Context;
+import com.intuit.ipp.core.ServiceType;
+import com.intuit.ipp.data.*;
+import com.intuit.ipp.exception.FMSException;
+import com.intuit.ipp.security.OAuth2Authorizer;
+import com.intuit.ipp.services.DataService;
+import com.intuit.ipp.util.Config;
+import com.intuit.oauth2.client.OAuth2PlatformClient;
+import com.intuit.oauth2.config.Environment;
+import com.intuit.oauth2.config.OAuth2Config;
+import com.intuit.oauth2.config.Scope;
+import com.intuit.oauth2.data.BearerTokenResponse;
+import com.intuit.oauth2.exception.InvalidRequestException;
+import com.intuit.oauth2.exception.OAuthException;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.servlet.View;
+import org.springframework.web.servlet.view.RedirectView;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * <p>
+ *
+ * </p>
+ *
+ * @Author: lisy
+ * @date: 2023-05-23 14:37
+ * @Description:
+ */
+@Slf4j
+public class InvoicesDataUploadUtil {
+
+    // private static final String redirectUrl = "http://cca19.com:8010/gunsApi/oauth2redirect";
+    private static final String redirectUrl = "http://cca19.com:8010/gunsApi/oauth2redirectOfCar";
+
+    private static final String createInvoiceUrl = "https://sandbox-quickbooks.api.intuit.com";
+
+    private static final String clientId = "ABXjfdoTHLWaBrkWRkoe6C8sk9mixpQJ1OlrFVkZznsdUzLPIf";
+
+    private static final String clientSecret = "WJ01VwbagGa23FJZQVJW4LGKPG9vaJIBgzxEEfEA";
+
+
+    public static View connectToQuickBooks() throws InvalidRequestException {
+
+
+        OAuth2Config oauth2Config = new OAuth2Config.OAuth2ConfigBuilder(clientId,clientSecret)
+                .callDiscoveryAPI(Environment.SANDBOX)
+                .buildConfig();
+
+        String csrf = oauth2Config.generateCSRFToken();
+
+        List<Scope> scopes = new ArrayList<Scope>();
+        scopes.add(Scope.Accounting);
+        String prepareUrl = oauth2Config.prepareUrl(scopes, redirectUrl, csrf);
+        System.out.println(prepareUrl);
+        return new RedirectView(prepareUrl, true, true, false);
+    }
+
+
+    public static String refreshToken() throws OAuthException {
+
+        //Prepare the config
+        OAuth2Config oauth2Config = new OAuth2Config.OAuth2ConfigBuilder(clientId,clientSecret).callDiscoveryAPI(Environment.SANDBOX).buildConfig();
+
+//Prepare OAuth2PlatformClient
+        OAuth2PlatformClient client  = new OAuth2PlatformClient(oauth2Config);
+
+//Call refresh endpoint
+        BearerTokenResponse bearerTokenResponse = client.refreshToken("refreshToken"); //set refresh token
+        return bearerTokenResponse.getAccessToken();
+    }
+
+    private static Context prepareContext(String realmId, String accessToken) throws FMSException {
+        String url = new OAuth2PlatformClientFactory().getHost() + "/v3/company";
+
+        Config.setProperty(Config.BASE_URL_QBO, url);
+        //create oauth object
+        OAuth2Authorizer oauth = new OAuth2Authorizer(accessToken);
+        //create context
+        Context context = new Context(oauth, ServiceType.QBO, realmId);
+        return context;
+    }
+
+    public static DataService getDataService(String realmId, String accessToken ) throws FMSException {
+        Context context = prepareContext(realmId, accessToken);
+
+        // create dataservice
+        return new DataService(context);
+    }
+
+
+
+    public static BearerTokenResponse callBackFromOAuth(String code) throws OAuthException {
+        OAuth2Config oauth2Config = new OAuth2Config.OAuth2ConfigBuilder(clientId,clientSecret)
+                .callDiscoveryAPI(Environment.SANDBOX)
+                .buildConfig();
+        //prepare OAuth2Platform client
+        OAuth2PlatformClient client  = new OAuth2PlatformClient(oauth2Config);
+        //retrieve access token by calling the token endpoint
+        return client.retrieveBearerTokens(code, redirectUrl);
+
+    }
+}
diff --git a/src/main/java/com/stylefeng/guns/modular/system/utils/OAuth2PlatformClientFactory.java b/src/main/java/com/stylefeng/guns/modular/system/utils/OAuth2PlatformClientFactory.java
new file mode 100644
index 0000000..87e81ce
--- /dev/null
+++ b/src/main/java/com/stylefeng/guns/modular/system/utils/OAuth2PlatformClientFactory.java
@@ -0,0 +1,56 @@
+package com.stylefeng.guns.modular.system.utils;
+
+import com.intuit.oauth2.client.OAuth2PlatformClient;
+import com.intuit.oauth2.config.Environment;
+import com.intuit.oauth2.config.OAuth2Config;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+
+/**
+ * 
+ * @author dderose
+ *
+ */
+@Component
+public class OAuth2PlatformClientFactory {
+
+	private static final String clientId = "ABXjfdoTHLWaBrkWRkoe6C8sk9mixpQJ1OlrFVkZznsdUzLPIf";
+
+	private static final String secret = "WJ01VwbagGa23FJZQVJW4LGKPG9vaJIBgzxEEfEA";
+
+	private static final String url = "http://cca19.com:8010/gunsApi/oauth2redirectOfCar";
+
+	private static final String host = "https://sandbox-quickbooks.api.intuit.com";
+
+	OAuth2PlatformClient client;
+
+	OAuth2Config oauth2Config;
+	
+	@PostConstruct
+	public void init() {
+		//initialize the config
+		oauth2Config = new OAuth2Config.OAuth2ConfigBuilder(clientId, secret) //set client id, secret
+				.callDiscoveryAPI(Environment.SANDBOX) // call discovery API to populate urls
+				.buildConfig();
+		//build the client
+		client  = new OAuth2PlatformClient(oauth2Config);
+	}
+	
+	
+	public OAuth2PlatformClient getOAuth2PlatformClient()  {
+		return client;
+	}
+	
+	public OAuth2Config getOAuth2Config()  {
+		return oauth2Config;
+	}
+	
+	public String getRedirectUrl() {
+		return url;
+	}
+
+	public String getHost() {
+		return host;
+	}
+}

--
Gitblit v1.7.1