mirror of
				https://github.com/invoiceninja/invoiceninja.git
				synced 2025-11-04 08:37:32 -05:00 
			
		
		
		
	Tests for pro rata calculations
This commit is contained in:
		
							parent
							
								
									4901b31c47
								
							
						
					
					
						commit
						5e7a184118
					
				@ -123,6 +123,8 @@ class Subscription extends BaseModel
 | 
				
			|||||||
        'updated_at' => 'timestamp',
 | 
					        'updated_at' => 'timestamp',
 | 
				
			||||||
        'created_at' => 'timestamp',
 | 
					        'created_at' => 'timestamp',
 | 
				
			||||||
        'deleted_at' => 'timestamp',
 | 
					        'deleted_at' => 'timestamp',
 | 
				
			||||||
 | 
					        'trial_enabled' => 'boolean',
 | 
				
			||||||
 | 
					        'allow_plan_changes' => 'boolean',
 | 
				
			||||||
    ];
 | 
					    ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected $with = [
 | 
					    protected $with = [
 | 
				
			||||||
 | 
				
			|||||||
@ -58,29 +58,6 @@ class ProRata extends AbstractService
 | 
				
			|||||||
        return $this;
 | 
					        return $this;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Calculates the number of seconds
 | 
					 | 
				
			||||||
     * of the current interval that has been used.
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return self
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    private function checkProRataDuration(): self
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        $primary_invoice = $this->recurring_invoice
 | 
					 | 
				
			||||||
                                ->invoices()
 | 
					 | 
				
			||||||
                                ->where('is_deleted', 0)
 | 
					 | 
				
			||||||
                                ->where('is_proforma', 0)
 | 
					 | 
				
			||||||
                                ->orderBy('id', 'desc')
 | 
					 | 
				
			||||||
                                ->first();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $duration = Carbon::parse($primary_invoice->date)->startOfDay()->diffInSeconds(now());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->setProRataDuration(max(0, $duration));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return $this;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private function calculateProRataRatio(): self
 | 
					    private function calculateProRataRatio(): self
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if($this->pro_rata_duration < $this->subscription_interval_duration)
 | 
					        if($this->pro_rata_duration < $this->subscription_interval_duration)
 | 
				
			||||||
@ -92,8 +69,6 @@ class ProRata extends AbstractService
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    private function calculateSubscriptionIntervalDuration(): self
 | 
					    private function calculateSubscriptionIntervalDuration(): self
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if($this->getIsTrial())
 | 
					 | 
				
			||||||
            return $this->setSubscriptionIntervalDuration(0);
 | 
					 | 
				
			||||||
       
 | 
					       
 | 
				
			||||||
        $primary_invoice = $this->recurring_invoice
 | 
					        $primary_invoice = $this->recurring_invoice
 | 
				
			||||||
                                ->invoices()
 | 
					                                ->invoices()
 | 
				
			||||||
@ -113,52 +88,6 @@ class ProRata extends AbstractService
 | 
				
			|||||||
        return $this;
 | 
					        return $this;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Determines if this subscription
 | 
					 | 
				
			||||||
     * is eligible for a refund.
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return self
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    private function checkRefundPeriod(): self
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        if(!$this->recurring_invoice->subscription->refund_period || $this->recurring_invoice->subscription->refund_period === 0)
 | 
					 | 
				
			||||||
            return $this->setRefundable(false);
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
        $primary_invoice = $this->recurring_invoice
 | 
					 | 
				
			||||||
                                ->invoices()
 | 
					 | 
				
			||||||
                                ->where('is_deleted', 0)
 | 
					 | 
				
			||||||
                                ->where('is_proforma', 0)
 | 
					 | 
				
			||||||
                                ->orderBy('id', 'desc')
 | 
					 | 
				
			||||||
                                ->first();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if($primary_invoice &&
 | 
					 | 
				
			||||||
        $primary_invoice->status_id == Invoice::STATUS_PAID &&
 | 
					 | 
				
			||||||
        Carbon::parse($primary_invoice->date)->addSeconds($this->recurring_invoice->subscription->refund_period)->lte(now()->startOfDay()->addSeconds($primary_invoice->client->timezone_offset()))
 | 
					 | 
				
			||||||
        ){
 | 
					 | 
				
			||||||
            return $this->setRefundable(true);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return $this->setRefundable(false);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Gathers any unpaid invoices for this subscription.
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return self
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    private function checkUnpaidInvoices(): self
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->unpaid_invoices = $this->recurring_invoice
 | 
					 | 
				
			||||||
                                ->invoices()
 | 
					 | 
				
			||||||
                                ->where('is_deleted', 0)
 | 
					 | 
				
			||||||
                                ->where('is_proforma', 0)
 | 
					 | 
				
			||||||
                                ->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL])
 | 
					 | 
				
			||||||
                                ->where('balance', '>', 0)
 | 
					 | 
				
			||||||
                                ->get();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return $this;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    private function setProRataRatio(int $ratio): self
 | 
					    private function setProRataRatio(int $ratio): self
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -192,117 +121,6 @@ class ProRata extends AbstractService
 | 
				
			|||||||
        return $this;
 | 
					        return $this;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * setRefundable
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @param  bool $refundable
 | 
					 | 
				
			||||||
     * @return self
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    private function setRefundable(bool $refundable): self
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->refundable = $refundable;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return $this;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Determines if this users is in their trial period
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return self
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    private function isInTrialPeriod(): self
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if(!$this->recurring_invoice->subscription->trial_enabled) 
 | 
					 | 
				
			||||||
            return $this->setIsTrial(false);
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
        $primary_invoice = $this->recurring_invoice
 | 
					 | 
				
			||||||
                            ->invoices()
 | 
					 | 
				
			||||||
                            ->where('is_deleted', 0)
 | 
					 | 
				
			||||||
                            ->where('is_proforma', 0)
 | 
					 | 
				
			||||||
                            ->orderBy('id', 'asc')
 | 
					 | 
				
			||||||
                            ->first();
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
        if($primary_invoice && Carbon::parse($primary_invoice->date)->addSeconds($this->recurring_invoice->subscription->trial_duration)->lte(now()->startOfDay()->addSeconds($primary_invoice->client->timezone_offset())))
 | 
					 | 
				
			||||||
            return $this->setIsTrial(true);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->setIsTrial(false);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return $this;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Sets the is_trial flag
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @param  bool $is_trial
 | 
					 | 
				
			||||||
     * @return self
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    private function setIsTrial(bool $is_trial): self
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->is_trial = $is_trial;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return $this;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Getter for unpaid invoices
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return \Illuminate\Database\Eloquent\Collection | null
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function getUnpaidInvoices(): ?\Illuminate\Database\Eloquent\Collection
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        return $this->unpaid_invoices;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Gets the is_trial flag
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return bool
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function getIsTrial(): bool
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        return $this->is_trial;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Getter for refundable flag
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return bool
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function getRefundable(): bool
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        return $this->refundable;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * The number of seconds used in the current duration
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return int
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function getProRataDuration(): int
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        return $this->pro_rata_duration;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * The total number of seconds in this subscription interval
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return int
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function getSubscriptionIntervalDuration(): int
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        return $this->subscription_interval_duration;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Returns the pro rata ratio to be applied to any credit.
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return int
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function getProRataRatio(): int
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        return $this->pro_rata_ratio;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -1352,7 +1352,7 @@ class SubscriptionService
 | 
				
			|||||||
     *
 | 
					     *
 | 
				
			||||||
     * @return int Number of days
 | 
					     * @return int Number of days
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    private function getDaysInFrequency(): int
 | 
					    public function getDaysInFrequency(): int
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        switch ($this->subscription->frequency_id) {
 | 
					        switch ($this->subscription->frequency_id) {
 | 
				
			||||||
            case RecurringInvoice::FREQUENCY_DAILY:
 | 
					            case RecurringInvoice::FREQUENCY_DAILY:
 | 
				
			||||||
 | 
				
			|||||||
@ -43,8 +43,15 @@ class SubscriptionStatus extends AbstractService
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        //calculate how much used.
 | 
					        //calculate how much used.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $primary_invoice = $this->recurring_invoice
 | 
					        $subscription_interval_end_date = Carbon::parse($this->recurring_invoice->next_send_date_client);
 | 
				
			||||||
                                ->invoices()
 | 
					        $subscription_interval_start_date = $subscription_interval_end_date->copy()->subDays($this->recurring_invoice->subscription->service()->getDaysInFrequency())->subDay();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $primary_invoice =Invoice::query()
 | 
				
			||||||
 | 
					                                ->where('company_id', $this->recurring_invoice->company_id)
 | 
				
			||||||
 | 
					                                ->where('client_id', $this->recurring_invoice->client_id)
 | 
				
			||||||
 | 
					                                ->where('recurring_id', $this->recurring_invoice->id)
 | 
				
			||||||
 | 
					                                ->whereIn('status_id', [Invoice::STATUS_PAID])
 | 
				
			||||||
 | 
					                                ->whereBetween('date', [$subscription_interval_start_date, $subscription_interval_end_date])
 | 
				
			||||||
                                ->where('is_deleted', 0)
 | 
					                                ->where('is_deleted', 0)
 | 
				
			||||||
                                ->where('is_proforma', 0)
 | 
					                                ->where('is_proforma', 0)
 | 
				
			||||||
                                ->orderBy('id', 'desc')
 | 
					                                ->orderBy('id', 'desc')
 | 
				
			||||||
@ -54,12 +61,10 @@ class SubscriptionStatus extends AbstractService
 | 
				
			|||||||
            return 0;
 | 
					            return 0;
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        $subscription_start_date = Carbon::parse($primary_invoice->date)->startOfDay();
 | 
					        $subscription_start_date = Carbon::parse($primary_invoice->date)->startOfDay();
 | 
				
			||||||
        $subscription_interval_end_date = Carbon::parse($this->recurring_invoice->next_send_date_client);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $seconds_of_subscription_used = $subscription_start_date->diffInDays(now());
 | 
					        $days_of_subscription_used = $subscription_start_date->copy()->diffInDays(now());
 | 
				
			||||||
        $total_seconds_in_subscription_interval = $subscription_start_date->diffInDays($subscription_interval_end_date);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $seconds_of_subscription_used / $total_seconds_in_subscription_interval;
 | 
					        return $days_of_subscription_used / $this->recurring_invoice->subscription->service()->getDaysInFrequency();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -71,11 +76,13 @@ class SubscriptionStatus extends AbstractService
 | 
				
			|||||||
    private function checkInGoodStanding(): self
 | 
					    private function checkInGoodStanding(): self
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->is_in_good_standing = $this->recurring_invoice
 | 
					        $this->is_in_good_standing = Invoice::query()
 | 
				
			||||||
                                     ->invoices()
 | 
					                                     ->where('company_id', $this->recurring_invoice->company_id)
 | 
				
			||||||
 | 
					                                     ->where('client_id', $this->recurring_invoice->client_id)
 | 
				
			||||||
 | 
					                                     ->where('recurring_id', $this->recurring_invoice->id)
 | 
				
			||||||
                                     ->where('is_deleted', 0)
 | 
					                                     ->where('is_deleted', 0)
 | 
				
			||||||
                                     ->where('is_proform', 0)
 | 
					                                     ->where('is_proforma', 0)
 | 
				
			||||||
                                     ->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PAID])
 | 
					                                     ->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL])
 | 
				
			||||||
                                     ->where('balance', '>', 0)
 | 
					                                     ->where('balance', '>', 0)
 | 
				
			||||||
                                     ->doesntExist();
 | 
					                                     ->doesntExist();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -92,7 +99,7 @@ class SubscriptionStatus extends AbstractService
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(!$this->subscription->trial_enabled)
 | 
					        if(!$this->subscription->trial_enabled)
 | 
				
			||||||
            $this->setIsTrial(false);
 | 
					            return $this->setIsTrial(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $primary_invoice = $this->recurring_invoice
 | 
					        $primary_invoice = $this->recurring_invoice
 | 
				
			||||||
                            ->invoices()
 | 
					                            ->invoices()
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										253
									
								
								tests/Feature/PaymentLink/PaymentLinkTest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										253
									
								
								tests/Feature/PaymentLink/PaymentLinkTest.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,253 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://www.elastic.co/licensing/elastic-license
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Tests\Feature;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Tests\TestCase;
 | 
				
			||||||
 | 
					use App\Models\Invoice;
 | 
				
			||||||
 | 
					use Tests\MockUnitData;
 | 
				
			||||||
 | 
					use App\Models\Subscription;
 | 
				
			||||||
 | 
					use Illuminate\Support\Carbon;
 | 
				
			||||||
 | 
					use App\Helpers\Invoice\ProRata;
 | 
				
			||||||
 | 
					use App\Models\RecurringInvoice;
 | 
				
			||||||
 | 
					use App\Factory\InvoiceItemFactory;
 | 
				
			||||||
 | 
					use App\Helpers\Subscription\SubscriptionCalculator;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @test
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class PaymentLinkTest extends TestCase
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    use MockUnitData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected function setUp(): void
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        parent::setUp();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->makeTestData();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function testCalcUpgradePrice()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $subscription = Subscription::factory()->create([
 | 
				
			||||||
 | 
					            'company_id' => $this->company->id,
 | 
				
			||||||
 | 
					            'user_id' => $this->user->id,
 | 
				
			||||||
 | 
					            'price' => 10,
 | 
				
			||||||
 | 
					        ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $target = Subscription::factory()->create([
 | 
				
			||||||
 | 
					            'company_id' => $this->company->id,
 | 
				
			||||||
 | 
					            'user_id' => $this->user->id,
 | 
				
			||||||
 | 
					            'price' => 20,
 | 
				
			||||||
 | 
					        ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $recurring_invoice = RecurringInvoice::factory()->create([
 | 
				
			||||||
 | 
					            'line_items' => $this->buildLineItems(),
 | 
				
			||||||
 | 
					            'company_id' => $this->company->id,
 | 
				
			||||||
 | 
					            'user_id' => $this->user->id,
 | 
				
			||||||
 | 
					            'client_id' => $this->client->id,
 | 
				
			||||||
 | 
					            'tax_rate1' => 0,
 | 
				
			||||||
 | 
					            'tax_name1' => '',
 | 
				
			||||||
 | 
					            'tax_rate2' => 0,
 | 
				
			||||||
 | 
					            'tax_name2' => '',
 | 
				
			||||||
 | 
					            'tax_rate3' => 0,
 | 
				
			||||||
 | 
					            'tax_name3' => '',
 | 
				
			||||||
 | 
					            'discount' => 0,
 | 
				
			||||||
 | 
					            'subscription_id' => $subscription->id,
 | 
				
			||||||
 | 
					            'date' => now()->subWeeks(2),
 | 
				
			||||||
 | 
					            'next_send_date_client' => now(),
 | 
				
			||||||
 | 
					        ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $invoice = Invoice::factory()->create([
 | 
				
			||||||
 | 
					            'line_items' => $this->buildLineItems(),
 | 
				
			||||||
 | 
					            'company_id' => $this->company->id,
 | 
				
			||||||
 | 
					            'user_id' => $this->user->id,
 | 
				
			||||||
 | 
					            'client_id' => $this->client->id,
 | 
				
			||||||
 | 
					            'tax_rate1' => 0,
 | 
				
			||||||
 | 
					            'tax_name1' => '',
 | 
				
			||||||
 | 
					            'tax_rate2' => 0,
 | 
				
			||||||
 | 
					            'tax_name2' => '',
 | 
				
			||||||
 | 
					            'tax_rate3' => 0,
 | 
				
			||||||
 | 
					            'tax_name3' => '',
 | 
				
			||||||
 | 
					            'discount' => 0,
 | 
				
			||||||
 | 
					            'subscription_id' => $subscription->id,
 | 
				
			||||||
 | 
					            'date' => now()->subWeeks(2),
 | 
				
			||||||
 | 
					            'recurring_id' => $recurring_invoice->id,
 | 
				
			||||||
 | 
					        ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $recurring_invoice = $recurring_invoice->calc()->getInvoice();
 | 
				
			||||||
 | 
					        $invoice = $invoice->calc()->getInvoice();
 | 
				
			||||||
 | 
					        $this->assertEquals(10, $invoice->amount);
 | 
				
			||||||
 | 
					        $invoice->service()->markSent()->save();
 | 
				
			||||||
 | 
					        $this->assertEquals(10, $invoice->amount);
 | 
				
			||||||
 | 
					        $this->assertEquals(10, $invoice->balance);
 | 
				
			||||||
 | 
					        $invoice = $invoice->service()->markPaid()->save();
 | 
				
			||||||
 | 
					        $this->assertEquals(0, $invoice->balance);
 | 
				
			||||||
 | 
					        $this->assertEquals(10, $invoice->paid_to_date);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $status = $recurring_invoice
 | 
				
			||||||
 | 
					                    ->subscription
 | 
				
			||||||
 | 
					                    ->status($recurring_invoice);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->assertFalse($status->is_trial);
 | 
				
			||||||
 | 
					        $this->assertFalse($status->is_refundable);
 | 
				
			||||||
 | 
					        $this->assertTrue($status->is_in_good_standing);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $days = $recurring_invoice->subscription->service()->getDaysInFrequency();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $ratio = (14 / $days);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->assertEquals($ratio, $status->getProRataRatio());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $price = $target->link_service()->calculateUpgradePriceV2($recurring_invoice, $target);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $refund = round($invoice->paid_to_date*$ratio,2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->assertEquals(($target->price - $refund), $price);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        // $this->assertEquals($target->price-$refund, $upgrade_price);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // $sub_calculator = new SubscriptionCalculator($target->fresh(), $invoice->fresh());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // $this->assertFalse($sub_calculator->isPaidUp());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // $invoice = $invoice->service()->markPaid()->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // $this->assertTrue($sub_calculator->isPaidUp());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // $this->assertEquals(10, $invoice->amount);
 | 
				
			||||||
 | 
					        // $this->assertEquals(0, $invoice->balance);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // $pro_rata = new ProRata();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // $refund = $pro_rata->refund($invoice->amount, Carbon::parse('2021-01-01'), Carbon::parse('2021-01-06'), $subscription->frequency_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // // $this->assertEquals(1.61, $refund);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // $pro_rata = new ProRata();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // $upgrade = $pro_rata->charge($target->price, Carbon::parse('2021-01-01'), Carbon::parse('2021-01-06'), $subscription->frequency_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // $this->assertEquals(3.23, $upgrade);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // public function testProrataDiscountRatioPercentage()
 | 
				
			||||||
 | 
					    // {
 | 
				
			||||||
 | 
					    //     $subscription = Subscription::factory()->create([
 | 
				
			||||||
 | 
					    //         'company_id' => $this->company->id,
 | 
				
			||||||
 | 
					    //         'user_id' => $this->user->id,
 | 
				
			||||||
 | 
					    //         'price' => 100,
 | 
				
			||||||
 | 
					    //     ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //     $item = InvoiceItemFactory::create();
 | 
				
			||||||
 | 
					    //     $item->quantity = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //     $item->cost = 100;
 | 
				
			||||||
 | 
					    //     $item->product_key = 'xyz';
 | 
				
			||||||
 | 
					    //     $item->notes = 'test';
 | 
				
			||||||
 | 
					    //     $item->custom_value1 = 'x';
 | 
				
			||||||
 | 
					    //     $item->custom_value2 = 'x';
 | 
				
			||||||
 | 
					    //     $item->custom_value3 = 'x';
 | 
				
			||||||
 | 
					    //     $item->custom_value4 = 'x';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //     $line_items[] = $item;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //     $invoice = Invoice::factory()->create([
 | 
				
			||||||
 | 
					    //         'line_items' => $line_items,
 | 
				
			||||||
 | 
					    //         'company_id' => $this->company->id,
 | 
				
			||||||
 | 
					    //         'user_id' => $this->user->id,
 | 
				
			||||||
 | 
					    //         'client_id' => $this->client->id,
 | 
				
			||||||
 | 
					    //         'tax_rate1' => 0,
 | 
				
			||||||
 | 
					    //         'tax_name1' => '',
 | 
				
			||||||
 | 
					    //         'tax_rate2' => 0,
 | 
				
			||||||
 | 
					    //         'tax_name2' => '',
 | 
				
			||||||
 | 
					    //         'tax_rate3' => 0,
 | 
				
			||||||
 | 
					    //         'tax_name3' => '',
 | 
				
			||||||
 | 
					    //         'discount' => 0,
 | 
				
			||||||
 | 
					    //         'subscription_id' => $subscription->id,
 | 
				
			||||||
 | 
					    //         'date' => '2021-01-01',
 | 
				
			||||||
 | 
					    //         'discount' => 10,
 | 
				
			||||||
 | 
					    //         'is_amount_discount' => false,
 | 
				
			||||||
 | 
					    //         'status_id' => 1,
 | 
				
			||||||
 | 
					    //     ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //     $invoice = $invoice->calc()->getInvoice();
 | 
				
			||||||
 | 
					    //     $this->assertEquals(90, $invoice->amount);
 | 
				
			||||||
 | 
					    //     $this->assertEquals(0, $invoice->balance);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //     $invoice->service()->markSent()->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //     $this->assertEquals(90, $invoice->amount);
 | 
				
			||||||
 | 
					    //     $this->assertEquals(90, $invoice->balance);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //     $ratio = $subscription->service()->calculateDiscountRatio($invoice);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //     $this->assertEquals(.1, $ratio);
 | 
				
			||||||
 | 
					    // }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // public function testProrataDiscountRatioAmount()
 | 
				
			||||||
 | 
					    // {
 | 
				
			||||||
 | 
					    //     $subscription = Subscription::factory()->create([
 | 
				
			||||||
 | 
					    //         'company_id' => $this->company->id,
 | 
				
			||||||
 | 
					    //         'user_id' => $this->user->id,
 | 
				
			||||||
 | 
					    //         'price' => 100,
 | 
				
			||||||
 | 
					    //     ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //     $item = InvoiceItemFactory::create();
 | 
				
			||||||
 | 
					    //     $item->quantity = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //     $item->cost = 100;
 | 
				
			||||||
 | 
					    //     $item->product_key = 'xyz';
 | 
				
			||||||
 | 
					    //     $item->notes = 'test';
 | 
				
			||||||
 | 
					    //     $item->custom_value1 = 'x';
 | 
				
			||||||
 | 
					    //     $item->custom_value2 = 'x';
 | 
				
			||||||
 | 
					    //     $item->custom_value3 = 'x';
 | 
				
			||||||
 | 
					    //     $item->custom_value4 = 'x';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //     $line_items[] = $item;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //     $invoice = Invoice::factory()->create([
 | 
				
			||||||
 | 
					    //         'line_items' => $line_items,
 | 
				
			||||||
 | 
					    //         'company_id' => $this->company->id,
 | 
				
			||||||
 | 
					    //         'user_id' => $this->user->id,
 | 
				
			||||||
 | 
					    //         'client_id' => $this->client->id,
 | 
				
			||||||
 | 
					    //         'tax_rate1' => 0,
 | 
				
			||||||
 | 
					    //         'tax_name1' => '',
 | 
				
			||||||
 | 
					    //         'tax_rate2' => 0,
 | 
				
			||||||
 | 
					    //         'tax_name2' => '',
 | 
				
			||||||
 | 
					    //         'tax_rate3' => 0,
 | 
				
			||||||
 | 
					    //         'tax_name3' => '',
 | 
				
			||||||
 | 
					    //         'discount' => 0,
 | 
				
			||||||
 | 
					    //         'subscription_id' => $subscription->id,
 | 
				
			||||||
 | 
					    //         'date' => '2021-01-01',
 | 
				
			||||||
 | 
					    //         'discount' => 20,
 | 
				
			||||||
 | 
					    //         'is_amount_discount' => true,
 | 
				
			||||||
 | 
					    //         'status_id' => 1,
 | 
				
			||||||
 | 
					    //     ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //     $invoice = $invoice->calc()->getInvoice();
 | 
				
			||||||
 | 
					    //     $this->assertEquals(80, $invoice->amount);
 | 
				
			||||||
 | 
					    //     $this->assertEquals(0, $invoice->balance);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //     $invoice->service()->markSent()->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //     $this->assertEquals(80, $invoice->amount);
 | 
				
			||||||
 | 
					    //     $this->assertEquals(80, $invoice->balance);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //     $ratio = $subscription->service()->calculateDiscountRatio($invoice);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //     $this->assertEquals(.2, $ratio);
 | 
				
			||||||
 | 
					    // }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user