Skip to content

Commit

Permalink
✨ Add payments resource
Browse files Browse the repository at this point in the history
  • Loading branch information
amcintosh committed Nov 20, 2021
1 parent 2ee2415 commit 3dac601
Show file tree
Hide file tree
Showing 9 changed files with 329 additions and 11 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@

Basic Invoicing workflow functionality

- Supports clients, invoices, line items, taxes
- Supports clients, invoices, line items, payments, taxes
12 changes: 12 additions & 0 deletions src/FreshBooksClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
use amcintosh\FreshBooks\Model\ClientList;
use amcintosh\FreshBooks\Model\Invoice;
use amcintosh\FreshBooks\Model\InvoiceList;
use amcintosh\FreshBooks\Model\Payment;
use amcintosh\FreshBooks\Model\PaymentList;
use amcintosh\FreshBooks\Model\Tax;
use amcintosh\FreshBooks\Model\TaxList;
use amcintosh\FreshBooks\Resource\AccountingResource;
Expand Down Expand Up @@ -88,6 +90,16 @@ public function invoices(): AccountingResource
return new AccountingResource($this->httpClient, 'invoices/invoices', Invoice::class, InvoiceList::class);
}

/**
* FreshBooks payments resource with calls to get, list, create, update, delete.
*
* @return AccountingResource
*/
public function payments(): AccountingResource
{
return new AccountingResource($this->httpClient, 'payments/payments', Payment::class, PaymentList::class);
}

/**
* FreshBooks taxes resource with calls to get, list, create, update, delete.
*
Expand Down
10 changes: 8 additions & 2 deletions src/Model/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -252,13 +252,13 @@ class Client extends DataTransferObject implements DataModel
public ?int $visState;

/**
* Get the client data as an array to POST or PUT to FreshBooks, removing any read-only fields.
* Get the data as an array to POST or PUT to FreshBooks, removing any read-only fields.
*
* @return array
*/
public function getContent(): array
{
return $this
$data = $this
->except('id')
->except('accountingSystemId')
->except('lastActivity')
Expand All @@ -267,5 +267,11 @@ public function getContent(): array
->except('userId')
->except('visState')
->toArray();
foreach ($data as $key => $value) {
if (is_null($value)) {
unset($data[$key]);
}
}
return $data;
}
}
2 changes: 1 addition & 1 deletion src/Model/Invoice.php
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,7 @@ class Invoice extends DataTransferObject implements DataModel
public ?int $visState;

/**
* Get the invoice data as an array to POST or PUT to FreshBooks, removing any read-only fields.
* Get the data as an array to POST or PUT to FreshBooks, removing any read-only fields.
*
* @return array
*/
Expand Down
180 changes: 180 additions & 0 deletions src/Model/Payment.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
<?php

declare(strict_types=1);

namespace amcintosh\FreshBooks\Model;

use DateTime;
use DateTimeImmutable;
use Spatie\DataTransferObject\Attributes\CastWith;
use Spatie\DataTransferObject\Attributes\MapFrom;
use Spatie\DataTransferObject\Attributes\MapTo;
use Spatie\DataTransferObject\Caster;
use Spatie\DataTransferObject\DataTransferObject;
use amcintosh\FreshBooks\Model\DataModel;
use amcintosh\FreshBooks\Model\Money;
use amcintosh\FreshBooks\Model\Caster\AccountingDateTimeImmutableCaster;
use amcintosh\FreshBooks\Model\Caster\DateCaster;
use amcintosh\FreshBooks\Model\Caster\MoneyCaster;

/**
* Payments are a record of the payments made on invoices.
*
* @package amcintosh\FreshBooks\Model
* @link https://www.freshbooks.com/api/payments
*/
class Payment extends DataTransferObject implements DataModel
{
public const RESPONSE_FIELD = 'payment';

/**
* @var int The unique id (across this business) for the payment.
*/
public ?int $id;

/**
* @var int Duplicate of id.
*
* _Note_: The API returns this as `logid`.
*/
#[MapFrom('logid')]
public ?int $paymentId;

/**
* @var string Unique identifier of account the payment exists on.
*/
#[MapFrom('accounting_systemid')]
public ?string $accountingSystemId;

/**
* @var Money The amount of the payment.
*
* Money object containing amount and currency code.
*/
#[CastWith(MoneyCaster::class)]
public ?Money $amount;

#[MapFrom('bulk_paymentid')]
#[MapTo('bulk_paymentid')]
public ?int $bulkPaymentId;

/**
* @var int Id of client who made the payment.
*/
#[MapFrom('clientid')]
public ?int $clientId;

/**
* @var int The id of a related credit resource.
*/
#[MapFrom('creditid')]
#[MapTo('creditid')]
public ?int $creditId;

/**
* @var DateTime Date the payment was made.
*
* The API returns this in YYYY-MM-DD format. It is converted to a DateTime.
*/
#[MapFrom('date')]
#[CastWith(DateCaster::class)]
public ?DateTime $date;


/**
* @var bool If the payment was converted from a Credit on a Client's account.
*/
#[MapFrom('from_credit')]
#[MapTo('from_credit')]
public ?bool $fromCredit;

/**
* @var string The payment processor (gateway) used to make the payment, if any.
*
* Eg. "stripe"
*/
public ?string $gateway;

/**
* @var int The id of a related Invoice resource.
*/
#[MapFrom('invoiceid')]
#[MapTo('invoiceid')]
public ?int $invoiceId;

/**
* @var string Notes on payment, often used for credit card reference number.
*
* **Do not store actual credit card numbers here.**
*/
public ?string $note;

#[MapFrom('orderid')]
#[MapTo('orderid')]
public ?int $orderId;

/**
* @var int Id of related overpayment Credit if relevant.
*/
#[MapFrom('overpaymentid')]
public ?int $overpaymentId;

/**
* @var bool Whether to send the client a notification of this payment.
*/
#[MapFrom('send_client_notification')]
#[MapTo('send_client_notification')]
public ?bool $sendClientNotification;

/**
* @var string Type of payment made.
*
* Eg. “Check”, “Credit”, “Cash”
*/
public ?string $type;

/**
* @var DateTimeImmutable The time of last modification.
*
* _Note:_ The API returns this data in "US/Eastern", but it is converted here to UTC.
*/
#[CastWith(AccountingDateTimeImmutableCaster::class)]
public ?DateTimeImmutable $updated;

/**
* @var int The visibility state: active, deleted, or archived
*
* See [FreshBooks API - Active and Deleted Objects](https://www.freshbooks.com/api/active_deleted)
*/
#[MapFrom('vis_state')]
public ?int $visState;

/**
* Get the data as an array to POST or PUT to FreshBooks, removing any read-only fields.
*
* @return array
*/
public function getContent(): array
{
$data = $this
->except('id')
->except('accountingSystemId')
->except('paymentId')
->except('clientId')
->except('date')
->except('gateway')
->except('overpaymentId')
->except('updated')
->except('visState')
->toArray();
if (isset($this->date)) {
$data['date'] = $this->date->format('Y-m-d');
}
foreach ($data as $key => $value) {
if (is_null($value)) {
unset($data[$key]);
}
}
return $data;
}
}
34 changes: 34 additions & 0 deletions src/Model/PaymentList.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

declare(strict_types=1);

namespace amcintosh\FreshBooks\Model;

use Spatie\DataTransferObject\Attributes\CastWith;
use Spatie\DataTransferObject\Attributes\MapFrom;
use Spatie\DataTransferObject\Casters\ArrayCaster;
use Spatie\DataTransferObject\DataTransferObject;
use amcintosh\FreshBooks\Model\Payment;

/**
* Results of Payments list call containing list of payments and pagination data.
*
* @package amcintosh\FreshBooks\Model
* @link https://www.freshbooks.com/api/payments
*/
class PaymentList extends DataTransferObject
{
public const RESPONSE_FIELD = 'payments';

public int $page;

public int $pages;

#[MapFrom('per_page')]
public int $perPage;

public int $total;

#[CastWith(ArrayCaster::class, itemType: Payment::class)]
public array $payments;
}
10 changes: 8 additions & 2 deletions src/Model/Tax.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,17 +64,23 @@ class Tax extends DataTransferObject implements DataModel
public ?DateTimeImmutable $updated;

/**
* Get the client data as an array to POST or PUT to FreshBooks, removing any read-only fields.
* Get the data as an array to POST or PUT to FreshBooks, removing any read-only fields.
*
* @return array
*/
public function getContent(): array
{
return $this
$data = $this
->except('id')
->except('accountingSystemId')
->except('taxId')
->except('updated')
->toArray();
foreach ($data as $key => $value) {
if (is_null($value)) {
unset($data[$key]);
}
}
return $data;
}
}
6 changes: 1 addition & 5 deletions tests/Model/ClientTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,6 @@ public function testClientGetContent(): void
$client = new Client($clientData['client']);
$this->assertSame([
'bus_phone' => '416-867-5309',
'company_industry' => null,
'company_size' => null,
'currency_code' => 'CAD',
'email' => 'gordon.shumway@AmericanCyanamid.com',
'fax' => '416-444-4444',
Expand All @@ -156,9 +154,7 @@ public function testClientGetContent(): void
's_country' => '',
's_province' => '',
's_street' => '',
's_street2' => '',
'vat_name' => null,
'vat_number' => null
's_street2' => ''
], $client->getContent());
}
}
Loading

0 comments on commit 3dac601

Please sign in to comment.