Version 5.0.0 beta 1
This commit is contained in:
1 parent
25ddeb65d6
commit
15c7beabc5
6736 files changed
+627902
-497943
No files matched your search
@@ -12,140 +12,148 @@
|
||||
namespace IPS\nexus\Invoice;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use BadMethodCallException;
|
||||
use DomainException;
|
||||
use IPS\File;
|
||||
use IPS\GeoLocation;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Math\Number;
|
||||
use IPS\Member;
|
||||
use IPS\nexus\Coupon;
|
||||
use IPS\nexus\Customer;
|
||||
use IPS\nexus\Invoice;
|
||||
use IPS\nexus\Money;
|
||||
use IPS\nexus\Purchase;
|
||||
use IPS\nexus\Tax;
|
||||
use IPS\Settings;
|
||||
use IPS\Theme;
|
||||
use function defined;
|
||||
use function gettype;
|
||||
use function in_array;
|
||||
use function is_int;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoice Abstract Item Interface
|
||||
*/
|
||||
abstract class _Item
|
||||
abstract class Item
|
||||
{
|
||||
/**
|
||||
* @brief Can use coupons?
|
||||
*/
|
||||
public static $canUseCoupons = TRUE;
|
||||
public static bool $canUseCoupons = TRUE;
|
||||
|
||||
/**
|
||||
* @brief Can use account credit?
|
||||
*/
|
||||
public static $canUseAccountCredit = TRUE;
|
||||
public static bool $canUseAccountCredit = TRUE;
|
||||
|
||||
/**
|
||||
* @brief Can you buy more than one of this item?
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public static bool $canChangeQuantity = false;
|
||||
|
||||
/**
|
||||
* @brief Icon
|
||||
*/
|
||||
public static string $icon = '';
|
||||
|
||||
/**
|
||||
* @brief string Name
|
||||
*/
|
||||
public $name;
|
||||
public string $name;
|
||||
|
||||
/**
|
||||
* @brief int Quantity
|
||||
*/
|
||||
public $quantity = 1;
|
||||
public int $quantity = 1;
|
||||
|
||||
/**
|
||||
* @brief \IPS\nexus\Money Price
|
||||
*/
|
||||
public $price;
|
||||
public Money $price;
|
||||
|
||||
/**
|
||||
* @brief int|NULL ID
|
||||
*/
|
||||
public $id;
|
||||
public ?int $id;
|
||||
|
||||
/**
|
||||
* @brief \IPS\nexus\Tax Tax Class
|
||||
*/
|
||||
public $tax;
|
||||
public ?Tax $tax = null;
|
||||
|
||||
/**
|
||||
* @brief Payment Methods IDs
|
||||
*/
|
||||
public $paymentMethodIds;
|
||||
public ?array $paymentMethodIds = null;
|
||||
|
||||
/**
|
||||
* @brief Key/Value array of extra details to display on the invoice
|
||||
*/
|
||||
public $details = array();
|
||||
public array $details = array();
|
||||
|
||||
/**
|
||||
* @brief Key/Value array of extra details to store on the purchase
|
||||
*/
|
||||
public $purchaseDetails = array();
|
||||
public array $purchaseDetails = array();
|
||||
|
||||
/**
|
||||
* @brief Physical?
|
||||
*/
|
||||
public $physical = FALSE;
|
||||
|
||||
/**
|
||||
* @brief Shipping Methods IDs
|
||||
*/
|
||||
public $shippingMethodIds;
|
||||
|
||||
/**
|
||||
* @brief Chosen Shipping Methods ID
|
||||
*/
|
||||
public $chosenShippingMethodId;
|
||||
|
||||
/**
|
||||
* @brief Weight
|
||||
*/
|
||||
public $weight;
|
||||
|
||||
/**
|
||||
* @brief Length
|
||||
*/
|
||||
public $length;
|
||||
|
||||
/**
|
||||
* @brief Width
|
||||
*/
|
||||
public $width;
|
||||
|
||||
/**
|
||||
* @brief Height
|
||||
*/
|
||||
public $height;
|
||||
|
||||
/**
|
||||
* @brief Pay To member
|
||||
*/
|
||||
public $payTo;
|
||||
public ?Member $payTo = null;
|
||||
|
||||
/**
|
||||
* @brief Application
|
||||
*/
|
||||
public static $application;
|
||||
public static string $application = '';
|
||||
|
||||
/**
|
||||
* @brief Commission percentage
|
||||
*/
|
||||
public $commission = 0;
|
||||
public int $commission = 0;
|
||||
|
||||
/**
|
||||
* @brief Commission fee
|
||||
*/
|
||||
public $fee = 0;
|
||||
public int|Money $fee = 0;
|
||||
|
||||
/**
|
||||
* @brief Extra
|
||||
*/
|
||||
public $extra;
|
||||
public mixed $extra = null;
|
||||
|
||||
/**
|
||||
* @brief Group With Parent
|
||||
*/
|
||||
public $groupWithParent = FALSE;
|
||||
public bool $groupWithParent = FALSE;
|
||||
|
||||
/**
|
||||
* @brief Application key
|
||||
*/
|
||||
public ?string $appKey = NULL;
|
||||
|
||||
/**
|
||||
* @brief Type key
|
||||
*/
|
||||
public ?string $typeKey = NULL;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $name Name
|
||||
* @param \IPS\nexus\Money $price Price
|
||||
* @param string $name Name
|
||||
* @param Money $price Price
|
||||
* @return void
|
||||
*/
|
||||
public function __construct( $name, \IPS\nexus\Money $price )
|
||||
public function __construct(string $name, Money $price )
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->price = $price;
|
||||
@@ -157,53 +165,117 @@ abstract class _Item
|
||||
* @param string $k Property
|
||||
* @return mixed
|
||||
*/
|
||||
public function __get( $k )
|
||||
public function __get( string $k ) : mixed
|
||||
{
|
||||
$k = mb_substr( $k, 1 );
|
||||
return static::$$k;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to override the static property, if necessary
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function canUseAccountCredit() : bool
|
||||
{
|
||||
return static::$canUseAccountCredit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to override the static property, if necessary
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function canUseCoupons() : bool
|
||||
{
|
||||
return static::$canUseCoupons;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function canChangeQuantity() : bool
|
||||
{
|
||||
return static::$canChangeQuantity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the coupon can be applied to this item
|
||||
*
|
||||
* @param array|string $data
|
||||
* @param Invoice $invoice
|
||||
* @param Customer $customer
|
||||
* @return bool
|
||||
*/
|
||||
public function isValid( array|string $data, Invoice $invoice, Customer $customer ) : bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get line price without tax
|
||||
*
|
||||
* @return \IPS\nexus\Money
|
||||
* @return Money
|
||||
*/
|
||||
public function linePrice()
|
||||
public function linePrice() : Money
|
||||
{
|
||||
return new \IPS\nexus\Money( $this->price->amount->multiply( new \IPS\Math\Number("{$this->quantity}") ), $this->price->currency );
|
||||
return new Money( $this->price->amount->multiply( new Number("{$this->quantity}") ), $this->price->currency );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get tax rate
|
||||
*
|
||||
* @param \IPS\GeoLocation|NULL $location Location to use for tax rate or NULL to use specified billing address
|
||||
* @return \IPS\Math\Number
|
||||
* @param GeoLocation|NULL $location Location to use for tax rate or NULL to use specified billing address
|
||||
* @return Number
|
||||
*/
|
||||
public function taxRate( \IPS\GeoLocation $location = NULL )
|
||||
public function taxRate( ?GeoLocation $location = NULL ) : Number
|
||||
{
|
||||
return new \IPS\Math\Number( $this->tax ? $this->tax->rate( $location ) : '0' );
|
||||
return new Number( $this->tax ? $this->tax->rate( $location ) : '0' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get item price with tax
|
||||
*
|
||||
* @param \IPS\GeoLocation|NULL $location Location to use for tax rate or NULL to use specified billing address
|
||||
* @return \IPS\nexus\Money
|
||||
* @param GeoLocation|NULL $location Location to use for tax rate or NULL to use specified billing address
|
||||
* @return Money
|
||||
*/
|
||||
public function grossPrice( \IPS\GeoLocation $location = NULL )
|
||||
public function grossPrice( ?GeoLocation $location = NULL ) : Money
|
||||
{
|
||||
return new \IPS\nexus\Money( $this->price->amount->add( $this->price->amount->multiply( $this->taxRate( $location ) ) ), $this->price->currency );
|
||||
return new Money( $this->price->amount->add( $this->price->amount->multiply( $this->taxRate( $location ) ) ), $this->price->currency );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get line price with tax
|
||||
*
|
||||
* @param \IPS\GeoLocation|NULL $location Location to use for tax rate or NULL to use specified billing address
|
||||
* @return \IPS\nexus\Money
|
||||
* @param GeoLocation|NULL $location Location to use for tax rate or NULL to use specified billing address
|
||||
* @return Money
|
||||
*/
|
||||
public function grossLinePrice( \IPS\GeoLocation $location = NULL )
|
||||
public function grossLinePrice( ?GeoLocation $location = NULL ) : Money
|
||||
{
|
||||
return new \IPS\nexus\Money( $this->linePrice()->amount->add( $this->linePrice()->amount->multiply( $this->taxRate( $location ) ) ), $this->price->currency );
|
||||
return new Money( $this->linePrice()->amount->add( $this->linePrice()->amount->multiply( $this->taxRate( $location ) ) ), $this->price->currency );
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the details to be displayed on the invoice
|
||||
* Moved to a method so that custom items can add line items
|
||||
* that may not be custom fields
|
||||
*
|
||||
* @param string $location checkout|invoice|print
|
||||
* @return string
|
||||
*/
|
||||
public function detailsForDisplay( string $location ) : string
|
||||
{
|
||||
switch( $location )
|
||||
{
|
||||
case 'checkout':
|
||||
return Theme::i()->getTemplate( 'checkout', 'nexus', 'front' )->packageFields( $this );
|
||||
|
||||
case 'print':
|
||||
return Theme::i()->getTemplate( 'invoices', 'nexus', 'global' )->packageFields( $this );
|
||||
|
||||
default:
|
||||
return Theme::i()->getTemplate( 'clients', 'nexus', 'front' )->packageFields( $this );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -211,7 +283,7 @@ abstract class _Item
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function recipientAmounts()
|
||||
public function recipientAmounts() : array
|
||||
{
|
||||
$return = array();
|
||||
|
||||
@@ -221,19 +293,19 @@ abstract class _Item
|
||||
$currency = $linePrice->currency;
|
||||
|
||||
$commission = $this->price->amount->percentage( $this->commission );
|
||||
$lineComission = $commission->multiply( new \IPS\Math\Number("{$this->quantity}") );
|
||||
$lineComission = $commission->multiply( new Number("{$this->quantity}") );
|
||||
|
||||
$return['site_commission_unit'] = new \IPS\nexus\Money( $commission, $currency );
|
||||
$return['site_commission_line'] = new \IPS\nexus\Money( $lineComission, $currency );
|
||||
$return['site_commission_unit'] = new Money( $commission, $currency );
|
||||
$return['site_commission_line'] = new Money( $lineComission, $currency );
|
||||
|
||||
$return['recipient_unit'] = new \IPS\nexus\Money( $this->price->amount->subtract( $return['site_commission_unit']->amount ), $currency );
|
||||
$return['recipient_line'] = new \IPS\nexus\Money( $linePrice->amount->subtract( $return['site_commission_line']->amount ), $currency );
|
||||
$return['recipient_unit'] = new Money( $this->price->amount->subtract( $return['site_commission_unit']->amount ), $currency );
|
||||
$return['recipient_line'] = new Money( $linePrice->amount->subtract( $return['site_commission_line']->amount ), $currency );
|
||||
|
||||
$fee = $this->fee ? $this->fee->amount : new \IPS\Math\Number('0');
|
||||
$fee = $this->fee ? $this->fee->amount : new Number('0');
|
||||
$siteTotal = $return['site_commission_line']->amount->add( $fee );
|
||||
$recipientTotal = $linePrice->amount->subtract( $siteTotal );
|
||||
$return['site_total'] = new \IPS\nexus\Money( $siteTotal, $currency );
|
||||
$return['recipient_final'] = new \IPS\nexus\Money( $recipientTotal->isGreaterThanZero() ? $recipientTotal : 0, $currency );
|
||||
$return['site_total'] = new Money( $siteTotal, $currency );
|
||||
$return['recipient_final'] = new Money( $recipientTotal->isGreaterThanZero() ? $recipientTotal : 0, $currency );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -246,14 +318,14 @@ abstract class _Item
|
||||
/**
|
||||
* Get amount for recipient (on line price)
|
||||
*
|
||||
* @return \IPS\nexus\Money
|
||||
* @throws \BadMethodCallException
|
||||
* @return Money
|
||||
* @throws BadMethodCallException
|
||||
*/
|
||||
public function amountForRecipient()
|
||||
public function amountForRecipient() : Money
|
||||
{
|
||||
if ( !$this->payTo )
|
||||
{
|
||||
throw new \BadMethodCallException;
|
||||
throw new BadMethodCallException;
|
||||
}
|
||||
|
||||
$recipientAmount = $this->recipientAmounts();
|
||||
@@ -263,9 +335,9 @@ abstract class _Item
|
||||
/**
|
||||
* Image
|
||||
*
|
||||
* @return |IPS\File|NULL
|
||||
* @return File|null
|
||||
*/
|
||||
public function image()
|
||||
public function image(): File|null
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
@@ -273,10 +345,10 @@ abstract class _Item
|
||||
/**
|
||||
* On Paid
|
||||
*
|
||||
* @param \IPS\nexus\Invoice $invoice The invoice
|
||||
* @return void
|
||||
* @param Invoice $invoice The invoice
|
||||
* @return void
|
||||
*/
|
||||
public function onPaid( \IPS\nexus\Invoice $invoice )
|
||||
public function onPaid( Invoice $invoice ): void
|
||||
{
|
||||
|
||||
}
|
||||
@@ -284,10 +356,10 @@ abstract class _Item
|
||||
/**
|
||||
* On Unpaid description
|
||||
*
|
||||
* @param \IPS\nexus\Invoice $invoice The invoice
|
||||
* @param Invoice $invoice The invoice
|
||||
* @return array
|
||||
*/
|
||||
public function onUnpaidDescription( \IPS\nexus\Invoice $invoice )
|
||||
public function onUnpaidDescription( Invoice $invoice ): array
|
||||
{
|
||||
return array();
|
||||
}
|
||||
@@ -295,11 +367,11 @@ abstract class _Item
|
||||
/**
|
||||
* On Unpaid
|
||||
*
|
||||
* @param \IPS\nexus\Invoice $invoice The invoice
|
||||
* @param Invoice $invoice The invoice
|
||||
* @param string $status Status
|
||||
* @return void
|
||||
* @return void
|
||||
*/
|
||||
public function onUnpaid( \IPS\nexus\Invoice $invoice, $status )
|
||||
public function onUnpaid( Invoice $invoice, string $status ): void
|
||||
{
|
||||
|
||||
}
|
||||
@@ -307,10 +379,10 @@ abstract class _Item
|
||||
/**
|
||||
* On Invoice Cancel (when unpaid)
|
||||
*
|
||||
* @param \IPS\nexus\Invoice $invoice The invoice
|
||||
* @return void
|
||||
* @param Invoice $invoice The invoice
|
||||
* @return void
|
||||
*/
|
||||
public function onInvoiceCancel( \IPS\nexus\Invoice $invoice )
|
||||
public function onInvoiceCancel( Invoice $invoice ): void
|
||||
{
|
||||
|
||||
}
|
||||
@@ -321,11 +393,11 @@ abstract class _Item
|
||||
* is ran to check the items they are purchasing can be bought.
|
||||
* Is expected to throw a DomainException with an error message to display to the user if not valid
|
||||
*
|
||||
* @param \IPS\Member $member The new member
|
||||
* @return void
|
||||
* @throws \DomainException
|
||||
* @param Member $member The new member
|
||||
* @return void
|
||||
* @throws DomainException
|
||||
*/
|
||||
public function memberCanPurchase( \IPS\Member $member )
|
||||
public function memberCanPurchase( Member $member ): void
|
||||
{
|
||||
|
||||
}
|
||||
@@ -334,19 +406,19 @@ abstract class _Item
|
||||
* Requires Billing Address
|
||||
*
|
||||
* @return bool
|
||||
* @throws \DomainException
|
||||
* @throws DomainException
|
||||
*/
|
||||
public function requiresBillingAddress()
|
||||
public function requiresBillingAddress(): bool
|
||||
{
|
||||
return \in_array( 'other', explode( ',', \IPS\Settings::i()->nexus_require_billing ) );
|
||||
return in_array( 'other', explode( ',', Settings::i()->nexus_require_billing ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Client Area URL
|
||||
*
|
||||
* @return |IPS\Http\Url|NULL
|
||||
* @return Url|string|NULL
|
||||
*/
|
||||
public function url()
|
||||
function url(): Url|string|null
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
@@ -354,9 +426,9 @@ abstract class _Item
|
||||
/**
|
||||
* ACP URL
|
||||
*
|
||||
* @return |IPS\Http\Url|NULL
|
||||
* @return Url|null
|
||||
*/
|
||||
public function acpUrl()
|
||||
public function acpUrl(): Url|null
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
@@ -365,16 +437,16 @@ abstract class _Item
|
||||
* Is this item the same as another item in the cart?
|
||||
* Used to decide when an item is added to the cart if we should just increase the quantity of this item instead of creating a new item.
|
||||
*
|
||||
* @param \IPS\nexus\Invoice\Item $item The other item
|
||||
* @return bool
|
||||
* @param Item $item The other item
|
||||
* @return bool
|
||||
*/
|
||||
public function isSameAsOtherItem( $item )
|
||||
public function isSameAsOtherItem( Item $item ): bool
|
||||
{
|
||||
/* If one is set to be associated with something in the cart and the other is set to be associated
|
||||
with an existing purchase, trying to compare those will throw an error */
|
||||
if ( isset( $item->parent ) and isset( $this->parent ) )
|
||||
{
|
||||
if ( \gettype( $this->parent ) != \gettype( $item->parent ) )
|
||||
if ( gettype( $this->parent ) != gettype( $item->parent ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
@@ -391,7 +463,7 @@ abstract class _Item
|
||||
/**
|
||||
* Get output for API
|
||||
*
|
||||
* @param \IPS\Member|NULL $authorizedMember The member making the API request or NULL for API Key / client_credentials
|
||||
* @param Member|NULL $authorizedMember The member making the API request or NULL for API Key / client_credentials
|
||||
* @return array
|
||||
* @apiresponse string name Item name
|
||||
* @apiresponse string itemApp Key for application. For example, 'nexus' for products and renewals; 'downloads' for Downloads files
|
||||
@@ -403,11 +475,6 @@ abstract class _Item
|
||||
* @apiresponse \IPS\nexus\Money itemPrice Item price, before tax
|
||||
* @apiresponse \IPS\nexus\Money linePrice Line price, before tax
|
||||
* @apiresponse \IPS\nexus\Tax taxClassId If the item should be taxed, the Tax Class that applies
|
||||
* @apiresponse bool physical If the item is physical
|
||||
* @apiresponse float weight If the item is physical, the weight in kilograms
|
||||
* @apiresponse float length If the item is physical, the length in metres
|
||||
* @apiresponse float width If the item is physical, the width in metres
|
||||
* @apiresponse float height If the item is physical, the height in metres
|
||||
* @apiresponse \IPS\nexus\Purchase\RenewalTerm renewalTerm If the item renews, the renewal term
|
||||
* @apiresponse datetime expireDate If the item has been set to expire at a certain date but not automatically renew, the dare it will expire
|
||||
* @apiresponse object details The values for any custom package fields
|
||||
@@ -418,7 +485,7 @@ abstract class _Item
|
||||
* @apiresponse float commission If the payment for this item goes to another user (for example for Downloads files), the percentage of the price that will be retained by the site (in addition to fee)
|
||||
* @apiresponse \IPS\nexus\Money fee If the payment for this item goes to another user (for example for Downloads files), the fee that will be deducted by the site (in addition to commission)
|
||||
*/
|
||||
public function apiOutput( \IPS\Member $authorizedMember = NULL )
|
||||
public function apiOutput( Member $authorizedMember = NULL ): array
|
||||
{
|
||||
return array(
|
||||
'name' => $this->name,
|
||||
@@ -430,19 +497,14 @@ abstract class _Item
|
||||
'quantity' => $this->quantity,
|
||||
'itemPrice' => $this->price->apiOutput( $authorizedMember ),
|
||||
'linePrice' => $this->linePrice()->apiOutput( $authorizedMember ),
|
||||
'taxClass' => $this->tax ? $this->tax->apiOutput( $authorizedMember ) : null,
|
||||
'physical' => $this->physical,
|
||||
'weight' => isset( $this->weight ) ? $this->weight->kilograms : null,
|
||||
'length' => isset( $this->length ) ? $this->length->metres : null,
|
||||
'width' => isset( $this->width ) ? $this->width->metres : null,
|
||||
'height' => isset( $this->height ) ? $this->height->metres : null,
|
||||
'taxClass' => $this->tax?->apiOutput($authorizedMember),
|
||||
'renewalTerm' => isset( $this->renewalTerm ) ? $this->renewalTerm->apiOutput( $authorizedMember ) : null,
|
||||
'expireDate' => isset( $this->expireDate ) ? $this->expireDate->rfc3339() : null,
|
||||
'details' => $this->details,
|
||||
'parentPurchase' => ( isset( $this->parent ) and $this->parent instanceof \IPS\nexus\Purchase ) ? $this->parent->apiOutput( $authorizedMember ) : null,
|
||||
'parentItem' => ( isset( $this->parent ) and \is_int( $this->parent ) ) ? $this->parent : null,
|
||||
'groupWithParent' => isset( $this->groupWithParent ) ? $this->groupWithParent : false,
|
||||
'payTo' => $this->payTo ? $this->payTo->apiOutput( $authorizedMember ) : null,
|
||||
'parentPurchase' => ( isset( $this->parent ) and $this->parent instanceof Purchase ) ? $this->parent->apiOutput( $authorizedMember ) : null,
|
||||
'parentItem' => ( isset( $this->parent ) and is_int( $this->parent ) ) ? $this->parent : null,
|
||||
'groupWithParent' => $this->groupWithParent ?? false,
|
||||
'payTo' => $this->payTo?->apiOutput($authorizedMember),
|
||||
'commission' => $this->commission,
|
||||
'fee' => $this->fee ? $this->fee->apiOutput( $authorizedMember ) : null,
|
||||
);
|
||||
|
||||
Reference in new issue
Block a user