[Ruby] If you issue a freeeAPI bill, let’s do + update automatically! !!

4 minute read

Hello, this is mk, which is aimed at engineers change jobs from inexperienced. This time I tried to touch freee API.

As the title suggests, uploading invoices and updating them every time is a hassle I wrote a program in Ruby that issues a bill via the API and +upgrades everything.

github

environment

macOS 10.15.5 ruby 2.7.1

What is + update in the first place

How to use freee when an advance payment occurs (external link) This article is organized in an easy-to-understand manner, In short, it is a button that allows you to change the advance payment to sales. (I appologize if I am mistaken,,,)

There is a freee frontend management app in the freee app store, I created this time because I wanted to automate the process of dividing the sales received n months in advance from the issue of invoices into monthly sales from scratch.

Required processing

  • Issue access token (GET)
  • Get company_id (GET)
  • Get account ID (GET)
  • Acquisition of customer ID (GET)
  • Get tax category id (GET)
  • Issue invoice (POST)
  • Get transaction details (GET) * Get transaction row id
    • Create Update (POST)

Invoicing → + Update code

First, I will describe the helper-like process.

helper.rb


# Month processing
def add_month(num)
  if num <12
    return num = num + 1
  elsif num == 12
    num = 1
  end
end

# Processing for the first month plus renewal amount
def first_price(price,times)
  (price% times) + (price / times)
end

Define the add_month because you need to get the end of the update count month including the billing month.

Also, if the billing amount is not divisible by the number of updates, define the first_price to include the surplus in the first update.

Module that specifies the header of http request

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

Invoicing code

invoice.rb



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

class Invoice
  BASE_URL ='https://api.freee.co.jp'
  Create invoice by passing # parameter as argument
  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

Plus update creation code

koushin.rb



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

class Koushin
  BASE_URL ='https://api.freee.co.jp'
  #Transaction id, plus update by passing parameters as arguments
  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

And implement from billing to plus renewal Billed amount is 12345678 yen (excluding tax), tax rate is 10%

  • Try to execute the process with 12 updates.

invoice_koushin.rb


require'invoice.rb'
require'koushin.rb'
require'date'
require'helper.rb'
# Various other require, but omitted

# Setting required items
month = Time.now.month
year = Time.now.year
count = 1
company_id = Company.company_id # See github Get the office id

# Billed amount (excluding tax)
amount = 12345678
# Consumption tax amount (10%)
vat = (amount * 0.1).floor
#+ number of updates
num = 12


# Invoice parameters
invoice_params = {
  "company_id": company_id,
  "issue_date": Date.today,
  "due_date": Date.new(year, month, -1),
  "partner_id": Supplier.supplier_id('CFO'), see #github Get supplier id
  "booking_date": Date.today,
  "description": "#{Date.today.month} Monthly Invoice",
  "invoice_status": "issue",
  "partner_display_name": "CFO Corporation",
  "partner_title": "Gochu",
  "partner_contact_info": "Sales Rep",
  "partner_zipcode": "012-0009",
  "partner_prefecture_code": 4,
  "partner_address1": "Yuzawa",
  "partner_address2": "A building",
  "company_name": "freee corporation",
  "company_zipcode": "000-0000",
  "company_prefecture_code": 12,
  "company_address1": "XX 1-1, YY1-1",
  "company_address2": "Building 1F",
  "company_contact_info": "Corporate Sales Representative",
  "payment_type": "transfer",
  "payment_bank_info": "XX Bank YY Branch 1111111",
  "message": "Please request as below.",
  "notes": "Thank you every time",
  "invoice_layout": "default_classic",
  "tax_entry_method": "exclusive",
  "invoice_contents": [
    {
      "order": 0,
      "type": "normal",
      "qty": 1,
      "unit": "piece",
      "unit_price": amount,
      "vat": vat,
      "description": "Remarks",
      "tax_code": 2,
      "account_item_id": AccountItem.account_item_id('Unearned revenue') See #github Get account_item_id of unearned revenue
    }
  ]
}

# Issue invoice
invoice = Invoice.make_invoice(invoice_params)
puts'issued invoice'
# Get transaction id from invoice response
torihiki_id = invoice['invoice']['deal_id']
# Get the transaction row id for the above transaction id
renew_target_id = Torihiki.target_id(torihiki_id) See #github GET the details of the transaction associated with torihiki_id and get the transaction line id from it
Get account ID (sales) at #+ update
uriagedaka_id = AccountItem.account_item_id('Sales') #see github

# Transaction id Num times + update using transaction line id
num.times do
  When #count is 1 + update amount is changed to 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)
#+ set update parameters
  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
      }
    ]
  }
  #Transaction id, with parameters + Create update
  Koushin.post_koushin(torihiki_id,koushin_params)
  puts "Updated #{date}"
  #Get the month of the next month
  month = add_month(month)
  If #month is January, add 1 AD
  year += 1 if month == 1
  count += 1
end

Try running it locally.

Screenshots 2020-07-15 20.01.48.png

The processing seems to have run properly. The execution time is about 5 seconds (a little long…) Let’s look at accounting freee.

Screenshot 2020-07-15 19.54.43.png

You can issue an invoice to CFO Corporation! Both the amount and the consumption tax amount are included properly. Screenshots 2020-07-15 22.06.04.png Next, let’s look at transactions.

Screenshot 2020-07-15 19.53.04.png The price after renewal is 0 yen!

 Screenshot 2020-07-15 19.52.21.png

The renewal date also includes the last day of 12 months including the end of the issue month.

Future tasks

I would like to improve it so that I can respond flexibly to what to do with the bill issued at the end of the month, to update from the next month after confirming the transfer. Also, we will be able to import each invoice parameter and update count with csv. Also, the code is not beautiful…lol

Daily devotion