Version 4.1.19
This commit is contained in:
1 parent
28bd025b35
commit
2bd5025018
2674 files changed
+233518
-77766
No files matched your search
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @brief Invoice Model
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @subpackage Nexus
|
||||
* @since 10 Feb 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
@@ -211,6 +211,12 @@ class _Invoice extends \IPS\Patterns\ActiveRecord
|
||||
try
|
||||
{
|
||||
$this->_member = \IPS\nexus\Customer::load( $this->_data['member'] );
|
||||
|
||||
/* \IPS\nexus\Customer does not necessarily throw an OutOfRangeException if passed a value of 0 (a guest instance is valid) - throw one here so we can bubble up to get the correct information for guests. */
|
||||
if ( !$this->_member->member_id )
|
||||
{
|
||||
throw new \OutOfRangeException;
|
||||
}
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
@@ -274,13 +280,13 @@ class _Invoice extends \IPS\Patterns\ActiveRecord
|
||||
{
|
||||
return is_array( $val ) and isset( $val['act'] );
|
||||
} );
|
||||
if ( !$itemsJson and $this->total->amount )
|
||||
if ( !$itemsJson and $this->total->amount->isGreaterThanZero() )
|
||||
{
|
||||
$itemsJson = array( array(
|
||||
'act' => 'charge',
|
||||
'app' => 'nexus',
|
||||
'type' => 'charge',
|
||||
'cost' => $this->total->amount,
|
||||
'cost' => $this->total->amountAsString(),
|
||||
'tax' => NULL,
|
||||
'quantity' => 1,
|
||||
'itemName' => $this->title,
|
||||
@@ -291,7 +297,7 @@ class _Invoice extends \IPS\Patterns\ActiveRecord
|
||||
'extra' => NULL,
|
||||
) );
|
||||
}
|
||||
|
||||
|
||||
/* Return it */
|
||||
$this->_itemsIterator = new \IPS\nexus\Invoice\ItemsIterator( $itemsJson );
|
||||
$this->_itemsIterator->currency = $this->currency;
|
||||
@@ -470,14 +476,7 @@ class _Invoice extends \IPS\Patterns\ActiveRecord
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
return \IPS\GeoLocation::buildFromJson( \IPS\Db::i()->select( 'address', 'nexus_customer_addresses', array( 'member=? AND primary_billing=1', $this->member->member_id ) )->first() );
|
||||
}
|
||||
catch ( \UnderflowException $e )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -514,6 +513,28 @@ class _Invoice extends \IPS\Patterns\ActiveRecord
|
||||
$this->_data['guest_data'] = $data ? json_encode( $data ) : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a title automatically based on item names
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setDefaultTitle()
|
||||
{
|
||||
$titles = array();
|
||||
foreach ( $this->items as $item )
|
||||
{
|
||||
$titles[] = ( $item->name . ( $item->quantity > 1 ? " x{$item->quantity}" : '' ) );
|
||||
}
|
||||
$thisTitle = implode( ', ', $titles );
|
||||
|
||||
if ( mb_strlen( $thisTitle ) > 128 )
|
||||
{
|
||||
$thisTitle = mb_substr( $thisTitle, 0, 125 ) . '...';
|
||||
}
|
||||
|
||||
$this->title = $thisTitle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save Changed Columns
|
||||
*
|
||||
@@ -523,19 +544,7 @@ class _Invoice extends \IPS\Patterns\ActiveRecord
|
||||
{
|
||||
if ( !$this->title )
|
||||
{
|
||||
$titles = array();
|
||||
foreach ( $this->items as $item )
|
||||
{
|
||||
$titles[] = ( $item->name . ( $item->quantity > 1 ? " x{$item->quantity}" : '' ) );
|
||||
}
|
||||
$thisTitle = implode( ', ', $titles );
|
||||
|
||||
if ( mb_strlen( $thisTitle ) > 128 )
|
||||
{
|
||||
$thisTitle = mb_substr( $thisTitle, 0, 125 ) . '...';
|
||||
}
|
||||
|
||||
$this->title = $thisTitle;
|
||||
$this->setDefaultTitle();
|
||||
}
|
||||
|
||||
if ( $this->_new )
|
||||
@@ -556,9 +565,11 @@ class _Invoice extends \IPS\Patterns\ActiveRecord
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
\IPS\File::unclaimAttachments( 'nexus_Purchases', NULL, NULL, "invoice-{$this->id}" );
|
||||
|
||||
parent::delete();
|
||||
|
||||
foreach ( $this->transactions( array( \IPS\nexus\Transaction::STATUS_PENDING, \IPS\nexus\Transaction::STATUS_WAITING, \IPS\nexus\Transaction::STATUS_HELD, \IPS\nexus\Transaction::STATUS_REVIEW ) ) as $transaction )
|
||||
foreach ( $this->transactions( array( \IPS\nexus\Transaction::STATUS_PENDING, \IPS\nexus\Transaction::STATUS_WAITING, \IPS\nexus\Transaction::STATUS_HELD, \IPS\nexus\Transaction::STATUS_REVIEW, \IPS\nexus\Transaction::STATUS_GATEWAY_PENDING ) ) as $transaction )
|
||||
{
|
||||
if ( $transaction->status === \IPS\nexus\Transaction::STATUS_PENDING )
|
||||
{
|
||||
@@ -596,7 +607,7 @@ class _Invoice extends \IPS\Patterns\ActiveRecord
|
||||
'act' => $item::$act,
|
||||
'app' => isset( $item::$application ) ? $item::$application : $item->application,
|
||||
'type' => isset( $item::$type ) ? $item::$type : $item->type,
|
||||
'cost' => $item->price->amount,
|
||||
'cost' => $item->price->amountAsString(),
|
||||
'tax' => $item->tax ? $item->tax->id : NULL,
|
||||
'quantity' => $item->quantity,
|
||||
'itemName' => $item->name,
|
||||
@@ -629,7 +640,7 @@ class _Invoice extends \IPS\Patterns\ActiveRecord
|
||||
$renewTermData = $item->renewalTerm->getTerm();
|
||||
$data['renew_term'] = $renewTermData['term'];
|
||||
$data['renew_units'] = $renewTermData['unit'];
|
||||
$data['renew_cost'] = $item->renewalTerm->cost->amount;
|
||||
$data['renew_cost'] = $item->renewalTerm->cost->amountAsString();
|
||||
if ( $item->renewalTerm->gracePeriod )
|
||||
{
|
||||
$data['grace_period'] = \IPS\DateTime::create()->add( $item->renewalTerm->gracePeriod )->getTimestamp() - time();
|
||||
@@ -748,10 +759,61 @@ class _Invoice extends \IPS\Patterns\ActiveRecord
|
||||
$return = array();
|
||||
$return['items'] = array();
|
||||
$shippingItems = array();
|
||||
$subtotal = 0;
|
||||
$subtotal = new \IPS\Math\Number('0');
|
||||
$taxableAmounts = array();
|
||||
$taxClasses = \IPS\nexus\Tax::roots();
|
||||
|
||||
|
||||
/* Reduce taxable amount from coupons */
|
||||
$couponTaxReductions = array();
|
||||
foreach ( $this->items as $itemId => $item )
|
||||
{
|
||||
if ( $item instanceof \IPS\nexus\extensions\nexus\Item\CouponDiscount )
|
||||
{
|
||||
if ( isset( $item->extra['type'] ) )
|
||||
{
|
||||
if ( isset( $item->extra['items'] ) )
|
||||
{
|
||||
$itemCount = count( $item->extra['items'] );
|
||||
}
|
||||
else
|
||||
{
|
||||
$itemCount = 0;
|
||||
foreach ( clone $this->items as $k => $_item ) // We have to clone because $items is an iterator, and we're already looping them, but we need a separate loop
|
||||
{
|
||||
if ( $_item != $item and !( $_item instanceof \IPS\nexus\extensions\nexus\Item\ShippingCharge ) and !( $_item instanceof \IPS\nexus\extensions\nexus\Item\CouponDiscount ) )
|
||||
{
|
||||
$itemCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( clone $this->items as $k => $_item ) // We have to clone because $items is an iterator, and we're already looping them, but we need a separate loop
|
||||
{
|
||||
if ( $_item != $item and !( $_item instanceof \IPS\nexus\extensions\nexus\Item\CouponDiscount ) and !( $_item instanceof \IPS\nexus\extensions\nexus\Item\ShippingCharge ) and ( !isset( $item->extra['items'] ) or in_array( $k, $item->extra['items'] ) ) )
|
||||
{
|
||||
if ( $item->extra['type'] == 'p' )
|
||||
{
|
||||
$reductionAmount = $_item->linePrice()->amount->multiply( new \IPS\Math\Number("{$item->extra['value']}") )->divide( new \IPS\Math\Number('100') );
|
||||
}
|
||||
else
|
||||
{
|
||||
$reductionAmount = ( new \IPS\Math\Number( "{$item->extra['value']}" ) )->divide( new \IPS\Math\Number( "{$itemCount}" ) )->multiply( new \IPS\Math\Number( '-1' ) );
|
||||
}
|
||||
|
||||
if ( isset( $couponTaxReductions[ $k ] ) )
|
||||
{
|
||||
$couponTaxReductions[ $k ] = $couponTaxReductions[ $k ]->add( $reductionAmount );
|
||||
}
|
||||
else
|
||||
{
|
||||
$couponTaxReductions[ $k ] = $reductionAmount;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Work out the line totals */
|
||||
foreach ( $this->items as $k => $item )
|
||||
{
|
||||
@@ -761,16 +823,24 @@ class _Invoice extends \IPS\Patterns\ActiveRecord
|
||||
}
|
||||
else
|
||||
{
|
||||
$subtotal += $item->linePrice()->amount;
|
||||
$subtotal = $subtotal->add( $item->linePrice()->amount );
|
||||
|
||||
if ( isset( $item->tax ) )
|
||||
{
|
||||
$taxAmount = $item->linePrice()->amount;
|
||||
|
||||
if ( isset( $couponTaxReductions[ $k ] ) )
|
||||
{
|
||||
$taxAmount = $taxAmount->subtract( $couponTaxReductions[ $k ] );
|
||||
}
|
||||
|
||||
if ( isset( $taxableAmounts[ $item->tax->id ] ) )
|
||||
{
|
||||
$taxableAmounts[ $item->tax->id ] += $item->linePrice()->amount;
|
||||
$taxableAmounts[ $item->tax->id ] = $taxableAmounts[ $item->tax->id ]->add( $taxAmount );
|
||||
}
|
||||
else
|
||||
{
|
||||
$taxableAmounts[ $item->tax->id ] = $item->linePrice()->amount;
|
||||
$taxableAmounts[ $item->tax->id ] = $taxAmount;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -783,17 +853,17 @@ class _Invoice extends \IPS\Patterns\ActiveRecord
|
||||
|
||||
/* Add shipping */
|
||||
$return['shipping'] = array();
|
||||
$shipping = 0;
|
||||
$shipping = new \IPS\Math\Number('0');
|
||||
foreach ( $shippingItems as $k => $item )
|
||||
{
|
||||
$linePrice = $item->linePrice()->amount;
|
||||
$shipping += $linePrice;
|
||||
$shipping = $shipping->add( $linePrice );
|
||||
|
||||
if ( isset( $item->tax ) )
|
||||
{
|
||||
if ( isset( $taxableAmounts[ $item->tax->id ] ) )
|
||||
{
|
||||
$taxableAmounts[ $item->tax->id ] += $linePrice;
|
||||
$taxableAmounts[ $item->tax->id ] = $taxableAmounts[ $item->tax->id ]->add( $linePrice );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -807,29 +877,45 @@ class _Invoice extends \IPS\Patterns\ActiveRecord
|
||||
|
||||
/* Now work out the tax */
|
||||
$return['tax'] = array();
|
||||
$tax = 0;
|
||||
$tax = new \IPS\Math\Number('0');
|
||||
foreach ( $taxableAmounts as $taxId => $amount )
|
||||
{
|
||||
$rate = $taxClasses[ $taxId ]->rate( $this->billaddress );
|
||||
$amount = $amount * $rate;
|
||||
$amount = $amount->multiply( new \IPS\Math\Number( $rate ) );
|
||||
|
||||
$amount = new \IPS\nexus\Money( $amount, $this->currency );
|
||||
$amount = $amount->round(); // Tax value may be something like $1.005, but needs to be a valid currency amount. Always rounds up.
|
||||
|
||||
$return['tax'][ $taxId ] = array( 'name' => $taxClasses[ $taxId ]->_title, 'rate' => $rate, 'amount' => $amount );
|
||||
$tax += $amount->amount;
|
||||
$tax = $tax->add( $amount->amount );
|
||||
}
|
||||
$return['taxTotal'] = new \IPS\nexus\Money( $tax, $this->currency );
|
||||
|
||||
/* Add it all together */
|
||||
$return['total'] = new \IPS\nexus\Money( $subtotal + $shipping + $tax, $this->currency );
|
||||
$return['total'] = $return['total']->round(); // Total value must also be a valid currency amount
|
||||
|
||||
$return['total'] = new \IPS\nexus\Money( $subtotal->add( $shipping )->add( $tax ), $this->currency );
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/* !Information */
|
||||
|
||||
/**
|
||||
* Does the invoice contain items that require a billing address?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasItemsRequiringBillingAddress()
|
||||
{
|
||||
foreach ( $this->items as $item )
|
||||
{
|
||||
if ( $item->requiresBillingAddress() )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the invoice contain physical items that need shipping?
|
||||
*
|
||||
@@ -881,23 +967,23 @@ class _Invoice extends \IPS\Patterns\ActiveRecord
|
||||
{
|
||||
if ( !isset( $recipients[ $item->payTo->member_id ] ) )
|
||||
{
|
||||
$recipients[ $item->payTo->member_id ] = 0;
|
||||
$recipients[ $item->payTo->member_id ] = new \IPS\Math\Number('0');
|
||||
}
|
||||
$itemRecipientAmounts = $item->recipientAmounts();
|
||||
$recipients[ $item->payTo->member_id ] += $itemRecipientAmounts['recipient_final']->amount;
|
||||
$recipients[ $item->payTo->member_id ] = $recipients[ $item->payTo->member_id ]->add( $itemRecipientAmounts['recipient_final']->amount );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return $recipients;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the commission information
|
||||
*
|
||||
* @param float $amountReceived The amount the invoice is for, minus amounts being given to other recipients
|
||||
* @param \IPS\Math\Number $amountReceived The amount the invoice is for, minus amounts being given to other recipients
|
||||
* @return array( 'rule' => \IPS\nexus\CommissionRule, 'referrer' => \IPS\nexus\Customer, 'amount' => \IPS\nexus\Money )
|
||||
*/
|
||||
public function commission( $amountReceived )
|
||||
public function commission( \IPS\Math\Number $amountReceived )
|
||||
{
|
||||
if ( !isset( $this->status_extra['commissionrule'] ) )
|
||||
{
|
||||
@@ -917,19 +1003,19 @@ class _Invoice extends \IPS\Patterns\ActiveRecord
|
||||
$forAmounts = iterator_to_array( \IPS\Db::i()->select( 'i_currency, SUM( i_total ) as value', 'nexus_invoices', array( "i_member=? AND i_status=?", $this->member->member_id, static::STATUS_PAID ), NULL, NULL, 'i_currency' )->setKeyField( 'i_currency' )->setValueField( 'value' ) );
|
||||
|
||||
/* Loop the rules to find out the best one */
|
||||
$maxAmount = 0;
|
||||
$maxAmount = new \IPS\Math\Number('0');
|
||||
$actingRule = NULL;
|
||||
foreach ( new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'nexus_referral_rules', array( array( "rrule_by_group='*' OR " . \IPS\Db::i()->findInSet( 'rrule_by_group', $referrer->groups ) ), array( "rrule_for_group='*' OR " . \IPS\Db::i()->findInSet( 'rrule_for_group', $this->member->groups ) ) ) ), 'IPS\nexus\CommissionRule' ) as $commissionRule )
|
||||
{
|
||||
/* Before we go nuts, don't bother if it's not going to give us more commission */
|
||||
if ( round( ( ( $amountReceived / 100 ) * $commissionRule->commission ), 2 ) <= $maxAmount )
|
||||
if ( $amountReceived->percentage( $commissionRule->commission )->compare( $maxAmount ) === -1 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ( $commissionRule->commission_limit )
|
||||
{
|
||||
$commisionLimit = json_decode( $commissionRule->commission_limit, TRUE );
|
||||
if ( isset( $commisionLimit[ $this->currency ] ) and $commisionLimit[ $this->currency ]['amount'] <= $maxAmount )
|
||||
if ( isset( $commisionLimit[ $this->currency ] ) and ( new \IPS\Math\Number( number_format( $commisionLimit[ $this->currency ]['amount'], \IPS\nexus\Money::numberOfDecimalsForCurrency( $this->currency ), '.', '' ) ) )->compare( $maxAmount ) === -1 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -984,7 +1070,7 @@ class _Invoice extends \IPS\Patterns\ActiveRecord
|
||||
{
|
||||
if ( $commissionRule->purchase_package_limit )
|
||||
{
|
||||
$amountToApplyCommissionOn = 0;
|
||||
$amountToApplyCommissionOn = new \IPS\Math\Number('0');
|
||||
}
|
||||
|
||||
$itemsToCount = array();
|
||||
@@ -995,7 +1081,7 @@ class _Invoice extends \IPS\Patterns\ActiveRecord
|
||||
{
|
||||
$packageId = $item->id;
|
||||
}
|
||||
elseif ( $commissionRule->purchase_renewal and $item instanceof \IPS\nexus\Invoice\Item\Renewal and $item->application == 'nexus' and $item->type == 'package' )
|
||||
elseif ( $commissionRule->purchase_renewal and $item instanceof \IPS\nexus\Invoice\Item\Renewal and $item::$application == 'nexus' and $item::$type == 'package' )
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -1017,14 +1103,7 @@ class _Invoice extends \IPS\Patterns\ActiveRecord
|
||||
}
|
||||
if ( $commissionRule->purchase_package_limit )
|
||||
{
|
||||
if ( isset( $amountReceivedForItem[ $k ] ) )
|
||||
{
|
||||
$amountToApplyCommissionOn += $amountReceivedForItem[ $k ];
|
||||
}
|
||||
else
|
||||
{
|
||||
$amountToApplyCommissionOn += ( $item->price->amount * $item->quantity );
|
||||
}
|
||||
$amountToApplyCommissionOn = $amountToApplyCommissionOn->add( $item->price->amount->multiply( new \IPS\Math\Number( "{$item->quantity}" ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1049,18 +1128,18 @@ class _Invoice extends \IPS\Patterns\ActiveRecord
|
||||
}
|
||||
|
||||
/* If we're still here, we're applying commission */
|
||||
$amountToGive = round( ( ( $amountToApplyCommissionOn / 100 ) * $commissionRule->commission ), 2 );
|
||||
$amountToGive = $amountToApplyCommissionOn->percentage( $commissionRule->commission );
|
||||
if ( $commissionRule->commission_limit and $commissionRule->commission_limit != '*' )
|
||||
{
|
||||
$limit = json_decode( $commissionRule->commission_limit, TRUE );
|
||||
if ( isset( $limit[ $this->currency ] ) and $amountToGive > $limit[ $this->currency ]['amount'] )
|
||||
if ( isset( $limit[ $this->currency ] ) and $amountToGive->compare( new \IPS\Math\Number( number_format( $limit[ $this->currency ]['amount'], \IPS\nexus\Money::numberOfDecimalsForCurrency( $this->currency ), '.', '' ) ) ) === 1 )
|
||||
{
|
||||
$amountToGive = $limit[ $this->currency ]['amount'];
|
||||
$amountToGive = new \IPS\Math\Number( number_format( $limit[ $this->currency ]['amount'], \IPS\nexus\Money::numberOfDecimalsForCurrency( $this->currency ), '.', '' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/* Is this more than what we have? */
|
||||
if ( ( $amountToGive > $maxAmount ) or ( $amountToGive and !$maxAmount ) )
|
||||
if ( ( $amountToGive->compare( $maxAmount ) === 1 ) or ( $amountToGive->isGreaterThanZero() and !$maxAmount->isGreaterThanZero() ) )
|
||||
{
|
||||
$maxAmount = $amountToGive;
|
||||
$actingRule = $commissionRule;
|
||||
@@ -1086,11 +1165,25 @@ class _Invoice extends \IPS\Patterns\ActiveRecord
|
||||
$this->save();
|
||||
}
|
||||
|
||||
return array(
|
||||
'rule' => $this->status_extra['commissionrule'] ? \IPS\nexus\CommissionRule::load( $this->status_extra['commissionrule'] ) : NULL,
|
||||
'referrer' => $this->status_extra['commissionref'] ? \IPS\nexus\Customer::load( $this->status_extra['commissionref'] ) : NULL,
|
||||
'amount' => $this->status_extra['commissionamount'] ? new \IPS\nexus\Money( $this->status_extra['commissionamount'], $this->currency ) : NULL
|
||||
);
|
||||
try
|
||||
{
|
||||
return array(
|
||||
'rule' => $this->status_extra['commissionrule'] ? \IPS\nexus\CommissionRule::load( $this->status_extra['commissionrule'] ) : NULL,
|
||||
'referrer' => $this->status_extra['commissionref'] ? \IPS\nexus\Customer::load( $this->status_extra['commissionref'] ) : NULL,
|
||||
'amount' => $this->status_extra['commissionamount'] ? new \IPS\nexus\Money( $this->status_extra['commissionamount'], $this->currency ) : NULL
|
||||
);
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
{
|
||||
/* If either the commission rule, or the commission ref, are no longer valid, then let's try again and see if it matches up with a different one. */
|
||||
$extra = $this->status_extra;
|
||||
unset( $extra['commissionrule'], $extra['commissionref'], $extra['commissionamount'] );
|
||||
$this->status_extra = $extra;
|
||||
|
||||
$this->save();
|
||||
|
||||
return $this->commission( $amountReceived );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1103,17 +1196,44 @@ class _Invoice extends \IPS\Patterns\ActiveRecord
|
||||
*/
|
||||
protected function _checkCondition( $a, $operator, $b )
|
||||
{
|
||||
$a = floatval( $a );
|
||||
$b = floatval( $b );
|
||||
if ( $a instanceof \IPS\Math\Number and !( $b instanceof \IPS\Math\Number ) )
|
||||
{
|
||||
$b = new \IPS\Math\Number( "{$b}" );
|
||||
}
|
||||
if ( !( $a instanceof \IPS\Math\Number ) and $b instanceof \IPS\Math\Number )
|
||||
{
|
||||
$a = new \IPS\Math\Number( "{$a}" );
|
||||
}
|
||||
|
||||
switch ( $operator )
|
||||
{
|
||||
case 'g':
|
||||
return $a > $b;
|
||||
if ( $a instanceof \IPS\Math\Number )
|
||||
{
|
||||
return $a->compare( $b ) === 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $a > $b;
|
||||
}
|
||||
case 'e':
|
||||
return $a == $b;
|
||||
if ( $a instanceof \IPS\Math\Number )
|
||||
{
|
||||
return $a->compare( $b ) === 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $a == $b;
|
||||
}
|
||||
case 'l':
|
||||
return $a < $b;
|
||||
if ( $a instanceof \IPS\Math\Number )
|
||||
{
|
||||
return $a->compare( $b ) === 11;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $a < $b;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
@@ -1123,19 +1243,33 @@ class _Invoice extends \IPS\Patterns\ActiveRecord
|
||||
*
|
||||
* @return \IPS\nexus\Money
|
||||
*/
|
||||
public function amountToPay()
|
||||
public function amountToPay( $deductHeldTransactions=FALSE )
|
||||
{
|
||||
$amountToPay = $this->total;
|
||||
$amountToPay = $this->total;
|
||||
|
||||
foreach ( $this->transactions( array( \IPS\nexus\Transaction::STATUS_PAID, \IPS\nexus\Transaction::STATUS_PART_REFUNDED ) ) as $transaction )
|
||||
$statuses = array( \IPS\nexus\Transaction::STATUS_PAID, \IPS\nexus\Transaction::STATUS_PART_REFUNDED );
|
||||
if ( $deductHeldTransactions )
|
||||
{
|
||||
$statuses[] = \IPS\nexus\Transaction::STATUS_HELD;
|
||||
$statuses[] = \IPS\nexus\Transaction::STATUS_REVIEW;
|
||||
$statuses[] = \IPS\nexus\Transaction::STATUS_GATEWAY_PENDING;
|
||||
}
|
||||
|
||||
foreach ( $this->transactions( $statuses ) as $transaction )
|
||||
{
|
||||
if ( $transaction->currency === $this->currency )
|
||||
{
|
||||
$amountToPay->amount -= ( $transaction->amount->amount - ( $transaction->status === \IPS\nexus\Transaction::STATUS_PART_REFUNDED ? $transaction->partial_refund->amount : 0 ) );
|
||||
$amountToSubtract = $transaction->amount->amount;
|
||||
if ( $transaction->status === \IPS\nexus\Transaction::STATUS_PART_REFUNDED )
|
||||
{
|
||||
$amountToSubtract = $amountToSubtract->subtract( $transaction->partial_refund->amount );
|
||||
}
|
||||
|
||||
$amountToPay->amount = $amountToPay->amount->subtract( $amountToSubtract );
|
||||
}
|
||||
}
|
||||
|
||||
return $amountToPay->round();
|
||||
return $amountToPay;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1149,6 +1283,15 @@ class _Invoice extends \IPS\Patterns\ActiveRecord
|
||||
$url = $this->acpUrl()->setQueryString( 'r', $ref );
|
||||
$return = array();
|
||||
|
||||
if ( $this->status !== \IPS\nexus\Invoice::STATUS_PAID and \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'invoices_add' ) )
|
||||
{
|
||||
$return['edit'] = array(
|
||||
'title' => 'edit',
|
||||
'icon' => 'pencil',
|
||||
'link' => $url->setQueryString( array( 'do' => 'generate', '_new' => 1 ) )
|
||||
);
|
||||
}
|
||||
|
||||
if ( $this->status === \IPS\nexus\Invoice::STATUS_PENDING )
|
||||
{
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'invoices_edit' ) )
|
||||
@@ -1157,7 +1300,7 @@ class _Invoice extends \IPS\Patterns\ActiveRecord
|
||||
'title' => 'invoice_mark_paid',
|
||||
'icon' => 'check',
|
||||
'link' => $url->setQueryString( 'do', 'paid' ),
|
||||
'data' => count( $this->transactions( array( \IPS\nexus\Transaction::STATUS_PENDING, \IPS\nexus\Transaction::STATUS_WAITING, \IPS\nexus\Transaction::STATUS_HELD, \IPS\nexus\Transaction::STATUS_REVIEW ) ) ) ? array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('invoice_mark_paid') ) : array( 'confirm' => '' )
|
||||
'data' => count( $this->transactions( array( \IPS\nexus\Transaction::STATUS_PENDING, \IPS\nexus\Transaction::STATUS_WAITING, \IPS\nexus\Transaction::STATUS_HELD, \IPS\nexus\Transaction::STATUS_REVIEW, \IPS\nexus\Transaction::STATUS_GATEWAY_PENDING ) ) ) ? array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('invoice_mark_paid') ) : array( 'confirm' => '' )
|
||||
);
|
||||
}
|
||||
if ( count( \IPS\nexus\Gateway::manualChargeGateways() ) and \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'chargetocard' ) )
|
||||
@@ -1168,7 +1311,7 @@ class _Invoice extends \IPS\Patterns\ActiveRecord
|
||||
'link' => $url->setQueryString( array( 'do' => 'card', '_new' => 1 ) ),
|
||||
);
|
||||
}
|
||||
if ( isset( $this->member->cm_credits[ $this->currency ] ) and $this->member->cm_credits[ $this->currency ]->amount and \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'invoices_edit' ) )
|
||||
if ( isset( $this->member->cm_credits[ $this->currency ] ) and $this->member->cm_credits[ $this->currency ]->amount->isGreaterThanZero() and \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'invoices_edit' ) )
|
||||
{
|
||||
$return['credit'] = array(
|
||||
'title' => 'invoice_charge_to_credit',
|
||||
@@ -1200,6 +1343,7 @@ class _Invoice extends \IPS\Patterns\ActiveRecord
|
||||
$return['print'] = array(
|
||||
'title' => 'print',
|
||||
'icon' => 'print',
|
||||
'target' => '_blank',
|
||||
'link' => $url->setQueryString( 'do', 'printout' ),
|
||||
);
|
||||
if ( $this->status !== \IPS\nexus\Invoice::STATUS_CANCELED and \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'invoices_edit' ) )
|
||||
@@ -1253,6 +1397,81 @@ class _Invoice extends \IPS\Patterns\ActiveRecord
|
||||
return 0.01;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get output for API
|
||||
*
|
||||
* @return array
|
||||
* @apiresponse int id ID number
|
||||
* @apiresponse string title Title
|
||||
* @apiresponse string status 'paid' = Paid; 'pend' = Pending; 'expd' = Expired; 'canc' = Cancelled
|
||||
* @apiresponse datetime issueDate The date the invoice was issued
|
||||
* @apiresponse datetime paidDate The date the invoice was paid
|
||||
* @apiresponse \IPS\nexus\Customer customer Customer
|
||||
* @apiresponse [\IPS\nexus\Invoice\Item] items Items
|
||||
* @apiresponse \IPS\nexus\Money subTotal Subtotal of item costs
|
||||
* @apiresponse [\IPS\nexus\Invoice\Item] shippingCharges Shipping charges
|
||||
* @apiresponse \IPS\nexus\Money shippingTotal Total cost of shipping charges
|
||||
* @apiresponse [\IPS\nexus\Invoice\Item\TaxItem] tax Tax charges
|
||||
* @apiresponse \IPS\nexus\Money taxTotal Total cost of tax charges
|
||||
* @apiresponse \IPS\nexus\Money total Total
|
||||
* @apiresponse \IPS\nexus\Money outstanding The outstanding amount to be paid
|
||||
* @apiresponse \IPS\GeoLocation billingAddress Billing address
|
||||
* @apiresponse \IPS\GeoLocation shippingAddress Shipping Address
|
||||
* @apiresponse string poNumber PO Number (set by customer)
|
||||
* @apiresponse string notes Notes (set by customer)
|
||||
* @apiresponse [\IPS\nexus\Transaction] transactions Transactions against this invoice
|
||||
* @apiresponse [\IPS\nexus\Shipping\Order] shipments Shipments generated from this invoice (if paid)
|
||||
* @apiresponse [\IPS\nexus\Purchase] purchases Purchases generated from this invoice (if paid)
|
||||
* @apiresponse string viewUrl The URL to where the customer can view this invoice
|
||||
* @apiresponse string checkoutUrl The URL to where the customer can pay this invoice
|
||||
*/
|
||||
public function apiOutput()
|
||||
{
|
||||
$summary = $this->summary();
|
||||
|
||||
$tax = array();
|
||||
foreach ( $summary['tax'] as $classId => $data )
|
||||
{
|
||||
$tax[] = ( new \IPS\nexus\Invoice\Item\TaxItem( $classId, $data ) )->apiOutput();
|
||||
}
|
||||
|
||||
return array(
|
||||
'id' => $this->id,
|
||||
'title' => $this->title,
|
||||
'status' => $this->status,
|
||||
'issueDate' => $this->date->rfc3339(),
|
||||
'paidDate' => $this->paid ? $this->paid->rfc3339() : null,
|
||||
'customer' => $this->member->apiOutput(),
|
||||
'items' => array_map( function( $item ){
|
||||
return $item->apiOutput();
|
||||
}, $summary['items'] ),
|
||||
'subTotal' => $summary['subtotal']->apiOutput(),
|
||||
'shippingCharges' => array_map( function( $item ){
|
||||
return $item->apiOutput();
|
||||
}, $summary['shipping'] ),
|
||||
'shippingTotal' => $summary['shippingTotal']->apiOutput(),
|
||||
'tax' => $tax,
|
||||
'taxTotal' => $summary['taxTotal']->apiOutput(),
|
||||
'total' => $summary['total']->apiOutput(),
|
||||
'outstanding' => $this->amountToPay()->apiOutput(),
|
||||
'billingAddress' => $this->billaddress ? $this->billaddress->apiOutput() : null,
|
||||
'shippingAddress' => $this->shipaddress ? $this->shipaddress->apiOutput() : null,
|
||||
'poNumber' => $this->po,
|
||||
'notes' => $this->notes,
|
||||
'transactions' => array_map( function( $transaction ){
|
||||
return $transaction->apiOutput();
|
||||
}, iterator_to_array( $this->transactions() ) ),
|
||||
'shipments' => array_map( function( $shipment ){
|
||||
return $shipment->apiOutput();
|
||||
}, iterator_to_array( $this->shipments() ) ),
|
||||
'purchases' => array_map( function( $purchase ){
|
||||
return $purchase->apiOutput();
|
||||
}, iterator_to_array( $this->purchasesCreated() ) ),
|
||||
'viewUrl' => (string) $this->url(),
|
||||
'checkoutUrl' => (string) $this->checkoutUrl(),
|
||||
);
|
||||
}
|
||||
|
||||
/* !Related Resources */
|
||||
|
||||
@@ -1260,11 +1479,11 @@ class _Invoice extends \IPS\Patterns\ActiveRecord
|
||||
* Get transactions
|
||||
*
|
||||
* @param array|null $statuses Statuses to get, or NULL for all
|
||||
* @param array $where Initial where clause
|
||||
* @return \IPS\Patterns\ActiveRecordIteator
|
||||
*/
|
||||
public function transactions( $statuses=NULL )
|
||||
public function transactions( $statuses=NULL, $where = array() )
|
||||
{
|
||||
$where = array();
|
||||
$where[] = array( 't_invoice=?', $this->id );
|
||||
if ( $statuses )
|
||||
{
|
||||
@@ -1312,25 +1531,56 @@ class _Invoice extends \IPS\Patterns\ActiveRecord
|
||||
* @note It is the responsibility of the code calling this to log the action on the customer's account *before* calling this method
|
||||
*/
|
||||
public function markPaid( \IPS\Member $member = NULL )
|
||||
{
|
||||
{
|
||||
if ( $this->status !== static::STATUS_PAID )
|
||||
{
|
||||
/* Create the member account if this was a guest */
|
||||
if ( !$this->member->member_id and $this->guest_data )
|
||||
if ( !$this->member->member_id and $this->guest_data and $this->requiresLogin() )
|
||||
{
|
||||
$profileFields = $this->guest_data['profileFields'];
|
||||
$securityAnswers = isset( $this->guest_data['securityAnswers'] ) ? $this->guest_data['securityAnswers'] : array();
|
||||
|
||||
$memberToSave = new \IPS\nexus\Customer;
|
||||
foreach ( $this->guest_data['member'] as $k => $v )
|
||||
/* If the member has already been created (the user made two separate purchases with the same data), use that, otherwise create one */
|
||||
try
|
||||
{
|
||||
$memberToSave->_data[ $k ] = $v;
|
||||
$memberToSave->changed[ $k ] = $v;
|
||||
$memberToSave = \IPS\nexus\Customer::load( $this->guest_data['member']['email'], 'email' );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
$memberToSave = new \IPS\nexus\Customer;
|
||||
foreach ( $this->guest_data['member'] as $k => $v )
|
||||
{
|
||||
$memberToSave->_data[ $k ] = $v;
|
||||
$memberToSave->changed[ $k ] = $v;
|
||||
}
|
||||
$memberToSave->save();
|
||||
}
|
||||
$memberToSave->save();
|
||||
$this->member = $memberToSave;
|
||||
$this->guest_data = NULL;
|
||||
$this->save();
|
||||
|
||||
/* If we provided answers to security questions in check out, save those */
|
||||
if ( \IPS\Settings::i()->security_questions_enabled and in_array( \IPS\Settings::i()->security_questions_prompt, array( 'register', 'optional' ) ) )
|
||||
{
|
||||
if ( $securityAnswers )
|
||||
{
|
||||
foreach ( $securityAnswers as $k => $v )
|
||||
{
|
||||
\IPS\Db::i()->insert( 'core_security_answers', array(
|
||||
'answer_question_id' => $k,
|
||||
'answer_member_id' => $this->member->member_id,
|
||||
'answer_answer' => $v
|
||||
) );
|
||||
}
|
||||
$this->member->members_bitoptions['has_security_answers'] = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->member->members_bitoptions['security_questions_opt_out'] = TRUE;
|
||||
}
|
||||
$this->member->save();
|
||||
}
|
||||
|
||||
/* If we've entered an address during checkout, save it */
|
||||
if ( $this->billaddress !== NULL )
|
||||
{
|
||||
@@ -1353,13 +1603,18 @@ class _Invoice extends \IPS\Patterns\ActiveRecord
|
||||
$profileFields['member_id'] = $memberToSave->member_id;
|
||||
\IPS\Db::i()->replace( 'core_pfields_content', $profileFields );
|
||||
|
||||
/* Notify the incoming mail address */
|
||||
if( \IPS\Settings::i()->new_reg_notify )
|
||||
/* Validation */
|
||||
if ( \IPS\Settings::i()->nexus_checkreg_validate or !$this->total->amount->isGreaterThanZero() )
|
||||
{
|
||||
\IPS\Email::buildFromTemplate( 'core', 'registration_notify', array( $memberToSave, $profileFields ) )->send( \IPS\Settings::i()->email_in );
|
||||
$this->member->postRegistration( FALSE, TRUE );
|
||||
}
|
||||
else if( \IPS\Settings::i()->new_reg_notify )
|
||||
{
|
||||
\IPS\Email::buildFromTemplate( 'core', 'registration_notify', array( $memberToSave, $profileFields ), \IPS\Email::TYPE_LIST )->send( \IPS\Settings::i()->email_in );
|
||||
}
|
||||
|
||||
/* Update associated transactions */
|
||||
/* Update associated transactions */
|
||||
\IPS\Db::i()->update( 'nexus_billing_agreements', array( 'ba_member' => $this->member->member_id ), array( 'ba_id IN(?)', \IPS\Db::i()->select( 't_billing_agreement', 'nexus_transactions', array( 't_billing_agreement>0 AND t_invoice=? AND t_member=0', $this->id ) ) ) );
|
||||
\IPS\Db::i()->update( 'nexus_transactions', array( 't_member' => $this->member->member_id ), array( 't_invoice=? AND t_member=0', $this->id ) );
|
||||
|
||||
/* Did we use any coupons? */
|
||||
@@ -1388,6 +1643,13 @@ class _Invoice extends \IPS\Patterns\ActiveRecord
|
||||
$extra = $this->status_extra;
|
||||
$shipOrders = array();
|
||||
|
||||
/* Find any billing agreements */
|
||||
$billingAgreement = NULL;
|
||||
foreach ( $this->transactions( array( \IPS\nexus\Transaction::STATUS_PAID, \IPS\nexus\Transaction::STATUS_PART_REFUNDED ), array( array( 't_billing_agreement IS NOT NULL' ) ) ) as $transaction )
|
||||
{
|
||||
$billingAgreement = $transaction->billing_agreement;
|
||||
}
|
||||
|
||||
/* Loop items */
|
||||
$purchases = array();
|
||||
$setParentIds = array();
|
||||
@@ -1418,6 +1680,10 @@ class _Invoice extends \IPS\Patterns\ActiveRecord
|
||||
{
|
||||
$purchase->grace_period = \IPS\DateTime::create()->add( $item->renewalTerm->gracePeriod )->getTimestamp() - time();
|
||||
}
|
||||
if ( $billingAgreement )
|
||||
{
|
||||
$purchase->billing_agreement = $billingAgreement;
|
||||
}
|
||||
}
|
||||
if ( $item->expireDate )
|
||||
{
|
||||
@@ -1463,6 +1729,14 @@ class _Invoice extends \IPS\Patterns\ActiveRecord
|
||||
}
|
||||
$purchases[ $k ][] = $purchase;
|
||||
|
||||
/* Claim attachments */
|
||||
foreach ( \IPS\Db::i()->select( '*', 'core_attachments_map', array( 'location_key=? AND id1=? AND id3=?', 'nexus_Purchases', $k, "invoice-{$this->id}" ) ) as $attachMap )
|
||||
{
|
||||
$attachMap['id1'] = $purchase->id;
|
||||
$attachMap['id3'] = 'purchase';
|
||||
\IPS\Db::i()->insert( 'core_attachments_map', $attachMap );
|
||||
}
|
||||
|
||||
/* Log */
|
||||
if ( $showPurchaseRecord )
|
||||
{
|
||||
@@ -1493,16 +1767,16 @@ class _Invoice extends \IPS\Patterns\ActiveRecord
|
||||
$recipientAmounts = $item->recipientAmounts();
|
||||
|
||||
$credits = $item->payTo->cm_credits;
|
||||
$credits[ $this->currency ]->amount += $recipientAmounts['recipient_final']->amount;
|
||||
$credits[ $this->currency ]->amount = $credits[ $this->currency ]->amount->add( $recipientAmounts['recipient_final']->amount );
|
||||
$item->payTo->cm_credits = $credits;
|
||||
$item->payTo->save();
|
||||
$amountReceived -= $recipientAmounts['recipient_final']->amount;
|
||||
$amountReceived = $amountReceived->subtract( $recipientAmounts['recipient_final']->amount );
|
||||
|
||||
if ( !isset( $extra['commission'][ $item->payTo->member_id ] ) )
|
||||
{
|
||||
$extra['commission'][ $item->payTo->member_id ] = array( 'amount' => 0 );
|
||||
$extra['commission'][ $item->payTo->member_id ] = array( 'amount' => new \IPS\Math\Number('0') );
|
||||
}
|
||||
$extra['commission'][ $item->payTo->member_id ]['amount'] += $recipientAmounts['recipient_final']->amount;
|
||||
$extra['commission'][ $item->payTo->member_id ]['amount'] = $extra['commission'][ $item->payTo->member_id ]['amount']->add( $recipientAmounts['recipient_final']->amount );
|
||||
|
||||
$item->payTo->log( 'comission', array(
|
||||
'type' => 'purchase',
|
||||
@@ -1514,7 +1788,7 @@ class _Invoice extends \IPS\Patterns\ActiveRecord
|
||||
'name' => $item->name
|
||||
), FALSE );
|
||||
|
||||
\IPS\Email::buildFromTemplate( 'nexus', 'commissionEarned', array( $this, $item, $recipientAmounts['recipient_final'] ) )
|
||||
\IPS\Email::buildFromTemplate( 'nexus', 'commissionEarned', array( $this, $item, $recipientAmounts['recipient_final'] ), \IPS\Email::TYPE_TRANSACTIONAL )
|
||||
->send(
|
||||
$item->payTo,
|
||||
array_map(
|
||||
@@ -1533,15 +1807,16 @@ class _Invoice extends \IPS\Patterns\ActiveRecord
|
||||
if ( \IPS\Settings::i()->cm_ref_on and $commission = $this->commission( $amountReceived ) and $commission['amount'] )
|
||||
{
|
||||
$credits = $commission['referrer']->cm_credits;
|
||||
$credits[ $this->currency ]->amount += $commission['amount']->amount;
|
||||
$credits[ $this->currency ]->amount = $credits[ $this->currency ]->amount->add( $commission['amount']->amount );
|
||||
$commission['referrer']->cm_credits = $credits;
|
||||
$commission['referrer']->save();
|
||||
|
||||
if ( !isset( $extra['commission'][ $commission['referrer']->member_id ] ) )
|
||||
{
|
||||
$extra['commission'][ $commission['referrer']->member_id ] = array( 'amount' => 0 );
|
||||
$extra['commission'][ $commission['referrer']->member_id ] = array( 'amount' => new \IPS\Math\Number('0') );
|
||||
}
|
||||
$extra['commission'][ $commission['referrer']->member_id ]['amount'] += $commission['amount']->amount;
|
||||
|
||||
$extra['commission'][ $commission['referrer']->member_id ]['amount'] = $extra['commission'][ $commission['referrer']->member_id ]['amount']->add( $commission['amount']->amount );
|
||||
|
||||
$commission['referrer']->log( 'comission', array(
|
||||
'type' => 'invoice',
|
||||
@@ -1557,12 +1832,16 @@ class _Invoice extends \IPS\Patterns\ActiveRecord
|
||||
$amounts = $record['amount'] ? json_decode( $record['amount'], TRUE ) : array();
|
||||
if ( !isset( $amounts[ $this->currency ] ) )
|
||||
{
|
||||
$amounts[ $this->currency ] = 0;
|
||||
$amounts[ $this->currency ] = new \IPS\Math\Number('0');
|
||||
}
|
||||
$amounts[ $this->currency ] += $commission['amount']->amount;
|
||||
elseif ( !( $amounts[ $this->currency ] instanceof \IPS\Math\Number ) )
|
||||
{
|
||||
$amounts[ $this->currency ] = new \IPS\Math\Number( number_format( $amounts[ $this->currency ], \IPS\nexus\Money::numberOfDecimalsForCurrency( $this->currency ), '.', '' ) );
|
||||
}
|
||||
$amounts[ $this->currency ] = $amounts[ $this->currency ]->add( $commission['amount']->amount );
|
||||
\IPS\Db::i()->update( 'nexus_referrals', array( 'amount' => json_encode( $amounts ) ), array( 'member_id=? AND referred_by=?', $this->member->member_id, $commission['referrer']->member_id ) );
|
||||
|
||||
\IPS\Email::buildFromTemplate( 'nexus', 'commissionEarned', array( $this, NULL, $commission['amount'] ) )
|
||||
\IPS\Email::buildFromTemplate( 'nexus', 'commissionEarned', array( $this, NULL, $commission['amount'] ), \IPS\Email::TYPE_TRANSACTIONAL )
|
||||
->send(
|
||||
$commission['referrer'],
|
||||
array_map(
|
||||
@@ -1576,6 +1855,18 @@ class _Invoice extends \IPS\Patterns\ActiveRecord
|
||||
);
|
||||
}
|
||||
|
||||
/* Change commission values back to numbers */
|
||||
if ( isset( $extra['commission'] ) )
|
||||
{
|
||||
foreach ( $extra['commission'] as $memberId => $data )
|
||||
{
|
||||
if ( $data['amount'] and $data['amount'] instanceof \IPS\Math\Number )
|
||||
{
|
||||
$extra['commission'][ $memberId ]['amount'] = (string) $data['amount'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Set parent IDs */
|
||||
foreach ( $setParentIds as $k => $v )
|
||||
{
|
||||
@@ -1629,7 +1920,7 @@ class _Invoice extends \IPS\Patterns\ActiveRecord
|
||||
}
|
||||
|
||||
/* Refuse any pending transactions */
|
||||
foreach ( $this->transactions( array( \IPS\nexus\Transaction::STATUS_PENDING, \IPS\nexus\Transaction::STATUS_WAITING, \IPS\nexus\Transaction::STATUS_HELD, \IPS\nexus\Transaction::STATUS_REVIEW ) ) as $transaction )
|
||||
foreach ( $this->transactions( array( \IPS\nexus\Transaction::STATUS_PENDING, \IPS\nexus\Transaction::STATUS_WAITING, \IPS\nexus\Transaction::STATUS_HELD, \IPS\nexus\Transaction::STATUS_REVIEW, \IPS\nexus\Transaction::STATUS_GATEWAY_PENDING ) ) as $transaction )
|
||||
{
|
||||
if ( $transaction->status === \IPS\nexus\Transaction::STATUS_PENDING )
|
||||
{
|
||||
@@ -1643,9 +1934,9 @@ class _Invoice extends \IPS\Patterns\ActiveRecord
|
||||
}
|
||||
catch ( \Exception $e ){}
|
||||
|
||||
$extra = $transaction->extra;
|
||||
$extra['history'][] = array( 's' => \IPS\nexus\Transaction::STATUS_REFUSED, 'on' => time(), 'note' => 'invoicePaid' );
|
||||
$transaction->extra = $extra;
|
||||
$textra = $transaction->extra;
|
||||
$textra['history'][] = array( 's' => \IPS\nexus\Transaction::STATUS_REFUSED, 'on' => time(), 'note' => 'invoicePaid' );
|
||||
$transaction->extra = $textra;
|
||||
$transaction->status = \IPS\nexus\Transaction::STATUS_REFUSED;
|
||||
$transaction->save();
|
||||
}
|
||||
@@ -1693,7 +1984,7 @@ class _Invoice extends \IPS\Patterns\ActiveRecord
|
||||
$recipientAmounts = $item->recipientAmounts();
|
||||
|
||||
$credits = $item->payTo->cm_credits;
|
||||
$credits[ $this->currency ]->amount -= $recipientAmounts['recipient_final']->amount;
|
||||
$credits[ $this->currency ]->amount = $credits[ $this->currency ]->amount->subtract( $recipientAmounts['recipient_final']->amount );
|
||||
$item->payTo->cm_credits = $credits;
|
||||
$item->payTo->save();
|
||||
|
||||
@@ -1707,7 +1998,7 @@ class _Invoice extends \IPS\Patterns\ActiveRecord
|
||||
'invoice_title' => $this->title
|
||||
), FALSE );
|
||||
|
||||
\IPS\Email::buildFromTemplate( 'nexus', 'commissionRevoked', array( $this, $item, $recipientAmounts['recipient_final'] ) )
|
||||
\IPS\Email::buildFromTemplate( 'nexus', 'commissionRevoked', array( $this, $item, $recipientAmounts['recipient_final'] ), \IPS\Email::TYPE_TRANSACTIONAL )
|
||||
->send(
|
||||
$item->payTo,
|
||||
array_map(
|
||||
@@ -1807,7 +2098,7 @@ class _Invoice extends \IPS\Patterns\ActiveRecord
|
||||
$message = \IPS\Member::loggedIn()->language()->addToStack('account_credit_remove', FALSE, array( 'sprintf' => array( $amount, $item->payTo->cm_name ) ) );
|
||||
|
||||
$credits = $item->payTo->cm_credits;
|
||||
if ( ( $credits[ $amount->currency ]->amount - $amount->amount ) < 0 )
|
||||
if ( !$credits[ $amount->currency ]->amount->subtract( $amount->amount )->isPositive() )
|
||||
{
|
||||
$return[] = array( 'message' => $message, 'warning' => \IPS\Member::loggedIn()->language()->addToStack('account_credit_remove_neg') );
|
||||
}
|
||||
@@ -1836,7 +2127,7 @@ class _Invoice extends \IPS\Patterns\ActiveRecord
|
||||
*/
|
||||
public function sendNotification()
|
||||
{
|
||||
\IPS\Email::buildFromTemplate( 'nexus', 'newInvoice', array( $this, $this->summary() ) )
|
||||
\IPS\Email::buildFromTemplate( 'nexus', 'newInvoice', array( $this, $this->summary() ), \IPS\Email::TYPE_TRANSACTIONAL )
|
||||
->send(
|
||||
$this->member,
|
||||
array_map(
|
||||
|
||||
Reference in new issue
Block a user