【FreeeAPIチュートリアル(画像多め)】クリック一つで請求書の内容をfreeeに保存してみる

## 前書き
### 技術環境
・使用言語(サーバーサイド)：PHP(5.3)
・使用言語(フロント):HTML,CSS,jQuery
・フレームワーク:CakePHP(2.3)

### 読者ターゲット
・これまでにAPIを使って何かを実装したことない人(筆者も)
・導入部分は言語関係なく書いているのでどなたでも読めると思います

### 実装、記事にする内容
・FreeeAPIの始め方
・請求書発行ボタンを押した時にメールが先方に送付される仕組みに、freeeに請求内容が登録される仕組みを追加する実装

### 記事にした理由
・もともと仕事で実装する予定だったけれども、施策が頓挫したので勉強がてら実装しながらQiita夏祭りにも参加してみようと思ったため

・どこのAPIもチュートリアルがちょっとわかりづらいので、実装ついでのメモ

## 導入部分

<a href="https://developer.freee.co.jp/">FreeeのDevelopersサイト</a>

### ユーザー登録
<img width="1216" alt="スクリーンショット 2020-07-05 17.44.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454305/43b7638a-d4fd-00c2-15af-cea3a57d9b82.png">

まずはTOPに飛んで、右上の「ユーザー登録」をクリック

<img width="1034" alt="スクリーンショット 2020-07-05 17.46.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454305/2d9459c5-24c3-e2db-4bf4-4f1fc8ddbb64.png">

表示名とメールアドレスと入力
(バリデーションエラーが英語なので日本語にして欲しい(願望))

<img width="889" alt="スクリーンショット 2020-07-05 17.49.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454305/ba48df08-b185-54e8-061e-49469e9c96af.png">

登録が完了できていれば上記の様なメールが届きます
記載されているURLをクリックするとパスワードの設定画面に遷移するのでパスワードの設定
<img width="432" alt="スクリーンショット 2020-07-05 17.52.09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454305/cc22176b-3ca1-30d2-2194-f2b250610399.png">

### ログイン後

<img width="1197" alt="スクリーンショット 2020-07-05 17.58.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454305/910907e8-d33e-1e12-fb2e-2379c2135ab9.png">

まずはヘッダーのスタートアップガイドをクリック

<img width="946" alt="スクリーンショット 2020-07-05 18.13.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454305/78d21de1-5643-a733-0ae9-2268505c1bc3.png">

セットアップの順序通り、まずはセットアップから「freeeアカウントをお持ちの方」をクリック

<img width="467" alt="スクリーンショット 2020-07-05 18.02.17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454305/08160592-84a8-134c-2522-e81f3a0e9fd1.png">

先ほど作成したアカウントでログイン

<img width="672" alt="スクリーンショット 2020-07-05 18.04.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454305/c146010b-3de7-6c09-d483-bd7934de4292.png">

#### 事業所とアプリの作成
テストで使用する事業所の作成「freee APIの利用を開始する」をクリック

<img width="672" alt="スクリーンショット 2020-07-05 18.06.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454305/ae3ce3f4-121c-b063-e984-465c88643839.png">

しばらくメールの到着をまつ
<img width="655" alt="スクリーンショット 2020-07-05 18.08.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454305/077aee57-97bb-181f-ffa4-33e31adbaa30.png">

上記の様なメールが届けば開発用テスト事業所とテストアプリ作成完了
「アクセストークン取得ページ」をクリック

<img width="655" alt="スクリーンショット 2020-07-05 18.10.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454305/3e224d6a-5aa4-b18e-3031-655e42792e10.png">

アプリ連携の開始が表示されるとの「許可」をクリック

<img width="673" alt="スクリーンショット 2020-07-05 18.15.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454305/d94818a2-91ed-5434-b4a3-8cbefd81159d.png">

「許可」をクリックした後に開発用テスト事業所ID・アクセストークンのページに遷移するので
アクセストークンをコピー

コピーした後に
<a href="https://developer.freee.co.jp/docs/accounting/reference#/Companies/get_companies">「APIリファレンスでCompaniesに移動」</a>をクリック


<img width="715" alt="スクリーンショット 2020-07-05 18.19.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454305/f5a83843-39de-0916-932d-6cec706c5a20.png">
<img width="1083" alt="スクリーンショット 2020-07-05 18.18.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454305/5d9603e0-800e-82ba-dbef-f2883d0495fa.png">

遷移先の説明文の下に「Authorize」があるのでクリックし、先ほどコピーしたアクセストークンを貼り付けて「Authorize」をクリック

## アクセストークンの設定確認

<img width="784" alt="スクリーンショット 2020-07-05 18.22.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454305/2af39f4f-f7cf-8788-4b5a-aa569be83ca3.png">

Companies　事業所までスクロールをして「Try it out」をクリック

<img width="784" alt="スクリーンショット 2020-07-05 18.21.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454305/68d892cd-092d-edfc-5ffb-324a24b580f1.png">

真下に「Execute」と「Clear」が表示されるので「Execute」をクリック

<img width="784" alt="スクリーンショット 2020-07-05 18.24.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454305/6d8f822f-db6e-8096-6901-2daab2a43f1e.png">

上記の様に「Responses」が表示されて「Server response」のコードが200ならブラウザ上で正しくAPIが動作しています

```

curl -X GET "https://api.freee.co.jp/api/1/companies" 
-H "accept: application/json" 
-H "Authorization: Bearer アクセストークン"
```

また、真ん中に書いてあるcurlの様にリクエストを投げればAPIでの連携が出来る状態になっています

「curl -X GET 」・・・リクエストするURL
「-H 」・・・ヘッダーの中身

また、取引内容をPOSTする際に事業所のIDが必要になりますのでResponse bodyをみてIDをメモしておきましょう。

<img width="1079" alt="スクリーンショット 2020-07-05 18.37.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454305/7d2f03d8-0ee6-2b20-d79c-cf95538be214.png">


Response bodyの例

```

{
  "companies": [
    {
      "id": 1234,  //このIDを利用する
      "name": null,
      "name_kana": null,
      "display_name": "開発用テスト事業所",
      "role": "admin"
    }
  ]
}
```

## WEB上で取引POSTテストの前準備

取引内容を登録する際に事業所IDと取引先ID、取引品目ID、勘定科目IDが必要になります。
上記では事業所IDを取得しましたが取引先のIDと取引品目IDと勘定科目IDを取得が必要ですので「会計APIリファレンス」で取得してみましょう。


### 取引先IDの取得

<img width="236" alt="スクリーンショット 2020-07-05 18.58.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454305/9b227a4f-eea1-cb9c-d0d0-5a4eecdd6075.png">

サイドメニューから「取引先」のGETをクリックしましょう。

<img width="1067" alt="スクリーンショット 2020-07-05 18.59.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454305/85154f7d-f181-dcb8-6bc7-1f6fc25f6a64.png">

<img width="1067" alt="スクリーンショット 2020-07-05 18.59.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454305/60cb40be-c0e7-4849-b9bf-b117e963eed7.png">

「Try it out 」をクリックした後に「company_id」の入力フォームが出てきますので、先ほどメモした事業所IDを入力をして「Execute」をクリックします。

<img width="1067" alt="68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3435343330352f62326662663438632d393366632d393333312d313665362d6531363035306361656136392e706e67.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454305/dafd7192-f9c7-74a5-34ba-2cd7d374ce8e.png">


Server responseから送付する取引先IDを取得します。

### 取引品目IDの取得

<img width="238" alt="スクリーンショット 2020-07-05 19.13.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454305/9584a899-485a-d603-41c7-98b985e003e1.png">

サイドメニューから「品目」のGETをクリックしましょう。

<img width="1065" alt="スクリーンショット 2020-07-05 19.14.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454305/2e129ae0-3c89-d8fc-19a5-5394cbd09b2d.png">
<img width="1065" alt="スクリーンショット 2020-07-05 19.15.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454305/cb1a978a-a927-3fd5-a935-a3127cc46396.png">


取引先ID同様に「Try it out 」をクリックした後に「company_id」の入力フォームが出てきますので、先ほどメモした事業所IDを入力をして「Execute」をクリックします。

<img width="1065" alt="スクリーンショット 2020-07-05 19.15.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454305/c4bb26ac-465b-e8ba-d94c-c31d518e3db6.png">

Server responseから送付する品目IDを取得します。

また、勘定科目も上記の様に勘定科目のGETから取得してください

## 取引のPOSTテスト

<img width="784" alt="スクリーンショット 2020-07-05 18.36.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454305/55c00ba9-930e-6f39-9542-4e9ef8254939.png">

サイドメニューから「取引（収入／支出）」の「POST」をクリックします

<img width="1065" alt="スクリーンショット 2020-07-05 19.40.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454305/c9e69d24-504f-1757-76d5-51190292048d.png">


上記の画像まで飛んだら
<img width="1065" alt="スクリーンショット 2020-07-05 19.41.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454305/b4b383d1-411d-3f1f-d1e2-0e5fcd85c9df.png">

今まで同様に「try it out」をクリック

<img width="1065" alt="スクリーンショット 2020-07-05 19.41.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454305/3b972c5f-0d62-e7c6-d9ca-aee6f90c38e5.png">

送信される内容を表示されるので今まで取得した内容を元に編集

```元々記載されていた内容.json

{
  "issue_date": "2013-01-01",
  "type": "income",
  "company_id": 1, //事業所IDを記載
  "due_date": "2018-12-31",
  "partner_id": 1,　//取引先IDを記載
  "partner_code": "code001", //取引先コードは設定していないので削除
  "ref_number": "1",
  "details": [
    {
      "tax_code": 1,
      "account_item_id": 1, //取得した勘定科目IDの入力
      "amount": 1,
      "item_id": 1, //取得した取引品目IDを入力
      "section_id": 1, //部門IDは今回は使わないので削除
      "tag_ids": [
        1 //タグも今回使用しないので削除
      ],
      "segment_1_tag_id": 1, //セグメントタグ情報は法人向けのプロフェッショナルプラン以上で利用可能なので削除
      "segment_2_tag_id": 1, //上記同様
      "segment_3_tag_id": 1, //上記同様
      "description": "備考",
      "vat": 800
    }
  ],
  "payments": [ //支払行一覧ですが、取引のPOSTテストなので今回は削除（ここは設定しないと未決済になるので実装する際は設定しましょう）
    {
      "amount": 5250,
      "from_walletable_id": 1,
      "from_walletable_type": "bank_account",
      "date": "2013-01-28"
    }
  ],
  "receipt_ids": [ //証憑ファイルIDですがこちらも取引のPOSTテストなので今回は削除
    1
  ]
}
```

```変更後の内容.json

{
  "issue_date": "2020-04-01",
  "type": "income",
  "company_id": 事業所ID,
  "due_date": "2020-05-01",
  "partner_id": 取引先ID,
  "ref_number": "1",
  "details": [
    {
      "tax_code": 1,
      "account_item_id": 勘定科目ID,
      "amount": 1,
      "item_id": 取引品目ID,
      "description": "備考",
      "vat": 800
    }
  ]
}
```

<img width="1065" alt="スクリーンショット 2020-07-05 20.08.59.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454305/ededef1f-a5bb-edf8-9e39-0fc7ddccc0ec.png">
上記の内容に変えてExecuteをクリックします。

<img width="1065" alt="スクリーンショット 2020-07-05 20.09.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454305/9a332321-a2c3-8490-4eb6-70e9f824bae5.png">
そうすると201でレスポンシブがきて登録が完了になります。

### ポストされたかの確認


<img width="1381" alt="スクリーンショット 2020-07-05 20.13.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454305/aab17c24-b807-1db9-6de1-8f3c61dda709.png">

<a href="https://www.freee.co.jp/index3.html">公式サイト</a>を表示して
右上のログインをクリック

<img width="1381" alt="スクリーンショット 2020-07-05 20.20.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454305/803c35ac-cff4-d727-20fd-e72c4b4f58a1.png">
会計freeeにログインをクリック

<img width="1410" alt="スクリーンショット 2020-07-05 20.35.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454305/6f6f5a7b-2797-518d-8e43-b8f3ceff054e.png">

下の決済期日の近い取引に先ほどポストした内容が記載されていれば、POSTはできています。
※POSTした際のdue_dateが古ければここに表示されない場合があります。

## ここからコード

まず請求書が発行されるボタンが下記の様に設置されていたとします。

```bill.ctp
<button id="bill_post" value="sale_id">請求書発行</button>
//sale_idには請求する内容が入ったsaleテーブルのIDが入っていたとします。
```

請求書発行ボタンが押されてコントローラーにPOSTされるまでの処理をjQueryで書きます。

```freee.js

<?php $this->Html->scriptStart(array('inline' => false)); ?>
  $(function() {
    $(document).on('click', '#bill_post',function() {
      var sale_id = $(this).val();
      $.ajax({
          type: 'post',
          //送信先はcakephpのhtmlヘルパーを使用
          url: '<?= $this->Html->url(['controller' => 'Sale', 'action' => 'bill']) ?>',
          dataType: 'JSON',
          //送信する内容はsaleテーブルのIDのみ
          data: {
            id: sale_id
          },
      //記事用なのでエラーメッセージは省略
      // 送信ができた時
      }).done(function(data) {
        window.alert('送信しました。');
      // 送信ができなかった時
      }).fail(function() {
        window.alert('送信できませんでした。');
      });
    });
  });
  <?php $this->Html->scriptEnd(); ?>
```

下記からcakephpで請求内容が送付される処理

```SalesController.php

class SalesController extends AppController{

    public function bill(){
    $this->autoRender = false;

    $post_date = $this->request->data['id'];

    //DBから販売データの取得
    $sale_date = $this->Sale->find('first', [
        'condition' => [
            'id' => $post_date ,
        ]
    ]);


    //ここからfreeeのAPIにPOST
    // 前準備で作っておいた、tokenを設定
    $token = 'freeeDevで取得したtokenの設定'; 
    $base_url = 'https://api.freee.co.jp';

    $post_data = [
        "issue_date": '"' . $sale_date['Sale']['create_date'] . '"', //発生日
        "type": "income",
        "company_id": 事業所ID,
        "due_date": '"' . $sale_date['Sale']['due_date'] . '"', //支払期日
        "partner_id": '"' . $sale_date['Sale']['trader'] . '"', //取引先ID
        "ref_number": "1",
        "details": [
            {
                "tax_code": 1,
                "account_item_id": 勘定科目ID,
                "amount": 1,
                "item_id": 取引品目ID,
                "description": "備考",
                "vat": 800
            }
        ]
    ];

    //APIリファレンスのcurlに書いてあったヘッダーと同じ内容にする
    $header = [
        // 前準備で取得したtokenをヘッダに含める
        'Authorization: Bearer '.$token,
        // json形式のデータをpostするので必要
        'Content-Type: application/json',
    ];


    $context = stream_context_create(array(
        'http' => array(
            'method' => 'POST',
            'header' => implode(PHP_EOL,$header),
            'content'=>  json_encode($post_data),
            'ignore_errors' => true
        )
    ));

    $response = file_get_contents(
        $base_url.'/api/1/deals'
        ,false
        ,$context
    );

    $header = $http_response_header;
    $result = json_decode($response,true);

    }
}

```


## まとめ

実際に実装する場合は各項目をDBから抽出しなければいけないし、もう少し変えなければいけないところはあると思うけれども一旦ざっくり作成は完了。
もし、実装することになってもこの記事の通りに進めれば問題なく実装できそうな気がする。

初めてAPI触ったけどもこういうのがあると楽でいいなぁ