richwestcoast / sage-one-php
用于Sage One API的PHP客户端
Requires
- php: ^7.0
- darrynten/any-cache: ^1.0
- guzzlehttp/guzzle: ^7.0.1
Requires (Dev)
- codacy/coverage: dev-master
- codeclimate/php-test-reporter: dev-master
- internations/http-mock: ^0.8.1
- mockery/mockery: dev-master
- phpunit/phpunit: ~5.0
- squizlabs/php_codesniffer: ^3.0
This package is auto-updated.
Last update: 2024-09-29 03:41:53 UTC
README
SageOne API的PHP客户端
这是一个100%单元测试和(主要)功能齐全的非官方SageOne PHP客户端
"简单的在线会计和工资软件"
composer require darrynten/sage-one-php
PHP 7.0+
基本使用
一些模型的方法未实现,因为它们与其他类似模型不一致,这些方法将抛出LibraryException异常,并显示方法占位符的位置。
如果您需要这些方法,请添加它们并更新测试。
定义
待办事项
功能
这是项目的初步轮廓,仍在进行中。
请在提交功能拉取请求时,在此README中勾选每个部分的复选框。
基本的ORM风格映射
相关模型将自动加载,并且在可能的情况下,都是可查询、可修改和可持久化的。
我相信这将在某个时候因为递归问题而出现问题!
一些示例
$account = new Account($config); // get $account->all(); // fetches ALL $account->get($id); // fetches that ID // If model supports some query parameters, we can pass it $company = new Company($config); $company->all(['includeStatus' => true]); // Currently get() does not support any query parameters but this might be required in future // related models echo $account->category->id; // dates echo $account->defaultTaxType->modified->format('Y-m-d'); // assign $account->name = 'New Name'; // save, delete $account->save(); // incomplete $account->category->save(); // saving a child does not save the parent and vice-versa $account->delete();
应用程序基础
- 使用Guzzle进行通信(我认为我们应该替换?)
- 该库具有100%的测试覆盖率
- 该库支持框架无关的缓存,因此您不必担心使用此包的包将最终进入哪个框架。
客户端尚未100%完成,仍在进行中,详细信息如下。
文档
有100多个API端点,初始重点仅关注其中的一些。
最终将完全模仿网站上的文档。 https://accounting.sageone.co.za/api/1.1.2
每个部分都必须有一个简短的解释和一些示例代码,就像API文档页面上的那样。
勾选的部分已完成。
注意
API调用大多数非常通用,因此有一个基础模型,所有其他模型都扩展自该模型,覆盖以下功能
- GET Model/Get
- GET Model/Get/{id}
- DELETE Model/Delete/{id}
- POST Model/Save ** 不完整 **
这意味着可以很容易地添加仅使用这些调用(或它们的任意组合)的新模型,因为构建基本模型有一个非常简单的“配方”。
因此,我们只需关注难点。
请注意,项目正在快速发展
这可能会过时
如果它过时了,请修复它并更新此文档
最佳查看位置是示例模型
基本模型模板
该链接中有一个表格,看起来像这样
Name | Type | Additional Information
-------------------------------------------------------------------
Name | string | None.
Category | AccountCategory | None.
Balance | decimal | Read Only / System Generated
ReportingGroupId | nullable integer | None.
我们将使用该模板进行此示例(示例中的docblocks已排除,但必需)
/** * The name of the class is the `modelName=` value from the URL */ class Account extends BaseModel // The name of the endpoint (same as filename), protected protected $endpoint = 'Account'; /** * Field definitions * * Used by the base class to decide what gets submitted in a save call, * validation, etc * * All must include a type, whether or not it's nullable, and whether or * not it's readonly, or default, required, min, max, or regex * * - nullable is `true` if the word 'nullable' is in the 'type' column * - readonly is `true` if the word 'Read-Only/System Generated' is in the Additional Info column otherwise it is `false` * - Type has the following rules * - `date` becomes "DateTime" * - `nullable` is removed, i.e. "nullable integer" is only "integer" * - Multiword linked terms are concatenated, eg: * - "Account Category" becomes "AccountCategory" * - "Tax Type" becomes "TaxType" * - `min` / `max` always come together * - `default` is when it's indicated in the docs * - `regex` is generally used with email address fields * - `enum` is for enumerated lists * - `optional` is true when this field can be omitted in SageOne response * - Example is Company's model all() method * By default when we execute all() it is the same as all(['includeStatus' = false]) * So `status` field is not returned in response * * Details on writable properties for Account: * https://accounting.sageone.co.za/api/1.1.2/Help/ResourceModel?modelName=Account * @var array $fields */ protected $fields = [ 'id' => [ 'type' => 'integer', 'nullable' => false, 'readonly' => true, ], 'name' => [ 'type' => 'string', 'nullable' => false, 'readonly' => false, 'required' => true, ], 'enum' => [ 'type' => 'integer', 'nullable' => false, 'readonly' => true, // $enumList would need to be a property of this model 'enum' => 'enumList', ], 'category' => [ 'type' => 'AccountCategory', 'nullable' => false, 'readonly' => false, 'min' => 0, 'max' => 100, ], 'reportingGroupId' => [ 'type' => 'integer', 'nullable' => true, 'readonly' => false, 'regex' => '/someregex/', ], 'isTaxLocked' => [ 'type' => 'boolean', 'nullable' => false, 'readonly' => true, ], 'status' => [ 'type' => 'integer', 'nullable' => false, 'readonly' => true, 'optional' => true, ], // etc etc etc ]; /** * Features supported by the endpoint * * These features enable and disable the CRUD calls based on what is * supported by the SageOne API * * Most models use at least one of these features, with a fair amount * using all the functionality. * * @var array $features */ protected $features = [ 'all' => true, 'get' => true, 'save' => true, 'delete' => true, ]; /** * Features HTTP methods * Not all models follow same conventions like GET for all() * Example AccountBalance all() requires POST method * or SupplierStatement get() requires POST method * @var array $featureMethods */ protected $featureMethods = [ 'all' => 'GET', 'get' => 'GET', 'save' => 'POST', 'delete' => 'DELETE' ]; /** * Specifies what get() returns * 'this' means current class * any other type must exist under src/Models/ * 'collection' is true when get() returns collection (very rare case, but SageOne's API works this way) * @var array $featureGetReturns */ protected $featureGetReturns = [ 'type' => 'this', 'collection' => false ]; // Construct (if you need to modify construction) public function __construct(array $config) { parent::__construct($config); } // Add methods for non-standard calls, like: // GET Account/GetAccountsByCategoryId/{id} public function getAccountsByCategoryId($id) { // etc ... } }
遵循该模板可以快速为项目创建模型。
还有一个示例测试(ExampleModelTest.php)和一个示例模拟文件夹,以帮助您快速入门。
大部分的重型测试由BaseModelTest类处理,您可以通过查看示例测试来了解约定。对于大多数事情,这使得测试和获得良好的防御性覆盖率变得非常简单。
目前,许多测试是对SageOne文档中提供的模拟进行的。它们与实际响应不一定一致,因此将来将用它们替换。
请注意,初始交付仅包括这些模型
带星号标记的模型是纯CRUD模型
- 基础
- 异常处理
- CRUD
- 保存调用
- 真实的CRUD响应模拟
- 分页
- 速率限制
- 模型
- 账户
- 账户余额
- 账户类别 *
- 账户备注 *
- 会计任务重复 *
- 账户备注附件
- 账户期初余额 *
- 账户付款 *
- 账户收款 *
- 附加项目价格 *
- 分析类别
- 分析类型
- 资产备注 *
- 公司
- 公司实体类型 *
- 公司备注
- 货币 *
- 汇率
- 供应商 *
- 供应商附加联系详情
- 供应商调整
- 供应商账龄
- 供应商银行详情 *
- 供应商类别 *
- 供应商发票
- 供应商发票附件(部分,未实现validate()函数)
- 供应商备注 *
- 供应商备注附件(部分,未实现validate()函数)
- 供应商期初余额 *
- 供应商付款
- 供应商采购历史
- 供应商退货
- 供应商退货附件(部分,未实现validate()函数)
- 供应商对账单 *
- 供应商交易列表
- 税种 *
- 账户
以及任何未列出的相关模型,所以如果ExampleModel引用了ExampleCategory但该类别未在上列中,也必须进行处理
==== 初始交付结束 ====
交付成果
- 100% 测试覆盖率
- 全面、详尽、冗长且具有防御性的单元测试
- 如果模型在
tests/mocks
目录中没有模拟,则提供模拟(可以从文件夹中现有名称推断出约定)
未来的路线图,按需提供
请随时为以下任何内容提交PR :)
- 会计事件
- 会计备注
- 会计任务
- 会计任务重复
- 附加价格列表
- 分配
- 资产
- 资产类别
- 资产位置
- 附件
- 银行账户(部分)
- 银行账户类别(部分)
- 银行账户备注
- 银行账户备注附件
- 银行账户期初余额
- 银行账户交易列表
- 银行导入映射
- 银行对账单交易
- 银行交易
- 银行交易附件
- BAS报告
- 预算
- 现金流动
- 核心事件
- 核心令牌
- CRM活动
- CRM活动类别
- 货币
- 客户
- 客户附加联系详情
- 客户调整
- 客户账龄
- 客户类别
- 客户备注
- 客户备注附件
- 客户期初余额
- 客户收款
- 客户退货
- 客户退货附件
- 客户销售历史
- 客户对账单
- 客户交易列表
- 客户坏账
- 客户区域
- 日期格式
- 详细账务交易
- 开发者数据
- 文档文件附件
- 文档抬头备注
- 文档历史
- 文档消息
- 文档自定义字段
- 电子邮件签名模板
- 电子邮件模板占位符
- 最终账目
- 财务年度
- 收入与支出
- 项目
- 项目调整
- 项目附件
- 项目类别
- 项目移动
- 项目备注
- 项目备注附件
- 项目期初余额
- 项目报告组
- 日记账分录
- 本地化
- 登录
- 逾期客户文档
- 逾期供应商文档
- 价格列表报告
- 处理银行和信用卡映射
- 采购订单
- 采购订单附件
- 按项目采购
- 报价
- 报价附件
- 周期性发票
- 报告组
- 按项目销售
- 按销售代表销售
- 销售代表
- 销售代表备注
- 调度频率
- 秘书公司角色
- 秘书股本类别
- 秘书股东
- 秘书利益相关者
- 支持登录审计
- 承担余额
- 税务发票
- 税务发票附件
- 税务期间
- 时间跟踪客户
- 时间跟踪费用
- 时间跟踪项目
- 时间跟踪任务
- 时间跟踪工时表
- 时间跟踪用户
- 待办事项列表
- 按未偿还余额最高的客户
- 按销售额最高的客户
- 最受欢迎的采购项目
- 最受欢迎的销项目
- 按库存价值最高的畅销商品
- 按未偿还余额最高的供应商
- 按采购量最高的供应商
- 试算平衡表
- 试算平衡表导出映射
- 用户定义字段
- VAT201报告
缓存
请求限制
所有Sage One公司每天有5000次API请求的限制。对于列表方法,无论发送的参数如何,最多返回100个结果。
因此,其中一些可以通过缓存受益。默认情况下,所有缓存都应关闭,并且仅在显式设置时使用。
尚未实施缓存,但已提供支持。
详细信息
这些通过darrynten/any-cache
包运行,不需要额外的配置。请确保任何包含缓存的特性都将其设置为可选,并最初设置为false
,以避免意外行为。
速率限制和排队
待办事项
贡献和测试
该项目目前有100%的测试覆盖率,请确保在贡献时更新测试。更多信息请参阅CONTRIBUTING.md。
我们非常乐意得到帮助,以建立良好的文档,如果您有任何想法,请与我们联系。