You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过QuickBooks API获取完整的按产品/服务明细销售报告

问题

我用Python代码尝试获取QuickBooks的「按产品/服务明细销售」报告数据时遇到几个问题:

  1. 官方文档里的报告实体是SalesByProduct,但实际调用的端点是ItemSales,这让我很困惑。
  2. 需要修改代码,获取报告的所有默认指标:
    • 产品/服务
    • 日期
    • 交易类型
    • 编号
    • 客户名称
    • 备注/描述
    • 数量
    • 单价
    • 金额
    • 余额
  3. 当前代码只返回96条数据,但UI里显示有2315行,想知道报表API是否有分页机制,该怎么实现。
  4. 我在UI里查看报告时没有设置任何分组,要看到行级数据是不是不该设置summarize_column_by属性?

当前代码如下:

def fetch_sales_by_product(access_token):

  url = f'https://quickbooks.api.intuit.com/v3/company/11111111111/reports/ItemSales' 
  headers = {
    'Authorization': f'Bearer {access_token}',
    'Accept': 'application/json'
  }

  params = {
    'start_date': '2021-01-01',
    'end_date': '2024-04-01',
    'summarize_column_by': 'ProductsAndServices'
  }

  all_data = []
  counter = 1

  while True:
    response = requests.get(url, headers=headers, params=params)
    print(f"{response.status_code=}")
    if response.status_code != 200:
      raise Exception(f"Failed to fetch report: {response.text}" )
    data = response.json()
    all_data.extend(data['Rows']['Row'])
    counter += 1

  return all_data

解决方案

端点澄清

QuickBooks UI中的「按产品/服务明细销售」报告,对应API的端点就是ItemSales。文档中提到的SalesByProduct是报告实体的名称,实际调用时使用ItemSales是正确的,无需困惑。

获取全部指标的参数调整

  • 移除summarize_column_by参数:既然不需要分组查看行级数据,这个参数会按产品/服务聚合数据,必须删掉才能拿到明细行。
  • 指定columns参数:明确列出需要的所有指标对应的API列名,确保返回完整数据:
    columns=Item,Date,TransactionType,DocNumber,Customer,Description,Quantity,Rate,Amount,Balance
    
    列名与需求指标的对应关系:
    • Item → 产品/服务
    • Date → 日期
    • TransactionType → 交易类型
    • DocNumber → 编号
    • Customer → 客户名称
    • Description → 备注/描述
    • Quantity → 数量
    • Rate → 单价
    • Amount → 金额
    • Balance → 余额

分页实现

报表API默认分页返回数据,每次返回条数有限。实现分页只需:

  1. 在请求参数中加入page,初始值为1,每次循环递增。
  2. 当返回的Rows.Row为空,或者已获取的数据量达到响应中的totalCount时,终止循环。

修改后的完整代码

import requests

def fetch_sales_by_product(access_token):
    company_id = '11111111111'
    url = f'https://quickbooks.api.intuit.com/v3/company/{company_id}/reports/ItemSales' 
    headers = {
        'Authorization': f'Bearer {access_token}',
        'Accept': 'application/json'
    }

    all_data = []
    page = 1

    while True:
        params = {
            'start_date': '2021-01-01',
            'end_date': '2024-04-01',
            'columns': 'Item,Date,TransactionType,DocNumber,Customer,Description,Quantity,Rate,Amount,Balance',
            'page': page
        }

        response = requests.get(url, headers=headers, params=params)
        print(f"{response.status_code=}, 当前页码: {page}")
        if response.status_code != 200:
            raise Exception(f"获取报告失败: {response.text}" )
        
        data = response.json()
        rows = data.get('Rows', {}).get('Row', [])
        if not rows:
            break
        
        all_data.extend(rows)
        
        # 按总条数判断是否结束分页
        total_count = data.get('totalCount', 0)
        if len(all_data) >= total_count:
            break
        
        page += 1

    return all_data

内容的提问来源于stack exchange,提问作者mongotop

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 19:52:44