freeeAPI 請求書発行したら、自動で+更新までやっちゃおうぜ！！


こんにちは、未経験からエンジニア転職を目指しているmkです。
今回はfreeeAPIを触ってみました。

表題の通り、請求書をアップロードして+更新を毎回ぽちぽちやるのが面倒なので、
請求書をAPI経由で発行して、+更新まで全てやってくれるプログラムをRubyで書いてみました。

[github](https://github.com/KwanjiChoi/freee_api)

### 環境
macOS 10.15.5
ruby 2.7.1

# そもそも+更新とは

[前受けが発生する場合のfreeeの活用法(外部リンク)
](https://naohiro.biz/freee-maeuke/)
こちらの記事にわかりやすくまとまっていますが、
要するに、前受金を売上に変更する作業ができるボタンです。（間違ってたらすいません、、、）

[freee謹製前受管理アプリ](https://www.freee.co.jp/blog/1906_distribution-deal.html)がfreeeアプリストアにはあるのですが、
請求書の発行からnヶ月分前受した売上金を月次の売上に分割する作業を一から自動化したかったので今回作成しました。

## 必要な処理
- アクセストークンの発行(GET) 
- company_idの取得(GET)　
- 勘定科目idの取得(GET)　
- 取引先idの取得(GET)　
- 税区分idの取得(GET) 
- 請求書の発行(POST)
- 取引詳細の取得(GET) *取引行idの取得
- +更新の作成(POST)



## 請求書発行→+更新のコード

まずはhelper的な処理を記述していきます。

```helper.rb
#月の処理
def add_month(num)
  if num < 12
    return num = num + 1
  elsif num == 12
    num = 1
  end
end

# 初月のプラス更新額を求める処理
def first_price(price,times)
  (price % times) + (price / times)
end
```
請求書発行月を含む更新回数月分の月末を取得しないといけないので、add_monthを定義。

また、請求金額が更新回数で割り切れない場合、初回の更新に余を含めるようfirst_priceを定義します。

httpリクエストのヘッダーを指定するモジュール

```set_header.rb

module Header
  def self.get_header
    headers = {
      "accept" => "application/json",
      "Authorization"=> "Bearer #{YOUR_ACCESS_TOKEN}"
    }
  end
  def self.post_header
    headers = {
      "accept" => "application/json",
      "Authorization"=> "Bearer #{YOUR_ACCESS_TOKEN}",
      "Content-Type" => "application/json"
    }
  end
end

```


請求書発行のコード

```invoice.rb

require 'set_header.rb'
require 'json'
require 'net/http'

class Invoice
  BASE_URL = 'https://api.freee.co.jp'
  #パラメータを引数に渡すことで請求書を作成
  def self.make_invoice(params)
    uri = URI.parse(BASE_URL + '/api/1/invoices')
    http = Net::HTTP.new(uri.host,uri.port)
    http.use_ssl = uri.scheme === "https"
    req = Net::HTTP::Post.new(uri.path)
    req.body = params.to_json
    req.initialize_http_header(Header.post_header)
    response = http.request(req)
    res_hash = JSON.parse(response.body)
  end
end

```

プラス更新作成のコード

```koushin.rb

require_relative 'set_header.rb'
require 'json'
require 'net/http'

class Koushin
  BASE_URL = 'https://api.freee.co.jp'
  #取引id,パラメータを引数に渡すことでプラス更新をかける
  def self.post_koushin(torihiki_id,params)
    uri = URI.parse(BASE_URL + "/api/1/deals/#{torihiki_id}/renews")
    http = Net::HTTP.new(uri.host, uri.port)
    http.use_ssl = uri.scheme === "https"
    req = Net::HTTP::Post.new(uri.path)
    req.body = params.to_json
    req.initialize_http_header(Header.post_header)
    response = http.request(req)
    res_hash = JSON.parse(response.body)
  end
end

```


そして請求書発行からプラス更新までを実装
請求金額は12345678円(外税)、税率は10%に
+更新回数は12回で処理を実行してみます。

```invoice_koushin.rb
require 'invoice.rb'
require 'koushin.rb'
require 'date'
require 'helper.rb'
# その他いろいろrequireしてますが省略

#必要項目の設定
month = Time.now.month
year = Time.now.year
count = 1
company_id = Company.company_id #github参照 事業所idの取得

#請求額(外税)
amount = 12345678
#消費税額(10%)
vat = (amount * 0.1).floor
#+更新回数
num = 12


# 請求書のパラメーター
invoice_params = {
  "company_id": company_id,
  "issue_date": Date.today,
  "due_date": Date.new(year, month, -1),
  "partner_id": Supplier.supplier_id('CFO'), #github参照 取引先idの取得
  "booking_date": Date.today,
  "description": "#{Date.today.month}月分請求書",
  "invoice_status": "issue",
  "partner_display_name": "CFO株式会社",
  "partner_title": "御中",
  "partner_contact_info": "営業担当",
  "partner_zipcode": "012-0009",
  "partner_prefecture_code": 4,
  "partner_address1": "湯沢市",
  "partner_address2": "Aビル",
  "company_name": "freee株式会社",
  "company_zipcode": "000-0000",
  "company_prefecture_code": 12,
  "company_address1": "ＸＸ区ＹＹ１−１−１",
  "company_address2": "ビル 1F",
  "company_contact_info": "法人営業担当",
  "payment_type": "transfer",
  "payment_bank_info": "ＸＸ銀行ＹＹ支店 1111111",
  "message": "下記の通りご請求申し上げます。",
  "notes": "毎度ありがとうございます",
  "invoice_layout": "default_classic",
  "tax_entry_method": "exclusive",
  "invoice_contents": [
    {
      "order": 0,
      "type": "normal",
      "qty": 1,
      "unit": "個",
      "unit_price": amount,
      "vat": vat,
      "description": "備考",
      "tax_code": 2,
      "account_item_id": AccountItem.account_item_id('前受収益') #github参照 前受収益のaccount_item_idを取得
    }
  ]
}

#請求書の発行
invoice = Invoice.make_invoice(invoice_params)
puts '請求書を発行しました'
#請求書発行のレスポンスから取引idを取得
torihiki_id = invoice['invoice']['deal_id']
#上記取引idの取引行idを取得
renew_target_id = Torihiki.target_id(torihiki_id) #github参照　torihiki_idに紐づく取引の詳細をGET、そこから取引行idを取得
#+更新時の勘定科目id(売上高)を取得
uriagedaka_id = AccountItem.account_item_id('売上高') #github参照

#取引id 取引行idを使ってnum回+更新をかける
num.times do
  #countが1の場合+更新額をfirst_priceに変更
  if count == 1
    koushin_amount = first_price(amount,num)
    koushin_vat = first_price(vat,num)
  else
    koushin_amount = amount / num
    koushin_vat = vat / num
  end

  date = Date.new(year, month, -1) 
#+更新のパラメータをセット
  koushin_params = {
    "company_id": company_id,
    "update_date": date,
    "renew_target_id": renew_target_id,
    "details": [
      {
        "account_item_id": uriagedaka_id,
        "tax_code": 21,
        "amount": (koushin_amount + koushin_vat),
        "vat": koushin_vat
      }
    ]
  }
  #取引id,パラメータを使って+更新の作成
  Koushin.post_koushin(torihiki_id,koushin_params)
  puts "#{date}の更新をしました"
  # 翌月の月を取得
  month = add_month(month)
  #monthが1月の場合西暦を1足す
  year += 1 if month == 1
  count += 1
end

```

ローカルで実行してみます。

<img width="567" alt="スクリーンショット 2020-07-15 20.01.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570675/09261095-fc14-71f1-9c3f-c47d56ae6a30.png">

ちゃんと処理は走ったみたいです。実行時間は5秒程（ちょっと長い、、、）
会計freeeをみてみます。

<img width="1255" alt="スクリーンショット 2020-07-15 19.54.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570675/3411fede-c5ba-7d8d-b319-105db035ac2e.png">

CFO株式会社宛に請求書が発行できてますね！
金額も消費税額もきちんと入ってます。
<img width="761" alt="スクリーンショット 2020-07-15 22.06.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570675/0b651ac5-2d88-8fe5-3ed7-13ecb9a61059.png">
次は取引を見てみましょう。

<img width="1272" alt="スクリーンショット 2020-07-15 19.53.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570675/c29e674a-2e50-0207-c16c-8104346b7e6a.png">
ばっちし更新後の金額が0円になってます！

<img width="1278" alt="スクリーンショット 2020-07-15 19.52.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570675/d05a1a14-dd01-3ee9-7409-6007010799fc.png">

更新日付も発行月の月末含む、12ヶ月分の末日が入っています。

### 今後の課題
月末発行の請求書はどうするんだとか、振り込み確認できた翌月から更新をかけたいだとか、柔軟に対応できるよう改良していきたいと思います。
また請求書の各パラメータと更新回数をcsvでインポートできるようします。
あとコードが美しくない、、、笑

日々精進