导入
列出费用类别并创建一项费用
了解费用类别以及如何使用 FreshBooks API 创建费用。
概述
费用相关的接口需要 user:expenses:read 和 user:expenses:write 范围权限才能执行操作。本课程将讨论以下两个接口:
- 获取费用分类列表:
{base_url}/accounting/account/{ACCOUNT_ID}/expenses/categories - 创建费用:
{base_url}/accounting/account/{ACCOUNT_ID}/expenses/expenses
获取费用分类列表
FreshBooks 提供了一些默认的分类和子分类,用于对费用进行分组,使追踪更加便捷。
本节将介绍如何获取所有可用的默认费用分类列表。我们使用以下接口来获取费用分类信息:
https://api.freshbooks.com/accounting/account/{ACCOUNT_ID}/expenses/categories
请求参数
该接口不接受任何请求参数。但可以通过 include[] 添加查询参数。使用 include 的语法如下:
1/expenses/categories?include[]=<VALUE>
include 可以传入两个值,分别是:
expense_usage_all_time:返回该分类在全部时间内的费用使用情况。expense_usage_this_year:返回该分类在本年度的费用使用情况。
1import requests 2import json 3 4url = "https://api.freshbooks.com/accounting/account/{{ACCOUNT_ID}}/expenses/categories" 5 6payload = {} 7headers = { 8 'Content-Type': 'application/json', 9 'Authorization': 'Bearer {{AUTH_CODE}}' 10} 11 12response = requests.request("GET", url, headers=headers, data=payload) 13if response.status_code != 200: 14 print("产生以下错误") 15 16print(json.dumps(response.json(), indent=4))
让我们分析上述代码中的关键行:
- 第4行:定义获取费用分类列表的URL。
- 第6行:此调用中
payload对象为空。 - 第12行:发起 GET 请求。
- 第16行:打印响应内容。
响应结果
上述代码成功执行后,返回 categories 数组,其中包含每个分类的详细信息。以下是部分响应字段说明:
| 响应字段 | 说明 |
|---|---|
| category | 分类名称。 |
| categoryid | 该分类的唯一标识ID。 |
| is_editable | 表示该分类是否可编辑,值为 "true" 或 "false"。 |
| vis_state | 分类状态:"0" 表示启用,"1" 表示已删除。 |
创建费用
本节将演示如何为特定分类创建一笔费用。使用的接口为:
https://api.freshbooks.com/accounting/account/{ACCOUNT_ID}/expenses/expenses
请求参数
HTTP POST 请求的 payload 对象中包含一个 expense 对象。以下是重要字段说明:
| 参数名 | 类型 | 必填/可选 | 说明 |
|---|---|---|---|
| has_receipt | 布尔值 | 可选 | 表示是否附带收据,值为 true 或 false。 |
| amount | 对象 | 必填 | 费用金额,包含 amount(金额,字符串)和 code(货币代码)。 |
| notes | 字符串 | 可选 | 添加关于该费用的备注。 |
| vendor | 字符串 | 可选 | 供应商名称。 |
| date | 字符串(格式:YYYY-MM-DD) | 必填 | 费用发生日期。 |
| staffid | 整数 | 必填 | 关联员工的ID(如适用)。 |
| categoryid / category_name | 字符串 | 必填 | 指定关联的费用分类ID或名称。 |
下面使用上表中的参数创建一笔费用。执行以下代码后,请记下响应中返回的费用 ID,后续课程会用到。
1import requests 2import json 3from datetime import date 4 5url = "https://api.freshbooks.com/accounting/account/{{ACCOUNT_ID}}/expenses/expenses" 6 7payload = json.dumps({ 8 "expense": { 9 "has_receipt": False, 10 "amount": { 11 "amount": "40.00", 12 "code": "USD" 13 }, 14 "notes": "购买了3件样品", 15 "vendor": "John Doe", 16 "date": str(date.today()), 17 "staffid": 1, 18 "category_name": "广告" 19 } 20}) 21 22headers = { 23 'Content-Type': 'application/json', 24 'Authorization': 'Bearer {{AUTH_CODE}}' 25} 26 27response = requests.request("POST", url, headers=headers, data=payload) 28if response.status_code != 200: 29 print("产生以下错误") 30 31print(json.dumps(response.json(), indent=4))
让我们分析上述代码中的关键行:
- 第5行:定义创建费用的URL。
- 第7–20行:定义
payload对象,其中包含expense子对象。 - 第26行:发起 POST 请求。
- 第30行:打印响应内容。
响应结果
上述代码返回一个 expense 对象,包含该费用的所有相关信息。以下是部分响应字段说明:
| 响应字段 | 说明 |
|---|---|
| accounting_systemid | 系统内唯一的标识ID。 |
| amount | 包含请求中指定的费用金额的对象。 |
| categoryid | 请求中指定的分类ID。 |
| id | 与该费用关联的唯一标识符。 |
| vis_state | 表示该费用是否处于启用状态或已被删除。 |