freeeとSalesforceとの取引連携（freee for Salesforceを使う方法）

freee APIでなくfreee for Salesforceのちょっとした改造です。(カレンダーネタでないですかね？　**ということで後半部分でSalesforceからfreee APIをコールするちょっとした自作ツールについて記述します。**)

弊社ではSalesforceで独自の請求書を作成するようにしています。その請求オブジェクト（ヘッダのみ）をfreeeの取引として連携させています。

FREEE請求書作成画面に請求オブジェクトを追加して連携させています。
(初めはこの機能を知らなかったのでfreee APIを使って取引を作ることを考えていましたよ。)

しかし、困ったことが１つ。連携は簡単にできるのですが、既に連携しているかどうかが分からないことです。
この画面からは何度でも連携できてしまいます。せめて既に送信したかどうかが分かればオペレーションミスを防ぐことができると考えました。

こんな感じにしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/a1060d5c-96b6-9fcd-95de-f72043fec3ae.png)

検索条件にも表示できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/6ba3b491-c447-b7cd-6d56-afb78e198f86.png)

# 改造内容（今回はSalesforce側の開発だけで済みます）

今回の対象である月次請求というカスタムオブジェクトに送信済みフラグを追加します。

オブジェクトを眺めていると送信時にはfreee__DealObjectLink__cというオブジェクトにレコードが作られているようです。
ここまで分かればこのオブジェクトにafter insertトリガーを書くことにします。

```
trigger Trigger_freeeDealObjectLink on freee__DealObjectLink__c (before insert, before update, before delete, after insert, after update, after delete, after undelete) {
	if (Trigger.isBefore && !Trigger.isDelete) {
        TRG_freeeDealObjectLink.beforeTrigger(Trigger.new, Trigger.old, Trigger.isInsert, Trigger.isUpdate);
    }
    if (Trigger.isAfter) {
        TRG_freeeDealObjectLink.afterTrigger(Trigger.new, Trigger.old, Trigger.isInsert, Trigger.isUpdate, Trigger.isDelete);
    }
}
```

```
public without sharing class TRG_freeeDealObjectLink {
    // *************************************************
    // freeeに送信したらisfreeeSendをtrueにする                        
    // K.Otsubo  
    //                      
    // *************************************************
    
    
    public static void beforeTrigger(List<freee__DealObjectLink__c> newList, List<freee__DealObjectLink__c> oldList, Boolean isInsert, Boolean isUpdate) {
    }
    
    public static void afterTrigger(List<freee__DealObjectLink__c> newList, List<freee__DealObjectLink__c> oldList, Boolean isInsert, Boolean isUpdate, Boolean isDelete) {
        
        List<GetsujiShiharai__c> updateGetsujiShiharaiList = new List<GetsujiShiharai__c>();
        List<GetsujiSeikyu__c>   updateGetsujiSeikyuList   = new List<GetsujiSeikyu__c>();
        
        set<Id> GetsujiShiharaiIdset = new set<Id>();
        set<Id> GetsujiSeikyuIdset = new set<Id>();
        
        for (freee__DealObjectLink__c fd: newList) {
            if (fd.GetsujiShiharai__c != null) GetsujiShiharaiIdset.add(fd.GetsujiShiharai__c);
            if (fd.GetsujiSeikyu__c != null) GetsujiSeikyuIdset.add(fd.GetsujiSeikyu__c);
        }
        
        for (Id gsId : GetsujiShiharaiIdset){
            GetsujiShiharai__c gs = new GetsujiShiharai__c();
            gs.Id = gsId;
            gs.isfreeeSent__c = true;
            updateGetsujiShiharaiList.add(gs);
        }
        
        for (Id gsId : GetsujiSeikyuIdset){
            GetsujiSeikyu__c gs = new GetsujiSeikyu__c();
            gs.Id = gsId;
            gs.isfreeeSent__c = true;
            updateGetsujiSeikyuList.add(gs);
        }
        
        if (updateGetsujiShiharaiList.size() > 0) update updateGetsujiShiharaiList;
        if (updateGetsujiSeikyuList.size() > 0) update updateGetsujiSeikyuList;
    }
    
    
}
```

# ここからはfreee APIを使ったお話です。

取得できるデータを解析するために作ったSalesforceのコンポーネント。
返ってきたJsonデータからSalesforceのオブジェクトにレコードを作りたいので解析しています。
Salesforceからfreeeに渡す分はアプリでできていまが、その逆のfreeeからSalesforceに貰う方はCSV連携なので
もっとスマートに実施したいということがあります。
まだ、出来てない。

jsonの解析
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/93cacfe4-c895-4ef4-46c3-4dd70477569a.png)

取引を一覧として取得(freee側で更新、新規登録があったレコードが欲しい... できん)

この画面はAPIで取得したJsonを表示していますが、まだSalesforceのオブジェクトとしては保存してない状態です。
Jsonからクラスに変換することで普通のオブジェクトと同じようにプログラミングすることができます。
SOQLで取得したのと同じように扱える。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/38d4a8d0-5b52-e83b-cf23-0df1f291d955.png)


SalesforceでJson形式のデータを扱う上ではいかにClassを定義できるかということが大切です。

こういうのは予約語とバッティングするので困るんだな。
public class payments {
        public Integer id;
        public String date_x;   //dateは定義できないので_xをつけて回避。使う時に強制的に変換する:disappointed_relieved:


```
//取引関係
    public class details {
        public Integer id;
        public Integer account_item_id;               
		public Integer tax_code;        
        public Integer item_id;
        public Integer section_id;        
        public Integer[] tag_ids;
        public Integer amount;
        public Integer vat;             //消費税額
        public String description;  
        public String entry_side;       //貸借（貸方: credit, 借方: debit） 
        
    }
    

    
    public class renews {
        public Integer id;
        public String update_date;  
        public String renew_target_id;
        public String renew_target_type;
        public List<details> details; 
    }
    
    public class payments {
        public Integer id;
        public String date_x;               //dateはエラーになる
        public String from_walletable_type;//口座区分
        public Integer from_walletable_id;
        public Integer amount;
    }
    public class user {
        public Integer id;
        public String email;
        public String display_name;
    }
    
    public class receipts {
		public Integer id;
		public String status;
		public String description;
		public String mime_type;  
        public String issue_date;  
        public String origin;
        public String created_at;
        public String file_src;
        public user user;
    }
    
    public class meta {
        public Integer total_count;
    }
    
    public class accruals {
        public Integer id;
        public Integer account_item_id;      
        public Integer tax_code;    
        public Integer partner_id;     
        public String partner_code;
        public Integer item_id;
        public Integer section_id;        
        public Integer[] tag_ids;
        public Integer amount;
        public Integer vat;             //消費税額
        public String description;  
        public String entry_side;       //貸借（貸方: credit, 借方: debit） 
    }
```


# 最後にfreee APIを使っていくうえでの悩み。

Salesforce側からfreeeにデータを投げるのはAPIを使えばできるのですが、
困っているのは
1. Salesforce --> freeeへの一括処理を行いたい。単純にコールアウトのプログラムを書いてもできないんですよね。
　 しかし、このアプリはやっている。どうやっているのかが不思議だし知りたいところです。
2. freee --> Saleforceへの一括の処理がしたい。これがAPIでは難しそう。キーに更新日が無いので全件取って処理するのは避けたいところです。

詳しい方に教えを乞いたいです。

https://qiita.com/advent-calendar/2021/freee-api